diff options
author | Thomas White <taw@bitwiz.org.uk> | 2012-10-15 00:17:13 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2012-10-15 00:17:13 +0200 |
commit | 5e3ff44338005f0b9783993e67c6395dcf5c9768 (patch) | |
tree | 85ec06404170adf3c3d9f8fe769a7d0316c46d88 | |
parent | 350c51a006edba2a46e7f17bf05098b398a4cb80 (diff) |
Rendering and redraw pipeline
-rw-r--r-- | src/mainwindow.c | 128 | ||||
-rw-r--r-- | src/presentation.c | 45 | ||||
-rw-r--r-- | src/presentation.h | 9 | ||||
-rw-r--r-- | src/render.c | 5 | ||||
-rw-r--r-- | src/render.h | 5 |
5 files changed, 156 insertions, 36 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c index 1a5f7d9..a5fdf8b 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -38,32 +38,27 @@ #include "frame.h" -static void redraw_slide(struct slide *s) +static void rerender_slide(struct presentation *p, PangoContext *pc) { int w, h; + struct slide *s = p->cur_edit_slide; if ( s->rendered_thumb != NULL ) { cairo_surface_destroy(s->rendered_thumb); } - w = s->parent->thumb_slide_width; - h = (s->parent->slide_height/s->parent->slide_width) * w; - s->rendered_thumb = render_slide(s, w, h); - /* FIXME: Request redraw for slide sorter if open */ - - /* Is this slide currently open in the editor? */ - if ( s == s->parent->cur_edit_slide ) { - - if ( s->rendered_edit != NULL ) { - cairo_surface_destroy(s->rendered_edit); - } - - w = s->parent->edit_slide_width; - h = (s->parent->slide_height/s->parent->slide_width) * w; - s->rendered_edit = render_slide(s, w, h); + w = p->thumb_slide_width; + h = (p->slide_height/p->slide_width) * w; + s->rendered_thumb = render_slide(s, w, h, pc); + if ( s->rendered_edit != NULL ) { + cairo_surface_destroy(s->rendered_edit); } + w = p->edit_slide_width; + h = (p->slide_height/p->slide_width) * w; + s->rendered_edit = render_slide(s, w, h, pc); +printf("rendered %p -> %p\n", s, s->rendered_edit); /* Is this slide currently being displayed on the projector? */ if ( s == s->parent->cur_proj_slide ) { @@ -73,12 +68,23 @@ static void redraw_slide(struct slide *s) w = s->parent->proj_slide_width; h = (s->parent->slide_height/s->parent->slide_width) * w; - s->rendered_proj = render_slide(s, w, h); + s->rendered_proj = render_slide(s, w, h, pc); } } +static void redraw(struct presentation *p) +{ + gint w, h; + + w = gtk_widget_get_allocated_width(GTK_WIDGET(p->drawingarea)); + h = gtk_widget_get_allocated_height(GTK_WIDGET(p->drawingarea)); + + gtk_widget_queue_draw_area(p->drawingarea, 0, 0, w, h); +} + + static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget, GtkContainer *container) { @@ -167,7 +173,7 @@ static gint open_response_sig(GtkWidget *d, gint response, show_error(p, "Failed to open presentation"); } p->cur_edit_slide = p->slides[0]; - redraw_slide(p->cur_edit_slide); + rerender_slide(p, p->pc); update_toolbar(p); } else { @@ -428,7 +434,7 @@ void notify_slide_changed(struct presentation *p, struct slide *np) /* FIXME: Free old rendered stuff */ update_toolbar(p); - redraw_slide(p->cur_edit_slide); + redraw(p); //if ( p->notes != NULL ) { // notify_notes_slide_changed(p, np); @@ -527,6 +533,11 @@ static gint add_furniture(GtkWidget *widget, struct presentation *p) fr = add_subframe(p->cur_edit_slide->top); fr->style = sty; + set_edit(p, p->cur_edit_slide); + fr->sc = "Hello"; + layout_frame(p->cur_edit_slide->top, p->slide_width, p->slide_height, + p->pc); + set_selection(p, fr); return 0; } @@ -695,6 +706,45 @@ static gint close_sig(GtkWidget *window, struct presentation *p) } +static void draw_editing_box(cairo_t *cr, struct frame *fr) +{ + const double dash[] = {2.0, 2.0}; + double xmin, ymin, width, height; + + xmin = fr->offs_x; + ymin = fr->offs_y; + width = fr->w; + height = fr->h; + + printf("box %f %f %f %f\n", xmin, ymin, width, height); + + cairo_new_path(cr); + cairo_rectangle(cr, xmin-5.0, ymin-5.0, width+10.0, height+10.0); + cairo_set_source_rgb(cr, 0.0, 0.69, 1.0); + cairo_set_line_width(cr, 0.5); + cairo_stroke(cr); + + cairo_new_path(cr); + cairo_rectangle(cr, xmin, ymin, width, height); + cairo_set_dash(cr, dash, 2, 0.0); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_set_line_width(cr, 0.1); + cairo_stroke(cr); + + cairo_set_dash(cr, NULL, 0, 0.0); +} + + +static void draw_overlay(cairo_t *cr, struct presentation *p) +{ + int i; + + for ( i=0; i<p->n_selection; i++ ) { + draw_editing_box(cr, p->selection[i]); + } +} + + static gboolean draw_sig(GtkWidget *da, cairo_t *cr, struct presentation *p) { @@ -719,15 +769,19 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, p->border_offs_x = xoff; p->border_offs_y = yoff; /* Draw the slide from the cache */ - cairo_rectangle(cr, xoff, yoff, p->slide_width, p->slide_height); - cairo_set_source_surface(cr, p->cur_edit_slide->rendered_edit, - xoff, yoff); - cairo_fill(cr); + if ( p->cur_edit_slide->rendered_edit != NULL ) { + cairo_rectangle(cr, xoff, yoff, p->slide_width, p->slide_height); + cairo_set_source_surface(cr, p->cur_edit_slide->rendered_edit, + xoff, yoff); + cairo_fill(cr); + fprintf(stderr, "Drew slide %p.\n", + p->cur_edit_slide->rendered_edit); + } else { + fprintf(stderr, "Current slide not rendered yet!\n"); + } cairo_translate(cr, xoff, yoff); - - /* FIXME */ - //draw_overlay(cr, p); + draw_overlay(cr, p); return FALSE; } @@ -750,6 +804,16 @@ void update_titlebar(struct presentation *p) } +static gint realise_sig(GtkWidget *da, struct presentation *p) +{ + /* FIXME: Can do this "properly" by setting up a separate font map */ + p->pc = gtk_widget_get_pango_context(da); + printf("got context %p\n", p->pc); + rerender_slide(p, p->pc); + return FALSE; +} + + int open_mainwindow(struct presentation *p) { GtkWidget *window; @@ -771,6 +835,10 @@ int open_mainwindow(struct presentation *p) vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(window), vbox); + p->edit_slide_width = 1024; + p->proj_slide_width = 2048; + p->thumb_slide_width = 320; /* FIXME: Completely made up */ + p->drawingarea = gtk_drawing_area_new(); sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), @@ -784,6 +852,8 @@ int open_mainwindow(struct presentation *p) add_menu_bar(p, vbox); gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(p->drawingarea), "realize", + G_CALLBACK(realise_sig), p); gtk_widget_set_can_focus(GTK_WIDGET(p->drawingarea), TRUE); gtk_widget_add_events(GTK_WIDGET(p->drawingarea), @@ -813,11 +883,5 @@ int open_mainwindow(struct presentation *p) gtk_widget_show_all(window); - p->edit_slide_width = 1024; - p->proj_slide_width = 2048; - p->thumb_slide_width = 320; /* FIXME: Completely made up */ - - redraw_slide(p->cur_edit_slide); - return 0; } diff --git a/src/presentation.c b/src/presentation.c index 1b3e00c..74f9c3c 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -111,6 +111,9 @@ struct slide *new_slide() new->rendered_proj = NULL; new->rendered_thumb = NULL; + new->top = frame_new(); + /* FIXME: Set zero margins etc on top level frame */ + new->notes = strdup(""); return new; @@ -193,6 +196,17 @@ int slide_number(struct presentation *p, struct slide *s) } +static int alloc_selection(struct presentation *p) +{ + struct frame **new_selection; + new_selection = realloc(p->selection, + p->max_selection*sizeof(struct frame *)); + if ( new_selection == NULL ) return 1; + p->selection = new_selection; + return 0; +} + + struct presentation *new_presentation() { struct presentation *new; @@ -228,6 +242,11 @@ struct presentation *new_presentation() new->n_menu_rebuild = 0; new->menu_rebuild_list = NULL; + new->selection = NULL; + new->n_selection = 0; + new->max_selection = 64; + if ( alloc_selection(new) ) return NULL; + return new; } @@ -417,3 +436,29 @@ int load_presentation(struct presentation *p, const char *filename) return 0; } + +void set_edit(struct presentation *p, struct slide *s) +{ + p->cur_edit_slide = s; +} + + +void set_selection(struct presentation *p, struct frame *fr) +{ + p->selection[0] = fr; + p->n_selection = 1; +} + + +void add_selection(struct presentation *p, struct frame *fr) +{ + if ( p->n_selection == p->max_selection ) { + p->max_selection += 64; + if ( alloc_selection(p) ) { + fprintf(stderr, "Not enough memory for selection.\n"); + return; + } + } + + p->selection[p->n_selection++] = fr; +} diff --git a/src/presentation.h b/src/presentation.h index c237aac..415147f 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -66,6 +66,7 @@ struct presentation GtkIMContext *im_context; GtkWidget **menu_rebuild_list; int n_menu_rebuild; + PangoContext *pc; /* Pointers to the current "editing" and "projection" slides */ struct slide *cur_edit_slide; @@ -73,6 +74,11 @@ struct presentation struct slide *cur_notes_slide; int slideshow_linked; + /* Pointers to the frame currently being edited */ + struct frame **selection; + int n_selection; + int max_selection; + /* This is the "native" size of the slide. It only exists to give * font size some meaning in the context of a somewhat arbitrary DPI */ double slide_width; @@ -116,6 +122,9 @@ extern int slide_number(struct presentation *p, struct slide *s); extern int load_presentation(struct presentation *p, const char *filename); extern int save_presentation(struct presentation *p, const char *filename); +extern void set_edit(struct presentation *p, struct slide *s); +extern void set_selection(struct presentation *p, struct frame *fr); +extern void add_selection(struct presentation *p, struct frame *fr); #define UNUSED __attribute__((unused)) diff --git a/src/render.c b/src/render.c index 8738b4b..4a0c819 100644 --- a/src/render.c +++ b/src/render.c @@ -120,7 +120,7 @@ int render_frame(struct frame *fr, cairo_t *cr, PangoContext *pc) } -cairo_surface_t *render_slide(struct slide *s, int w, int h) +cairo_surface_t *render_slide(struct slide *s, int w, int h, PangoContext *pc) { cairo_surface_t *surf; cairo_t *cr; @@ -145,7 +145,8 @@ cairo_surface_t *render_slide(struct slide *s, int w, int h) cairo_font_options_set_antialias(fopts, CAIRO_ANTIALIAS_SUBPIXEL); cairo_set_font_options(cr, fopts); - //render_frame(s->top, cr, NULL); /* FIXME: pc */ + printf("rendered to %p %ix%i\n", surf, w, h); + render_frame(s->top, cr, pc); cairo_font_options_destroy(fopts); cairo_destroy(cr); diff --git a/src/render.h b/src/render.h index 2fbaa22..4b5b607 100644 --- a/src/render.h +++ b/src/render.h @@ -29,11 +29,12 @@ #include "presentation.h" -extern cairo_surface_t *render_slide(struct slide *s, int w, int h); - extern int render_sc(const char *sc, cairo_t *cr, double w, double h, PangoContext *pc); extern int render_frame(struct frame *fr, cairo_t *cr, PangoContext *pc); +extern cairo_surface_t *render_slide(struct slide *s, int w, int h, + PangoContext *pc); + #endif /* RENDER_H */ |