From d523d6fa44e79bbca2b2cce792a7f25cca0d3aef Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 26 Dec 2018 08:22:15 -0800 Subject: [PATCH] output: Support rotation. --- src/output/cairo.c | 61 ++++++++++++++++++++++++++++++++-------------- src/output/table.h | 3 ++- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/output/cairo.c b/src/output/cairo.c index d00a66be68..32369a7a0e 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -1201,6 +1201,14 @@ markup_escape (const char *in, struct string *out) } } +static int +get_layout_dimension (PangoLayout *layout, enum table_axis axis) +{ + int size[TABLE_N_AXES]; + pango_layout_get_size (layout, &size[H], &size[V]); + return size[axis]; +} + static int xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, int bb[TABLE_N_AXES][2], int clip[TABLE_N_AXES][2], @@ -1208,7 +1216,10 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, { const struct cell_style *style = cell->style; unsigned int options = cell->options; - int w, h; + + enum table_axis X = options & TAB_ROTATE ? V : H; + enum table_axis Y = !X; + int R = options & TAB_ROTATE ? 0 : 1; struct xr_font *font = (options & TAB_FIX ? &xr->fonts[XR_FONT_FIXED] : options & TAB_EMPH ? &xr->fonts[XR_FONT_EMPHASIS] @@ -1236,21 +1247,22 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, footnote_adjustment = 0; else if (cell->n_footnotes == 1 && (options & TAB_HALIGN) == TAB_RIGHT) { - PangoAttrList *attrs; - const char *marker = cell->footnotes[0]->marker; pango_layout_set_text (font->layout, marker, strlen (marker)); - attrs = pango_attr_list_new (); + PangoAttrList *attrs = pango_attr_list_new (); pango_attr_list_insert (attrs, pango_attr_rise_new (7000)); pango_layout_set_attributes (font->layout, attrs); pango_attr_list_unref (attrs); - pango_layout_get_size (font->layout, &w, &h); - footnote_adjustment = MIN (w, px_to_xr (style->margin[H][1])); + int w = get_layout_dimension (font->layout, X); + int right_margin = px_to_xr (cell->style->margin[X][R]); + footnote_adjustment = MIN (w, right_margin); + + pango_layout_set_attributes (font->layout, NULL); } else - footnote_adjustment = px_to_xr (style->margin[H][1]); + footnote_adjustment = px_to_xr (cell->style->margin[X][R]); struct string tmp = DS_EMPTY_INITIALIZER; const char *text = cell->text; @@ -1269,7 +1281,7 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, happen with grouping like 1,234,567.89 or 1.234.567,89 because if groups are present then there will always be a digit on both sides of every period and comma. */ - if (bb[H][1] != INT_MAX) + if (options & TAB_ROTATE || bb[H][1] != INT_MAX) { const char *decimal = text + strcspn (text, ".,"); if (decimal[0] @@ -1285,7 +1297,10 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, if (footnote_adjustment) { - bb[H][1] += footnote_adjustment; + if (R) + bb[X][R] += footnote_adjustment; + else + bb[X][R] -= footnote_adjustment; if (ds_is_empty (&tmp)) { @@ -1348,16 +1363,25 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, : PANGO_ALIGN_CENTER)); pango_layout_set_width ( font->layout, - bb[H][1] == INT_MAX ? -1 : xr_to_pango (bb[H][1] - bb[H][0])); + bb[X][1] == INT_MAX ? -1 : xr_to_pango (bb[X][1] - bb[X][0])); pango_layout_set_wrap (font->layout, PANGO_WRAP_WORD); if (clip[H][0] != clip[H][1]) { cairo_save (xr->cairo); - xr_clip (xr, clip); - cairo_translate (xr->cairo, - xr_to_pt (bb[H][0] + xr->x), - xr_to_pt (bb[V][0] + xr->y)); + if (!(options & TAB_ROTATE)) + xr_clip (xr, clip); + if (options & TAB_ROTATE) + { + cairo_translate (xr->cairo, + xr_to_pt (bb[H][0] + xr->x), + xr_to_pt (bb[V][1] + xr->y)); + cairo_rotate (xr->cairo, -M_PI_2); + } + else + cairo_translate (xr->cairo, + xr_to_pt (bb[H][0] + xr->x), + xr_to_pt (bb[V][0] + xr->y)); pango_cairo_show_layout (xr->cairo, font->layout); /* If enabled, this draws a blue rectangle around the extents of each @@ -1388,12 +1412,13 @@ xr_layout_cell_text (struct xr_driver *xr, const struct table_cell *cell, cairo_restore (xr->cairo); } - pango_layout_get_size (font->layout, &w, &h); - w = pango_to_xr (w); - h = pango_to_xr (h); + int size[TABLE_N_AXES]; + pango_layout_get_size (font->layout, &size[H], &size[V]); + int w = pango_to_xr (size[X]); + int h = pango_to_xr (size[Y]); if (w > *widthp) *widthp = w; - if (bb[V][0] + h >= bb[V][1]) + if (bb[V][0] + h >= bb[V][1] && !(options & TAB_ROTATE)) { PangoLayoutIter *iter; int best UNUSED = 0; diff --git a/src/output/table.h b/src/output/table.h index 7949fedd24..8586ac1779 100644 --- a/src/output/table.h +++ b/src/output/table.h @@ -64,11 +64,12 @@ enum TAB_EMPH = 1 << 4, /* Emphasize cell contents. */ TAB_FIX = 1 << 5, /* Use fixed font. */ TAB_MARKUP = 1 << 6, /* Text contains Pango markup. */ + TAB_ROTATE = 1 << 7, /* Rotate cell contents 90 degrees. */ /* Bits with values (1 << TAB_FIRST_AVAILABLE) and higher are not used, so they are available for subclasses to use as they wish. */ - TAB_FIRST_AVAILABLE = 7 + TAB_FIRST_AVAILABLE = 8 }; /* Styles for the rules around table cells. */ -- 2.30.2