[cairo-commit] 5 commits - src/cairo-atsui-font.c src/cairo-directfb-surface.c src/cairo-ft-font.c src/cairo-glitz-surface.c src/cairo-image-surface.c src/cairo-paginated-surface.c src/cairo-ps-surface.c src/cairo-scaled-font.c src/cairo-svg-surface.c src/cairo-xcb-surface.c src/cairo-xlib-surface.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Aug 20 18:02:12 PDT 2007


 src/cairo-atsui-font.c        |    4 -
 src/cairo-directfb-surface.c  |    4 -
 src/cairo-ft-font.c           |   46 ++++++++-------
 src/cairo-glitz-surface.c     |    8 +-
 src/cairo-image-surface.c     |   10 +--
 src/cairo-paginated-surface.c |    1 
 src/cairo-ps-surface.c        |   12 ++--
 src/cairo-scaled-font.c       |  122 +++++++++++++++++++++++++++++++++++++++---
 src/cairo-svg-surface.c       |    2 
 src/cairo-xcb-surface.c       |   40 -------------
 src/cairo-xlib-surface.c      |   40 -------------
 11 files changed, 163 insertions(+), 126 deletions(-)

New commits:
diff-tree bf4bdbb6076dbe3b74534bc4308dbc9213bf628d (from 31f5aafa36015ee6ea8ff769c2e1d5841f62642f)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Aug 20 20:29:51 2007 -0400

    [cairo-scaled-font] Document how glyph surfaces use device offsets

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 967e50b..cb3af9f 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -34,11 +34,117 @@
  *	Carl D. Worth <cworth at cworth.org>
  *      Graydon Hoare <graydon at redhat.com>
  *      Owen Taylor <otaylor at redhat.com>
+ *      Behdad Esfahbod <behdad at behdad.org>
  */
 
 #include "cairoint.h"
 #include "cairo-scaled-font-private.h"
 
+/*
+ *  NOTES:
+ *
+ *  To store rasterizations of glyphs, we use an image surface and the
+ *  device offset to represent the glyph origin.
+ *
+ *  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
+ *           |                |
+ *           |                |
+ *           +----------------+
+ *                    (width-x,height-y)
+ *
+ *  Surface space:
+ *         (0,0) <-- surface-space origin
+ *           +---------------+
+ *           |      .        |
+ *           |      .        |
+ *           |......(x,y) <--|-- device_offset
+ *           |               |
+ *           |               |
+ *           +---------------+
+ *                     (width,height)
+ *
+ *  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
+ *           |                |
+ *           |                |
+ *           +----------------+
+ *                    (width+x_bearing,height+y_bearing)
+ *
+ *      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.
+ */
+
 static cairo_bool_t
 _cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
 {
diff-tree 31f5aafa36015ee6ea8ff769c2e1d5841f62642f (from d55da1aa621d76b1411300932be5d37883b25dfa)
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
             |                |
             |                |
             +----------------+
                      (width-x,height-y)
    
    Surface space:
           (0,0) <-- surface-space origin
             +---------------+
             |      .        |
             |      .        |
             |......(x,y) <--|-- device_offset
             |               |
             |               |
             +---------------+
                       (width,height)
    
    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
             |                |
             |                |
             +----------------+
                      (width+x_bearing,height+y_bearing)
    
        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.

diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index d1196f0..1e174ec 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -730,8 +730,8 @@ _cairo_atsui_scaled_font_init_glyph_surf
     /* correct for difference between cairo and quartz 
      * coordinate systems.
      */
-    cairo_surface_set_device_offset ((cairo_surface_t *)surface, left, 
-				    -bbox.size.height - bottom);
+    cairo_surface_set_device_offset ((cairo_surface_t *)surface,
+				     -left, (bbox.size.height + bottom));
     _cairo_scaled_glyph_set_surface (scaled_glyph,
 				     &base,
 				     surface);
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 78b3517..409f79d 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1284,8 +1284,8 @@ _directfb_acquire_font_cache (cairo_dire
                 return CAIRO_INT_STATUS_UNSUPPORTED;
         }
         
-        points[n].x = _cairo_lround (glyphs[i].x + img->base.device_transform.x0);
-        points[n].y = _cairo_lround (glyphs[i].y + img->base.device_transform.y0);
+        points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
+        points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);
         
         if (points[n].x >= surface->width  ||
             points[n].y >= surface->height ||
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 04441d0..201d1ad 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -584,7 +584,6 @@ _compute_transform (cairo_ft_font_transf
 		    cairo_matrix_t      *scale)
 {
     cairo_matrix_t normalized = *scale;
-    double tx, ty;
 
     /* The font matrix has x and y "scale" components which we extract and
      * use as character scale values. These influence the way freetype
@@ -603,7 +602,7 @@ _compute_transform (cairo_ft_font_transf
 	_cairo_matrix_get_affine (&normalized,
 				  &sf->shape[0][0], &sf->shape[0][1],
 				  &sf->shape[1][0], &sf->shape[1][1],
-				  &tx, &ty);
+				  NULL, NULL);
     } else {
 	sf->shape[0][0] = sf->shape[1][1] = 1.0;
 	sf->shape[0][1] = sf->shape[1][0] = 0.0;
@@ -1058,11 +1057,13 @@ _render_glyph_outline (FT_Face          
 
     /*
      * Note: the font's coordinate system is upside down from ours, so the
-     * Y coordinate of the control box needs to be negated.
+     * Y coordinate of the control box needs to be negated.  Moreover, device
+     * offsets are position of glyph origin relative to top left while xMin
+     * and yMax are offsets of top left relative to origin.  Another negation.
      */
     cairo_surface_set_device_offset (&(*surface)->base,
-				     floor ((double) cbox.xMin / 64.0),
-				     floor (-(double) cbox.yMax / 64.0));
+				     floor (-(double) cbox.xMin / 64.0),
+				     floor (+(double) cbox.yMax / 64.0));
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1096,11 +1097,14 @@ _render_glyph_bitmap (FT_Face		      fac
 
     /*
      * Note: the font's coordinate system is upside down from ours, so the
-     * Y coordinate of the control box needs to be negated.
+     * Y coordinate of the control box needs to be negated.  Moreover, device
+     * offsets are position of glyph origin relative to top left while
+     * bitmap_left and bitmap_top are offsets of top left relative to origin.
+     * Another negation.
      */
     cairo_surface_set_device_offset (&(*surface)->base,
-				     glyphslot->bitmap_left,
-				     -glyphslot->bitmap_top);
+				     -glyphslot->bitmap_left,
+				     +glyphslot->bitmap_top);
 
     return status;
 }
@@ -1115,7 +1119,7 @@ _transform_glyph_bitmap (cairo_matrix_t 
     cairo_surface_t *image;
     double x[4], y[4];
     double origin_x, origin_y;
-    int origin_width, origin_height;
+    int orig_width, orig_height;
     int i;
     int x_min, y_min, x_max, y_max;
     int width, height;
@@ -1129,19 +1133,19 @@ _transform_glyph_bitmap (cairo_matrix_t 
     original_to_transformed = *shape;
     
     cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
-    origin_width = cairo_image_surface_get_width (&(*surface)->base);
-    origin_height = cairo_image_surface_get_height (&(*surface)->base);
+    orig_width = cairo_image_surface_get_width (&(*surface)->base);
+    orig_height = cairo_image_surface_get_height (&(*surface)->base);
 
     cairo_matrix_translate (&original_to_transformed,
-			    origin_x, origin_y);
+			    -origin_x, -origin_y);
 
     /* Find the bounding box of the original bitmap under that
      * transform
      */
-    x[0] = 0;            y[0] = 0;
-    x[1] = origin_width; y[1] = 0;
-    x[2] = origin_width; y[2] = origin_height;
-    x[3] = 0;            y[3] = origin_height;
+    x[0] = 0;          y[0] = 0;
+    x[1] = orig_width; y[1] = 0;
+    x[2] = orig_width; y[2] = orig_height;
+    x[3] = 0;          y[3] = orig_height;
 
     for (i = 0; i < 4; i++)
       cairo_matrix_transform_point (&original_to_transformed,
@@ -1153,11 +1157,11 @@ _transform_glyph_bitmap (cairo_matrix_t 
     for (i = 1; i < 4; i++) {
 	if (x[i] < x_min)
 	    x_min = floor (x[i]);
-	if (x[i] > x_max)
+	else if (x[i] > x_max)
 	    x_max = ceil (x[i]);
 	if (y[i] < y_min)
 	    y_min = floor (y[i]);
-	if (y[i] > y_max)
+	else if (y[i] > y_max)
 	    y_max = ceil (y[i]);
     }
 
@@ -1216,8 +1220,6 @@ _transform_glyph_bitmap (cairo_matrix_t 
     /* Now update the cache entry for the new bitmap, recomputing
      * the origin based on the final transform.
      */
-    origin_x = - origin_x;
-    origin_y = - origin_y;
     cairo_matrix_transform_point (&original_to_transformed,
 				  &origin_x, &origin_y);
 
@@ -1226,8 +1228,8 @@ _transform_glyph_bitmap (cairo_matrix_t 
     cairo_surface_destroy (&old_image->base);
 
     cairo_surface_set_device_offset (&(*surface)->base,
-				     - _cairo_lround (origin_x),
-				     - _cairo_lround (origin_y));
+				     _cairo_lround (origin_x),
+				     _cairo_lround (origin_y));
     return status;
 }
 
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 00a3d68..8f497a9 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -2202,8 +2202,8 @@ _cairo_glitz_surface_old_show_glyphs (ca
 		x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;
 		y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;
 
-		x1 = _cairo_lround (glyphs[i].x) + x_offset;
-		y1 = _cairo_lround (glyphs[i].y) + y_offset;
+		x1 = _cairo_lround (glyphs[i].x - x_offset);
+		y1 = _cairo_lround (glyphs[i].y - y_offset);
 		x2 = x1 + glyph_private->area->width;
 		y2 = y1 + glyph_private->area->height;
 
@@ -2246,8 +2246,8 @@ _cairo_glitz_surface_old_show_glyphs (ca
 
 		x_offset = scaled_glyphs[i]->surface->base.device_transform.x0;
 		y_offset = scaled_glyphs[i]->surface->base.device_transform.y0;
-		x1 = _cairo_lround (glyphs[i].x) + x_offset;
-		y1 = _cairo_lround (glyphs[i].y) + y_offset;
+		x1 = _cairo_lround (glyphs[i].x - x_offset);
+		y1 = _cairo_lround (glyphs[i].y - y_offset);
 
 		glitz_composite (_glitz_operator (op),
 				 src->surface,
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 7db9d0a..05746a8 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -574,12 +574,12 @@ _cairo_ps_surface_emit_bitmap_glyph_data
 				 "   /BitsPerComponent 1\n",
 				 image->width,
 				 image->height,
-				 image->base.device_transform_inverse.xx,
-				 image->base.device_transform_inverse.yx,
-				 image->base.device_transform_inverse.xy,
-				 image->base.device_transform_inverse.yy,
-				 image->base.device_transform_inverse.x0,
-				 image->base.device_transform_inverse.y0);
+				 image->base.device_transform.xx,
+				 image->base.device_transform.yx,
+				 image->base.device_transform.xy,
+				 image->base.device_transform.yy,
+				 image->base.device_transform.x0,
+				 image->base.device_transform.y0);
 
     _cairo_output_stream_printf (surface->final_stream,
 				 "   /DataSource   {<");
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index a2920de..967e50b 100755
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1110,10 +1110,8 @@ _cairo_scaled_font_show_glyphs (cairo_sc
 
 	/* round glyph locations to the nearest pixel */
 	/* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */
-	x = _cairo_lround (glyphs[i].x +
-                           glyph_surface->base.device_transform.x0);
-	y = _cairo_lround (glyphs[i].y +
-                           glyph_surface->base.device_transform.y0);
+	x = _cairo_lround (glyphs[i].x - glyph_surface->base.device_transform.x0);
+	y = _cairo_lround (glyphs[i].y - glyph_surface->base.device_transform.y0);
 
 	_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);
 
@@ -1288,7 +1286,7 @@ _trace_mask_to_path (cairo_image_surface
 	    for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
 		if (byte & (1 << bit)) {
 		    status = _add_unit_rectangle_to_path (path,
-							  x + xoff, y + yoff);
+							  x - xoff, y - yoff);
 		    if (status)
 			return status;
 		}
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 956dbb7..6be3098 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -616,7 +616,7 @@ _cairo_svg_document_emit_bitmap_glyph_da
     }
 
     _cairo_output_stream_printf (document->xml_node_glyphs, "<g");
-    _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", ">/n", &image->base.device_transform);
+    _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", ">/n", &image->base.device_transform_inverse);
 
     for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
 	for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index d10ee90..bcdadae 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -2087,45 +2087,9 @@ _cairo_xcb_surface_add_glyph (xcb_connec
 	    goto BAIL;
     }
 
-    /*
-     *  Most of the font rendering system thinks of glyph tiles as having
-     *  an origin at (0,0) and an x and y bounding box "offset" which
-     *  extends possibly off into negative coordinates, like so:
-     *
-     *
-     *       (x,y) <-- probably negative numbers
-     *         +----------------+
-     *         |      .         |
-     *         |      .         |
-     *         |......(0,0)     |
-     *         |                |
-     *         |                |
-     *         +----------------+
-     *                  (width+x,height+y)
-     *
-     *  This is a postscript-y model, where each glyph has its own
-     *  coordinate space, so it's what we expose in terms of metrics. It's
-     *  apparently what everyone's expecting. Everyone except the Render
-     *  extension. Render wants to see a glyph tile starting at (0,0), with
-     *  an origin offset inside, like this:
-     *
-     *       (0,0)
-     *         +---------------+
-     *         |      .        |
-     *         |      .        |
-     *         |......(x,y)    |
-     *         |               |
-     *         |               |
-     *         +---------------+
-     *                   (width,height)
-     *
-     *  Luckily, this is just the negation of the numbers we already have
-     *  sitting around for x and y.
-     */
-
     /* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */
-    glyph_info.x = - _cairo_lround (glyph_surface->base.device_transform.x0);
-    glyph_info.y = - _cairo_lround (glyph_surface->base.device_transform.y0);
+    glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0);
+    glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0);
     glyph_info.width = glyph_surface->width;
     glyph_info.height = glyph_surface->height;
     glyph_info.x_off = 0;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4c4b561..7c4fa02 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2691,45 +2691,9 @@ _cairo_xlib_surface_add_glyph (Display *
 	    goto BAIL;
     }
 
-    /*
-     *  Most of the font rendering system thinks of glyph tiles as having
-     *  an origin at (0,0) and an x and y bounding box "offset" which
-     *  extends possibly off into negative coordinates, like so:
-     *
-     *
-     *       (x,y) <-- probably negative numbers
-     *         +----------------+
-     *         |      .         |
-     *         |      .         |
-     *         |......(0,0)     |
-     *         |                |
-     *         |                |
-     *         +----------------+
-     *                  (width+x,height+y)
-     *
-     *  This is a postscript-y model, where each glyph has its own
-     *  coordinate space, so it's what we expose in terms of metrics. It's
-     *  apparently what everyone's expecting. Everyone except the Render
-     *  extension. Render wants to see a glyph tile starting at (0,0), with
-     *  an origin offset inside, like this:
-     *
-     *       (0,0)
-     *         +---------------+
-     *         |      .        |
-     *         |      .        |
-     *         |......(x,y)    |
-     *         |               |
-     *         |               |
-     *         +---------------+
-     *                   (width,height)
-     *
-     *  Luckily, this is just the negation of the numbers we already have
-     *  sitting around for x and y.
-     */
-
     /* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */
-    glyph_info.x = - _cairo_lround (glyph_surface->base.device_transform.x0);
-    glyph_info.y = - _cairo_lround (glyph_surface->base.device_transform.y0);
+    glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0);
+    glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0);
     glyph_info.width = glyph_surface->width;
     glyph_info.height = glyph_surface->height;
     glyph_info.xOff = scaled_glyph->x_advance;
diff-tree d55da1aa621d76b1411300932be5d37883b25dfa (from a394e5870e2c5ccedfd9d116b4a42c58b459334d)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 7 00:20:29 2007 -0800

    [scaled-font] Really ignore ctm translation
    
    Previously we were ignoring ctm translation in scaled fonts when hashing, but
    still storing it into the scaled font.  Now we zero the translation components
    when storing.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
old mode 100644
new mode 100755
index 01b1cc6..a2920de
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -297,14 +297,16 @@ _cairo_scaled_font_init_key (cairo_scale
     scaled_font->font_face = font_face;
     scaled_font->font_matrix = *font_matrix;
     scaled_font->ctm = *ctm;
+    /* ignore translation values in the ctm */
+    scaled_font->ctm.x0 = 0.;
+    scaled_font->ctm.y0 = 0.;
     scaled_font->options = *options;
 
-    /* We do a bytewise hash on the font matrices, ignoring the
-     * translation values in the ctm */
+    /* We do a bytewise hash on the font matrices */
     hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->font_matrix.xx),
 			    sizeof(cairo_matrix_t), hash);
     hash = _hash_bytes_fnv ((unsigned char *)(&scaled_font->ctm.xx),
-			    sizeof(double) * 4, hash);
+			    sizeof(cairo_matrix_t), hash);
 
     hash ^= (unsigned long) scaled_font->font_face;
 
diff-tree a394e5870e2c5ccedfd9d116b4a42c58b459334d (from 61f736d0d1166b050ee948ce2738feab0327ece9)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Feb 5 16:53:18 2007 -0500

    [cairo-image-surface] Simplify device-offset usage

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3059e78..27d6cba 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1143,15 +1143,15 @@ _cairo_image_surface_clone (cairo_image_
 	cairo_image_surface_create (format,
 				    surface->width, surface->height);
 
-    /* Use _cairo_surface_composite directly */
-    cr = cairo_create (&clone->base);
     cairo_surface_get_device_offset (&surface->base, &x, &y);
-    cairo_set_source_surface (cr, &surface->base, x, y);
+    cairo_surface_set_device_offset (&clone->base, x, y);
+
+    /* XXX Use _cairo_surface_composite directly */
+    cr = cairo_create (&clone->base);
+    cairo_set_source_surface (cr, &surface->base, 0, 0);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
     cairo_destroy (cr);
 
-    cairo_surface_set_device_offset (&clone->base, x, y);
-
     return clone;
 }
diff-tree 61f736d0d1166b050ee948ce2738feab0327ece9 (from f97bb5613a7fb3d92f2d730460f9c721ee13a41a)
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Feb 5 15:51:30 2007 -0500

    [cairo-paginated-surface] Add XXX mark to integer width,height arguments

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 00a1ef2..d687037 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -63,6 +63,7 @@ _cairo_paginated_surface_create_similar 
 					 width, height);
 }
 
+/* XXX The integer width,height here should be doubles and all uses updated */
 cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t				*target,
 				 cairo_content_t				 content,


More information about the cairo-commit mailing list