At 02.02.2014 02:28, Octavio Alvarez wrote:
On 02/01/2014 02:14 PM, Octavio Alvarez wrote:
* Considering that the only difference between cairo-pdf and
cairo-alpha-png is the cairo_*_surface_create() call and that
cairosimple also renders to a PNG file, I considered cairosimple should
failed too, so I compiled and cairosimple. Text rendered correctly.

I must correct myself. I think I have some useful information.

After reading bug #341481 [1] (pango), I modified cairosimple, the
example from Pango docs, to use a tweakable cairo_scale(). I attach the
resulting code. Here's how to use it:

[1] https://bugzilla.gnome.org/show_bug.cgi?id=341481

Compile it with:

gcc -o cairosimple-scale cairosimple-scale.c \
   `pkg-config --cflags --libs pangocairo` -lm

Run it with:

./cairosimple-scale test-output.png

... and check test-output.png with eog or your favorite visualizer.

The new Pango bug is https://bugzilla.gnome.org/show_bug.cgi?id=700592

[...]
>
When debugging I changed DIAG_NOTES to fprintf(stderr, ...) because I
didn't know how to enable DIAG_NOTES and added some extras.

Please look into diacairo.h for the intended definition.

I noticed pango_font_description_set_absolute_size() was being called
with a value of 866. Curiously enough, in the default cairosimple, it
must be called with about 27 * PANGO_SCALE * DPI / 72.0 where
PANGO_SCALE == 1024 and DPI == 96, so about 36,000 to get the an
equivalent font size. This means a value of 866 would be the equivalent
of 0.6 points. This results in a big precision loss.

So, even though the Pango team clearly has to fix some calculations to
do, Dia also has to find the way to scale back to better font sizes.

Thanks for the analysis. I tend to agree although I think it could be fixed completely on the Pango side. But patching Dia is easier for me ;-)

I'm not sure my interpretation of the tests are correct, but if they
are, the options for fix/workaround for Dia are:

If there is another internal rendering scaling multiplier, it will be
simpler: to adjust cairo_scale() to bring it back to better values and
use the internal multiplier to adjust the actual sizes of the objects to
render.

If there is not, an implementation of it is in order, but this could
horribly require to modify each rendering calculation, like the
TWEAKABLE_SCALE technique.

The attached patch basically does a mix of the two. But only for fonts/text to avoid the huge modification otherwise required.

I gave it a shot, modifying renderer->scale at diacairo.c:165 but the
image just increases in DPI. Font size is still called with absolute
size of 866. So, no sucess yet.

Thanks again for the analysis. I'll commit the patch to master as soon as I've tested it on Linux with Pango > 1.32

        Hans

-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it.                -- Dilbert
diff --git a/plug-ins/cairo/diacairo-renderer.c 
b/plug-ins/cairo/diacairo-renderer.c
index 334a416..c9a0bc6 100644
--- a/plug-ins/cairo/diacairo-renderer.c
+++ b/plug-ins/cairo/diacairo-renderer.c
@@ -507,6 +507,15 @@ set_fillstyle(DiaRenderer *self, FillStyle mode)
   DIAG_STATE(DIA_CAIRO_RENDERER (self)->cr)
 }
 
+/* There is a recurring bug with pangocairo related to kerning and font 
scaling.
+ * See: https://bugzilla.gnome.org/buglist.cgi?quicksearch=341481+573261+700592
+ * Rather than waiting for another fix let's try to implement the ultimate work
+ * around. With Pango-1.32 and HarfBuzz the kludge in Pango is gone and 
apparently
+ * substituted with a precision problem. If we now use huge fonts when talking
+ * to Pango and downscale these with cairo it should work with all Pango 
versions.
+ */
+#define FONT_SIZE_TWEAK (72.0)
+
 static void
 set_font(DiaRenderer *self, DiaFont *font, real height)
 {
@@ -519,7 +528,7 @@ set_font(DiaRenderer *self, DiaFont *font, real height)
 
 #ifdef HAVE_PANGOCAIRO_H
   /* select font and size */
-  pango_font_description_set_absolute_size (pfd, (int)(size * PANGO_SCALE));
+  pango_font_description_set_absolute_size (pfd, (int)(size * FONT_SIZE_TWEAK 
* PANGO_SCALE));
   pango_layout_set_font_description (renderer->layout, pfd);
   pango_font_description_free (pfd);
 #else
@@ -905,14 +914,17 @@ draw_string(DiaRenderer *self,
     pango_layout_iter_get_line_extents (iter, NULL, &extents);
     shift = alignment == ALIGN_CENTER ? PANGO_RBEARING(extents)/2 :
             alignment == ALIGN_RIGHT ? PANGO_RBEARING(extents) : 0;
+    shift /= FONT_SIZE_TWEAK;
+    bline /= FONT_SIZE_TWEAK;
     cairo_move_to (renderer->cr, pos->x - (double)shift / PANGO_SCALE, pos->y 
- (double)bline / PANGO_SCALE);
     pango_layout_iter_free (iter);
   }
   /* does this hide bug #341481? */
-  pango_cairo_update_context (renderer->cr, pango_layout_get_context 
(renderer->layout));
-  pango_layout_context_changed (renderer->layout);
+  cairo_scale (renderer->cr, 1.0/FONT_SIZE_TWEAK, 1.0/FONT_SIZE_TWEAK);
+  pango_cairo_update_layout (renderer->cr, renderer->layout);
 
   pango_cairo_show_layout (renderer->cr, renderer->layout);
+  /* restoring the previous scale */
   cairo_restore (renderer->cr);
 #else
   /* using the 'toy API' */
diff --git a/plug-ins/cairo/diacairo.c b/plug-ins/cairo/diacairo.c
index ef5ac10..a18cf96 100644
--- a/plug-ins/cairo/diacairo.c
+++ b/plug-ins/cairo/diacairo.c
@@ -159,9 +159,10 @@ export_data(DiagramData *data, DiaContext *ctx,
     /* fall through */
   case OUTPUT_PNG :
     /* quite arbitrary, but consistent with ../pixbuf ;-) */
-    renderer->scale = 20.0 * data->paper.scaling; 
-    width  = ceil((data->extents.right - data->extents.left) * 
renderer->scale) + 1;
-    height = ceil((data->extents.bottom - data->extents.top) * 
renderer->scale) + 1;
+    renderer->scale = 20.0 * data->paper.scaling;
+    /* to avoid clipping this is highly obscure */
+    width  = ceil((data->extents.right - data->extents.left) * renderer->scale 
+ 0.5) + 1;
+    height = ceil((data->extents.bottom - data->extents.top) * renderer->scale 
+ 0.5) + 1;
     DIAG_NOTE(g_message ("PNG Surface %dx%d\n", (int)width, (int)height));
     /* use case screwed by API shakeup. We need to special case */
     renderer->surface = cairo_image_surface_create(
_______________________________________________
dia-list mailing list
dia-list@gnome.org
https://mail.gnome.org/mailman/listinfo/dia-list
FAQ at http://live.gnome.org/Dia/Faq
Main page at http://live.gnome.org/Dia

Reply via email to