Re: Fixed point cairo.. or no cairo?



Jorn Baayen wrote:
> On Fri, 2006-08-11 at 09:42 +0100, Michael Meeks wrote:
>   
>> 	Is the common case of that a multiplication by a unit matrix, [ ie. a
>> no-op ;-] that could be elided if that's detectable /  propagate-able ?
>> [ though it seems there is no space in 'matrix' to ram an 'unsigned int
>> is-unit : 1' into ;-) Or is it perhaps a simple scaling [ reduce by 2x
>> the muls ? ].
>>     
>
> I'm not so sure. Carl?
>   

Matrix with values like { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } does not
require any multiplication, because result is the same as input. Both
gstate->ctm and gstate->target->device_transform had such values when I
run your test program. This often seems to be true for "real"
applications as well (tried gedit). Sometimes x0 and y0 are not 0.0, but
for such cases we could add another workaround (x += x0, y+= y0).

Does this patch make any difference in your tests? I can't measure it
myself because cairo_matrix_transform_point() takes only a tiny fraction
of time on my laptop.

-- 
Aivars

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 2f9079b..fd9c9bc 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1409,6 +1409,18 @@ _cairo_gstate_glyph_extents (cairo_gstat
     return CAIRO_STATUS_SUCCESS;
 }
 
+static int
+_cairo_gstate_must_transform (cairo_matrix_t *matrix)
+{
+    static const cairo_matrix_t no_transformation = {
+	.xx = 1., .yx = 0.,
+	.xy = 0., .yy = 1.,
+	.x0 = 0., .y0 = 0.
+    };
+
+    return memcmp (matrix, &no_transformation, sizeof(no_transformation));
+}
+
 cairo_status_t
 _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
 			   cairo_glyph_t *glyphs,
@@ -1418,6 +1430,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_
     cairo_pattern_union_t source_pattern;
     cairo_glyph_t *transformed_glyphs;
     int i;
+    int to_device, to_backend;
 
     if (gstate->source->status)
 	return gstate->source->status;
@@ -1434,14 +1447,23 @@ _cairo_gstate_show_glyphs (cairo_gstate_
     if (transformed_glyphs == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
+    to_device = _cairo_gstate_must_transform (&gstate->ctm);
+    to_backend = _cairo_gstate_must_transform (&gstate->target->device_transform);
+
     for (i = 0; i < num_glyphs; ++i)
     {
 	transformed_glyphs[i].index = glyphs[i].index;
 	transformed_glyphs[i].x = glyphs[i].x + gstate->font_matrix.x0;
 	transformed_glyphs[i].y = glyphs[i].y + gstate->font_matrix.y0;
-	_cairo_gstate_user_to_backend (gstate,
-				       &transformed_glyphs[i].x,
-				       &transformed_glyphs[i].y);
+
+	if (to_device)
+	    cairo_matrix_transform_point (&gstate->ctm,
+					  &transformed_glyphs[i].x,
+					  &transformed_glyphs[i].y);
+	if (to_backend)
+	    cairo_matrix_transform_point (&gstate->target->device_transform,
+				          &transformed_glyphs[i].x,
+				          &transformed_glyphs[i].y);
     }
 
     _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]