[gs-commits] rev 10877 - trunk/gs/psi

chrisl at ghostscript.com chrisl at ghostscript.com
Mon Mar 8 09:28:49 UTC 2010


Author: chrisl
Date: 2010-03-08 09:28:49 +0000 (Mon, 08 Mar 2010)
New Revision: 10877

Modified:
   trunk/gs/psi/fapi_ft.c
   trunk/gs/psi/zfapi.c
Log:
Latest improvements to the FAPI/FT bridge code. This code resolves the issues with font matrices which do more than just scale. It is not yet "finished", but is too big a step forward to risk losing.

Modified: trunk/gs/psi/fapi_ft.c
===================================================================
--- trunk/gs/psi/fapi_ft.c	2010-03-05 21:01:34 UTC (rev 10876)
+++ trunk/gs/psi/fapi_ft.c	2010-03-08 09:28:49 UTC (rev 10877)
@@ -422,20 +422,51 @@
 static void
 transform_decompose(FT_Matrix *a_transform, FT_Fixed *a_x_scale, FT_Fixed *a_y_scale)
 {
-    float a = a_transform->xx / 65536.0;
-    float b = a_transform->xy / 65536.0;
-    float c = a_transform->yx / 65536.0;
-    float d = a_transform->yy / 65536.0;
-
-    float scale = sqrt(fabs(a * d - b * c));
-
-    a_transform->xx = a / scale * 65536.0;
-    a_transform->xy = b / scale * 65536.0;
-    a_transform->yx = c / scale * 65536.0;
-    a_transform->yy = d / scale * 65536.0;
-
-    *a_x_scale = scale * 65536.0;
-    *a_y_scale = scale * 65536.0;
+    double scalex, scaley, fact = 1.0;
+    FT_Matrix ftscale_mat;
+    
+    scalex = hypot ((double)a_transform->xx, (double)a_transform->xy) / 65536.0;
+    scaley = hypot ((double)a_transform->yx, (double)a_transform->yy) / 65536.0;
+    
+    /* FT clamps the width and height to a lower limit of 1.0 units
+     * (note: as FT stores it in 64ths of a unit, that is 64)
+     * So if either the width or the height are <1.0 here, we scale
+     * the width and height appropriately, and then compensate using
+     * the "final" matrix for FT
+     */
+    /* We use 1 1/64th to calculate the scale, so that we *guarantee* the
+     * scalex/y we calculate will be >64 after rounding.
+     */
+    if (scalex > scaley)
+    {
+        if (scaley < 1.0)
+	{
+	    fact = 1.016 / scaley;
+	    scaley = scaley * fact;
+	    scalex = scalex * fact;
+	}
+    }
+    else
+    {
+        if (scalex < 1.0)
+	{
+	    fact = 1.016 / scalex;
+	    scalex = scalex * fact;
+	    scaley = scaley * fact;
+	}
+    }
+    
+    ftscale_mat.xx = ((1.0 / scalex)) * 65536.0;
+    ftscale_mat.xy = 0;
+    ftscale_mat.yx = 0;
+    ftscale_mat.yy = ((1.0 / scaley)) * 65536.0;
+    
+    FT_Matrix_Multiply (a_transform, &ftscale_mat);
+    memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix));
+        
+    /* Return values ready scaled for FT */
+    *a_x_scale = scalex * 64;
+    *a_y_scale = scaley * 64;
 }
 
 /*
@@ -580,10 +611,9 @@
      */
     if (face)
     {
-	static const FT_Matrix ft_reflection = { 65536, 0, 0, -65536 };
 	FT_Matrix ft_transform;
 	FT_F26Dot6 width, height;
-
+	
 	/* Convert the GS transform into an FT transform.
 	 * Ignore the translation elements because they contain very large values
 	 * derived from the current transformation matrix and so are of no use.
@@ -597,10 +627,7 @@
 	 * transform.
 	 */
 	transform_decompose(&ft_transform, &width, &height);
-
-	/* Convert width and height to 64ths of pixels and set the FreeType sizes. */
-	width >>= 10;
-	height >>= 10;
+		
 	ft_error = FT_Set_Char_Size(face->ft_face, width, height,
 		a_font_scale->HWResolution[0] >> 16,
 		a_font_scale->HWResolution[1] >> 16);

Modified: trunk/gs/psi/zfapi.c
===================================================================
--- trunk/gs/psi/zfapi.c	2010-03-05 21:01:34 UTC (rev 10876)
+++ trunk/gs/psi/zfapi.c	2010-03-08 09:28:49 UTC (rev 10877)
@@ -577,7 +577,9 @@
 
     switch((int)var_id) {
         case FAPI_FONT_FEATURE_FontMatrix:
+#if 0
             {   double FontMatrix_div = (ff->is_cid && !IsCIDFont(pbfont) ? 1000 : 1);
+		
                 switch(index) {
                     case 0 : return pbfont->base->FontMatrix.xx / FontMatrix_div;
                     case 1 : return pbfont->base->FontMatrix.xy / FontMatrix_div;
@@ -587,6 +589,19 @@
                     case 5 : return pbfont->base->FontMatrix.ty / FontMatrix_div;
                 }
             } 
+#else
+            /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
+	    {		
+                switch(index) {
+                    case 0 : return 1.0;
+                    case 1 : return 0.0;
+                    case 2 : return 0.0;
+                    case 3 : return 1.0;
+                    case 4 : return 0.0;
+                    case 5 : return 0.0;
+                }
+            } 
+#endif
         case FAPI_FONT_FEATURE_WeightVector: 
 	    {   ref *Array, value; 
 
@@ -1364,10 +1379,16 @@
 
 static void compute_em_scale(const gs_font_base *pbfont, FAPI_metrics *metrics, double FontMatrix_div, double *em_scale_x, double *em_scale_y)
 {   /* optimize : move this stuff to FAPI_refine_font */
+    gs_matrix mat;
     gs_matrix *m = &pbfont->base->orig_FontMatrix;
     int rounding_x, rounding_y; /* Striking out the 'float' representation error in FontMatrix. */
     double sx, sy;
-
+    
+    /* Temporary: replace with a FAPI call to check *if* the library needs a replacement matrix */
+    m = &mat;
+    memset(m, 0x00, sizeof(gs_matrix));
+    m->xx = m->yy = 1.0;
+    
     if (m->xx == 0 && m->xy == 0 && m->yx == 0 && m->yy == 0)
 	m = &pbfont->base->FontMatrix;
     sx = hypot(m->xx, m->xy) * metrics->em_x / FontMatrix_div;
@@ -1478,12 +1499,18 @@
 		    int dx = arith_rshift_slow((pgs->ctm.tx_fixed >> shift_rd) + rast_orig_x + rounding, frac_pixel_shift);
 		    int dy = arith_rshift_slow((pgs->ctm.ty_fixed >> shift_rd) + rast_orig_y + rounding, frac_pixel_shift);
 
-		    if (dx + rast.left_indent < 0 || dx + rast.left_indent + rast.black_width > dev1->width)
+		    if (dx + rast.left_indent < 0 || dx + rast.left_indent + rast.black_width > dev1->width) {
 			eprintf2("Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n", 
 				dx + rast.left_indent, dx + rast.left_indent + rast.black_width - dev1->width);
-		    if (dy + rast.top_indent < 0 || dy + rast.top_indent + rast.black_height > dev1->height)
+			if (dx + rast.left_indent < 0)
+			    dx -= dx + rast.left_indent;
+		    }
+		    if (dy + rast.top_indent < 0 || dy + rast.top_indent + rast.black_height > dev1->height) {
 			eprintf2("Warning : Cropping a FAPI glyph while caching : dx=%d,%d.\n", 
 				dy + rast.top_indent, dy + rast.top_indent + rast.black_height - dev1->height);
+			if (dy + rast.top_indent < 0)
+			    dy -= dy + rast.top_indent;
+		    }
 		    if ((code = fapi_copy_mono(dev1, &rast, dx, dy)) < 0)
 			return code;
 
@@ -1614,7 +1641,7 @@
 	I->face.HWResolution[1] != dev->HWResolution[1]
        ) {
 	FAPI_font_scale font_scale = {{1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true};
-        gs_matrix *base_font_matrix = &I->initial_FontMatrix;
+        gs_matrix imat, scale_mat, scale_ctm, *base_font_matrix;
         double dx, dy;
 
 	I->face.font_id = pbfont->id;
@@ -1628,6 +1655,32 @@
 	font_scale.subpixels[1] = 1 << log2_scale.y;
 	font_scale.align_to_pixels = align_to_pixels;
 
+#if 1
+	/* We apply the entire transform to the glyph (that is ctm x FontMatrix)
+	 * at render time.
+	 */
+	
+	memset(&scale_ctm, 0x00, sizeof(gs_matrix));
+	scale_ctm.xx = dev->HWResolution[0]/72;
+	scale_ctm.yy = dev->HWResolution[1]/72;
+
+	code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm);
+	
+	code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat);		/* scale_mat ==  CTM - resolution scaling */
+        
+	font_scale.matrix[0] =  (FracInt)(scale_mat.xx * FontMatrix_div * scale + 0.5);
+	font_scale.matrix[1] =  -(FracInt)(scale_mat.xy * FontMatrix_div * scale + 0.5);
+        font_scale.matrix[2] =  (FracInt)(scale_mat.yx * FontMatrix_div * scale + 0.5);
+        font_scale.matrix[3] =  -(FracInt)(scale_mat.yy * FontMatrix_div * scale + 0.5);
+        font_scale.matrix[4] =  (FracInt)(scale_mat.tx * FontMatrix_div * scale + 0.5);
+        font_scale.matrix[5] =  (FracInt)(scale_mat.ty * FontMatrix_div * scale + 0.5);
+#else
+
+#  if 1
+	base_font_matrix = &I->initial_FontMatrix;
+#  else
+	base_font_matrix = &pbfont->base->orig_FontMatrix;
+#  endif
 	if (base_font_matrix->xx == 0 && base_font_matrix->xy == 0 &&
 	    base_font_matrix->yx == 0 && base_font_matrix->yy == 0)
 	    base_font_matrix = &pbfont->base->FontMatrix;
@@ -1643,13 +1696,14 @@
             for X and Y. It is not clear what to do when base_font_matrix is anisotropic
             (i.e. dx != dy), but we did not meet such fonts before now.
         */
-        font_scale.matrix[0] =  (FracInt)(ctm->xx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
-        font_scale.matrix[1] = -(FracInt)(ctm->xy * FontMatrix_div / dy * 72 / dev->HWResolution[0] * scale + 0.5);
+	font_scale.matrix[0] =  (FracInt)(ctm->xx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
+	font_scale.matrix[1] = -(FracInt)(ctm->xy * FontMatrix_div / dy * 72 / dev->HWResolution[0] * scale + 0.5);
         font_scale.matrix[2] =  (FracInt)(ctm->yx * FontMatrix_div / dx * 72 / dev->HWResolution[1] * scale + 0.5);
         font_scale.matrix[3] = -(FracInt)(ctm->yy * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
         font_scale.matrix[4] =  (FracInt)(ctm->tx * FontMatrix_div / dx * 72 / dev->HWResolution[0] * scale + 0.5);
         font_scale.matrix[5] =  (FracInt)(ctm->ty * FontMatrix_div / dy * 72 / dev->HWResolution[1] * scale + 0.5);
-        /* Note: the ctm mapping here is upside down. */
+#endif
+	/* Note: the ctm mapping here is upside down. */
 	font_scale.HWResolution[0] = (FracInt)((double)dev->HWResolution[0] * font_scale.subpixels[0] * scale);
 	font_scale.HWResolution[1] = (FracInt)((double)dev->HWResolution[1] * font_scale.subpixels[1] * scale);
 



More information about the gs-commits mailing list