summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--docs/tmpl/glyphs.sgml4
-rw-r--r--pango/pango-layout.c19
-rw-r--r--pango/pango-matrix.c15
-rw-r--r--pango/pango-types.h4
-rw-r--r--pango/pango-utils.c51
6 files changed, 72 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index bdd3e2e0..45008911 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2008-01-21 Behdad Esfahbod <behdad@gnome.org>
+
+ Bug 508002 – change pango_layout_pixel_extents() to round logical rect
+ to be inclusive
+
+ * pango/pango-layout.c (pango_layout_get_pixel_extents),
+ (pango_layout_line_get_pixel_extents): Round extents to pixels
+ inclusively. That is, pass both ink_rect and logical_rect as first
+ argument to pango_extents_to_pixels().
+
+ * pango/pango-matrix.c (pango_matrix_transform_pixel_rectangle):
+ Fix rounding.
+
+ * pango/pango-types.h:
+ * docs/tmpl/glyphs.sgml:
+ * pango/pango-utils.c (pango_extents_to_pixels):
+ Rename pango_extents_to_pixels() function arguments from @ink_rect and
+ @logical_rect to @inclusive and @nearest. Given that this API is a
+ fairly new addition and not commonly used, language bindings are
+ encouraged to update their argument names accordingly. Moreover, they
+ are encouraged to wrap this function as two different calls:
+ extents_to_pixels_inclusive() and extents_to_pixels_nearest(), or
+ similar conventions that best reflect their native language.
+
2008-01-16 Behdad Esfahbod <behdad@gnome.org>
* pango/opentype/Makefile.am: Remove COPYING.GPL and COPYING.FTL that
diff --git a/docs/tmpl/glyphs.sgml b/docs/tmpl/glyphs.sgml
index 5f019c1c..fb9bd7bf 100644
--- a/docs/tmpl/glyphs.sgml
+++ b/docs/tmpl/glyphs.sgml
@@ -156,8 +156,8 @@ horizontal origin.
</para>
-@ink_rect:
-@logical_rect:
+@inclusive:
+@nearest:
<!-- ##### STRUCT PangoMatrix ##### -->
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 235f0731..c1c79999 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -2576,12 +2576,9 @@ pango_layout_get_extents (PangoLayout *layout,
*
* Computes the logical and ink extents of @layout in device units.
* This function just calls pango_layout_get_extents() followed by
- * pango_extents_to_pixels().
- *
- * See pango_extents_to_pixels() for details of how ink and logical rectangles
- * are rounded to pixels. In certain situations you may want to use
- * pango_layout_get_extents() directly and pass the resulting logical
- * rectangle to pango_extents_to_pixels() as an ink rectangle().
+ * two pango_extents_to_pixels() calls, rounding @ink_rect and @logical_rect
+ * such that the rounded rectangles fully contain the unrounded one (that is,
+ * passes them as first argument to pango_extents_to_pixels()).
**/
void
pango_layout_get_pixel_extents (PangoLayout *layout,
@@ -2591,7 +2588,8 @@ pango_layout_get_pixel_extents (PangoLayout *layout,
g_return_if_fail (PANGO_IS_LAYOUT (layout));
pango_layout_get_extents (layout, ink_rect, logical_rect);
- pango_extents_to_pixels (ink_rect, logical_rect);
+ pango_extents_to_pixels (ink_rect, NULL);
+ pango_extents_to_pixels (logical_rect, NULL);
}
/**
@@ -4610,7 +4608,9 @@ pango_layout_line_new (PangoLayout *layout)
*
* Computes the logical and ink extents of @layout_line in device units.
* This function just calls pango_layout_line_get_extents() followed by
- * pango_extents_to_pixels().
+ * two pango_extents_to_pixels() calls, rounding @ink_rect and @logical_rect
+ * such that the rounded rectangles fully contain the unrounded one (that is,
+ * passes them as first argument to pango_extents_to_pixels()).
**/
void
pango_layout_line_get_pixel_extents (PangoLayoutLine *layout_line,
@@ -4620,7 +4620,8 @@ pango_layout_line_get_pixel_extents (PangoLayoutLine *layout_line,
g_return_if_fail (LINE_IS_VALID (layout_line));
pango_layout_line_get_extents (layout_line, ink_rect, logical_rect);
- pango_extents_to_pixels (ink_rect, logical_rect);
+ pango_extents_to_pixels (ink_rect, NULL);
+ pango_extents_to_pixels (logical_rect, NULL);
}
/*
diff --git a/pango/pango-matrix.c b/pango/pango-matrix.c
index a8df59e3..3168be35 100644
--- a/pango/pango-matrix.c
+++ b/pango/pango-matrix.c
@@ -332,8 +332,9 @@ pango_matrix_transform_point (const PangoMatrix *matrix,
* If you have the rectangle in Pango units and want to convert to
* transformed pixel bounding box, it is more accurate to transform it first
* (using this function) and pass the result to pango_extents_to_pixels(),
- * as @ink_rect. However, there is a reason that you may want to convert
- * to pixels first and then transform, and that is when the transformed
+ * first argument, for an inclusive rounded rectangle.
+ * However, there are valid reasons that you may want to convert
+ * to pixels first and then transform, for example when the transformed
* coordinates may overflow in Pango units (large matrix translation for
* example).
*
@@ -408,7 +409,7 @@ pango_matrix_transform_rectangle (const PangoMatrix *matrix,
*
* For better accuracy, you should use pango_matrix_transform_rectangle() on
* original rectangle in Pango units and convert to pixels afterward
- * using pango_extents_to_pixels() as @ink_rect.
+ * using pango_extents_to_pixels()'s first argument.
*
* Since: 1.16
**/
@@ -460,8 +461,8 @@ pango_matrix_transform_pixel_rectangle (const PangoMatrix *matrix,
max_y = quad_y[i];
}
- rect->x = min_x;
- rect->y = min_y;
- rect->width = max_x - rect->x;
- rect->height = max_y - rect->y;
+ rect->x = floor (min_x);
+ rect->y = floor (min_y);
+ rect->width = ceil (max_x - rect->x);
+ rect->height = ceil (max_y - rect->y);
}
diff --git a/pango/pango-types.h b/pango/pango-types.h
index 642a06c6..41d68e98 100644
--- a/pango/pango-types.h
+++ b/pango/pango-types.h
@@ -84,8 +84,8 @@ struct _PangoRectangle
#define PANGO_LBEARING(rect) ((rect).x)
#define PANGO_RBEARING(rect) ((rect).x + (rect).width)
-void pango_extents_to_pixels (PangoRectangle *ink_rect,
- PangoRectangle *logical_rect);
+void pango_extents_to_pixels (PangoRectangle *inclusive,
+ PangoRectangle *nearest);
/**
* PangoDirection:
diff --git a/pango/pango-utils.c b/pango/pango-utils.c
index f4b52d71..580a4d3f 100644
--- a/pango/pango-utils.c
+++ b/pango/pango-utils.c
@@ -1655,52 +1655,53 @@ pango_units_to_double (int i)
/**
* pango_extents_to_pixels:
- * @ink_rect: ink rectangle to convert, or %NULL.
- * @logical_rect: logical rectangle to convert, or %NULL.
+ * @inclusive: rectangle to round to pixels inclusively, or %NULL.
+ * @nearest: rectangle to round to nearest pixels, or %NULL.
*
* Converts extents from Pango units to device units, dividing by the
* %PANGO_SCALE factor and performing rounding.
*
- * The ink rectangle is converted by flooring the x/y coordinates and extending
+ * The @inclusive rectangle is converted by flooring the x/y coordinates and extending
* width/height, such that the final rectangle completely includes the original
* rectangle.
*
- * The logical rectangle is converted by rounding the coordinates
- * of the rectangle to the nearest device unit.
+ * The @nearest rectangle is converted by rounding the coordinates
+ * of the rectangle to the nearest device unit (pixel).
*
- * Note that in certain situations you may want pass a logical extents
- * rectangle to this function as @ink_rect. The rule is: if you want the
- * resulting device-space rectangle to completely contain the original
- * rectangle, pass it in as @ink_rect.
+ * The rule to which argument to use is: if you want the resulting device-space
+ * rectangle to completely contain the original rectangle, pass it in as @inclusive.
+ * If you want two touching-but-not-overlapping rectangles stay
+ * touching-but-not-overlapping after rounding to device units, pass them in
+ * as @nearest.
*
* Since: 1.16
**/
void
-pango_extents_to_pixels (PangoRectangle *ink_rect,
- PangoRectangle *logical_rect)
+pango_extents_to_pixels (PangoRectangle *inclusive,
+ PangoRectangle *nearest)
{
- if (ink_rect)
+ if (inclusive)
{
- int orig_x = ink_rect->x;
- int orig_y = ink_rect->y;
+ int orig_x = inclusive->x;
+ int orig_y = inclusive->y;
- ink_rect->x = PANGO_PIXELS_FLOOR (ink_rect->x);
- ink_rect->y = PANGO_PIXELS_FLOOR (ink_rect->y);
+ inclusive->x = PANGO_PIXELS_FLOOR (inclusive->x);
+ inclusive->y = PANGO_PIXELS_FLOOR (inclusive->y);
- ink_rect->width = PANGO_PIXELS_CEIL (orig_x + ink_rect->width ) - ink_rect->x;
- ink_rect->height = PANGO_PIXELS_CEIL (orig_y + ink_rect->height) - ink_rect->y;
+ inclusive->width = PANGO_PIXELS_CEIL (orig_x + inclusive->width ) - inclusive->x;
+ inclusive->height = PANGO_PIXELS_CEIL (orig_y + inclusive->height) - inclusive->y;
}
- if (logical_rect)
+ if (nearest)
{
- int orig_x = logical_rect->x;
- int orig_y = logical_rect->y;
+ int orig_x = nearest->x;
+ int orig_y = nearest->y;
- logical_rect->x = PANGO_PIXELS (logical_rect->x);
- logical_rect->y = PANGO_PIXELS (logical_rect->y);
+ nearest->x = PANGO_PIXELS (nearest->x);
+ nearest->y = PANGO_PIXELS (nearest->y);
- logical_rect->width = PANGO_PIXELS (orig_x + logical_rect->width ) - logical_rect->x;
- logical_rect->height = PANGO_PIXELS (orig_y + logical_rect->height) - logical_rect->y;
+ nearest->width = PANGO_PIXELS (orig_x + nearest->width ) - nearest->x;
+ nearest->height = PANGO_PIXELS (orig_y + nearest->height) - nearest->y;
}
}