From: Ben Pfaff Date: Tue, 15 Dec 2020 07:36:31 +0000 (-0800) Subject: cairo: Use pango_cairo_context_set_resolution() to get font sizes correct. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ec15713eb9ba3b4bd991172204f8c1f67d30170;p=pspp cairo: Use pango_cairo_context_set_resolution() to get font sizes correct. I never understood before why fonts didn't appear the right side in PDF and PostScript output. This fixes the problem. --- diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index c9794d4630..a9e4d4c68d 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -88,7 +88,7 @@ xr_fsm_style_equals (const struct xr_fsm_style *a, || 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++) @@ -608,13 +608,16 @@ 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; @@ -1111,7 +1114,10 @@ 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); diff --git a/src/output/cairo-fsm.h b/src/output/cairo-fsm.h index 60a6efb489..74b43860c8 100644 --- a/src/output/cairo-fsm.h +++ b/src/output/cairo-fsm.h @@ -44,7 +44,13 @@ struct xr_fsm_style PangoFontDescription *fonts[XR_N_FONTS]; bool use_system_colors; bool transparent; - double font_scale; + + /* Resolution, in units per inch, used for measuring font "points". If + this is 72.0, for example, then 1pt = 1 device unit, which is + appropriate for rendering to a surface created by + cairo_ps_surface_create() with its default transformation matrix of 72 + units/inch. For a screen-based surface, it is traditionally 96.0. */ + double font_resolution; }; struct xr_fsm_style *xr_fsm_style_ref (const struct xr_fsm_style *); void xr_fsm_style_unref (struct xr_fsm_style *); diff --git a/src/output/cairo.c b/src/output/cairo.c index f5bf1f6a93..c3cef5c62a 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -117,7 +117,6 @@ struct xr_driver /* Internal state. */ struct xr_fsm_style *style; - double font_scale; int char_width, char_height; cairo_t *cairo; cairo_surface_t *surface; @@ -251,21 +250,13 @@ apply_options (struct xr_driver *xr, struct string_map *o) } static struct xr_driver * -xr_allocate (const char *name, int device_type, struct string_map *o, - double font_scale) +xr_allocate (const char *name, int device_type, struct string_map *o) { struct xr_driver *xr = xzalloc (sizeof *xr); struct output_driver *d = &xr->driver; output_driver_init (d, &cairo_driver_class, name, device_type); - /* This is a nasty kluge for an issue that does not make sense. On any - surface other than a screen (e.g. for output to PDF or PS or SVG), the - fonts are way too big by default. A "9-point" font seems to appear about - 16 points tall. We use a scale factor for these surfaces to help, but the - underlying issue is a mystery. */ - xr->font_scale = font_scale; - apply_options (xr, o); return xr; @@ -295,7 +286,10 @@ xr_measure_fonts (cairo_t *cairo, PangoFontDescription *fonts[XR_N_FONTS], *char_height = 0; for (int i = 0; i < XR_N_FONTS; i++) { - PangoLayout *layout = pango_cairo_create_layout (cairo); + PangoContext *context = pango_cairo_create_context (cairo); + pango_cairo_context_set_resolution (context, 72.0); + PangoLayout *layout = pango_layout_new (context); + g_object_unref (context); pango_layout_set_font_description (layout, fonts[i]); pango_layout_set_text (layout, "0", 1); @@ -322,7 +316,11 @@ xr_render_page_heading (cairo_t *cairo, const PangoFontDescription *font, const struct page_heading *ph, int page_number, int width, bool draw, int base_y) { - PangoLayout *layout = pango_cairo_create_layout (cairo); + PangoContext *context = pango_cairo_create_context (cairo); + pango_cairo_context_set_resolution (context, 72.0); + PangoLayout *layout = pango_layout_new (context); + g_object_unref (context); + pango_layout_set_font_description (layout, font); int y = 0; @@ -432,7 +430,7 @@ xr_set_cairo (struct xr_driver *xr, cairo_t *cairo) .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, + .font_resolution = 72.0, }; for (size_t i = 0; i < XR_N_FONTS; i++) @@ -449,7 +447,7 @@ xr_create (struct file_handle *fh, enum settings_output_devices device_type, struct string_map *o, enum xr_output_type file_type) { const char *file_name = fh_get_file_name (fh); - struct xr_driver *xr = xr_allocate (file_name, device_type, o, 72.0 / 128.0); + struct xr_driver *xr = xr_allocate (file_name, device_type, o); double paper_pt[TABLE_N_AXES]; for (int a = 0; a < TABLE_N_AXES; a++) @@ -729,7 +727,7 @@ static const struct output_driver_class cairo_driver_class = struct xr_driver * xr_driver_create (cairo_t *cairo, struct string_map *options) { - struct xr_driver *xr = xr_allocate ("cairo", 0, options, 1.0); + struct xr_driver *xr = xr_allocate ("cairo", 0, options); xr_set_cairo (xr, cairo); return xr; } diff --git a/src/ui/gui/psppire-output-view.c b/src/ui/gui/psppire-output-view.c index 8ad1904184..626d52e07e 100644 --- a/src/ui/gui/psppire-output-view.c +++ b/src/ui/gui/psppire-output-view.c @@ -165,7 +165,7 @@ get_xr_fsm_style (struct psppire_output_view *view) }, .use_system_colors = true, .transparent = true, - .font_scale = 1.0, + .font_resolution = 96.0, }; return style;