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

chrisl at ghostscript.com chrisl at ghostscript.com
Fri Oct 15 15:07:06 UTC 2010


Author: chrisl
Date: 2010-10-15 15:07:05 +0000 (Fri, 15 Oct 2010)
New Revision: 11816

Modified:
   trunk/gs/psi/fapi_ft.c
Log:
With the latest release of Freetype, reinstate the "sensible" method of
limiting the size of the bitmap that we let Freetype create. It is
limited to 1.5x the current maximum cacheable glyph bitmap, as it is *vital*
that we avoid creating an outline when the cache expects a bitmap,
but not a problem if we create a bitmap for a non-cached glyph.

Bug 691569.

No cluster differences expected.



Modified: trunk/gs/psi/fapi_ft.c
===================================================================
--- trunk/gs/psi/fapi_ft.c	2010-10-15 14:21:51 UTC (rev 11815)
+++ trunk/gs/psi/fapi_ft.c	2010-10-15 15:07:05 UTC (rev 11816)
@@ -430,10 +430,10 @@
         /* maintain consistency better.  (FT_LOAD_NO_BITMAP) */
         a_fapi_font->char_data = saved_char_data;
         if (!a_fapi_font->is_type1)
-            ft_error = FT_Load_Glyph(ft_face, index, a_bitmap ?  FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP : FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP);
+            ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP);
 	else {
             /* Current FreeType hinting for type 1 fonts is so poor we are actually better off without it (fewer files render incorrectly) (FT_LOAD_NO_HINTING) */
-            ft_error = FT_Load_Glyph(ft_face, index, a_bitmap ?  FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP: FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+            ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
 	    if (ft_error == FT_Err_Invalid_File_Format) 
 		return index+1;
 	}
@@ -444,7 +444,7 @@
         /* We want to prevent hinting, even for a "tricky" font - it shouldn't matter for the notdef */
         fflags = ft_face->face_flags;
         ft_face->face_flags &= ~FT_FACE_FLAG_TRICKY;
-        ft_error = FT_Load_Glyph(ft_face, index, a_bitmap ?  FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP: FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+        ft_error = FT_Load_Glyph(ft_face, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
 
         ft_face->face_flags = fflags;
     }
@@ -462,7 +462,7 @@
         fflags = ft_face->face_flags;
         ft_face->face_flags &= ~FT_FACE_FLAG_TRICKY;
         
-        ft_error_fb = FT_Load_Glyph(ft_face, 0, a_bitmap ?  FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP: FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
+        ft_error_fb = FT_Load_Glyph(ft_face, 0, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
         
         ft_face->face_flags = fflags;
         
@@ -480,8 +480,6 @@
         FT_Long hadv;
         FT_Long vadv;
         
-        FT_BBox      cbox;
-
         /* In order to get the metrics in the form we need them, we have to remove the size scaling
          * the resolution scaling, and convert to points.
          */
@@ -514,19 +512,41 @@
 
     }
 
-    if ((!ft_error || !ft_error_fb) && a_glyph)
-        ft_error = FT_Get_Glyph(ft_face->glyph, a_glyph);
+    if ((!ft_error || !ft_error_fb) && a_bitmap == true) {
 
-    if (a_bitmap && a_glyph && ft_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
-        FT_BitmapGlyph bg = (FT_BitmapGlyph)*a_glyph;
+        FT_BBox      cbox;
+        /* compute the control box, and grid fit it - lifted from ft_raster1_render() */
+        FT_Outline_Get_CBox(&ft_face->glyph->outline,&cbox);
 
-        if (bitmap_raster(bg->bitmap.width) * bg->bitmap.rows > max_bitmap) {
-            FT_Done_Glyph(bg);
-            *a_glyph = NULL;
+        /* These round operations are only to preserve behaviour compared to the 9.00 release 
+           which used the bitmap dimensions as calculated by Freetype.
+           But FT_PIX_FLOOR/FT_PIX_CEIL aren't public.
+        */
+        cbox.xMin = ((cbox.xMin) & ~63); /* FT_PIX_FLOOR( cbox.xMin ) */
+        cbox.yMin = ((cbox.yMin) & ~63);
+        cbox.xMax = (((cbox.xMax) + 63) & ~63);
+        cbox.yMax = (((cbox.yMax) + 63) & ~63); /* FT_PIX_CEIL( cbox.yMax ) */
+
+        w = (FT_UInt)(( cbox.xMax - cbox.xMin ) >> 6 );
+        h = (FT_UInt)(( cbox.yMax - cbox.yMin ) >> 6 );
+
+        if (ft_face->glyph->format != FT_GLYPH_FORMAT_BITMAP && ft_face->glyph->format != FT_GLYPH_FORMAT_COMPOSITE) {
+            if ((bitmap_raster(w) * h) < max_bitmap) {
+               FT_Render_Mode  mode = FT_RENDER_MODE_MONO;
+               
+               ft_error = FT_Render_Glyph(ft_face->glyph, mode);           
+            }
+            else {
+                (*a_glyph) = NULL;
             return (e_VMerror);
         }
     }
+    }
 
+    if ((!ft_error || !ft_error_fb) && a_glyph) {
+        ft_error = FT_Get_Glyph(ft_face->glyph, a_glyph);
+    }
+
     if (ft_error == FT_Err_Too_Many_Hints) {
 #ifdef DEBUG
 	if (gs_debug_c('1')) {



More information about the gs-commits mailing list