X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=src%2Foutput%2Fcairo-fsm.c;h=58bbf230d5aada148969733bd73eefe4ebdb66e5;hb=c7660b4a54e32aebfbda642c52afff57284a306c;hp=c485eb7225bd0a64f580d4fb73232477304265b2;hpb=7fceea6249f2a570ecc44b5cb35f94711da957c1;p=pspp diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index c485eb7225..58bbf230d5 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -115,12 +115,27 @@ xr_fsm_style_equals (const struct xr_fsm_style *a, return true; } +/* Renders a single output_item to an output device in one of two ways: + + - 'print == true': Broken across multiple pages if necessary. + + - 'print == false': In a single region that the user may scroll around if + needed. + + Normally 'output_item' corresponds to a single rendering. There is a + special case when 'print == true' and 'output_item' is a table_item with + multiple layers and 'item->pt->table_look->print_all_layers == true'. In + that case, each layer is rendered separately from the FSM's internal point + of view; from the client's point of view, it is all one operation. +*/ struct xr_fsm { struct xr_fsm_style *style; struct output_item *item; + bool print; /* Table items only. */ + size_t *layer_indexes; struct render_params rp; struct render_pager *p; cairo_t *cairo; /* XXX should this be here?! */ @@ -185,8 +200,6 @@ xr_draw_line (struct xr_fsm *xr, int x0, int y0, int x1, int y1, int style, const struct cell_color *color) { cairo_new_path (xr->cairo); - if (!xr->style->use_system_colors) - xr_set_source_rgba (xr->cairo, color); cairo_set_line_width ( xr->cairo, xr_to_pt (style == RENDER_LINE_THICK ? XR_LINE_WIDTH * 2 @@ -194,7 +207,14 @@ xr_draw_line (struct xr_fsm *xr, int x0, int y0, int x1, int y1, int style, : XR_LINE_WIDTH)); cairo_move_to (xr->cairo, xr_to_pt (x0), xr_to_pt (y0)); cairo_line_to (xr->cairo, xr_to_pt (x1), xr_to_pt (y1)); + + if (!xr->style->use_system_colors) + xr_set_source_rgba (xr->cairo, color); + if (style == RENDER_LINE_DASHED) + cairo_set_dash (xr->cairo, (double[]) { 2 }, 1, 0); cairo_stroke (xr->cairo); + if (style == RENDER_LINE_DASHED) + cairo_set_dash (xr->cairo, NULL, 0, 0); } static void UNUSED @@ -514,6 +534,13 @@ xrr_adjust_break (void *xr_, const struct table_cell *cell, xr_layout_cell (xr, cell, bb, clip, &w, &h, &brk); return brk; } + +static void +xrr_scale (void *xr_, double scale) +{ + struct xr_fsm *xr = xr_; + cairo_scale (xr->cairo, scale, scale); +} static void xr_clip (struct xr_fsm *xr, int clip[TABLE_N_AXES][2]) @@ -713,7 +740,7 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, PANGO_UNDERLINE_SINGLE)); } - if (cell->n_footnotes || cell->n_subscripts || cell->superscript) + if (cell->n_footnotes || cell->n_subscripts) { /* If we haven't already put TEXT into tmp, do it now. */ if (ds_is_empty (&tmp)) @@ -730,10 +757,6 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, ds_put_cstr (&tmp, cell->subscripts[i]); } - size_t superscript_ofs = ds_length (&tmp); - if (cell->superscript) - ds_put_cstr (&tmp, cell->superscript); - size_t footnote_ofs = ds_length (&tmp); for (size_t i = 0; i < cell->n_footnotes; i++) { @@ -781,9 +804,9 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, subscript_ofs, PANGO_ATTR_INDEX_TO_TEXT_END); if (cell->n_subscripts) add_attr (attrs, pango_attr_rise_new (-3000), subscript_ofs, - superscript_ofs - subscript_ofs); - if (cell->superscript || cell->n_footnotes) - add_attr (attrs, pango_attr_rise_new (3000), superscript_ofs, + footnote_ofs - subscript_ofs); + if (cell->n_footnotes) + add_attr (attrs, pango_attr_rise_new (3000), footnote_ofs, PANGO_ATTR_INDEX_TO_TEXT_END); } @@ -810,6 +833,9 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, bb[X][1] == INT_MAX ? -1 : xr_to_pango (bb[X][1] - bb[X][0])); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); + int size[TABLE_N_AXES]; + pango_layout_get_size (layout, &size[H], &size[V]); + if (clip[H][0] != clip[H][1]) { cairo_save (xr->cairo); @@ -817,8 +843,10 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, xr_clip (xr, clip); if (options & TAB_ROTATE) { + int extra = bb[H][1] - bb[H][0] - size[V]; + int halign_offset = extra > 0 ? extra / 2 : 0; cairo_translate (xr->cairo, - xr_to_pt (bb[H][0]), + xr_to_pt (bb[H][0] + halign_offset), xr_to_pt (bb[V][1])); cairo_rotate (xr->cairo, -M_PI_2); } @@ -857,8 +885,6 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, cairo_restore (xr->cairo); } - int size[TABLE_N_AXES]; - pango_layout_get_size (layout, &size[H], &size[V]); int w = pango_to_xr (size[X]); int h = pango_to_xr (size[Y]); if (w > *widthp) @@ -946,9 +972,10 @@ xr_layout_cell (struct xr_fsm *xr, const struct table_cell *cell, #define CHART_WIDTH 500 #define CHART_HEIGHT 375 -struct xr_fsm * +static struct xr_fsm * xr_fsm_create (const struct output_item *item_, - const struct xr_fsm_style *style, cairo_t *cr) + const struct xr_fsm_style *style, cairo_t *cr, + bool print) { if (is_page_setup_item (item_) || is_group_open_item (item_) @@ -981,7 +1008,8 @@ xr_fsm_create (const struct output_item *item_, item = table_item_super ( text_item_to_table_item ( text_item_create (TEXT_ITEM_TITLE, - to_group_open_item (item_)->command_name))); + to_group_open_item (item_)->command_name, + NULL))); } else NOT_REACHED (); @@ -989,12 +1017,21 @@ xr_fsm_create (const struct output_item *item_, || is_chart_item (item) || is_page_eject_item (item)); + size_t *layer_indexes = NULL; + if (is_table_item (item)) + { + layer_indexes = pivot_table_next_layer (table_item->pt, NULL, print); + if (!layer_indexes) + return NULL; + } + static const struct render_ops xrr_render_ops = { .measure_cell_width = xrr_measure_cell_width, .measure_cell_height = xrr_measure_cell_height, .adjust_break = xrr_adjust_break, .draw_line = xrr_draw_line, .draw_cell = xrr_draw_cell, + .scale = xrr_scale, }; enum { LW = XR_LINE_WIDTH, LS = XR_LINE_SPACE }; @@ -1008,10 +1045,16 @@ xr_fsm_create (const struct output_item *item_, [RENDER_LINE_DOUBLE] = 2 * LW + LS, }; + size_t *layer_indexes = NULL; + if (is_table_item (item) + pivot_table_next_display_layer ( + struct xr_fsm *fsm = xmalloc (sizeof *fsm); *fsm = (struct xr_fsm) { .style = xr_fsm_style_ref (style), .item = item, + .print = print, + .layer_indexes = layer_indexes, .rp = { .ops = &xrr_render_ops, .aux = fsm, @@ -1023,13 +1066,6 @@ xr_fsm_create (const struct output_item *item_, } }; - if (is_table_item (item)) - { - fsm->cairo = cr; - fsm->p = render_pager_create (&fsm->rp, to_table_item (item)); - fsm->cairo = NULL; - } - for (int i = 0; i < XR_N_FONTS; i++) { PangoContext *context = pango_cairo_create_context (cr); @@ -1052,6 +1088,15 @@ xr_fsm_create (const struct output_item *item_, g_object_unref (G_OBJECT (layout)); } + if (is_table_item (item)) + { + struct table_item *table_item = to_table_item (item); + + fsm->cairo = cr; + fsm->p = render_pager_create (&fsm->rp, table_item); + fsm->cairo = NULL; + } + return fsm; }