shithub: freetype+ttf2subf

Download patch

ref: 210d61894b416ccf6b3bb0700eff34f1a4d7138d
parent: a56e526671f9d124744de69760e86543cb4c52e2
author: Werner Lemberg <[email protected]>
date: Tue Apr 1 01:55:48 EDT 2008

Fix support for subsetted CID-keyed CFFs.

* include/freetype/freetype.h (FT_FACE_FLAG_CID_KEYED,
FT_IS_CID_KEYED): New macros.

* src/cff/cffobjs.c (cff_face_init): Set number of glyphs to the
maximum CID value in CID-keyed CFFs.
Handle FT_FACE_FLAG_CID_KEYED flag.

* docs/CHANGES: Document it.


Fix CFF font matrix calculation and improve precision.

* src/cff/cffparse.c (cff_parse_real): Increase precision if integer
part is zero.
(cff_parse_font_matrix): Simplify computation of `units_per_em';
this prevents overflow also.


Support FT_Get_CID_Registry_Ordering_Supplement for PS CID fonts.

* src/cid/cidriver.c: Include FT_SERVICE_CID_H.
(cid_get_ros): New function.
(cid_service_cid_info): New service structure.
(cid_services): Register it.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2008-03-31  Werner Lemberg  <[email protected]>
+
+	Fix support for subsetted CID-keyed CFFs.
+
+	* include/freetype/freetype.h (FT_FACE_FLAG_CID_KEYED,
+	FT_IS_CID_KEYED): New macros.
+
+	* src/cff/cffobjs.c (cff_face_init): Set number of glyphs to the
+	maximum CID value in CID-keyed CFFs.
+	Handle FT_FACE_FLAG_CID_KEYED flag.
+
+	* docs/CHANGES: Document it.
+
+
+	Fix CFF font matrix calculation and improve precision.
+
+	* src/cff/cffparse.c (cff_parse_real): Increase precision if integer
+	part is zero.
+	(cff_parse_font_matrix): Simplify computation of `units_per_em';
+	this prevents overflow also.
+
+
+	Support FT_Get_CID_Registry_Ordering_Supplement for PS CID fonts.
+
+	* src/cid/cidriver.c: Include FT_SERVICE_CID_H.
+	(cid_get_ros): New function.
+	(cid_service_cid_info): New service structure.
+	(cid_services): Register it.
+
 2008-03-23  Werner Lemberg  <[email protected]>
 
 	Adjustments for Visual C++ 8.0, as reported by Rainer Deyke.
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -12,7 +12,9 @@
 
     - Improved Mac support.
 
+    - Subsetted CID-keyed CFFs are now supported correctly.
 
+
   II. IMPORTANT CHANGES
 
     - The new function `FT_Get_CID_Registry_Ordering_Supplement' gives
@@ -25,6 +27,10 @@
 
     - An API for cmap 14 support  (for Unicode Variant Selectors, UVS)
       has been contributed by George Williams.
+
+    - A new face flag FT_FACE_FLAG_CID_KEYED has been added,  together
+      with a macro FT_IS_CID_KEYED which evaluates to 1 if the font is
+      CID-keyed.
 
 
   III. MISCELLANEOUS
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -1021,6 +1021,15 @@
   /*      the SFNT `gasp' table only if the native TrueType hinting engine */
   /*      (with the bytecode interpreter) is available and active.         */
   /*                                                                       */
+  /*    FT_FACE_FLAG_CID_KEYED ::                                          */
+  /*      Set if the font is CID-keyed.  In that case, the font is not     */
+  /*      accessed by glyph indices but by CID values.  For subsetted      */
+  /*      CID-keyed fonts this has the consequence that not all index      */
+  /*      values are a valid argument to FT_Load_Glyph.  Only the CID      */
+  /*      values for which corresponding glyphs in the subsetted font      */
+  /*      exist make FT_Load_Glyph return successfully; in all other cases */
+  /*      you get an `FT_Err_Invalid_Argument' error.                      */
+  /*                                                                       */
 #define FT_FACE_FLAG_SCALABLE          ( 1L <<  0 )
 #define FT_FACE_FLAG_FIXED_SIZES       ( 1L <<  1 )
 #define FT_FACE_FLAG_FIXED_WIDTH       ( 1L <<  2 )
@@ -1033,6 +1042,7 @@
 #define FT_FACE_FLAG_GLYPH_NAMES       ( 1L <<  9 )
 #define FT_FACE_FLAG_EXTERNAL_STREAM   ( 1L << 10 )
 #define FT_FACE_FLAG_HINTER            ( 1L << 11 )
+#define FT_FACE_FLAG_CID_KEYED         ( 1L << 12 )
 
   /* */
 
@@ -1189,6 +1199,24 @@
           ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
 
 
+  /*************************************************************************
+   *
+   * @macro:
+   *   FT_IS_CID_KEYED( face )
+   *
+   * @description:
+   *   A macro that returns true whenever a face object contains a CID-keyed
+   *   font.  See the discussion of @FT_FACE_FLAG_CID_KEYED for more
+   *   details.
+   *
+   *   If this macro is true, all functions defined in @FT_CID_H are
+   *   available.
+   *
+   */
+#define FT_IS_CID_KEYED( face ) \
+          ( face->face_flags & FT_FACE_FLAG_CID_KEYED )
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
@@ -2193,6 +2221,11 @@
   /* <Note>                                                                */
   /*    The loaded glyph may be transformed.  See @FT_Set_Transform for    */
   /*    the details.                                                       */
+  /*                                                                       */
+  /*    For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is        */
+  /*    returned for invalid CID values (this is, for CID values which     */
+  /*    don't have a corresponding glyph in the font).  See the discussion */
+  /*    of the @FT_FACE_FLAG_CID_KEYED flag for more details.              */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Load_Glyph( FT_Face   face,
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -38,6 +38,7 @@
 #include FT_SERVICE_XFREE86_NAME_H
 #include FT_SERVICE_GLYPH_DICT_H
 
+
   /*************************************************************************/
   /*                                                                       */
   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
@@ -165,10 +166,10 @@
     if ( !size )
       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
+    /* reset the size object if necessary */
     if ( load_flags & FT_LOAD_NO_SCALE )
       size = NULL;
 
-    /* reset the size object if necessary */
     if ( size )
     {
       /* these two objects must have the same parent */
@@ -186,10 +187,10 @@
   }
 
 
- /*
-  *  GLYPH DICT SERVICE
-  *
-  */
+  /*
+   *  GLYPH DICT SERVICE
+   *
+   */
 
   static FT_Error
   cff_get_glyph_name( CFF_Face    face,
@@ -286,10 +287,10 @@
   };
 
 
- /*
-  *  POSTSCRIPT INFO SERVICE
-  *
-  */
+  /*
+   *  POSTSCRIPT INFO SERVICE
+   *
+   */
 
   static FT_Int
   cff_ps_has_glyph_names( FT_Face  face )
@@ -356,9 +357,9 @@
 
 
   /*
-  *  POSTSCRIPT NAME SERVICE
-  *
-  */
+   *  POSTSCRIPT NAME SERVICE
+   *
+   */
 
   static const char*
   cff_get_ps_name( CFF_Face  face )
@@ -422,7 +423,7 @@
 
 
   /*
-   * CID INFO SERVICE
+   *  CID INFO SERVICE
    *
    */
   static FT_Error
@@ -467,11 +468,10 @@
 
       if ( supplement )
         *supplement = dict->cid_supplement;
-
     }
       
-    Fail:
-      return error;
+  Fail:
+    return error;
   }
 
 
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -446,7 +446,7 @@
 
         /* compute number of glyphs */
         if ( dict->cid_registry != 0xFFFFU )
-          cffface->num_glyphs = dict->cid_count;
+          cffface->num_glyphs = cff->charset.max_cid;
         else
           cffface->num_glyphs = cff->charstrings_index.count;
 
@@ -647,10 +647,14 @@
 
 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
       /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
-      /* has unset this flag because of the 3.0 `post' table           */
+      /* has unset this flag because of the 3.0 `post' table.          */
       if ( dict->cid_registry == 0xFFFFU )
         cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
 #endif
+
+      if ( dict->cid_registry != 0xFFFFU )
+        cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
+
 
       /*******************************************************************/
       /*                                                                 */
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (body)                                       */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2007 by                         */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -202,11 +202,21 @@
         if ( nib >= 10 )
           break;
 
-        if ( divider < 10000000L )
+        /* Increase precision if the integer part is zero */
+        /* and we have to scale the real number.          */
+        if ( !result && power_ten )
         {
-          num      = num * 10 + nib;
-          divider *= 10;
+          power_ten--;
+          num = num * 10 + nib;
         }
+        else
+        {
+          if ( divider < 10000000L )
+          {
+            num      = num * 10 + nib;
+            divider *= 10;
+          }
+        }
       }
 
     /* read exponent, if any */
@@ -248,10 +258,10 @@
       power_ten += (FT_Int)exponent;
     }
 
-    /* Move the integer part into the high 16 bits. */
+    /* Move the integer part into the higher 16 bits. */
     result <<= 16;
 
-    /* Place the decimal part into the low 16 bits. */
+    /* Place the decimal part into the lower 16 bits. */
     if ( num )
       result |= FT_DivFix( num, divider );
 
@@ -337,7 +347,10 @@
 
       temp = FT_ABS( matrix->yy );
 
-      *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
+      *upm = (FT_UShort)FT_DivFix( 1000, temp );
+
+      /* we normalize the matrix so that `matrix->xx' is 1; */
+      /* the scaling is done with `units_per_em' then       */
 
       if ( temp != 0x10000L )
       {
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID driver interface (body).                                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006 by                         */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -27,7 +27,9 @@
 #include FT_SERVICE_POSTSCRIPT_NAME_H
 #include FT_SERVICE_XFREE86_NAME_H
 #include FT_SERVICE_POSTSCRIPT_INFO_H
+#include FT_SERVICE_CID_H
 
+
   /*************************************************************************/
   /*                                                                       */
   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
@@ -38,10 +40,10 @@
 #define FT_COMPONENT  trace_ciddriver
 
 
- /*
-  *  POSTSCRIPT NAME SERVICE
-  *
-  */
+  /*
+   *  POSTSCRIPT NAME SERVICE
+   *
+   */
 
   static const char*
   cid_get_postscript_name( CID_Face  face )
@@ -62,10 +64,10 @@
   };
 
 
- /*
-  *  POSTSCRIPT INFO SERVICE
-  *
-  */
+  /*
+   *  POSTSCRIPT INFO SERVICE
+   *
+   */
 
   static FT_Error
   cid_ps_get_font_info( FT_Face          face,
@@ -84,16 +86,49 @@
   };
 
 
- /*
-  *  SERVICE LIST
-  *
-  */
+  /*
+   *  CID INFO SERVICE
+   *
+   */
+  static FT_Error
+  cid_get_ros( CID_Face      face,
+               const char*  *registry,
+               const char*  *ordering,
+               FT_Int       *supplement )
+  {
+    CID_FaceInfo  cid = &face->cid;
 
+
+    if ( registry )
+      *registry = cid->registry;
+      
+    if ( ordering )
+      *ordering = cid->ordering;
+
+    if ( supplement )
+      *supplement = cid->supplement;
+      
+    return CID_Err_Ok;
+  }
+
+
+  static const FT_Service_CIDRec  cid_service_cid_info =
+  {
+    (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros
+  };
+
+
+  /*
+   *  SERVICE LIST
+   *
+   */
+
   static const FT_ServiceDescRec  cid_services[] =
   {
-    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name },
     { FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CID },
+    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name },
     { FT_SERVICE_ID_POSTSCRIPT_INFO,      &cid_service_ps_info },
+    { FT_SERVICE_ID_CID,                  &cid_service_cid_info },
     { NULL, NULL }
   };