diff options
-rw-r--r-- | src/layout.c | 66 | ||||
-rw-r--r-- | src/layout.h | 22 | ||||
-rw-r--r-- | src/presentation.h | 6 | ||||
-rw-r--r-- | src/render.c | 34 | ||||
-rw-r--r-- | src/storycode.c | 2 | ||||
-rw-r--r-- | tests/render_test.c | 2 | ||||
-rw-r--r-- | tests/render_test_sc1.c | 2 |
7 files changed, 99 insertions, 35 deletions
diff --git a/src/layout.c b/src/layout.c index a257112..ae7a5e8 100644 --- a/src/layout.c +++ b/src/layout.c @@ -42,7 +42,8 @@ static void copy_lop_from_style(struct frame *fr, struct style *style) } -static void layout_subframe(struct frame *fr, double w, double h) +static void layout_subframe(struct frame *fr, double w, double h, + PangoContext *pc) { int i; @@ -53,6 +54,8 @@ static void layout_subframe(struct frame *fr, double w, double h) struct frame *child; double child_w, child_h; + double offs_x, offs_y; + PangoFontDescription *fontdesc; child = fr->rendering_order[i]; @@ -60,21 +63,72 @@ static void layout_subframe(struct frame *fr, double w, double h) copy_lop_from_style(child, child->style); - child->offs_x = child->lop.margin_l + fr->lop.pad_l; - child->offs_y = child->lop.margin_t + fr->lop.pad_r; + /* First, calculate the region inside which the child frame must + * fit, having excluded the padding of its parent and its own + * margins. */ + offs_x = child->lop.margin_l + fr->lop.pad_l; + offs_y = child->lop.margin_t + fr->lop.pad_r; child_w = w - (child->lop.margin_l + child->lop.margin_r); child_h = h - (child->lop.margin_t + child->lop.margin_b); child_w -= (fr->lop.pad_l + fr->lop.pad_r); child_h -= (fr->lop.pad_t + fr->lop.pad_b); - layout_subframe(child, child_w, child_h); + /* Put the contents inside, and see how much space is needed */ + if ( child->pl == NULL ) { + child->pl = pango_layout_new(pc); + pango_layout_set_justify(child->pl, 1); + pango_layout_set_ellipsize(child->pl, 1); + } + pango_layout_set_width(child->pl, child_w*PANGO_SCALE); + pango_layout_set_height(child->pl, child_h*PANGO_SCALE); + + /* FIXME: Check for Level 1 markup e.g. image */ + pango_layout_set_text(child->pl, child->sc, -1); + + fontdesc = pango_font_description_from_string("Sans 12"); + pango_layout_set_font_description(child->pl, fontdesc); + pango_font_description_free(fontdesc); + + /* Now, apply the minimum size if given */ + if ( child->lop.min_w > 0.0 ) { + if ( child_w < child->lop.min_w ) { + child_w = child->lop.min_w; + } + } + if ( child->lop.min_h > 0.0 ) { + if ( child_h < child->lop.min_h ) { + child_h = child->lop.min_h; + } + } + + /* Finally, apply the gravity */ + switch ( child->lop.grav ) + { + case DIR_NONE : + break; + + case DIR_UL : + case DIR_U : + case DIR_UR : + case DIR_R : + case DIR_DR : + case DIR_D : + case DIR_DL : + case DIR_L : + break; + } + + /* Record values and recurse */ + child->offs_x = offs_x; + child->offs_y = offs_y; + layout_subframe(child, child_w, child_h, pc); } } -void layout_frame(struct frame *fr, double w, double h) +void layout_frame(struct frame *fr, double w, double h, PangoContext *pc) { copy_lop_from_style(fr, fr->style); - layout_subframe(fr, w, h); + layout_subframe(fr, w, h, pc); } diff --git a/src/layout.h b/src/layout.h index e389d67..b35a532 100644 --- a/src/layout.h +++ b/src/layout.h @@ -28,6 +28,20 @@ #endif +typedef enum +{ + DIR_NONE, + DIR_UL, + DIR_U, + DIR_UR, + DIR_R, + DIR_DR, + DIR_D, + DIR_DL, + DIR_L +} Direction; + + struct layout_parameters { double margin_l; @@ -39,11 +53,17 @@ struct layout_parameters double pad_r; double pad_t; double pad_b; + + Direction grav; + + double min_w; + double min_h; }; /* Calculate layout for frame (and all its children) based on size */ -extern void layout_frame(struct frame *fr, double w, double h); +extern void layout_frame(struct frame *fr, double w, double h, + PangoContext *pc); #endif /* LAYOUT_H */ diff --git a/src/presentation.h b/src/presentation.h index 72a1512..daa016b 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -55,8 +55,6 @@ struct slide struct frame { - PangoContext *pc; /* FIXME: Doesn't belong here */ - struct frame **rendering_order; int num_ro; int max_ro; @@ -66,12 +64,14 @@ struct frame struct layout_parameters lop; struct style *style; /* Non-NULL if 'lop' came from SS */ - /* Location relative to parent, calculated from alignment parameters */ + /* Location relative to parent, calculated from layout parameters */ double offs_x; double offs_y; double w; double h; + PangoLayout *pl; + /* True if this frame should be deleted on the next mouse click */ int empty; }; diff --git a/src/render.c b/src/render.c index 1e4bf54..ba0ae69 100644 --- a/src/render.c +++ b/src/render.c @@ -38,35 +38,23 @@ /* Render Level 1 Storycode */ -int render_sc(const char *sc, cairo_t *cr, double w, double h, PangoContext *pc) +int render_sc(struct frame *fr, cairo_t *cr, double w, double h, + PangoContext *pc) { - PangoLayout *layout; - PangoFontDescription *fontdesc; GdkColor col; - /* FIXME: Check for Level 1 markup e.g. image */ + if ( fr->pl != NULL ) { - layout = pango_layout_new(pc); - pango_layout_set_width(layout, w*PANGO_SCALE); - pango_layout_set_height(layout, h*PANGO_SCALE); + pango_cairo_update_layout(cr, fr->pl); - pango_cairo_update_layout(cr, layout); - pango_layout_set_justify(layout, 1); - pango_layout_set_ellipsize(layout, 1); + /* FIXME: Honour alpha as well */ + gdk_color_parse("#000000", &col); + gdk_cairo_set_source_color(cr, &col); - pango_layout_set_text(layout, sc, -1); - fontdesc = pango_font_description_from_string("Sans 12"); + pango_cairo_show_layout(cr, fr->pl); - pango_layout_set_font_description(layout, fontdesc); - - /* FIXME: Honour alpha as well */ - gdk_color_parse("#000000", &col); - gdk_cairo_set_source_color(cr, &col); - - pango_cairo_show_layout(cr, layout); - - pango_font_description_free(fontdesc); - g_object_unref(G_OBJECT(layout)); + //g_object_unref(G_OBJECT(layout)); + } return 0; } @@ -106,7 +94,7 @@ int render_frame(struct frame *fr, cairo_t *cr, PangoContext *pc) cairo_move_to(cr, fr->lop.pad_l, fr->lop.pad_t); w = fr->w - (fr->lop.pad_l + fr->lop.pad_r); h = fr->h - (fr->lop.pad_t + fr->lop.pad_b); - render_sc(fr->sc, cr, w, h, pc); + render_sc(fr, cr, w, h, pc); d = 1; diff --git a/src/storycode.c b/src/storycode.c index 42e6db9..3432090 100644 --- a/src/storycode.c +++ b/src/storycode.c @@ -421,6 +421,8 @@ static struct frame *frame_new() n->num_ro = 1; n->rendering_order[0] = n; + n->pl = NULL; + return n; } diff --git a/tests/render_test.c b/tests/render_test.c index 4124216..fc4784e 100644 --- a/tests/render_test.c +++ b/tests/render_test.c @@ -59,7 +59,7 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, struct frame *fr) gtk_widget_get_allocation(da, &allocation); - layout_frame(fr, allocation.width, allocation.height); + layout_frame(fr, allocation.width, allocation.height, pc); render_frame(fr, cr, pc); return FALSE; diff --git a/tests/render_test_sc1.c b/tests/render_test_sc1.c index bccc49d..03a8ec5 100644 --- a/tests/render_test_sc1.c +++ b/tests/render_test_sc1.c @@ -60,7 +60,7 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, struct frame *fr) gtk_widget_get_allocation(da, &allocation); - layout_frame(fr, allocation.width, allocation.height); + layout_frame(fr, allocation.width, allocation.height, pc); render_frame(fr, cr, pc); return FALSE; |