diff options
author | Thomas White <taw@bitwiz.org.uk> | 2012-10-08 21:09:16 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2012-10-08 21:09:16 +0200 |
commit | 43f4a4df59d960442df2faedfd50e5c7c7a55d99 (patch) | |
tree | 2ee01715b93ae567a01854485299ac33c6878131 /src | |
parent | d52c17c36ada874e6a0702808577a603331af095 (diff) |
Create PangoLayout when laying out the frame
Because it's necessary to know how much space the contents take up
Diffstat (limited to 'src')
-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 |
5 files changed, 97 insertions, 33 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; } |