X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Foutput%2Fcairo-fsm.c;h=16cf47dec43883b711da0d14cf4fd371f7a1e22a;hb=e91782a2d25dec932c93b7a57bd03d836614ba43;hp=c9794d4630a942ece7cf0d9d0802d2a317bc7891;hpb=6fa20f2f419eac61340d9b93d5cdde01c281c9ec;p=pspp diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index c9794d4630..16cf47dec4 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -52,7 +52,7 @@ /* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */ #define H TABLE_HORZ #define V TABLE_VERT - + struct xr_fsm_style * xr_fsm_style_ref (const struct xr_fsm_style *style_) { @@ -63,6 +63,24 @@ xr_fsm_style_ref (const struct xr_fsm_style *style_) return style; } +struct xr_fsm_style * +xr_fsm_style_unshare (struct xr_fsm_style *old) +{ + assert (old->ref_cnt > 0); + if (old->ref_cnt == 1) + return old; + + xr_fsm_style_unref (old); + + struct xr_fsm_style *new = xmemdup (old, sizeof *old); + new->ref_cnt = 1; + for (int i = 0; i < XR_N_FONTS; i++) + if (old->fonts[i]) + new->fonts[i] = pango_font_description_copy (old->fonts[i]); + + return new; +} + void xr_fsm_style_unref (struct xr_fsm_style *style) { @@ -87,8 +105,7 @@ xr_fsm_style_equals (const struct xr_fsm_style *a, || a->min_break[H] != b->min_break[H] || a->min_break[V] != b->min_break[V] || a->use_system_colors != b->use_system_colors - || a->transparent != b->transparent - || a->font_scale != b->font_scale) + || a->font_resolution != b->font_resolution) return false; for (size_t i = 0; i < XR_N_FONTS; i++) @@ -168,8 +185,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 @@ -177,7 +192,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 @@ -433,7 +455,8 @@ xrr_draw_cell (void *xr_, const struct table_cell *cell, int color_idx, struct xr_fsm *xr = xr_; int w, h, brk; - if (!xr->style->transparent) + const struct cell_color *bg = &cell->style->font_style.bg[color_idx]; + if ((bg->r != 255 || bg->g != 255 || bg->b != 255) && bg->alpha) { cairo_save (xr->cairo); int bg_clip[TABLE_N_AXES][2]; @@ -448,7 +471,7 @@ xrr_draw_cell (void *xr_, const struct table_cell *cell, int color_idx, bg_clip[axis][1] += spill[axis][1]; } xr_clip (xr, bg_clip); - xr_set_source_rgba (xr->cairo, &cell->style->font_style.bg[color_idx]); + xr_set_source_rgba (xr->cairo, bg); fill_rectangle (xr, bb[H][0] - spill[H][0], bb[V][0] - spill[V][0], @@ -496,6 +519,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]) @@ -608,13 +638,17 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, if (font_style->typeface) desc = parse_font ( font_style->typeface, - font_style->size ? font_style->size * 1000 * xr->style->font_scale : 10000, + font_style->size ? font_style->size * 1000 : 10000, font_style->bold, font_style->italic); if (!desc) desc = xr->style->fonts[font_type]; assert (xr->cairo); - PangoLayout *layout = pango_cairo_create_layout (xr->cairo); + PangoContext *context = pango_cairo_create_context (xr->cairo); + pango_cairo_context_set_resolution (context, xr->style->font_resolution); + PangoLayout *layout = pango_layout_new (context); + g_object_unref (context); + pango_layout_set_font_description (layout, desc); const char *text = cell->text; @@ -788,6 +822,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); @@ -795,8 +832,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); } @@ -835,8 +874,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) @@ -920,106 +957,6 @@ xr_layout_cell (struct xr_fsm *xr, const struct table_cell *cell, *brk = bb[V][0]; *height = xr_layout_cell_text (xr, cell, bb, clip, width, brk); } - -#if 0 -static bool -xr_table_render (struct xr_render_fsm *fsm, struct xr_fsm *xr) -{ - struct xr_table_state *ts = UP_CAST (fsm, struct xr_table_state, fsm); - - while (render_pager_has_next (ts->p)) - { - int used; - - used = render_pager_draw_next (ts->p, xr->length); - if (!used) - { - assert (xr->y > 0); - return true; - } - else - xr->y += used; - } - return false; -} - -static void -xr_table_destroy (struct xr_render_fsm *fsm) -{ - struct xr_table_state *ts = UP_CAST (fsm, struct xr_table_state, fsm); - - render_pager_destroy (ts->p); - free (ts); -} - -static struct xr_render_fsm * -xr_render_table (struct xr_fsm *xr, struct table_item *table_item) -{ - struct xr_table_state *ts; - - ts = xmalloc (sizeof *ts); - ts->fsm.render = xr_table_render; - ts->fsm.destroy = xr_table_destroy; - - if (xr->y > 0) - xr->y += xr->char_height; - - ts->p = render_pager_create (xr->params, table_item); - table_item_unref (table_item); - - return &ts->fsm; -} - -static bool -xr_eject_render (struct xr_render_fsm *fsm UNUSED, struct xr_fsm *xr) -{ - return xr->y > 0; -} - -static void -xr_eject_destroy (struct xr_render_fsm *fsm UNUSED) -{ - /* Nothing to do. */ -} - -static struct xr_render_fsm * -xr_render_eject (void) -{ - static struct xr_render_fsm eject_renderer = - { - xr_eject_render, - xr_eject_destroy - }; - - return &eject_renderer; -} - -#define CHART_WIDTH 500 -#define CHART_HEIGHT 375 - -static struct xr_render_fsm * -xr_render_text (struct xr_fsm *xr, const struct text_item *text_item) -{ - enum text_item_type type = text_item_get_type (text_item); - - switch (type) - { - case TEXT_ITEM_PAGE_TITLE: - break; - - case TEXT_ITEM_EJECT_PAGE: - if (xr->y > 0) - return xr_render_eject (); - break; - - default: - return xr_render_table ( - xr, text_item_to_table_item (text_item_ref (text_item))); - } - - return NULL; -} -#endif #define CHART_WIDTH 500 #define CHART_HEIGHT 375 @@ -1073,6 +1010,7 @@ xr_fsm_create (const struct output_item *item_, .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 }; @@ -1094,7 +1032,6 @@ xr_fsm_create (const struct output_item *item_, .ops = &xrr_render_ops, .aux = fsm, .size = { [H] = style->size[H], [V] = style->size[V] }, - /* XXX font_size */ .line_widths = xr_line_widths, .min_break = { [H] = style->min_break[H], [V] = style->min_break[V] }, .supports_margins = true, @@ -1111,17 +1048,21 @@ xr_fsm_create (const struct output_item *item_, for (int i = 0; i < XR_N_FONTS; i++) { - PangoLayout *layout = pango_cairo_create_layout (cr); + PangoContext *context = pango_cairo_create_context (cr); + pango_cairo_context_set_resolution (context, style->font_resolution); + PangoLayout *layout = pango_layout_new (context); + g_object_unref (context); + pango_layout_set_font_description (layout, style->fonts[i]); pango_layout_set_text (layout, "0", 1); int char_size[TABLE_N_AXES]; pango_layout_get_size (layout, &char_size[H], &char_size[V]); - for (int j = 0; j < TABLE_N_AXES; j++) + for (int a = 0; a < TABLE_N_AXES; a++) { - int csj = pango_to_xr (char_size[j]); - fsm->rp.font_size[j] = MAX (fsm->rp.font_size[j], csj); + int csa = pango_to_xr (char_size[a]); + fsm->rp.font_size[a] = MAX (fsm->rp.font_size[a], csa); } g_object_unref (G_OBJECT (layout)); @@ -1143,7 +1084,6 @@ xr_fsm_destroy (struct xr_fsm *fsm) } } - /* This is primarily meant for use with screen rendering since the result is a fixed value for charts. */ void @@ -1175,17 +1115,9 @@ xr_fsm_measure (struct xr_fsm *fsm, cairo_t *cr, int *wp, int *hp) static int xr_fsm_draw_table (struct xr_fsm *fsm, int space) { - int used = 0; - while (render_pager_has_next (fsm->p)) - { - int chunk = render_pager_draw_next (fsm->p, space - used); - if (!chunk) - return used; - - used += chunk; - cairo_translate (fsm->cairo, 0, chunk); - } - return used; + return (render_pager_has_next (fsm->p) + ? render_pager_draw_next (fsm->p, space) + : 0); } static int