From: Ben Pfaff Date: Sat, 17 Nov 2018 19:12:55 +0000 (-0800) Subject: output: Add support for vertical alignment of cells. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=commitdiff_plain;h=214ed115df21d414f1a785a090d74e8b2525108a output: Add support for vertical alignment of cells. It makes sense to bottom-align top headings but to top-align data cells, for example. --- diff --git a/src/output/ascii.c b/src/output/ascii.c index 507e758e3f..ff5b1ba826 100644 --- a/src/output/ascii.c +++ b/src/output/ascii.c @@ -627,7 +627,7 @@ text_draw (struct ascii_driver *a, unsigned int options, if (y < y0 || y >= y1) return; - switch (options & TAB_ALIGNMENT) + switch (options & TAB_HALIGN) { case TAB_LEFT: x = bb[H][0]; diff --git a/src/output/cairo.c b/src/output/cairo.c index c0a2b5ee0f..b363aef51d 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -926,7 +926,7 @@ xr_layout_cell_text (struct xr_driver *xr, if (contents->n_footnotes == 0) merge_footnotes = false; - else if (contents->n_footnotes == 1 && (options & TAB_ALIGNMENT) == TAB_RIGHT) + else if (contents->n_footnotes == 1 && (options & TAB_HALIGN) == TAB_RIGHT) { PangoAttrList *attrs; @@ -991,8 +991,8 @@ xr_layout_cell_text (struct xr_driver *xr, pango_layout_set_alignment ( font->layout, - ((options & TAB_ALIGNMENT) == TAB_RIGHT ? PANGO_ALIGN_RIGHT - : (options & TAB_ALIGNMENT) == TAB_LEFT ? PANGO_ALIGN_LEFT + ((options & TAB_HALIGN) == TAB_RIGHT ? PANGO_ALIGN_RIGHT + : (options & TAB_HALIGN) == TAB_LEFT ? PANGO_ALIGN_LEFT : PANGO_ALIGN_CENTER)); pango_layout_set_width ( font->layout, diff --git a/src/output/html.c b/src/output/html.c index 55bcb6daa0..9cc9a5c2b8 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -466,7 +466,7 @@ html_output_table (struct html_driver *html, const struct table_item *item) struct table_cell cell; const char *tag; bool is_header; - int alignment, colspan, rowspan; + int colspan, rowspan; int top, left, right, bottom, n_borders; table_get_cell (t, x, y, &cell); @@ -481,12 +481,19 @@ html_output_table (struct html_driver *html, const struct table_item *item) tag = is_header ? "TH" : "TD"; fprintf (html->file, " <%s", tag); - alignment = (cell.n_contents > 0 - ? cell.contents[0].options & TAB_ALIGNMENT - : TAB_LEFT); - if (alignment != TAB_LEFT) + int halign = (cell.n_contents > 0 + ? cell.contents[0].options & TAB_HALIGN + : TAB_LEFT); + if (halign != TAB_LEFT) fprintf (html->file, " ALIGN=\"%s\"", - alignment == TAB_RIGHT ? "RIGHT" : "CENTER"); + halign == TAB_RIGHT ? "RIGHT" : "CENTER"); + + int valign = (cell.n_contents > 0 + ? cell.contents[0].options & TAB_VALIGN + : TAB_LEFT); + if (valign != TAB_TOP) + fprintf (html->file, " ALIGN=\"%s\"", + valign == TAB_BOTTOM ? "BOTTOM" : "MIDDLE"); colspan = table_cell_colspan (&cell); if (colspan > 1) diff --git a/src/output/render.c b/src/output/render.c index 9a9370ad17..60cda45b16 100644 --- a/src/output/render.c +++ b/src/output/render.c @@ -59,7 +59,9 @@ struct render_page int n[TABLE_N_AXES]; int h[TABLE_N_AXES][2]; - /* cp[H] represents x positions within the table. + /* "Cell positions". + + cp[H] represents x positions within the table. cp[H][0] = 0. cp[H][1] = the width of the leftmost vertical rule. cp[H][2] = cp[H][1] + the width of the leftmost column. @@ -967,6 +969,22 @@ render_cell (const struct render_page *page, const int ofs[TABLE_N_AXES], bb[V][0] = clip[V][0] = ofs[V] + page->cp[V][cell->d[V][0] * 2 + 1]; bb[V][1] = clip[V][1] = ofs[V] + page->cp[V][cell->d[V][1] * 2]; + int valign = (cell->n_contents + ? cell->contents->options & TAB_VALIGN + : TAB_TOP); + if (valign != TAB_TOP) + { + int height = page->params->measure_cell_height ( + page->params->aux, cell, bb[H][1] - bb[H][0]); + int extra = bb[V][1] - bb[V][0] - height; + if (extra > 0) + { + if (valign == TAB_MIDDLE) + extra /= 2; + bb[V][0] += extra; + } + } + of = find_overflow (page, cell->d[H][0], cell->d[V][0]); if (of) { diff --git a/src/output/table.h b/src/output/table.h index d93c69e38c..0a7c4b61b5 100644 --- a/src/output/table.h +++ b/src/output/table.h @@ -48,20 +48,26 @@ enum { TAB_NONE = 0, - /* Alignment of cell contents. */ - TAB_RIGHT = 0 << 0, /* Right justify. */ - TAB_LEFT = 1 << 0, /* Left justify. */ - TAB_CENTER = 2 << 0, /* Centered. */ - TAB_ALIGNMENT = 3 << 0, /* Alignment mask. */ + /* Horizontal alignment of cell contents. */ + TAB_RIGHT = 0 << 0, + TAB_LEFT = 1 << 0, + TAB_CENTER = 2 << 0, + TAB_HALIGN = 3 << 0, /* Alignment mask. */ + + /* Vertical alignment of cell contents. */ + TAB_TOP = 0 << 2, + TAB_MIDDLE = 1 << 2, + TAB_BOTTOM = 2 << 2, + TAB_VALIGN = 3 << 2, /* Alignment mask. */ /* These flags may be combined with any alignment. */ - TAB_EMPH = 1 << 2, /* Emphasize cell contents. */ - TAB_FIX = 1 << 3, /* Use fixed font. */ + TAB_EMPH = 1 << 4, /* Emphasize cell contents. */ + TAB_FIX = 1 << 5, /* Use fixed font. */ /* 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 = 4 + TAB_FIRST_AVAILABLE = 6 }; /* Styles for the rules around table cells. */ diff --git a/tests/output/render-test.c b/tests/output/render-test.c index 2a874d1c91..e286f6bea4 100644 --- a/tests/output/render-test.c +++ b/tests/output/render-test.c @@ -426,17 +426,17 @@ read_table (FILE *stream) break; case '(': - opt &= ~TAB_ALIGNMENT; + opt &= ~TAB_HALIGN; opt |= TAB_LEFT; break; case ')': - opt &= ~TAB_ALIGNMENT; + opt &= ~TAB_HALIGN; opt |= TAB_RIGHT; break; case '|': - opt &= ~TAB_ALIGNMENT; + opt &= ~TAB_HALIGN; opt |= TAB_CENTER; break;