aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2012-10-15 00:17:13 +0200
committerThomas White <taw@bitwiz.org.uk>2012-10-15 00:17:13 +0200
commit5e3ff44338005f0b9783993e67c6395dcf5c9768 (patch)
tree85ec06404170adf3c3d9f8fe769a7d0316c46d88
parent350c51a006edba2a46e7f17bf05098b398a4cb80 (diff)
Rendering and redraw pipeline
-rw-r--r--src/mainwindow.c128
-rw-r--r--src/presentation.c45
-rw-r--r--src/presentation.h9
-rw-r--r--src/render.c5
-rw-r--r--src/render.h5
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 */