]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Don't force bitmap font enable in default configuration; allows users to
[fontconfig.git] / src / fcfreetype.c
index 7ca65fdeec36504f7b2f6e7f79b89d62ae26a2c1..ee4af405644f847d25c191febe537831496e5642 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $RCSId: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
  *
- * Copyright © 2001 Keith Packard
+ * Copyright Â© 2001 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -23,7 +23,7 @@
  */
 
 /*
-  Copyright © 2002-2003 by Juliusz Chroboczek
+  Copyright Â© 2002-2003 by Juliusz Chroboczek
 
   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
@@ -128,7 +128,7 @@ static const FcFtEncoding   fcFtEncoding[] = {
  {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_GB2312,        "GB3212" },
  {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_BIG_5,         "BIG-5" },
  {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_WANSUNG,       "Wansung" },
- {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,         "Johap" },
+ {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,         "Johab" },
  {  TT_PLATFORM_MICROSOFT,     TT_MS_ID_UCS_4,         "UCS4" },
  {  TT_PLATFORM_ISO,           TT_ISO_ID_7BIT_ASCII,   "ASCII" },
  {  TT_PLATFORM_ISO,           TT_ISO_ID_10646,        "UCS-2BE" },
@@ -606,36 +606,6 @@ FcSfntNameTranscode (FT_SfntName *sname)
        if (!fromcode)
            return 0;
     }
-#if USE_ICONV
-    cd = iconv_open ("UTF-8", fromcode);
-    if (cd)
-    {
-       size_t      in_bytes_left = sname->string_len;
-       size_t      out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN;
-       char        *inbuf, *outbuf;
-       
-       utf8 = malloc (out_bytes_left + 1);
-       if (!utf8)
-           return 0;
-       
-       outbuf = (char *) utf8;
-       inbuf = (char *) sname->string;
-       
-       while (in_bytes_left)
-       {
-           size_t      did = iconv (cd, 
-                                &inbuf, &in_bytes_left,
-                                &outbuf, &out_bytes_left);
-           if (did == (size_t) (-1))
-           {
-               free (utf8);
-               return 0;
-           }
-       }
-       *outbuf = '\0';
-       goto done;
-    }
-#endif
     if (!strcmp (fromcode, "UCS-2BE") || !strcmp (fromcode, "UTF-16BE"))
     {
        FcChar8     *src = sname->string;
@@ -726,6 +696,41 @@ FcSfntNameTranscode (FT_SfntName *sname)
        *u8 = '\0';
        goto done;
     }
+#if USE_ICONV
+    cd = iconv_open ("UTF-8", fromcode);
+    if (cd && cd != (iconv_t) (-1))
+    {
+       size_t      in_bytes_left = sname->string_len;
+       size_t      out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN;
+       char        *inbuf, *outbuf;
+       
+       utf8 = malloc (out_bytes_left + 1);
+       if (!utf8)
+       {
+           iconv_close (cd);
+           return 0;
+       }
+       
+       outbuf = (char *) utf8;
+       inbuf = (char *) sname->string;
+       
+       while (in_bytes_left)
+       {
+           size_t      did = iconv (cd, 
+                                &inbuf, &in_bytes_left,
+                                &outbuf, &out_bytes_left);
+           if (did == (size_t) (-1))
+           {
+               iconv_close (cd);
+               free (utf8);
+               return 0;
+           }
+       }
+       iconv_close (cd);
+       *outbuf = '\0';
+       goto done;
+    }
+#endif
     return 0;
 done:
     if (FcStrCmpIgnoreBlanksAndCase (utf8, "") == 0)
@@ -1163,19 +1168,21 @@ FcFreeTypeQuery (const FcChar8  *file,
            free (utf8);
     }
     
-    if (!nfamily && face->family_name)
+    if (!nfamily && face->family_name && 
+       FcStrCmpIgnoreBlanksAndCase (face->family_name, "") != 0)
     {
        if (FcDebug () & FC_DBG_SCANV)
-           printf ("using FreeType family %s", face->family_name);
+           printf ("using FreeType family \"%s\"\n", face->family_name);
        if (!FcPatternAddString (pat, FC_FAMILY, face->family_name))
            goto bail1;
        ++nfamily;
     }
     
-    if (!nstyle && face->style_name)
+    if (!nstyle && face->style_name &&
+       FcStrCmpIgnoreBlanksAndCase (face->style_name, "") != 0)
     {
        if (FcDebug () & FC_DBG_SCANV)
-           printf ("using FreeType style %s", face->family_name);
+           printf ("using FreeType style \"%s\"\n", face->style_name);
        if (!FcPatternAddString (pat, FC_STYLE, face->style_name))
            goto bail1;
        ++nstyle;
@@ -1199,7 +1206,7 @@ FcFreeTypeQuery (const FcChar8    *file,
        strncpy ((char *) family, (char *) start, end - start);
        family[end - start] = '\0';
        if (FcDebug () & FC_DBG_SCANV)
-           printf ("using filename for family %s", family);
+           printf ("using filename for family %s\n", family);
        if (!FcPatternAddString (pat, FC_FAMILY, family))
        {
            free (family);
@@ -1279,9 +1286,6 @@ FcFreeTypeQuery (const FcChar8    *file,
     if (!FcPatternAddInteger (pat, FC_INDEX, id))
        goto bail1;
 
-    if (!FcPatternAddString (pat, FC_SOURCE, (FcChar8 *) "FreeType"))
-       goto bail1;
-
 #if 0
     /*
      * don't even try this -- CJK 'monospace' fonts are really
@@ -2121,6 +2125,12 @@ static const FcFontDecode fcFontDecoders[] = {
 
 #define NUM_DECODE  (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
 
+static const FcChar32  prefer_unicode[] = {
+    0x20ac,    /* EURO SIGN */
+};
+
+#define NUM_PREFER_UNICODE  (sizeof (prefer_unicode) / sizeof (prefer_unicode[0]))
+
 FcChar32
 FcFreeTypeUcs4ToPrivate (FcChar32 ucs4, const FcCharMap *map)
 {
@@ -2282,6 +2292,7 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
     int                    initial, offset, decode;
     FT_UInt        glyphindex;
     FcChar32       charcode;
+    int                    p;
 
     initial = 0;
     /*
@@ -2295,6 +2306,12 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
        if (initial == NUM_DECODE)
            initial = 0;
     }
+    for (p = 0; p < NUM_PREFER_UNICODE; p++)
+       if (ucs4 == prefer_unicode[p])
+       {
+           initial = 0;
+           break;
+       }
     /*
      * Check each encoding for the glyph, starting with the current one
      */
@@ -2342,12 +2359,6 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
     FT_Int         load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     FT_GlyphSlot    slot;
     
-    /*
-     * For bitmap-only fonts, assume that they're OK.
-     */
-    if ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
-       return FcTrue;
-
     /*
      * When using scalable fonts, only report those glyphs
      * which can be scaled; otherwise those fonts will
@@ -2644,17 +2655,43 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
 #define TTO_Err_Empty_Script              0x1005
 #define TTO_Err_Invalid_SubTable          0x1001
 
+#define OTLAYOUT_HEAD      "otlayout:"
+#define OTLAYOUT_HEAD_LEN   9
+#define OTLAYOUT_ID_LEN            4
+/* space + head + id */
+#define OTLAYOUT_LEN       (1 + OTLAYOUT_HEAD_LEN + OTLAYOUT_ID_LEN)
 
+/*
+ * This is a bit generous; the registry has only lower case and space
+ * except for 'DFLT'.
+ */
+#define FcIsSpace(x)       (040 == (x))
+#define FcIsValidScript(x)  (FcIsLower(x) || FcIsUpper (x) || FcIsSpace(x))
+                            
 static void
 addtag(FcChar8 *complex, FT_ULong tag)
 {
-    FcChar8 tagstring[15];
-    sprintf (tagstring, "otlayout:%c%c%c%c ",
-       (unsigned char)(tag >> 24),
-       (unsigned char)((tag & 0xff0000) >> 16),
-       (unsigned char)((tag & 0xff00) >> 8),
-       (unsigned char)(tag & 0xff));
-    strncat(complex, tagstring, 14);
+    FcChar8 tagstring[OTLAYOUT_ID_LEN + 1];
+
+    tagstring[0] = (FcChar8)(tag >> 24),
+    tagstring[1] = (FcChar8)(tag >> 16),
+    tagstring[2] = (FcChar8)(tag >> 8),
+    tagstring[3] = (FcChar8)(tag);
+    tagstring[4] = '\0';
+    
+    /* skip tags which aren't alphabetic, under the assumption that
+     * they're probably broken
+     */
+    if (!FcIsValidScript(tagstring[0]) ||
+       !FcIsValidScript(tagstring[1]) ||
+       !FcIsValidScript(tagstring[2]) ||
+       !FcIsValidScript(tagstring[3]))
+       return;
+
+    if (*complex != '\0')
+       strcat (complex, " ");
+    strcat (complex, "otlayout:");
+    strcat (complex, tagstring);
 }
 
 static int
@@ -2746,6 +2783,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri
     return TT_Err_Ok;
 
 Fail:
+    *script_count = 0;
     FT_FREE( *stags );
     return error;
 }
@@ -2757,7 +2795,8 @@ FcFontCapabilities(FT_Face face)
     FT_Error err;
     FT_ULong len = 0;
     FT_ULong *gsubtags=NULL, *gpostags=NULL;
-    FT_UShort gsub_count=0, gpos_count=0, maxsize;
+    FT_UShort gsub_count=0, gpos_count=0;
+    FT_ULong maxsize;
     FT_Memory  memory = face->stream->memory;
     FcChar8 *complex = NULL;
     int indx1 = 0, indx2 = 0;
@@ -2765,23 +2804,23 @@ FcFontCapabilities(FT_Face face)
     err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
     issilgraphitefont = ( err == FT_Err_Ok);
 
-    err = GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count);
-    err = GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count);
+    if (GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count) != FT_Err_Ok)
+       gpos_count = 0;
+    if (GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count) != FT_Err_Ok)
+       gsub_count = 0;
+    
     if (!issilgraphitefont && !gsub_count && !gpos_count)
-    {
        goto bail;
-    }
 
-    maxsize = ((gpos_count + gsub_count) * 15) + (issilgraphitefont ? 13 : 0);
+    maxsize = (((FT_ULong) gpos_count + (FT_ULong) gsub_count) * OTLAYOUT_LEN + 
+              (issilgraphitefont ? 13 : 0));
     complex = malloc (sizeof (FcChar8) * maxsize);
+    if (!complex)
+       goto bail;
+
+    complex[0] = '\0';
     if (issilgraphitefont)
-    {
         strcpy(complex, "ttable:Silf ");
-    }
-    else
-    {
-        strcpy(complex, "");
-    }
 
     while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
        if (indx1 == gsub_count) {