From: Ben Pfaff Date: Mon, 7 Dec 2020 03:40:39 +0000 (-0800) Subject: cairo: Get rid of xr_render_fsm. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8189264ecb8621207ec403f0d9856e4df6ee0d8b;p=pspp cairo: Get rid of xr_render_fsm. --- diff --git a/src/output/cairo.c b/src/output/cairo.c index 2556ab6fc1..f08e27b319 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -114,18 +114,6 @@ struct xr_font PangoLayout *layout; }; -/* An output item whose rendering is in progress. */ -struct xr_render_fsm - { - /* Renders as much of itself as it can on the current page. Returns true - if rendering is complete, false if the output item needs another - page. */ - bool (*render) (struct xr_render_fsm *, struct xr_driver *); - - /* Destroys the output item. */ - void (*destroy) (struct xr_render_fsm *); - }; - /* Cairo output driver. */ struct xr_driver { @@ -157,13 +145,14 @@ struct xr_driver /* Internal state. */ struct render_params *params; + struct xr_fsm_style *style; double font_scale; int char_width, char_height; cairo_t *cairo; cairo_surface_t *surface; int page_number; /* Current page number. */ int y; - struct xr_render_fsm *fsm; + struct xr_fsm *fsm; }; static const struct output_driver_class cairo_driver_class; @@ -184,9 +173,6 @@ static void xr_draw_cell (void *, const struct table_cell *, int color_idx, int clip[TABLE_N_AXES][2]); static int xr_adjust_break (void *, const struct table_cell *, int width, int height); - -static struct xr_render_fsm *xr_render_output_item ( - struct xr_driver *, const struct output_item *); /* Output driver basics. */ @@ -531,6 +517,22 @@ xr_set_cairo (struct xr_driver *xr, cairo_t *cairo) xr->params->rtl = render_direction_rtl (); } + if (xr->style == NULL) + { + xr->style = xmalloc (sizeof *xr->style); + *xr->style = (struct xr_fsm_style) { + .ref_cnt = 1, + .size = { [H] = xr->width, [V] = xr->length }, + .min_break = { [H] = xr->min_break[H], [V] = xr->min_break[V] }, + .use_system_colors = xr->systemcolors, + .transparent = xr->transparent, + .font_scale = xr->font_scale, + }; + + for (size_t i = 0; i < XR_N_FONTS; i++) + xr->style->fonts[i] = pango_font_description_copy (xr->fonts[i].desc); + } + if (!xr->systemcolors) cairo_set_source_rgb (xr->cairo, xr->fg.r / 255.0, xr->fg.g / 255.0, xr->fg.b / 255.0); @@ -625,6 +627,7 @@ xr_destroy (struct output_driver *driver) g_object_unref (font->layout); } + xr_fsm_style_unref (xr->style); free (xr->params); free (xr); } @@ -757,7 +760,7 @@ xr_driver_output_item (struct xr_driver *xr, const struct output_item *output_item) { assert (xr->fsm == NULL); - xr->fsm = xr_render_output_item (xr, output_item); + xr->fsm = xr_fsm_create (output_item, xr->style, xr->cairo); xr_driver_run_fsm (xr); } @@ -780,18 +783,24 @@ xr_driver_is_page_blank (const struct xr_driver *xr) static void xr_driver_destroy_fsm (struct xr_driver *xr) { - if (xr->fsm != NULL) - { - xr->fsm->destroy (xr->fsm); - xr->fsm = NULL; - } + xr_fsm_destroy (xr->fsm); + xr->fsm = NULL; } static void xr_driver_run_fsm (struct xr_driver *xr) { - if (xr->fsm != NULL && !xr->fsm->render (xr->fsm, xr)) - xr_driver_destroy_fsm (xr); + if (xr->fsm != NULL) + { + cairo_save (xr->cairo); + cairo_translate (xr->cairo, 0, xr_to_pt (xr->y)); + int used = xr_fsm_draw_slice (xr->fsm, xr->cairo, xr->length - xr->y); + xr->y += used; + cairo_restore (xr->cairo); + + if (xr_fsm_is_empty (xr->fsm)) + xr_driver_destroy_fsm (xr); + } } static void @@ -1695,179 +1704,3 @@ xr_draw_eps_chart (const struct chart_item *item, return file_name; } - - -struct xr_table_state - { - struct xr_render_fsm fsm; - struct render_pager *p; - }; - -static bool -xr_table_render (struct xr_render_fsm *fsm, struct xr_driver *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 - xr->y); - 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_driver *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; -} - -struct xr_chart_state - { - struct xr_render_fsm fsm; - struct chart_item *chart_item; - }; - -static bool -xr_chart_render (struct xr_render_fsm *fsm, struct xr_driver *xr) -{ - struct xr_chart_state *cs = UP_CAST (fsm, struct xr_chart_state, fsm); - - const int chart_height = 0.8 * (xr->length < xr->width ? xr->length : xr->width); - - if (xr->y > xr->length - chart_height) - return true; - - if (xr->cairo != NULL) - { - xr_draw_chart (cs->chart_item, xr->cairo, - 0.0, - xr_to_pt (xr->y), - xr_to_pt (xr->width), - xr_to_pt (chart_height)); - } - xr->y += chart_height; - - return false; -} - -static void -xr_chart_destroy (struct xr_render_fsm *fsm) -{ - struct xr_chart_state *cs = UP_CAST (fsm, struct xr_chart_state, fsm); - - chart_item_unref (cs->chart_item); - free (cs); -} - -static struct xr_render_fsm * -xr_render_chart (const struct chart_item *chart_item) -{ - struct xr_chart_state *cs; - - cs = xmalloc (sizeof *cs); - cs->fsm.render = xr_chart_render; - cs->fsm.destroy = xr_chart_destroy; - cs->chart_item = chart_item_ref (chart_item); - - return &cs->fsm; -} - -static bool -xr_eject_render (struct xr_render_fsm *fsm UNUSED, struct xr_driver *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; -} - -static struct xr_render_fsm * -xr_render_text (struct xr_driver *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; - - default: - return xr_render_table ( - xr, text_item_to_table_item (text_item_ref (text_item))); - } - - return NULL; -} - -static struct xr_render_fsm * -xr_render_message (struct xr_driver *xr, - const struct message_item *message_item) -{ - char *s = msg_to_string (message_item_get_msg (message_item)); - struct text_item *item = text_item_create (TEXT_ITEM_LOG, s); - free (s); - return xr_render_table (xr, text_item_to_table_item (item)); -} - -static struct xr_render_fsm * -xr_render_output_item (struct xr_driver *xr, - const struct output_item *output_item) -{ - if (is_table_item (output_item)) - return xr_render_table (xr, table_item_ref (to_table_item (output_item))); - else if (is_chart_item (output_item)) - return xr_render_chart (to_chart_item (output_item)); - else if (is_text_item (output_item)) - return xr_render_text (xr, to_text_item (output_item)); - else if (is_page_eject_item (output_item)) - return xr->y > 0 ? xr_render_eject () : NULL; - else if (is_message_item (output_item)) - return xr_render_message (xr, to_message_item (output_item)); - else - return NULL; -}