[CMAKE]
[reactos.git] / lib / 3rdparty / freetype / src / cff / cffobjs.c
index bd56c4b..1cd35c9 100644 (file)
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -24,8 +25,6 @@
 #include FT_TRUETYPE_IDS_H
 #include FT_TRUETYPE_TAGS_H
 #include FT_INTERNAL_SFNT_H
-#include FT_SERVICE_POSTSCRIPT_CMAPS_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
 #include "cffobjs.h"
 #include "cffload.h"
 #include "cffcmap.h"
@@ -58,7 +57,7 @@
   {
     CFF_Face          face     = (CFF_Face)size->root.face;
     CFF_Font          font     = (CFF_Font)face->extra.data;
-    PSHinter_Service  pshinter = (PSHinter_Service)font->pshinter;
+    PSHinter_Service  pshinter = font->pshinter;
     FT_Module         module;
 
 
   {
     CFF_Face          face     = (CFF_Face)slot->face;
     CFF_Font          font     = (CFF_Font)face->extra.data;
-    PSHinter_Service  pshinter = (PSHinter_Service)font->pshinter;
+    PSHinter_Service  pshinter = font->pshinter;
 
 
     if ( pshinter )
   }
 
 
+  /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */
+  /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */
+  /* have been seen in the wild.                                      */
+
+  static void
+  remove_subset_prefix( FT_String*  name )
+  {
+    FT_Int32  idx             = 0;
+    FT_Int32  length          = strlen( name ) + 1;
+    FT_Bool   continue_search = 1;
+
+    while ( continue_search )
+    {
+      if ( length >= 7 && name[6] == '+' )
+      {
+        for ( idx = 0; idx < 6; idx++ )
+        {
+          /* ASCII uppercase letters */
+          if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
+            continue_search = 0;
+        }
+
+        if ( continue_search )
+        {
+          for ( idx = 7; idx < length; idx++ )
+            name[idx - 7] = name[idx];
+        }
+      }
+      else
+        continue_search = 0;
+    }
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   cff_face_init( FT_Stream      stream,
                  FT_Face        cffface,        /* CFF_Face */
     FT_Library library = cffface->driver->root.library;
 
 
-#if 0
-    FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt,     SFNT );
-    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames,  POSTSCRIPT_NAMES );
-    FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER );
-
-    if ( !sfnt )
-      goto Bad_Format;
-#else
     sfnt = (SFNT_Service)FT_Get_Module_Interface(
              library, "sfnt" );
     if ( !sfnt )
 
     pshinter = (PSHinter_Service)FT_Get_Module_Interface(
                  library, "pshinter" );
-#endif
 
     /* create input stream from resource */
     if ( FT_STREAM_SEEK( 0 ) )
         goto Exit;
 
       cff->pshinter = pshinter;
-      cff->psnames  = (void*)psnames;
+      cff->psnames  = psnames;
 
       cffface->face_index = face_index;
 
 
         /* compute number of glyphs */
         if ( dict->cid_registry != 0xFFFFU )
-          cffface->num_glyphs = cff->charset.max_cid;
+          cffface->num_glyphs = cff->charset.max_cid + 1;
         else
           cffface->num_glyphs = cff->charstrings_index.count;
 
           (FT_Short)( dict->underline_thickness >> 16 );
 
         /* retrieve font family & style name */
-        cffface->family_name = cff_index_get_name( &cff->name_index,
-                                                   face_index );
-
+        cffface->family_name = cff_index_get_name( cff, face_index );
         if ( cffface->family_name )
         {
-          char*  full   = cff_index_get_sid_string( &cff->string_index,
-                                                    dict->full_name,
-                                                    psnames );
+          char*  full   = cff_index_get_sid_string( cff,
+                                                    dict->full_name );
           char*  fullp  = full;
           char*  family = cffface->family_name;
-          char*  family_name = 0;
+          char*  family_name = NULL;
 
 
+          remove_subset_prefix( cffface->family_name ); 
+
           if ( dict->family_name )
           {
-            family_name = cff_index_get_sid_string( &cff->string_index,
-                                                    dict->family_name,
-                                                    psnames);
+            family_name = cff_index_get_sid_string( cff,
+                                                    dict->family_name );
             if ( family_name )
               family = family_name;
           }
               }
               break;
             }
-
-            if ( family_name )
-              FT_FREE( family_name );
-            FT_FREE( full );
           }
         }
         else
         {
           char  *cid_font_name =
-                   cff_index_get_sid_string( &cff->string_index,
-                                             dict->cid_font_name,
-                                             psnames );
+                   cff_index_get_sid_string( cff,
+                                             dict->cid_font_name );
 
 
           /* do we have a `/FontName' for a CID-keyed font? */
           if ( cid_font_name )
-            cffface->family_name = cid_font_name;
+            cffface->family_name = cff_strcpy( memory, cid_font_name );
         }
 
         if ( style_name )
           flags |= FT_STYLE_FLAG_ITALIC;
 
         {
-          char  *weight = cff_index_get_sid_string( &cff->string_index,
-                                                    dict->weight,
-                                                    psnames );
+          char  *weight = cff_index_get_sid_string( cff,
+                                                    dict->weight );
 
 
           if ( weight )
             if ( !ft_strcmp( weight, "Bold"  ) ||
                  !ft_strcmp( weight, "Black" ) )
               flags |= FT_STYLE_FLAG_BOLD;
-          FT_FREE( weight );
         }
 
         /* double check */
         {
           cmap = cffface->charmaps[nn];
 
-          /* Windows Unicode (3,1)? */
-          if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
+          /* Windows Unicode? */
+          if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
+               cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
             goto Skip_Unicode;
 
-          /* Deprecated Unicode platform id? */
-          if ( cmap->platform_id == 0 )
-            goto Skip_Unicode; /* Standard Unicode (deprecated) */
+          /* Apple Unicode platform id? */
+          if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
+            goto Skip_Unicode; /* Apple Unicode */
         }
 
         /* since CID-keyed fonts don't contain glyph names, we can't */
         if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
           goto Exit;
 
+#ifdef FT_MAX_CHARMAP_CACHEABLE
+        if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
+        {
+          FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
+                     "and too many subtables (%d) to add synthesized cmap\n",
+                     nn ));
+          goto Exit;
+        }
+#endif
+
         /* we didn't find a Unicode charmap -- synthesize one */
         cmaprec.face        = cffface;
-        cmaprec.platform_id = 3;
-        cmaprec.encoding_id = 1;
+        cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
+        cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
         cmaprec.encoding    = FT_ENCODING_UNICODE;
 
         nn = (FT_UInt)cffface->num_charmaps;
 
-        FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL );
+        error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
+                             &cmaprec, NULL );
+        if ( error && FT_Err_No_Unicode_Glyph_Name != error )
+          goto Exit;
+        error = FT_Err_Ok;
 
         /* if no Unicode charmap was previously selected, select this one */
         if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
           cffface->charmap = cffface->charmaps[nn];
 
       Skip_Unicode:
+#ifdef FT_MAX_CHARMAP_CACHEABLE
+        if ( nn > FT_MAX_CHARMAP_CACHEABLE )
+        {
+          FT_ERROR(( "cff_face_init: Unicode cmap is found, "
+                     "but too many preceding subtables (%d) to access\n",
+                     nn - 1 ));
+          goto Exit;
+        }
+#endif
         if ( encoding->count > 0 )
         {
           FT_CMap_Class  clazz;
 
 
           cmaprec.face        = cffface;
-          cmaprec.platform_id = 7;  /* Adobe platform id */
+          cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
 
           if ( encoding->offset == 0 )
           {
             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
           }
 
-          FT_CMap_New( clazz, NULL, &cmaprec, NULL );
+          error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
         }
       }
     }