summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog31
-rw-r--r--docs/pango-sections.txt7
-rw-r--r--docs/tmpl/glyphs.sgml56
-rw-r--r--examples/renderdemo.c48
-rw-r--r--pango/pango-layout.c59
-rw-r--r--pango/pango-matrix.c216
-rw-r--r--pango/pango-types.h24
-rw-r--r--pango/pango-utils.c84
-rw-r--r--pango/pango-utils.h5
-rw-r--r--pango/pango.def7
-rw-r--r--pango/pangocairo-fcfont.c20
11 files changed, 452 insertions, 105 deletions
diff --git a/ChangeLog b/ChangeLog
index 9bfa1237..afb5c969 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2007-01-04 Behdad Esfahbod <behdad@gnome.org>
+
+ Part of Bug 332266 – gdk_draw_layout fails for coordinates >= 2^21
+
+ * pango/pango-types.h:
+ * pango/pango-matrix.c: New public API:
+ pango_matrix_transform_distance()
+ pango_matrix_transform_point()
+ pango_matrix_transform_rectangle()
+ pango_matrix_transform_pixel_rectangle()
+
+ * pango/pango-utils.h:
+ * pango/pango-utils.c: New public API:
+ pango_units_from_double()
+ pango_units_to_double()
+ pango_extents_to_pixels()
+
+ * pango/pango-layout.c (pango_layout_get_pixel_extents),
+ (pango_layout_line_get_pixel_extents): Use pango_extents_to_pixels().
+
+ * pango/pangocairo-fcfont.c:
+ (pango_cairo_fc_font_glyph_extents_cache_init),
+ (compute_glyph_extents): Use pango_units_from_double().
+
+ * examples/renderdemo.c (do_output): Use
+ pango_matrix_transform_pixel_rectangle();
+
+ * pango/pango.def:
+ * docs/pango-sections.txt:
+ * docs/tmpl/glyphs.sgml: Update.
+
2007-01-03 Changwoo Ryu <cwryu@debian.org>
Bug 388702 - Crash when there's no Hangul glyph in the font.
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index c684a02d..271d4597 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -73,11 +73,14 @@ PANGO_SCALE
PANGO_PIXELS
PANGO_PIXELS_FLOOR
PANGO_PIXELS_CEIL
+pango_units_to_double
+pango_units_from_double
PangoRectangle
PANGO_ASCENT
PANGO_DESCENT
PANGO_LBEARING
PANGO_RBEARING
+pango_extents_to_pixels
PangoMatrix
PANGO_TYPE_MATRIX
PANGO_MATRIX_INIT
@@ -87,6 +90,10 @@ pango_matrix_translate
pango_matrix_scale
pango_matrix_rotate
pango_matrix_concat
+pango_matrix_transform_point
+pango_matrix_transform_distance
+pango_matrix_transform_rectangle
+pango_matrix_transform_pixel_rectangle
pango_matrix_get_font_scale_factor
pango_matrix_to_gravity
PangoGlyph
diff --git a/docs/tmpl/glyphs.sgml b/docs/tmpl/glyphs.sgml
index a2c8f087..fde3dd26 100644
--- a/docs/tmpl/glyphs.sgml
+++ b/docs/tmpl/glyphs.sgml
@@ -59,6 +59,24 @@ Converts a dimension to device units by ceiling.
@d: a dimension in Pango units.
+<!-- ##### FUNCTION pango_units_to_double ##### -->
+<para>
+
+</para>
+
+@i:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_units_from_double ##### -->
+<para>
+
+</para>
+
+@d:
+@Returns:
+
+
<!-- ##### STRUCT PangoRectangle ##### -->
<para>
The #PangoRectangle structure represents a rectangle. It is frequently
@@ -117,6 +135,15 @@ horizontal origin.
@rect: a #PangoRectangle
+<!-- ##### FUNCTION pango_extents_to_pixels ##### -->
+<para>
+
+</para>
+
+@ink_rect:
+@logical_rect:
+
+
<!-- ##### STRUCT PangoMatrix ##### -->
<para>
@@ -198,6 +225,35 @@ horizontal origin.
@new_matrix:
+<!-- ##### FUNCTION pango_matrix_transform_point ##### -->
+<para>
+
+</para>
+
+@matrix:
+@x:
+@y:
+
+
+<!-- ##### FUNCTION pango_matrix_transform_distance ##### -->
+<para>
+
+</para>
+
+@matrix:
+@dx:
+@dy:
+
+
+<!-- ##### FUNCTION pango_matrix_transform_rectangle ##### -->
+<para>
+
+</para>
+
+@matrix:
+@rect:
+
+
<!-- ##### FUNCTION pango_matrix_get_font_scale_factor ##### -->
<para>
diff --git a/examples/renderdemo.c b/examples/renderdemo.c
index 4c0912bc..9fd16ff0 100644
--- a/examples/renderdemo.c
+++ b/examples/renderdemo.c
@@ -154,17 +154,6 @@ get_options_string (void)
}
static void
-transform_point (PangoMatrix *matrix,
- double x_in,
- double y_in,
- double *x_out,
- double *y_out)
-{
- *x_out = x_in * matrix->xx + y_in * matrix->xy + matrix->x0;
- *y_out = x_in * matrix->yx + y_in * matrix->yy + matrix->y0;
-}
-
-static void
output_body (PangoContext *context,
const char *text,
RenderCallback render_cb,
@@ -245,19 +234,13 @@ do_output (PangoContext *context,
int *height_out)
{
PangoLayout *layout;
- PangoRectangle logical_rect;
+ PangoRectangle rect;
PangoMatrix matrix = PANGO_MATRIX_INIT;
PangoMatrix *orig_matrix;
gboolean supports_matrix;
int rotated_width, rotated_height;
int x = opt_margin;
int y = opt_margin;
- double p1x, p1y;
- double p2x, p2y;
- double p3x, p3y;
- double p4x, p4y;
- double minx, miny;
- double maxx, maxy;
int width, height;
width = 0;
@@ -283,15 +266,15 @@ do_output (PangoContext *context,
char *options_string = get_options_string ();
pango_context_set_base_gravity (context, PANGO_GRAVITY_SOUTH);
layout = make_layout (context, options_string, 10);
- pango_layout_get_extents (layout, NULL, &logical_rect);
+ pango_layout_get_extents (layout, NULL, &rect);
- width = MAX (width, PANGO_PIXELS (logical_rect.width));
- height += PANGO_PIXELS (logical_rect.height);
+ width = MAX (width, PANGO_PIXELS (rect.width));
+ height += PANGO_PIXELS (rect.height);
if (render_cb)
(*render_cb) (layout, x, y, cb_context, cb_data);
- y += PANGO_PIXELS (logical_rect.height);
+ y += PANGO_PIXELS (rect.height);
g_object_unref (layout);
g_free (options_string);
@@ -315,19 +298,14 @@ do_output (PangoContext *context,
&rotated_width, &rotated_height,
supports_matrix);
- transform_point (&matrix, 0, 0, &p1x, &p1y);
- transform_point (&matrix, rotated_width, 0, &p2x, &p2y);
- transform_point (&matrix, rotated_width, rotated_height, &p3x, &p3y);
- transform_point (&matrix, 0, rotated_height, &p4x, &p4y);
-
- minx = MIN (MIN (p1x, p2x), MIN (p3x, p4x));
- miny = MIN (MIN (p1y, p2y), MIN (p3y, p4y));
+ rect.x = rect.y = 0;
+ rect.width = rotated_width;
+ rect.height = rotated_height;
- maxx = MAX (MAX (p1x, p2x), MAX (p3x, p4x));
- maxy = MAX (MAX (p1y, p2y), MAX (p3y, p4y));
+ pango_matrix_transform_pixel_rectangle (&matrix, &rect);
- matrix.x0 = x - minx;
- matrix.y0 = y - miny;
+ matrix.x0 = x - rect.x;
+ matrix.y0 = y - rect.y;
set_transform (context, transform_cb, cb_context, cb_data, &matrix);
@@ -338,8 +316,8 @@ do_output (PangoContext *context,
&rotated_width, &rotated_height,
supports_matrix);
- width = MAX (width, maxx - minx);
- height += maxy - miny;
+ width = MAX (width, rect.width);
+ height += rect.height;
width += 2 * opt_margin;
height += 2 * opt_margin;
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 7d78af9a..cc6edc79 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -2387,9 +2387,8 @@ pango_layout_get_extents (PangoLayout *layout,
* layout or %NULL to indicate that the result is not needed.
*
* Computes the logical and ink extents of @layout in device units.
- * See pango_layout_get_extents(); this function just calls
- * pango_layout_get_extents() and then converts the extents to
- * device units using the %PANGO_SCALE factor.
+ * This function just calls pango_layout_get_extents() followed by
+ * pango_extents_to_pixels().
**/
void
pango_layout_get_pixel_extents (PangoLayout *layout,
@@ -2399,30 +2398,7 @@ pango_layout_get_pixel_extents (PangoLayout *layout,
g_return_if_fail (PANGO_IS_LAYOUT (layout));
pango_layout_get_extents (layout, ink_rect, logical_rect);
-
- if (ink_rect)
- {
- int orig_x = ink_rect->x;
- int orig_y = ink_rect->y;
-
- ink_rect->x = PANGO_PIXELS_FLOOR (ink_rect->x);
- ink_rect->y = PANGO_PIXELS_FLOOR (ink_rect->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;
- }
-
- if (logical_rect)
- {
- int orig_x = logical_rect->x;
- int orig_y = logical_rect->y;
-
- logical_rect->x = PANGO_PIXELS (logical_rect->x);
- logical_rect->y = PANGO_PIXELS (logical_rect->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;
- }
+ pango_extents_to_pixels (ink_rect, logical_rect);
}
/**
@@ -2432,7 +2408,7 @@ pango_layout_get_pixel_extents (PangoLayout *layout,
* @height: location to store the logical height, or %NULL
*
* Determines the logical width and height of a #PangoLayout
- * in Pango units. (device units scaled by %PANGO_SCALE). This
+ * in Pango units (device units scaled by %PANGO_SCALE). This
* is simply a convenience function around pango_layout_get_extents().
**/
void
@@ -4376,11 +4352,9 @@ pango_layout_line_new (PangoLayout *layout)
* @logical_rect: rectangle used to store the logical extents of the glyph
* string, or %NULL
*
- * Computes the logical and ink extents of a layout line. See
- * pango_font_get_glyph_extents() for details about the interpretation
- * of the rectangles. The returned rectangles are in device units, as
- * opposed to pango_layout_line_get_extents(), which returns the extents in
- * #PangoGlyphUnit.
+ * 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().
**/
void
pango_layout_line_get_pixel_extents (PangoLayoutLine *layout_line,
@@ -4390,24 +4364,7 @@ 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);
-
- if (ink_rect)
- {
- ink_rect->width = (ink_rect->width + PANGO_SCALE / 2) / PANGO_SCALE;
- ink_rect->height = (ink_rect->height + PANGO_SCALE / 2) / PANGO_SCALE;
-
- ink_rect->x = PANGO_PIXELS (ink_rect->x);
- ink_rect->y = PANGO_PIXELS (ink_rect->y);
- }
-
- if (logical_rect)
- {
- logical_rect->width = (logical_rect->width + PANGO_SCALE / 2) / PANGO_SCALE;
- logical_rect->height = (logical_rect->height + PANGO_SCALE / 2) / PANGO_SCALE;
-
- logical_rect->x = PANGO_PIXELS (logical_rect->x);
- logical_rect->y = PANGO_PIXELS (logical_rect->y);
- }
+ pango_extents_to_pixels (ink_rect, logical_rect);
}
/*
diff --git a/pango/pango-matrix.c b/pango/pango-matrix.c
index e63ecab1..49c05f0b 100644
--- a/pango/pango-matrix.c
+++ b/pango/pango-matrix.c
@@ -282,3 +282,219 @@ pango_matrix_to_gravity (const PangoMatrix *matrix)
return gravity;
}
+
+/**
+ * pango_matrix_transform_distance:
+ * @matrix: a #PangoMatrix, or %NULL
+ * @dx: in/out X component of a distance vector
+ * @dy: yn/out Y component of a distance vector
+ *
+ * Transforms the distance vector (@dx,@dy) by @matrix. This is
+ * similar to pango_matrix_transform_point() except that the translation
+ * components of the transformation are ignored. The calculation of
+ * the returned vector is as follows:
+ *
+ * <programlisting>
+ * dx2 = dx1 * xx + dy1 * xy;
+ * dy2 = dx1 * yx + dy1 * yy;
+ * </programlisting>
+ *
+ * Affine transformations are position invariant, so the same vector
+ * always transforms to the same vector. If (@x1,@y1) transforms
+ * to (@x2,@y2) then (@x1+@dx1,@y1+@dy1) will transform to
+ * (@x1+@dx2,@y1+@dy2) for all values of @x1 and @x2.
+ *
+ * Since: 1.16
+ **/
+void
+pango_matrix_transform_distance (const PangoMatrix *matrix,
+ double *dx,
+ double *dy)
+{
+ if (matrix)
+ {
+ double new_x, new_y;
+
+ new_x = (matrix->xx * *dx + matrix->xy * *dy);
+ new_y = (matrix->yx * *dx + matrix->yy * *dy);
+
+ *dx = new_x;
+ *dy = new_y;
+ }
+}
+
+/**
+ * pango_matrix_transform_point:
+ * @matrix: a #PangoMatrix, or %NULL
+ * @x: in/out X position
+ * @y: in/out Y position
+ *
+ * Transforms the point (@x, @y) by @matrix.
+ *
+ * Since: 1.16
+ **/
+void
+pango_matrix_transform_point (const PangoMatrix *matrix,
+ double *x,
+ double *y)
+{
+ if (matrix)
+ {
+ pango_matrix_transform_distance (matrix, x, y);
+
+ *x += matrix->x0;
+ *y += matrix->y0;
+ }
+}
+
+/**
+ * pango_matrix_transform_rectangle:
+ * @matrix: a #PangoMatrix, or %NULL
+ * @rect: in/out bounding box in Pango units, or %NULL
+ *
+ * First transforms the @rect using @matrix, then calculates the bounding box
+ * of the transformed rectangle. The rectangle should be in Pango units.
+ *
+ * This function is useful for example when you want to draw a rotated
+ * @PangoLayout to an image buffer, and want to know how large the image
+ * should be and how much you should shift the layout when rendering.
+ *
+ * If you have a rectangle in device units (pixels), use
+ * pango_matrix_transform_pixel_rectangle().
+ *
+ * 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 the 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
+ * coordinates may overflow in Pango units (large matrix translation for
+ * example).
+ *
+ * Since: 1.16
+ **/
+void
+pango_matrix_transform_rectangle (const PangoMatrix *matrix,
+ PangoRectangle *rect)
+{
+ int i;
+ double quad_x[4], quad_y[4];
+ double dx1, dy1;
+ double dx2, dy2;
+ double min_x, max_x;
+ double min_y, max_y;
+
+ if (!rect || !matrix)
+ return;
+
+ quad_x[0] = pango_units_to_double (rect->x);
+ quad_y[0] = pango_units_to_double (rect->y);
+ pango_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]);
+
+ dx1 = pango_units_to_double (rect->width);
+ dy1 = 0;
+ pango_matrix_transform_distance (matrix, &dx1, &dy1);
+ quad_x[1] = quad_x[0] + dx1;
+ quad_y[1] = quad_y[0] + dy1;
+
+ dx2 = 0;
+ dy2 = pango_units_to_double (rect->height);
+ pango_matrix_transform_distance (matrix, &dx2, &dy2);
+ quad_x[2] = quad_x[0] + dx2;
+ quad_y[2] = quad_y[0] + dy2;
+
+ quad_x[3] = quad_x[0] + dx1 + dx2;
+ quad_y[3] = quad_y[0] + dy1 + dy2;
+
+ min_x = max_x = quad_x[0];
+ min_y = max_y = quad_y[0];
+
+ for (i=1; i < 4; i++) {
+ if (quad_x[i] < min_x)
+ min_x = quad_x[i];
+ else if (quad_x[i] > max_x)
+ max_x = quad_x[i];
+
+ if (quad_y[i] < min_y)
+ min_y = quad_y[i];
+ else if (quad_y[i] > max_y)
+ max_y = quad_y[i];
+ }
+
+ rect->x = pango_units_from_double (min_x);
+ rect->y = pango_units_from_double (min_y);
+ rect->width = pango_units_from_double (max_x) - rect->x;
+ rect->height = pango_units_from_double (max_y) - rect->y;
+}
+
+/**
+ * pango_matrix_transform_pixel_rectangle:
+ * @matrix: a #PangoMatrix, or %NULL
+ * @rect: in/out bounding box in device units, or %NULL
+ *
+ * First transforms the @rect using @matrix, then calculates the bounding box
+ * of the transformed rectangle. The rectangle should be in device units
+ * (pixels).
+ *
+ * This function is useful for example when you want to draw a rotated
+ * @PangoLayout to an image buffer, and want to know how large the image
+ * should be and how much you should shift the layout when rendering.
+ *
+ * For better accuracy, you should use pango_matrix_transform_rectangle() on
+ * original rectangle in Pango units and convert to pixels afterwards
+ * using pango_extents_to_pixels() as the ink_rect.
+ *
+ * Since: 1.16
+ **/
+void
+pango_matrix_transform_pixel_rectangle (const PangoMatrix *matrix,
+ PangoRectangle *rect)
+{
+ int i;
+ double quad_x[4], quad_y[4];
+ double dx1, dy1;
+ double dx2, dy2;
+ double min_x, max_x;
+ double min_y, max_y;
+
+ if (!rect || !matrix)
+ return;
+
+ quad_x[0] = rect->x;
+ quad_y[0] = rect->y;
+ pango_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]);
+
+ dx1 = rect->width;
+ dy1 = 0;
+ pango_matrix_transform_distance (matrix, &dx1, &dy1);
+ quad_x[1] = quad_x[0] + dx1;
+ quad_y[1] = quad_y[0] + dy1;
+
+ dx2 = 0;
+ dy2 = rect->height;
+ pango_matrix_transform_distance (matrix, &dx2, &dy2);
+ quad_x[2] = quad_x[0] + dx2;
+ quad_y[2] = quad_y[0] + dy2;
+
+ quad_x[3] = quad_x[0] + dx1 + dx2;
+ quad_y[3] = quad_y[0] + dy1 + dy2;
+
+ min_x = max_x = quad_x[0];
+ min_y = max_y = quad_y[0];
+
+ for (i=1; i < 4; i++) {
+ if (quad_x[i] < min_x)
+ min_x = quad_x[i];
+ else if (quad_x[i] > max_x)
+ max_x = quad_x[i];
+
+ if (quad_y[i] < min_y)
+ min_y = quad_y[i];
+ else if (quad_y[i] > max_y)
+ 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;
+}
diff --git a/pango/pango-types.h b/pango/pango-types.h
index 221bc64b..75c31278 100644
--- a/pango/pango-types.h
+++ b/pango/pango-types.h
@@ -56,11 +56,8 @@ typedef guint32 PangoGlyph;
* integers and floating point.
*/
-/* Hint line position and thickness.
- */
-void pango_quantize_line_geometry (int *thickness,
- int *position);
-
+int pango_units_from_double (double d) G_GNUC_CONST;
+double pango_units_to_double (int i) G_GNUC_CONST;
/* Dummy typedef - internally it's a 'const char *' */
@@ -99,7 +96,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);
/**
* PangoDirection:
@@ -139,7 +137,7 @@ typedef enum {
PANGO_DIRECTION_NEUTRAL
} PangoDirection;
-PangoDirection pango_unichar_direction (gunichar ch);
+PangoDirection pango_unichar_direction (gunichar ch) G_GNUC_CONST;
PangoDirection pango_find_base_dir (const gchar *text,
gint length);
@@ -177,7 +175,7 @@ typedef enum {
PANGO_GRAVITY_AUTO
} PangoGravity;
-double pango_gravity_to_rotation (PangoGravity gravity);
+double pango_gravity_to_rotation (PangoGravity gravity) G_GNUC_CONST;
@@ -248,6 +246,16 @@ void pango_matrix_rotate (PangoMatrix *matrix,
double degrees);
void pango_matrix_concat (PangoMatrix *matrix,
const PangoMatrix *new_matrix);
+void pango_matrix_transform_point (const PangoMatrix *matrix,
+ double *x,
+ double *y);
+void pango_matrix_transform_distance (const PangoMatrix *matrix,
+ double *dx,
+ double *dy);
+void pango_matrix_transform_rectangle (const PangoMatrix *matrix,
+ PangoRectangle *rect);
+void pango_matrix_transform_pixel_rectangle (const PangoMatrix *matrix,
+ PangoRectangle *rect);
double pango_matrix_get_font_scale_factor (const PangoMatrix *matrix);
PangoGravity pango_matrix_to_gravity (const PangoMatrix *matrix);
diff --git a/pango/pango-utils.c b/pango/pango-utils.c
index 5b59e33c..ec1ba168 100644
--- a/pango/pango-utils.c
+++ b/pango/pango-utils.c
@@ -1856,3 +1856,87 @@ pango_gravity_to_rotation (PangoGravity gravity)
return rotation;
}
+/**
+ * pango_units_from_double:
+ * @d: double floating-point value
+ *
+ * Converts a floating-point number to Pango units: multiplys
+ * it by %PANGO_SCALE and rounds to nearest integer.
+ *
+ * Return value: the value in Pango units.
+ *
+ * Since: 1.16
+ */
+int
+pango_units_from_double (double d)
+{
+ return (int)floor (d * PANGO_SCALE + 0.5);
+}
+
+/**
+ * pango_units_to_double:
+ * @i: value in Pango units
+ *
+ * Converts a number in Pango units to floating-point: divides
+ * it by %PANGO_SCALE.
+ *
+ * Return value: the double value.
+ *
+ * Since: 1.16
+ */
+double
+pango_units_to_double (int i)
+{
+ return (double)i / PANGO_SCALE;
+}
+
+/**
+ * pango_extents_to_pixels:
+ * @ink_rect: ink rectangle to convert, or %NULL.
+ * @logical_rect: logical rectangle to convert, 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
+ * 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.
+ *
+ * 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.
+ *
+ * Since: 1.16
+ **/
+void
+pango_extents_to_pixels (PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ if (ink_rect)
+ {
+ int orig_x = ink_rect->x;
+ int orig_y = ink_rect->y;
+
+ ink_rect->x = PANGO_PIXELS_FLOOR (ink_rect->x);
+ ink_rect->y = PANGO_PIXELS_FLOOR (ink_rect->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;
+ }
+
+ if (logical_rect)
+ {
+ int orig_x = logical_rect->x;
+ int orig_y = logical_rect->y;
+
+ logical_rect->x = PANGO_PIXELS (logical_rect->x);
+ logical_rect->y = PANGO_PIXELS (logical_rect->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;
+ }
+}
diff --git a/pango/pango-utils.h b/pango/pango-utils.h
index 7b008a90..2d409c05 100644
--- a/pango/pango-utils.h
+++ b/pango/pango-utils.h
@@ -86,6 +86,11 @@ G_CONST_RETURN char * pango_get_lib_subdirectory (void);
#endif /* PANGO_ENABLE_BACKEND */
+/* Hint line position and thickness.
+ */
+void pango_quantize_line_geometry (int *thickness,
+ int *position);
+
/* A routine from fribidi that we either wrap or provide ourselves.
*/
guint8 * pango_log2vis_get_embedding_levels (const gchar *text,
diff --git a/pango/pango.def b/pango/pango.def
index 94aeccd3..14a591e3 100644
--- a/pango/pango.def
+++ b/pango/pango.def
@@ -86,6 +86,7 @@ EXPORTS
pango_engine_get_type
pango_engine_lang_get_type
pango_engine_shape_get_type
+ pango_extents_to_pixels
pango_find_base_dir
pango_find_map
pango_find_paragraph_boundary
@@ -287,6 +288,10 @@ EXPORTS
pango_matrix_rotate
pango_matrix_scale
pango_matrix_to_gravity
+ pango_matrix_transform_distance
+ pango_matrix_transform_pixel_rectangle
+ pango_matrix_transform_point
+ pango_matrix_transform_rectangle
pango_matrix_translate
pango_module_register
pango_parse_markup
@@ -343,6 +348,8 @@ EXPORTS
pango_trim_string
pango_underline_get_type
pango_unichar_direction
+ pango_units_from_double
+ pango_units_to_double
pango_variant_get_type
pango_version
pango_version_check
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
index 0854a032..1d90ab48 100644
--- a/pango/pangocairo-fcfont.c
+++ b/pango/pangocairo-fcfont.c
@@ -46,8 +46,6 @@ typedef struct _GlyphExtentsCacheEntry GlyphExtentsCacheEntry;
#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */
#define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)
-#define PANGO_UNITS(Double) ((int)floor((Double) * PANGO_SCALE + 0.5))
-
/* An entry in the fixed-size cache for the glyph -> ink_rect mapping.
* The cache is indexed by the lower N bits of the glyph (see
* GLYPH_CACHE_NUM_ENTRIES). For scripts with few glyphs,
@@ -296,20 +294,20 @@ pango_cairo_fc_font_glyph_extents_cache_init (PangoCairoFcFont *cffont)
cffont->font_extents.x = 0;
cffont->font_extents.width = 0;
- cffont->font_extents.height = PANGO_UNITS (font_extents.ascent + font_extents.descent);
+ cffont->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent);
switch (cffont->gravity)
{
default:
case PANGO_GRAVITY_AUTO:
case PANGO_GRAVITY_SOUTH:
- cffont->font_extents.y = - PANGO_UNITS (font_extents.ascent);
+ cffont->font_extents.y = - pango_units_from_double (font_extents.ascent);
break;
case PANGO_GRAVITY_NORTH:
- cffont->font_extents.y = - PANGO_UNITS (font_extents.descent);
+ cffont->font_extents.y = - pango_units_from_double (font_extents.descent);
break;
case PANGO_GRAVITY_EAST:
case PANGO_GRAVITY_WEST:
- cffont->font_extents.y = - PANGO_UNITS ((font_extents.ascent + font_extents.descent) * 0.5);
+ cffont->font_extents.y = - pango_units_from_double ((font_extents.ascent + font_extents.descent) * 0.5);
}
cffont->glyph_extents_cache = g_new0 (GlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);
@@ -335,11 +333,11 @@ compute_glyph_extents (PangoCairoFcFont *cffont,
&cairo_glyph, 1, &extents);
entry->glyph = glyph;
- entry->width = PANGO_UNITS (extents.x_advance);
- entry->ink_rect.x = PANGO_UNITS (extents.x_bearing);
- entry->ink_rect.y = PANGO_UNITS (extents.y_bearing);
- entry->ink_rect.width = PANGO_UNITS (extents.width);
- entry->ink_rect.height = PANGO_UNITS (extents.height);
+ entry->width = pango_units_from_double (extents.x_advance);
+ entry->ink_rect.x = pango_units_from_double (extents.x_bearing);
+ entry->ink_rect.y = pango_units_from_double (extents.y_bearing);
+ entry->ink_rect.width = pango_units_from_double (extents.width);
+ entry->ink_rect.height = pango_units_from_double (extents.height);
}
static GlyphExtentsCacheEntry *