]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Add extended, caps, dunhill style mappings.
[fontconfig.git] / src / fcfreetype.c
index 7773c836c215df3b32c4ae6968d185ee270097bb..a79308cf417a625e82bf94fe90c38dfc40c9b204 100644 (file)
@@ -45,6 +45,7 @@
 */
 
 #include "fcint.h"
+#include "fcftint.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -801,29 +802,47 @@ FcSfntNameLanguage (FT_SfntName *sname)
 /* Order is significant.  For example, some B&H fonts are hinted by
    URW++, and both strings appear in the notice. */
 
-static const struct {
-    const FT_String *notice;
-    const FcChar8   *foundry;
-} FcNoticeFoundries[] = {
-    { (const FT_String *) "Bigelow",   (const FcChar8 *) "b&h" },
-    { (const FT_String *) "Adobe",     (const FcChar8 *) "adobe" },
-    { (const FT_String *) "Bitstream", (const FcChar8 *) "bitstream" },
-    { (const FT_String *) "Monotype",  (const FcChar8 *) "monotype" },
-    { (const FT_String *) "Linotype",  (const FcChar8 *) "linotype" },
-    { (const FT_String *) "LINOTYPE-HELL",
-                                       (const FcChar8 *) "linotype" },
-    { (const FT_String *) "IBM",       (const FcChar8 *) "ibm" },
-    { (const FT_String *) "URW",       (const FcChar8 *) "urw" },
-    { (const FT_String *) "International Typeface Corporation", 
-                                       (const FcChar8 *) "itc" },
-    { (const FT_String *) "Tiro Typeworks",
-                                       (const FcChar8 *) "tiro" },
-    { (const FT_String *) "XFree86",   (const FcChar8 *) "xfree86" },
-    { (const FT_String *) "Microsoft", (const FcChar8 *) "microsoft" },
-    { (const FT_String *) "Omega",     (const FcChar8 *) "omega" },
-    { (const FT_String *) "Font21",    (const FcChar8 *) "hwan" },
-    { (const FT_String *) "HanYang System",
-                                       (const FcChar8 *) "hanyang" }
+static const char notice_foundry_data[] =
+       "Bigelow\0b&h\0"
+       "Adobe\0adobe\0"
+       "Bitstream\0bitstream\0"
+       "Monotype\0monotype\0"
+       "Linotype\0linotype\0"
+       "LINOTYPE-HELL\0linotype\0"
+       "IBM\0ibm\0"
+       "URW\0urw\0"
+       "International Typeface Corporation\0itc\0"
+       "Tiro Typeworks\0tiro\0"
+       "XFree86\0xfree86\0"
+       "Microsoft\0microsoft\0"
+       "Omega\0omega\0"
+       "Font21\0hwan\0"
+       "HanYang System\0hanyang";
+
+struct _notice_foundry {
+    /* these are the offsets into the
+     * notice_foundry_data array.
+     */
+    unsigned char notice_offset;
+    unsigned char foundry_offset;
+};
+
+static const struct _notice_foundry FcNoticeFoundries[] = {
+    { 0, 8 },
+    { 12, 18 },
+    { 24, 34 },
+    { 44, 53 },
+    { 62, 71 },
+    { 80, 94 },
+    { 103, 107 },
+    { 111, 115 },
+    { 119, 154 },
+    { 158, 173 },
+    { 178, 186 },
+    { 194, 204 },
+    { 214, 220 },
+    { 226, 233 },
+    { 238, 253 }
 };
 
 #define NUM_NOTICE_FOUNDRIES   (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
@@ -835,8 +854,14 @@ FcNoticeFoundry(const FT_String *notice)
 
     if (notice)
        for(i = 0; i < NUM_NOTICE_FOUNDRIES; i++)
-           if (strstr ((const char *) notice, (const char *) FcNoticeFoundries[i].notice))
-               return FcNoticeFoundries[i].foundry;
+        {
+            const struct _notice_foundry *nf = &FcNoticeFoundries[i];
+            const char *n = notice_foundry_data + nf->notice_offset;
+            const char *f = notice_foundry_data + nf->foundry_offset;
+
+           if (strstr ((const char *) notice, n))
+               return (const FcChar8 *) f;
+        }
     return 0;
 }
 
@@ -861,38 +886,38 @@ FcVendorMatch(const FT_Char vendor[4], const FT_Char *vendor_string)
    entries for padding both with spaces and NULs. */
 
 static const struct {
-    const FT_Char   *vendor;
-    const FcChar8   *foundry;
+    const FT_Char   vendor[5];
+    const FcChar8   foundry[13];
 } FcVendorFoundries[] = {
-    { (const FT_Char *) "ADBE", (const FcChar8 *) "adobe"},
-    { (const FT_Char *) "AGFA", (const FcChar8 *) "agfa"},
-    { (const FT_Char *) "ALTS", (const FcChar8 *) "altsys"},
-    { (const FT_Char *) "APPL", (const FcChar8 *) "apple"},
-    { (const FT_Char *) "ARPH", (const FcChar8 *) "arphic"},
-    { (const FT_Char *) "ATEC", (const FcChar8 *) "alltype"},
-    { (const FT_Char *) "B&H",  (const FcChar8 *) "b&h"},
-    { (const FT_Char *) "BITS", (const FcChar8 *) "bitstream"},
-    { (const FT_Char *) "CANO", (const FcChar8 *) "cannon"},
-    { (const FT_Char *) "DYNA", (const FcChar8 *) "dynalab"},
-    { (const FT_Char *) "EPSN", (const FcChar8 *) "epson"},
-    { (const FT_Char *) "FJ",   (const FcChar8 *) "fujitsu"},
-    { (const FT_Char *) "IBM",  (const FcChar8 *) "ibm"},
-    { (const FT_Char *) "ITC",  (const FcChar8 *) "itc"},
-    { (const FT_Char *) "IMPR", (const FcChar8 *) "impress"},
-    { (const FT_Char *) "LARA", (const FcChar8 *) "larabiefonts"},
-    { (const FT_Char *) "LEAF", (const FcChar8 *) "interleaf"},
-    { (const FT_Char *) "LETR", (const FcChar8 *) "letraset"},
-    { (const FT_Char *) "LINO", (const FcChar8 *) "linotype"},
-    { (const FT_Char *) "MACR", (const FcChar8 *) "macromedia"},
-    { (const FT_Char *) "MONO", (const FcChar8 *) "monotype"},
-    { (const FT_Char *) "MS",   (const FcChar8 *) "microsoft"},
-    { (const FT_Char *) "MT",   (const FcChar8 *) "monotype"},
-    { (const FT_Char *) "NEC",  (const FcChar8 *) "nec"},
-    { (const FT_Char *) "PARA", (const FcChar8 *) "paratype"},
-    { (const FT_Char *) "QMSI", (const FcChar8 *) "qms"},
-    { (const FT_Char *) "RICO", (const FcChar8 *) "ricoh"},
-    { (const FT_Char *) "URW",  (const FcChar8 *) "urw"},
-    { (const FT_Char *) "Y&Y",  (const FcChar8 *) "y&y"}
+    { "ADBE", "adobe"},
+    { "AGFA", "agfa"},
+    { "ALTS", "altsys"},
+    { "APPL", "apple"},
+    { "ARPH", "arphic"},
+    { "ATEC", "alltype"},
+    { "B&H",  "b&h"},
+    { "BITS", "bitstream"},
+    { "CANO", "cannon"},
+    { "DYNA", "dynalab"},
+    { "EPSN", "epson"},
+    { "FJ",   "fujitsu"},
+    { "IBM",  "ibm"},
+    { "ITC",  "itc"},
+    { "IMPR", "impress"},
+    { "LARA", "larabiefonts"},
+    { "LEAF", "interleaf"},
+    { "LETR", "letraset"},
+    { "LINO", "linotype"},
+    { "MACR", "macromedia"},
+    { "MONO", "monotype"},
+    { "MS",   "microsoft"},
+    { "MT",   "monotype"},
+    { "NEC",  "nec"},
+    { "PARA", "paratype"},
+    { "QMSI", "qms"},
+    { "RICO", "ricoh"},
+    { "URW",  "urw"},
+    { "Y&Y",  "y&y"}
 };
 
 #define NUM_VENDOR_FOUNDRIES   (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
@@ -935,8 +960,18 @@ FcStringContainsConst (const FcChar8           *string,
     int        i;
 
     for (i = 0; i < nc; i++)
-       if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
-           return c[i].value;
+    {
+       if (c[i].name[0] == '<')
+       {
+           if (FcStrContainsWord (string, c[i].name + 1))
+               return c[i].value;
+       }
+       else
+       {
+           if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
+               return c[i].value;
+       }
+    }
     return -1;
 }
 
@@ -958,6 +993,10 @@ static const FcStringConst  weightConsts[] = {
     { (FC8) "superbold",       FC_WEIGHT_EXTRABOLD },
     { (FC8) "ultrabold",       FC_WEIGHT_ULTRABOLD },
     { (FC8) "bold",            FC_WEIGHT_BOLD },
+    { (FC8) "ultrablack",      FC_WEIGHT_ULTRABLACK },
+    { (FC8) "superblack",      FC_WEIGHT_EXTRABLACK },
+    { (FC8) "extrablack",      FC_WEIGHT_EXTRABLACK },
+    { (FC8) "<ultra",          FC_WEIGHT_ULTRABOLD }, /* only if a word */
     { (FC8) "black",           FC_WEIGHT_BLACK },
     { (FC8) "heavy",           FC_WEIGHT_HEAVY },
 };
@@ -977,6 +1016,7 @@ static const FcStringConst  widthConsts[] = {
     { (FC8) "extraexpanded",   FC_WIDTH_EXTRAEXPANDED },
     { (FC8) "ultraexpanded",   FC_WIDTH_ULTRAEXPANDED },
     { (FC8) "expanded",                FC_WIDTH_EXPANDED },    /* must be after *expanded */
+    { (FC8) "extended",                FC_WIDTH_EXPANDED },
 };
 
 #define NUM_WIDTH_CONSTS    (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
@@ -997,11 +1037,11 @@ static const FcStringConst  slantConsts[] = {
 
 static const FcStringConst  decorativeConsts[] = {
     { (FC8) "shadow",          FcTrue },
-    { (FC8) "smallcaps",       FcTrue },
+    { (FC8) "caps",            FcTrue },
     { (FC8) "antiqua",         FcTrue },
     { (FC8) "romansc",         FcTrue },
     { (FC8) "embosed",         FcTrue },
-    { (FC8) "romansmallcaps",  FcTrue },
+    { (FC8) "dunhill",         FcTrue },
 };
 
 #define NUM_DECORATIVE_CONSTS  (int) (sizeof (decorativeConsts) / sizeof (decorativeConsts[0]))
@@ -1415,8 +1455,10 @@ FcFreeTypeQueryFace (const FT_Face  face,
            weight = FC_WEIGHT_BOLD;
        else if (os2->usWeightClass < 850)
            weight = FC_WEIGHT_EXTRABOLD;
-       else if (os2->usWeightClass < 950)
+       else if (os2->usWeightClass < 925)
            weight = FC_WEIGHT_BLACK;
+       else if (os2->usWeightClass < 1000)
+           weight = FC_WEIGHT_EXTRABLACK;
        if ((FcDebug() & FC_DBG_SCANV) && weight != -1)
            printf ("\tos2 weight class %d maps to weight %d\n",
                    os2->usWeightClass, weight);
@@ -1659,40 +1701,6 @@ FcFreeTypeQueryFace (const FT_Face  face,
                goto bail2;
        if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
            goto bail2;
-#if HAVE_FT_GET_BDF_PROPERTY
-        if(face->num_fixed_sizes == 1) {
-            int rc;
-            int value;
-
-           /* skip bitmap fonts which do not even have a family name */
-           rc =  FT_Get_BDF_Property(face, "FAMILY_NAME", &prop);
-           if (rc != 0 || prop.type != BDF_PROPERTY_TYPE_ATOM)
-               goto bail2;
-
-            rc = FT_Get_BDF_Property(face, "POINT_SIZE", &prop);
-            if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
-                value = prop.u.integer;
-            else if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_CARDINAL)
-                value = prop.u.cardinal;
-            else
-                goto nevermind;
-            if(!FcPatternAddDouble(pat, FC_SIZE, value / 10.0))
-                goto nevermind;
-
-            rc = FT_Get_BDF_Property(face, "RESOLUTION_Y", &prop);
-            if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
-                value = prop.u.integer;
-            else if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_CARDINAL)
-                value = prop.u.cardinal;
-            else
-                goto nevermind;
-            if(!FcPatternAddDouble(pat, FC_DPI, (double)value))
-                goto nevermind;
-
-        }
-    nevermind:
-        ;
-#endif
     }
 #if HAVE_FT_GET_X11_FONT_FORMAT
     /*
@@ -2460,11 +2468,15 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
 static FcBool
 FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, 
                      FT_UInt glyph, FcBlanks *blanks,
-                     FT_Pos *advance)
+                     FT_Pos *advance,
+                     FcBool using_strike)
 {
     FT_Int         load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     FT_GlyphSlot    slot;
     
+    if (using_strike)
+       load_flags &= ~FT_LOAD_NO_SCALE;
+
     /*
      * When using scalable fonts, only report those glyphs
      * which can be scaled; otherwise those fonts will
@@ -2518,8 +2530,8 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
 #define FC_ABS(a)   ((a) < 0 ? -(a) : (a))
 #define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
 
-FcCharSet *
-FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+static FcCharSet *
+FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing, FT_Int strike_index)
 {
     FcChar32       page, off, ucs4;
 #ifdef CHECK
@@ -2533,11 +2545,18 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
     FT_UInt        glyph;
     FT_Pos         advance, advance_one = 0, advance_two = 0;
     FcBool         has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse;
+    FcBool         using_strike = FcFalse;
 
     fcs = FcCharSetCreate ();
     if (!fcs)
        goto bail0;
     
+    if (strike_index >= 0) {
+       if (FT_Select_Size (face, strike_index) != FT_Err_Ok)
+           goto bail1;
+       using_strike = FcTrue;
+    }
+
 #ifdef CHECK
     printf ("Family %s style %s\n", face->family_name, face->style_name);
 #endif
@@ -2557,7 +2576,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
                ucs4 = map->ent[i].bmp;
                glyph = FT_Get_Char_Index (face, map->ent[i].encode);
                if (glyph && 
-                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    /* 
                     * ignore glyphs with zero advance. They’re
@@ -2605,7 +2624,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
             ucs4 = FT_Get_First_Char (face, &glyph);
             while (glyph != 0)
            {
-               if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+               if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    if (advance)
                    {
@@ -2672,7 +2691,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
            {
                ucs4 = FcGlyphNameToUcs4 (name_buf);
                if (ucs4 != 0xffff && 
-                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                {
                    if (advance)
                    {
@@ -2715,7 +2734,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
 
        if (has_char && !has_bit)
        {
-           if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+           if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
                printf ("Bitmap missing broken char 0x%x\n", ucs4);
            else
                printf ("Bitmap missing char 0x%x\n", ucs4);
@@ -2737,6 +2756,39 @@ bail0:
     return 0;
 }
 
+FcCharSet *
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+{
+    FcCharSet  *cs;
+    
+    cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, -1);
+    /*
+     * Check for bitmap-only ttf fonts that are missing the glyf table.
+     * In that case, pick a size and look for glyphs in that size instead
+     */
+    if (FcCharSetCount (cs) == 0) 
+    {
+       /* Check for non-scalable TT fonts */
+       if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) &&
+           face->num_fixed_sizes > 0 &&
+           FT_Get_Sfnt_Table (face, ft_sfnt_head))
+       {
+           FT_Int  strike_index = 0;
+           int     i;
+
+           /* Select the face closest to 16 pixels tall */
+           for (i = 1; i < face->num_fixed_sizes; i++) {
+               if (abs (face->available_sizes[i].height - 16) < 
+                   abs (face->available_sizes[strike_index].height - 16))
+                   strike_index = i;
+           }
+           FcCharSetDestroy (cs);
+           cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, strike_index);
+       }
+    }
+    return cs;
+}
+
 FcCharSet *
 FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
 {
@@ -2948,4 +3000,5 @@ bail:
 
 #define __fcfreetype__
 #include "fcaliastail.h"
+#include "fcftaliastail.h"
 #undef __fcfreetype__