font resolution works! dev2
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 15 Dec 2020 07:13:11 +0000 (23:13 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 15 Dec 2020 07:13:11 +0000 (23:13 -0800)
src/output/cairo-fsm.c
src/output/cairo-fsm.h
src/output/cairo-pager.c
src/output/cairo.c
src/ui/gui/psppire-output-view.c

index 24ae81fbbdead43f144c77f5f78069d7f69e616f..b96a2ec05eef9f6ec802385c1b8b080746a3e0b8 100644 (file)
@@ -106,7 +106,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++)
@@ -626,16 +626,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 : 10000) * xr->style->font_scale,
+        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);
   PangoContext *context = pango_cairo_create_context (xr->cairo);
-  if (xr->style->font_scale != 1.0)
-    pango_cairo_context_set_resolution (context, 72.0);
+  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;
@@ -1131,7 +1132,11 @@ 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);
index b61f099035246de8a5237d37c1b97a56f9f785b9..37f4b8b40be32a9bd856b4e31d6705d3ccbc3b10 100644 (file)
@@ -49,7 +49,13 @@ struct xr_fsm_style
     struct cell_color fg;
     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 *);
 struct xr_fsm_style *xr_fsm_style_unshare (struct xr_fsm_style *);
index 2d287499a2b43858c2914186bea386aec1b001ae..36823bd9452344168722b6b7b5c4a0d81823aa1f 100644 (file)
@@ -143,9 +143,13 @@ get_layout_height (PangoLayout *layout)
 static int
 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)
+                        int width, int base_y, double font_resolution)
 {
-  PangoLayout *layout = pango_cairo_create_layout (cairo);
+  PangoContext *context = pango_cairo_create_context (cairo);
+  pango_cairo_context_set_resolution (context, font_resolution);
+  PangoLayout *layout = pango_layout_new (context);
+  g_object_unref (context);
+
   pango_layout_set_font_description (layout, font);
 
   int y = 0;
@@ -165,13 +169,11 @@ xr_render_page_heading (cairo_t *cairo, const PangoFontDescription *font,
          : pp->halign == TABLE_HALIGN_MIXED ? PANGO_ALIGN_LEFT
          : PANGO_ALIGN_RIGHT));
       pango_layout_set_width (layout, xr_to_pango (width));
-      if (draw)
-        {
-          cairo_save (cairo);
-          cairo_translate (cairo, 0, xr_to_pt (y + base_y));
-          pango_cairo_show_layout (cairo, layout);
-          cairo_restore (cairo);
-        }
+
+      cairo_save (cairo);
+      cairo_translate (cairo, 0, xr_to_pt (y + base_y));
+      pango_cairo_show_layout (cairo, layout);
+      cairo_restore (cairo);
 
       y += pango_to_xr (get_layout_height (layout));
     }
@@ -193,8 +195,8 @@ xr_measure_headings (const struct xr_page_style *ps,
     {
       int *h = &heading_heights[i];
       *h = xr_render_page_heading (cairo, fs->fonts[XR_FONT_PROPORTIONAL],
-                                   &ps->headings[i], -1, fs->size[H], false,
-                                   0);
+                                   &ps->headings[i], -1, fs->size[H], 0,
+                                   fs->font_resolution);
       if (*h)
         *h += ps->object_spacing;
     }
@@ -206,7 +208,6 @@ struct xr_pager *
 xr_pager_create (const struct xr_page_style *ps_,
                  const struct xr_fsm_style *fs_)
 {
-  printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
   struct xr_page_style *ps = xr_page_style_ref (ps_);
   struct xr_fsm_style *fs = xr_fsm_style_ref (fs_);
 
@@ -233,7 +234,6 @@ xr_pager_destroy (struct xr_pager *p)
 {
   if (p)
     {
-      printf (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
       xr_page_style_unref (p->page_style);
       xr_fsm_style_unref (p->fsm_style);
 
@@ -258,7 +258,6 @@ xr_pager_has_item (const struct xr_pager *p)
 void
 xr_pager_add_item (struct xr_pager *p, const struct output_item *item)
 {
-  printf ("add_item\n");
   assert (!p->item);
   p->item = output_item_ref (item);
   xr_pager_run (p);
@@ -273,7 +272,6 @@ xr_pager_has_page (const struct xr_pager *p)
 void
 xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
 {
-  printf ("add_page\n");
   assert (!p->cr);
   cairo_save (cr);
   p->cr = cr;
@@ -299,12 +297,13 @@ xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
   int page_number = p->page_index++ + ps->initial_page_number;
   if (p->heading_heights[0])
     xr_render_page_heading (cr, font, &ps->headings[0], page_number,
-                            fs->size[H], true, -p->heading_heights[0]);
+                            fs->size[H], -p->heading_heights[0],
+                            fs->font_resolution);
 
   if (p->heading_heights[1])
     xr_render_page_heading (cr, font, &ps->headings[1], page_number,
-                            fs->size[H], true,
-                            fs->size[V] + ps->object_spacing);
+                            fs->size[H], fs->size[V] + ps->object_spacing,
+                            fs->font_resolution);
 
   xr_pager_run (p);
 }
@@ -329,16 +328,13 @@ xr_pager_needs_new_page (struct xr_pager *p)
 static void
 xr_pager_run (struct xr_pager *p)
 {
-  printf ("run:\n");
   if (p->item && p->cr && p->y < p->fsm_style->size[V])
     {
       if (!p->fsm)
         {
-          printf ("\tcreate fsm\n");
           p->fsm = xr_fsm_create (p->item, p->fsm_style, p->cr);
           if (!p->fsm)
             {
-              printf ("\t(was null)\n");
               output_item_unref (p->item);
               p->item = NULL;
 
@@ -348,7 +344,6 @@ xr_pager_run (struct xr_pager *p)
 
       for (;;)
         {
-          printf ("\tdraw slice\n");
           int spacing = p->page_style->object_spacing;
           int chunk = xr_fsm_draw_slice (p->fsm, p->cr,
                                          p->fsm_style->size[V] - p->y);
@@ -357,7 +352,6 @@ xr_pager_run (struct xr_pager *p)
 
           if (xr_fsm_is_empty (p->fsm))
             {
-              printf ("\tfinished object\n");
               xr_fsm_destroy (p->fsm);
               p->fsm = NULL;
               output_item_unref (p->item);
@@ -366,16 +360,10 @@ xr_pager_run (struct xr_pager *p)
             }
           else if (!chunk)
             {
-              printf ("\tobject doesn't fit on page\n");
               assert (p->y > 0);
               p->y = INT_MAX;
               return;
             }
-          printf ("\tneed to draw another slice\n");
         }
     }
-  if (!p->item)
-    printf ("\tno item\n");
-  if (!p->cr)
-    printf ("\tno page\n");
 }
index a85054ebccc0ca5f6fd78d8a5264df8ac0556ddd..b3b2f4378e5ba4dd3b8abbd181999150349586ab 100644 (file)
@@ -174,14 +174,8 @@ parse_font_option (struct output_driver *d, struct string_map *options,
   return desc;
 }
 
-/* FONT_SCALE 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. */
 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;
@@ -260,7 +254,7 @@ xr_allocate (const char *name, int device_type, struct string_map *o,
     .fg = fg,
     .use_system_colors = systemcolors,
     .transparent = transparent,
-    .font_scale = font_scale,
+    .font_resolution = 72.0,
   };
 
   return xr;
@@ -271,7 +265,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[TABLE_N_AXES];
   for (int a = 0; a < TABLE_N_AXES; a++)
index ff19f64babe68d5ff3b88a7d850859170ce85c1b..e8a839fe5f9024207c9b0c4a8640e055b1636d80 100644 (file)
@@ -168,7 +168,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;
@@ -1043,7 +1043,7 @@ create_xr_print_driver (GtkPrintContext *context, struct psppire_output_view *vi
     .fg = CELL_COLOR_BLACK,
     .use_system_colors = false,
     .transparent = false,
-    .font_scale = 72.0 / 128.0
+    .font_resolution = 72.0
   };
 
   view->pager = xr_pager_create (view->page_style, view->fsm_style);