File ghostscript-fapi_fix_fontmatrix.diff of Package ghostscript-library

X-Git-Url: http://git.ghostscript.com/?p=ghostpdl.git;a=blobdiff_plain;f=gs%2Fpsi%2Ffapi_ft.c;h=88c63516222609db3776a57a4efe40a711516117;hp=deaa82d8a71a0201d6dd1c9385b6bdf3fd1fe060;hb=056c8a6dc2409db6ac06ead1fc1b58b277400b04;hpb=83e1c7b77e8a23ed0683b3677a7cccba94ad5fe8

diff --git a/gs/psi/fapi_ft.c b/gs/psi/fapi_ft.c
index deaa82d..88c6351 100644
--- a/gs/psi/fapi_ft.c
+++ b/gs/psi/fapi_ft.c
@@ -720,26 +720,25 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
     scaley = hypot ((double)a_transform->yx, (double)a_transform->yy);
 
     if (*xresp != *yresp) {
-        /* We need to give the resolution in "glyph space", taking account
-         * of rotation and shearing, so that makes life a little complicated
-         * when non-square resolutions are used.
+        /* To get good results, we have to pull the implicit scaling from
+         * non-square resolutions, and apply it in the matrix. This means
+         * we get the correct "shearing" effect for rotated glyphs.
+         * The previous solution was only effective for for glyphs whose
+         * axes were coincident with the axes of the page.
          */
-        ftscale_mat.xx = scalex;
-        ftscale_mat.xy = ftscale_mat.yx = 0;
-        ftscale_mat.yy = scaley;
-
-        FT_Matrix_Invert(&ftscale_mat);
+        bool use_x = true;
+                
+        if (*xresp < *yresp) {
+            use_x = false;
+        }
 
-        FT_Matrix_Multiply (a_transform, &ftscale_mat);
+        ftscale_mat.xx = (((double)(*xresp) / ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
+        ftscale_mat.xy = ftscale_mat.yx = 0;
+        ftscale_mat.yy = (((double)(*yresp) / ((double)(use_x ? (*xresp) : (*yresp)))) * 65536);
 
-        vectx.x = *xresp << 16;
-        vecty.y = *yresp << 16;
-        vectx.y = vecty.x = 0;
+        FT_Matrix_Multiply (&ftscale_mat, a_transform);
 
-        FT_Vector_Transform (&vectx, &ftscale_mat);
-        FT_Vector_Transform (&vecty, &ftscale_mat);
-        xres = (FT_UInt)((hypot ((double)vectx.x, (double)vecty.x) * (1.0/65536.0)) + 0.5);
-        yres = (FT_UInt)((hypot ((double)vectx.y, (double)vecty.y) * (1.0/65536.0)) + 0.5);
+        xres = yres = (use_x ? (*xresp) : (*yresp));
     }
     else {
         /* Life is considerably easier when square resolutions are in use! */
@@ -797,14 +796,21 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
         }
 
         /* We also have to watch for variable overflow in Freetype.
-         * I've opted to fiddle with the resolution here, as it is
-         * almost always a larger value than the text size, and therefore
-         * we have more scope to manipulate it.
+         * We fiddle with whichever of the resolution or the scale
+         * is larger for the current iteration, but change the scale
+         * by a smaller multiple, firstly because it is a floating point
+         * value, so we can, but also because varying the scale by larger
+         * amounts is more prone to causing rounding errors.
          */
         facty = 1.0;
-        while (scaley * yres > 256.0 * 72 && yres > 0) {
-            yres >>= 1;
-            facty *= 2.0;
+        while (scaley * yres > 512.0 * 72 && yres > 0 && scaley > 0.0) {
+            if (scaley < yres) {
+                yres >>= 1;
+                facty *= 2.0;
+            }
+            else {
+                scaley /= 1.25;
+            }
         }
 
         if (scalex < 10.0) {
@@ -820,9 +826,14 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
 
         /* see above */
         factx = 1.0;
-        while (scalex * xres > 256.0 * 72.0 && xres > 0) {
-            xres >>= 1;
-            factx *= 2.0;
+        while (scalex * xres > 512.0 * 72.0 && xres > 0 && scalex > 0.0) {
+            if (scalex < xres) {
+                xres >>= 1;
+                factx *= 2.0;
+            }
+            else {
+                scalex /= 1.25;
+            }
         }
     }
     else {
@@ -852,15 +863,21 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
             }
 
             /* We also have to watch for variable overflow in Freetype.
-             * I've opted to fiddle with the resolution here, as it is
-             * almost always a larger value than the text size, and therefore
-             * we have more scope to manipulate it.
+             * We fiddle with whichever of the resolution or the scale
+             * is larger for the current iteration.
              */
             fact = 1.0;
-            while (scalex * xres > 256.0 * 72 && xres > 0 && yres > 0) {
-                xres >>= 1;
-                yres >>= 1;
-                fact *= 2.0;
+            while (scalex * xres > 512.0 * 72 && xres > 0 && yres > 0
+                   && (scalex > 0.0 && scaley > 0.0)) {
+                if (scalex < xres) {
+                    xres >>= 1;
+                    yres >>= 1;
+                    fact *= 2.0;
+                }
+                else {
+                  scalex /= 1.25;
+                  scaley /= 1.25;
+                }
             }
         }
         else {
@@ -879,11 +896,17 @@ transform_decompose(FT_Matrix *a_transform, FT_UInt *xresp, FT_UInt *yresp,
 
             /* see above */
             fact = 1.0;
-            while (scaley * yres > 256.0 * 72.0 && xres > 0 && yres > 0) {
-                xres >>= 1;
-                yres >>= 1;
-
-                fact *= 2.0;
+            while (scaley * yres > 512.0 * 72.0 && (xres > 0 && yres > 0)
+                   && (scalex > 0.0 && scaley > 0.0)) {
+                if (scaley < yres) {
+                    xres >>= 1;
+                    yres >>= 1;
+                    fact *= 2.0;
+                }
+                else {
+                  scalex /= 1.25;
+                  scaley /= 1.25;
+                }
             }
         }
         factx = facty = fact;
openSUSE Build Service is sponsored by