After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 565158 - Metrics of underline and striketrough is quantized, with minimum 1device unit, so can't fade with glyph strokes
Metrics of underline and striketrough is quantized, with minimum 1device unit...
Status: RESOLVED OBSOLETE
Product: pango
Classification: Platform
Component: cairo
1.22.x
Other All
: Normal normal
: ---
Assigned To: pango-maint
pango-maint
Depends on:
Blocks:
 
 
Reported: 2008-12-20 06:21 UTC by Peter Clifton
Modified: 2018-05-22 12:44 UTC
See Also:
GNOME target: ---
GNOME version: 2.25/2.26



Description Peter Clifton 2008-12-20 06:21:02 UTC
Please describe the problem:
I'm using a custom PangoRenderer to render Electronic CAD system text with overbars. I'm borrowing metrics from the underline, retrieved with pango_font_metrics_get_underline_thickness(). Hinting is switched on.

When we zoom out, and the text gets really small, stroke width (appears) to reduce below 1 device pixel, and fades out. Since the underline metric is quantized and clamped with a minimum of one device pixel, when we zoom out, the drawn overbar becomes far more prominenet than the rest of the glyphs.

I had hoped that when the width of strokes goes below zero, the quantisation of the metrics would still allow it to report a fractional device unit thickness, since this keeps the overbar in proportion to the stroke's "boldness" on screen, and still renders without looking blurry.

The overbar rendering code:

  if (priv->overbar) {
    double rx, ry, rwidth, rheight, cheight;
    PangoFontMetrics *metrics;
    PangoRectangle logical;
    int underline_thickness;

    /* Make the thickness the same as for the font's underline */
    metrics = pango_font_get_metrics (font, NULL);
    underline_thickness = pango_font_metrics_get_underline_thickness (metrics);
    pango_font_metrics_unref (metrics);

    pango_glyph_string_extents (glyphs, font, NULL, &logical);

    rx = x;
    ry = y - logical.height * MAGIC_OVERBAR_POS_CONSTANT;
    rwidth = logical.width;
    rheight = underline_thickness;

    cheight = rheight / PANGO_SCALE;

    /* Allow the overbar to fade out as it becomes < 1px high */
    if (cheight > 1.0)
      cheight = (int)(cheight);

    cairo_rectangle (cr,
                     (int)(rx / PANGO_SCALE), (int)(ry / PANGO_SCALE),
                     (int)(rwidth / PANGO_SCALE), cheight);
    cairo_fill (cr);
  }

The problem in pango appears to be where g pangogc-font.c's get_face_metrics() function calls:

  /* If hinting is on for this font, quantize the underline and strikethrough position
   * to integer values.
   */
  if (fcfont->is_hinted)
    {
      pango_quantize_line_geometry (&metrics->underline_thickness,
                                    &metrics->underline_position);
      pango_quantize_line_geometry (&metrics->strikethrough_thickness,
                                    &metrics->strikethrough_position);
    }

This probably also applies to the win32 backend, which calls the same routine.


The following patch gives me the desired behaviour, my overbar (made
with thickness underline metrics), now fades (due to width < 1
anti-aliasing) with the stroke of the font, looking much more uniform
than before. It still achieves the desired non-blurred look buy hinting
the position, and only allowing non-integer widths for width < 1.

--- pango-utils.c.old   2008-12-18 16:00:18.000000000 +0000
+++ pango-utils.c       2008-12-18 16:04:03.000000000 +0000
@@ -1488,9 +1488,11 @@
  * multiples of %PANGO_SCALE. The purpose of this function is to avoid
  * such lines looking blurry.
  *
- * Care is taken to make sure @thickness is at least one pixel when this
- * function returns, but returned @position may become zero as a result
- * of rounding.
+ * If the input @thickness is less than one pixel, it is passed through
+ * unchanged to allow the intensity of the resulting line to fade with
+ * the stroke of the font.
+ *
+ * The returned @position may become zero as a result of rounding.
  *
  * Since: 1.12
  */
@@ -1513,7 +1515,8 @@
       *position = new_center + (PANGO_SCALE * thickness_pixels) / 2;
     }
 
-  *thickness = thickness_pixels * PANGO_SCALE;
+  if (*thickness > PANGO_SCALE)
+    *thickness = thickness_pixels * PANGO_SCALE;
 }
 
 /**

Steps to reproduce:


Actual results:


Expected results:


Does this happen every time?


Other information:
Comment 1 GNOME Infrastructure Team 2018-05-22 12:44:50 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pango/issues/144.