[cairo-bugs] [Bug 20779] text improperly positioned - scaled font glyph device transform misapplied

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Sat Mar 21 13:26:22 PDT 2009


Behdad Esfahbod <freedesktop at behdad.org> changed:

           What    |Removed                     |Added
                 CC|                            |freedesktop at behdad.org
             Status|NEW                         |RESOLVED
         Resolution|                            |NOTOURBUG

--- Comment #1 from Behdad Esfahbod <freedesktop at behdad.org>  2009-03-21 13:26:19 PST ---
That's because of your patch.  Perhaps because the patch was written before the
following commit.  At any rate, cairo master compiles without fontconfig.

commit 31f5aafa36015ee6ea8ff769c2e1d5841f62642f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Feb 5 20:46:48 2007 -0500

    Fix device_offset misuse in all glyph surface uses

    Seems like all over the code, we have been using negated device_offset
    values for glyph surfaces.  Here is all the math(!):

    A device_transform converts from device space (a conceptual space) to
    surface space.  For simple cases of translation only, it's called a
    device_offset and is public API (cairo_surface_[gs]et_device_offset).
    A possibly better name for those functions could have been
    cairo_surface_[gs]et_origing.  So, that's what they do: they set where
    the device-space origin (0,0) is in the surface.  If the origin is inside
    the surface, device_offset values are positive.  It may look like this:

    Device space:
          (-x,-y) <-- negative numbers
             |      .         |
             |      .         |
             |......(0,0) <---|-- device-space origin
             |                |
             |                |

    Surface space:
           (0,0) <-- surface-space origin
             |      .        |
             |      .        |
             |......(x,y) <--|-- device_offset
             |               |
             |               |

    In other words: device_offset is the coordinates of the device-space
    origin relative to the top-left of the surface.

    We use device offsets in a couple of places:

      - Public API: To let toolkits like Gtk+ give user a surface that
        only represents part of the final destination (say, the expose
        area), but has the same device space as the destination.  In these
        cases device_offset is typically negative.  Example:

             application window
             |      .        |
             | (x,y).        |
             |......+---+    |
             |      |   | <--|-- expose area
             |      +---+    |

        In this case, the user of cairo API can set the device_space on
        the expose area to (-x,-y) to move the device space origin to that
        of the application window, such that drawing in the expose area
        surface and painting it in the application window has the same
        effect as drawing in the application window directly.  Gtk+ has
        been using this feature.

      - Glyph surfaces: In most font rendering systems, glyph surfaces
        have an origin at (0,0) and a bounding box that is typically
        represented as (x_bearing,y_bearing,width,height).  Depending on
        which way y progresses in the system, y_bearing may typically be
        negative (for systems similar to cairo, with origin at top left),
        or be positive (in systems like PDF with origin at bottom left).
        No matter which is the case, it is important to note that
        (x_bearing,y_bearing) is the coordinates of top-left of the glyph
        relative to the glyph origin.  That is, for example:

        Scaled-glyph space:

          (x_bearing,y_bearing) <-- negative numbers
             |      .         |
             |      .         |
             |......(0,0) <---|-- glyph origin
             |                |
             |                |

        Note the similarity of the origin to the device space.  That is
        exactly how we use the device_offset to represent scaled glyphs:
        to use the device-space origin as the glyph origin.

    Now compare the scaled-glyph space to device-space and surface-space
    and convince yourself that:

        (x_bearing,y_bearing) = (-x,-y) = - device_offset

    That's right.  If you are not convinced yet, contrast the definition
    of the two:

        "(x_bearing,y_bearing) is the coordinates of top-left of the
         glyph relative to the glyph origin."

        "In other words: device_offset is the coordinates of the
         device-space origin relative to the top-left of the surface."

    and note that glyph origin = device-space origin.

    So, that was the bug.  Fixing it removed lots of wonders and magic
    negation signs.

    The way I discovered the bug was that in the user-font API, to make
    rendering the glyph from meta-surface to an image-surface work I had
    to do:

        cairo_surface_set_device_offset (surface, -x_bearing, -y_bearing);
        _cairo_meta_surface_replay (meta_surface, surface);
        cairo_surface_set_device_offset (surface, x_bearing, y_bearing);

    This suggested that the use of device_offset for glyph origin is
    different from its use for rendering with meta-surface.  This reminded
    me of the large comment in the xlib backend blaming XRender for having
    weird glyph space, and of a similar problem I had in the PS backend
    for bitmap glyph positioning (see d47388ad759b0a1a0869655a87d9b5eb6ae2445d)

    ...those are all fixed now.

Configure bugmail: http://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.

More information about the cairo-bugs mailing list