]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Guess that mac roman names with lots of high bits are actually SJIS.
[fontconfig.git] / src / fcfreetype.c
index cc73f5ce4154993887855a52e35f2e1ead6be152..082d17bfb8865010c5ac38fdda737f572ca11f62 100644 (file)
   THE SOFTWARE.
 */
 
+#include "fcint.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <libgen.h>
-#include "fcint.h"
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_TRUETYPE_TABLES_H
@@ -65,6 +64,7 @@
 
 #include "ftglue.h"
 
+#if HAVE_WARNING_CPP_DIRECTIVE
 #if !HAVE_FT_GET_BDF_PROPERTY
 #warning "No FT_Get_BDF_Property: Please install freetype 2.1.4 or later"
 #endif
@@ -72,6 +72,7 @@
 #if !HAVE_FT_GET_PS_FONT_INFO
 #warning "No FT_Get_PS_Font_Info: Please install freetype 2.1.1 or later"
 #endif
+#endif
 
 /*
  * Keep Han languages separated by eliminating languages
@@ -555,11 +556,32 @@ FcFontCapabilities(FT_Face face);
 
 #define NUM_FC_MAC_ROMAN_FAKE  (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
 
-#if HAVE_ICONV && HAVE_ICONV_H
-#define USE_ICONV 1
+#if USE_ICONV
 #include <iconv.h>
 #endif
 
+/*
+ * A shift-JIS will have many high bits turned on
+ */
+static FcBool
+FcLooksLikeSJIS (FcChar8 *string, int len)
+{
+    int            nhigh = 0, nlow = 0;
+
+    while (len-- > 0)
+    {
+       if (*string++ & 0x80) nhigh++;
+       else nlow++;
+    }
+    /*
+     * Heuristic -- if more than 1/3 of the bytes have the high-bit set,
+     * this is likely to be SJIS and not ROMAN
+     */
+    if (nhigh * 2 > nlow)
+       return FcTrue;
+    return FcFalse;
+}
+
 static FcChar8 *
 FcSfntNameTranscode (FT_SfntName *sname)
 {
@@ -580,24 +602,35 @@ FcSfntNameTranscode (FT_SfntName *sname)
     fromcode = fcFtEncoding[i].fromcode;
 
     /*
-     * "real" Mac language IDs are all less than 150.
-     * Names using one of the MS language IDs are assumed
-     * to use an associated encoding (Yes, this is a kludge)
+     * Many names encoded for TT_PLATFORM_MACINTOSH are broken
+     * in various ways. Kludge around them.
      */
-    if (!strcmp (fromcode, FC_ENCODING_MAC_ROMAN) &&
-       sname->language_id >= 0x100)
+    if (!strcmp (fromcode, FC_ENCODING_MAC_ROMAN))
     {
-       int     f;
+       if (sname->language_id == TT_MAC_LANGID_ENGLISH &&
+           FcLooksLikeSJIS (sname->string, sname->string_len))
+       {
+           fromcode = "SJIS";
+       }
+       else if (sname->language_id >= 0x100)
+       {
+           /*
+            * "real" Mac language IDs are all less than 150.
+            * Names using one of the MS language IDs are assumed
+            * to use an associated encoding (Yes, this is a kludge)
+            */
+           int f;
 
-       fromcode = NULL;
-       for (f = 0; f < NUM_FC_MAC_ROMAN_FAKE; f++)
-           if (fcMacRomanFake[f].language_id == sname->language_id)
-           {
-               fromcode = fcMacRomanFake[f].fromcode;
-               break;
-           }
-       if (!fromcode)
-           return 0;
+           fromcode = NULL;
+           for (f = 0; f < NUM_FC_MAC_ROMAN_FAKE; f++)
+               if (fcMacRomanFake[f].language_id == sname->language_id)
+               {
+                   fromcode = fcMacRomanFake[f].fromcode;
+                   break;
+               }
+           if (!fromcode)
+               return 0;
+       }
     }
     if (!strcmp (fromcode, "UCS-2BE") || !strcmp (fromcode, "UTF-16BE"))
     {
@@ -738,10 +771,24 @@ static const FcChar8 *
 FcSfntNameLanguage (FT_SfntName *sname)
 {
     int i;
+    FT_UShort  platform_id = sname->platform_id;
+    FT_UShort  language_id = sname->language_id;
+
+    /*
+     * Many names encoded for TT_PLATFORM_MACINTOSH are broken
+     * in various ways. Kludge around them.
+     */
+    if (platform_id == TT_PLATFORM_MACINTOSH &&
+       sname->encoding_id == TT_MAC_ID_ROMAN &&
+       FcLooksLikeSJIS (sname->string, sname->string_len))
+    {
+       language_id = TT_MAC_LANGID_JAPANESE;
+    }
+    
     for (i = 0; i < NUM_FC_FT_LANGUAGE; i++)
-       if (fcFtLanguage[i].platform_id == sname->platform_id &&
+       if (fcFtLanguage[i].platform_id == platform_id &&
            (fcFtLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
-            fcFtLanguage[i].language_id == sname->language_id))
+            fcFtLanguage[i].language_id == language_id))
        {
            if (fcFtLanguage[i].lang[0] == '\0')
              return NULL;
@@ -976,7 +1023,6 @@ FcStringInPatternElement (FcPattern *pat, const char *elt, FcChar8 *string)
        if (!FcStrCmpIgnoreBlanksAndCase (old, string))
        {
            return FcTrue;
-           break;
        }
     return FcFalse;
 }
@@ -1000,7 +1046,6 @@ FcFreeTypeQuery (const FcChar8    *file,
     FcChar8        *family = 0;
 #endif
     FcChar8        *complex;
-    FcChar8        *file2;
     const FcChar8   *foundry = 0;
     int                    spacing;
     TT_OS2         *os2;
@@ -1222,7 +1267,7 @@ FcFreeTypeQuery (const FcChar8    *file,
      * or which are simply a FC_FAMILY and FC_STYLE glued together
      */
     {
-       int     fn, fa, st;
+       int     fn, fa;
        FcChar8 *full;
        FcChar8 *fam;
        FcChar8 *style;
@@ -1281,15 +1326,8 @@ FcFreeTypeQuery (const FcChar8   *file,
                printf ("Saving unique fullname %s\n", full);
     }
 
-    file2 = FcStrCopy (file);
-    if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)file2)))
-    {
-       FcStrFree (file2);
+    if (!FcPatternAddString (pat, FC_FILE, file))
        goto bail1;
-    }
-    FcStrFree (file2);
-
-    FcPatternAddFullFname (pat, (const char *)FcStrCopy (file));
 
     if (!FcPatternAddInteger (pat, FC_INDEX, id))
        goto bail1;
@@ -1439,7 +1477,6 @@ FcFreeTypeQuery (const FcChar8    *file,
     if (!foundry)
     {
        int             rc;
-       BDF_PropertyRec prop;
        rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop);
        if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM)
            foundry = (FcChar8 *) prop.u.atom;
@@ -1607,7 +1644,6 @@ FcFreeTypeQuery (const FcChar8    *file,
         if(face->num_fixed_sizes == 1) {
             int rc;
             int value;
-            BDF_PropertyRec prop;
 
            /* skip bitmap fonts which do not even have a family name */
            rc =  FT_Get_BDF_Property(face, "FAMILY_NAME", &prop);
@@ -2313,6 +2349,10 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
     int                    p;
 
     initial = 0;
+
+    if (!face)
+        return 0;
+
     /*
      * Find the current encoding
      */
@@ -2433,7 +2473,7 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
 FcCharSet *
 FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
 {
-    FcChar32       page, off, max, ucs4;
+    FcChar32       page, off, ucs4;
 #ifdef CHECK
     FcChar32       font_max = 0;
 #endif
@@ -2514,7 +2554,6 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
        {
            FT_UInt gindex;
          
-           max = fcFontDecoders[o].max;
            /*
             * Find the first encoded character in the font
             */
@@ -2745,11 +2784,13 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
     FT_Stream  stream = face->stream;
     FT_Error   error;
     FT_UShort          n, p;
-    FT_Memory  memory = stream->memory;
+    FT_Memory  memory;
 
     if ( !stream )
        return TT_Err_Invalid_Face_Handle;
 
+    memory = stream->memory;
+
     if (( error = ftglue_face_goto_table( face, tabletag, stream ) ))
        return error;
 
@@ -2760,7 +2801,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
     if ( ftglue_stream_seek ( stream, base_offset + 4L ) || ftglue_stream_frame_enter( stream, 2L ) )
        return error;
 
-    new_offset = ((FT_UShort)ftglue_stream_get_short ( stream )) + base_offset;
+    new_offset = GET_UShort() + base_offset;
 
     ftglue_stream_frame_exit( stream );
 
@@ -2774,7 +2815,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
     if ( ftglue_stream_frame_enter( stream, 2L ) )
        return error;
 
-    *script_count = ((FT_UShort)ftglue_stream_get_short ( stream ));
+    *script_count = GET_UShort ();
 
     ftglue_stream_frame_exit( stream );
 
@@ -2789,20 +2830,17 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
         if ( ftglue_stream_frame_enter( stream, 6L ) )
            goto Fail;
 
-       (*stags)[p] = ((FT_ULong)ftglue_stream_get_long ( stream ));
-       new_offset = ((FT_UShort)ftglue_stream_get_short ( stream )) + base_offset;
+       (*stags)[p] = GET_ULong ();
+       new_offset = GET_UShort () + base_offset;
 
         ftglue_stream_frame_exit( stream );
 
        cur_offset = ftglue_stream_pos( stream );
 
-       if ( ftglue_stream_seek( stream, new_offset ) )
-           goto Fail;
+       error = ftglue_stream_seek( stream, new_offset );
 
        if ( error == TT_Err_Ok )
            p++;
-       else if ( error != TTO_Err_Empty_Script )
-           goto Fail;
 
        (void)ftglue_stream_seek( stream, cur_offset );
     }
@@ -2813,7 +2851,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
        goto Fail;
     }
 
-    // sort the tag list before returning it
+    /* sort the tag list before returning it */
     qsort(*stags, *script_count, sizeof(FT_ULong), compareulong);
 
     return TT_Err_Ok;
@@ -2821,6 +2859,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
 Fail:
     *script_count = 0;
     ftglue_free( memory, *stags );
+    *stags = NULL;
     return error;
 }