]> git.wh0rd.org - fontconfig.git/commitdiff
Grub through style to find weight/slant/width values when other techniques
authorKeith Packard <keithp@keithp.com>
Fri, 2 May 2003 01:11:53 +0000 (01:11 +0000)
committerKeith Packard <keithp@keithp.com>
Fri, 2 May 2003 01:11:53 +0000 (01:11 +0000)
    fail

src/fcfreetype.c
src/fcint.h
src/fcstr.c

index f46e1394ecae5794761f6dfc38b34a4b76f7260e..eef7081e2959714f0619e94adc100a6393781809 100644 (file)
@@ -255,6 +255,87 @@ FcVendorFoundry(const char *vendor)
     return 0;
 }
 
+typedef struct _FcStringConst {
+    const char *name;
+    int                value;
+} FcStringConst;
+
+static int
+FcStringIsConst (const FcChar8         *string,
+                const FcStringConst    *c,
+                int                    nc)
+{
+    int        i;
+
+    for (i = 0; i < nc; i++)
+       if (FcStrCmpIgnoreBlanksAndCase (string, c[i].name) == 0)
+           return c[i].value;
+    return -1;
+}
+
+static int
+FcStringContainsConst (const FcChar8       *string,
+                      const FcStringConst  *c,
+                      int                  nc)
+{
+    int        i;
+
+    for (i = 0; i < nc; i++)
+       if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
+           return c[i].value;
+    return -1;
+}
+
+static const FcStringConst  weightConsts[] = {
+    { "thin",          FC_WEIGHT_THIN },
+    { "extralight",    FC_WEIGHT_EXTRALIGHT },
+    { "ultralight",    FC_WEIGHT_ULTRALIGHT },
+    { "light",         FC_WEIGHT_LIGHT },
+    { "book",          FC_WEIGHT_BOOK },
+    { "regular",       FC_WEIGHT_REGULAR },
+    { "normal",                FC_WEIGHT_NORMAL },
+    { "medium",                FC_WEIGHT_MEDIUM },
+    { "demibold",      FC_WEIGHT_DEMIBOLD },
+    { "demi",          FC_WEIGHT_DEMIBOLD },
+    { "semibold",      FC_WEIGHT_SEMIBOLD },
+    { "bold",          FC_WEIGHT_BOLD },
+    { "extrabold",     FC_WEIGHT_EXTRABOLD },
+    { "ultrabold",     FC_WEIGHT_ULTRABOLD },
+    { "black",         FC_WEIGHT_BLACK },
+    { "heavy",         FC_WEIGHT_HEAVY },
+};
+
+#define NUM_WEIGHT_CONSTS  (sizeof (weightConsts) / sizeof (weightConsts[0]))
+
+#define FcIsWeight(s)      FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
+#define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
+
+static const FcStringConst  widthConsts[] = {
+    { "ultracondensed",        FC_WIDTH_ULTRACONDENSED },
+    { "extracondensed",        FC_WIDTH_EXTRACONDENSED },
+    { "semicondensed",  FC_WIDTH_SEMICONDENSED },
+    { "condensed",     FC_WIDTH_CONDENSED },   /* must be after *condensed */
+    { "normal",                FC_WIDTH_NORMAL },
+    { "semiexpanded",  FC_WIDTH_SEMIEXPANDED },
+    { "extraexpanded", FC_WIDTH_EXTRAEXPANDED },
+    { "ultraexpanded", FC_WIDTH_ULTRAEXPANDED },
+    { "expanded",      FC_WIDTH_EXPANDED },    /* must be after *expanded */
+};
+
+#define NUM_WIDTH_CONSTS    (sizeof (widthConsts) / sizeof (widthConsts[0]))
+
+#define FcIsWidth(s)       FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
+#define FcContainsWidth(s)  FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
+
+static const FcStringConst  slantConsts[] = {
+    { "italic",                FC_SLANT_ITALIC },
+    { "oblique",       FC_SLANT_OBLIQUE },
+};
+
+#define NUM_SLANT_CONSTS    (sizeof (slantConsts) / sizeof (slantConsts[0]))
+
+#define FcIsSlant(s)       FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
+#define FcContainsSlant(s)  FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
 
 FcPattern *
 FcFreeTypeQuery (const FcChar8 *file,
@@ -264,8 +345,8 @@ FcFreeTypeQuery (const FcChar8      *file,
 {
     FT_Face        face;
     FcPattern      *pat;
-    int                    slant;
-    int                    weight;
+    int                    slant = -1;
+    int                    weight = -1;
     int                    width = -1;
     int                    i;
     FcCharSet      *cs;
@@ -307,15 +388,6 @@ FcFreeTypeQuery (const FcChar8     *file,
        goto bail1;
 
 
-    slant = FC_SLANT_ROMAN;
-    if (face->style_flags & FT_STYLE_FLAG_ITALIC)
-       slant = FC_SLANT_ITALIC;
-
-
-    weight = FC_WEIGHT_MEDIUM;
-    if (face->style_flags & FT_STYLE_FLAG_BOLD)
-       weight = FC_WEIGHT_BOLD;
-
     /*
      * Get the OS/2 table
      */
@@ -598,30 +670,15 @@ FcFreeTypeQuery (const FcChar8    *file,
     }
 
     if (FcDebug() & FC_DBG_SCAN)
-       printf ("\"%s\" \"%s\" ", family, style ? style : (FcChar8 *) "<none>");
+       printf ("\n\"%s\" \"%s\"\n", family, style ? style : (FcChar8 *) "<none>");
 
     if (!FcPatternAddString (pat, FC_FAMILY, family))
-    {
-       if (family_allocated)
-           free (family);
-       if (style_allocated)
-           free (style);
        goto bail1;
-    }
-
-    if (family_allocated)
-       free (family);
 
     if (style)
     {
        if (!FcPatternAddString (pat, FC_STYLE, style))
-       {
-           if (style_allocated)
-               free (style);
            goto bail1;
-       }
-       if (style_allocated)
-           free (style);
     }
 
     if (!FcPatternAddString (pat, FC_FILE, file))
@@ -695,7 +752,7 @@ FcFreeTypeQuery (const FcChar8      *file,
     if (os2 && os2->version != 0xffff)
     {
        if (os2->usWeightClass == 0)
-           weight = -1;
+           ;
        else if (os2->usWeightClass < 150)
            weight = FC_WEIGHT_THIN;
        else if (os2->usWeightClass < 250)
@@ -714,8 +771,6 @@ FcFreeTypeQuery (const FcChar8      *file,
            weight = FC_WEIGHT_EXTRABOLD;
        else if (os2->usWeightClass < 950)
            weight = FC_WEIGHT_BLACK;
-       else
-           weight = FC_WEIGHT_MEDIUM;
 
        switch (os2->usWidthClass) {
        case 1: width = FC_WIDTH_ULTRACONDENSED; break;
@@ -737,44 +792,15 @@ FcFreeTypeQuery (const FcChar8    *file,
     
     if (FT_Get_PS_Font_Info(face, &psfontinfo) == 0)
     {
-       if (psfontinfo.weight)
+#if 0
+       if (weight == -1 && psfontinfo.weight)
        {
-           static struct {
-               char    *name;
-               int     value;
-           } ps_weights[] = {
-               { "thin",               FC_WEIGHT_THIN },
-               { "extralight",         FC_WEIGHT_EXTRALIGHT },
-               { "ultralight",         FC_WEIGHT_ULTRALIGHT },
-               { "light",              FC_WEIGHT_LIGHT },
-               { "book",               FC_WEIGHT_BOOK },
-               { "regular",            FC_WEIGHT_REGULAR },
-               { "normal",             FC_WEIGHT_NORMAL },
-               { "medium",             FC_WEIGHT_MEDIUM },
-               { "demibold",           FC_WEIGHT_DEMIBOLD },
-               { "demi",               FC_WEIGHT_DEMIBOLD },
-               { "semibold",           FC_WEIGHT_SEMIBOLD },
-               { "bold",               FC_WEIGHT_BOLD },
-               { "extrabold",          FC_WEIGHT_EXTRABOLD },
-               { "ultrabold",          FC_WEIGHT_ULTRABOLD },
-               { "black",              FC_WEIGHT_BLACK },
-               { "heavy",              FC_WEIGHT_HEAVY },
-           };
-#define NUM_PS_WEIGHTS (sizeof (ps_weights) / sizeof (ps_weights[0]))
-           int w;
-           for (w = 0; w < NUM_PS_WEIGHTS; w++)
-               if (!FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) ps_weights[w].name,
-                                        (FcChar8 *) psfontinfo.weight))
-               {
-                   weight = ps_weights[w].value;
-                   break;
-               }
-           if (FcDebug () & FC_DBG_SCANV)
-           {
-               if (w == NUM_PS_WEIGHTS)
-                   printf ("\tunknown PS weight name %s\n", psfontinfo.weight);
-           }
+           weight = FcIsWeight (psfontinfo.weight);
+           if (FcDebug() & FC_DBG_SCANV)
+               printf ("\tType1 weight %s maps to %d\n",
+                       psfontinfo.weight, weight);
        }
+#endif
      
 #if 0
        /* 
@@ -838,14 +864,11 @@ FcFreeTypeQuery (const FcChar8    *file,
                FcChar8     *width_name;
                int         width;
            } FcSetWidths[] = {
-               { "Condensed",      FC_WIDTH_CONDENSED },
-               { "SemiCondensed",  FC_WIDTH_SEMICONDENSED },
-               { "Normal",         FC_WIDTH_NORMAL },
            };
            int i;
 
            if (FcDebug () & FC_DBG_SCANV)
-               printf ("\nsetwidth: %s\n", prop.u.atom);
+               printf ("\tsetwidth: %s\n", prop.u.atom);
            for (i = 0; i < sizeof (FcSetWidths) / sizeof (FcSetWidths[0]); i++)
                if (!FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) prop.u.atom,
                                         FcSetWidths[i].width_name))
@@ -858,6 +881,48 @@ FcFreeTypeQuery (const FcChar8     *file,
 
 #endif
 
+    /*
+     * Look for weight, width and slant names in the style value
+     */
+    if (style)
+    {
+       if (weight == -1)
+       {
+           weight = FcContainsWeight (style);
+           if (FcDebug() & FC_DBG_SCANV)
+               printf ("\tStyle %s maps to weight %d\n", style, weight);
+       }
+       if (width == -1)
+       {
+           width = FcContainsWidth (style);
+           if (FcDebug() & FC_DBG_SCANV)
+               printf ("\tStyle %s maps to width %d\n", style, width);
+       }
+       if (slant == -1)
+       {
+           slant = FcContainsSlant (style);
+           if (FcDebug() & FC_DBG_SCANV)
+               printf ("\tStyle %s maps to slant %d\n", style, slant);
+       }
+    }
+    /*
+     * Pull default values from the FreeType flags if more
+     * specific values not found above
+     */
+    if (slant == -1)
+    {
+       slant = FC_SLANT_ROMAN;
+       if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+           slant = FC_SLANT_ITALIC;
+    }
+
+    if (weight == -1)
+    {
+       weight = FC_WEIGHT_MEDIUM;
+       if (face->style_flags & FT_STYLE_FLAG_BOLD)
+           weight = FC_WEIGHT_BOLD;
+    }
+
     if (!FcPatternAddInteger (pat, FC_SLANT, slant))
        goto bail1;
 
@@ -905,11 +970,6 @@ FcFreeTypeQuery (const FcChar8     *file,
        if (!FcPatternAddInteger (pat, FC_SPACING, spacing))
            goto bail2;
 
-    /*
-     * Drop our reference to the charset
-     */
-    FcCharSetDestroy (cs);
-    
     if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
     {
        for (i = 0; i < face->num_fixed_sizes; i++)
@@ -920,6 +980,20 @@ FcFreeTypeQuery (const FcChar8     *file,
            goto bail1;
     }
 
+    /*
+     * Drop our reference to the charset
+     */
+    FcCharSetDestroy (cs);
+    
+    /*
+     * Deallocate family/style values
+     */
+    
+    if (family_allocated)
+       free (family);
+    if (style_allocated)
+       free (style);
+    
     FT_Done_Face (face);
     FT_Done_FreeType (ftLibrary);
     return pat;
@@ -928,6 +1002,10 @@ bail2:
     FcCharSetDestroy (cs);
 bail1:
     FcPatternDestroy (pat);
+    if (family_allocated)
+       free (family);
+    if (style_allocated)
+       free (style);
 bail0:
     FT_Done_Face (face);
 bail:
index 7ffc3a627f42d91191b12555158384b0fc5c1137..9b469b72b54152ad2d2d51d9fd4071cee0647312 100644 (file)
@@ -653,6 +653,12 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
 int
 FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
 
+const FcChar8 *
+FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
+
+const FcChar8 *
+FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
+
 FcBool
 FcStrUsesHome (const FcChar8 *s);
 
index 5b75f0e62eaf4488649ef17d8b6a90e2af9961da..ecbfd297c59120627659146eb8532cb9d8f52039 100644 (file)
@@ -114,6 +114,80 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
     return (int) c1 - (int) c2;
 }
 
+/*
+ * Is the head of s1 equal to s2?
+ */
+
+static FcBool
+FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
+{
+    FcChar8 c1, c2;
+    
+    for (;;) 
+    {
+       do
+           c1 = *s1++;
+       while (c1 == ' ');
+       do
+           c2 = *s2++;
+       while (c2 == ' ');
+       if (!c1 || (c1 != c2 && (c1 = FcToLower(c1)) != (c2 = FcToLower(c2))))
+           break;
+    }
+    return c1 == c2 || !c2;
+}
+
+/*
+ * Does s1 contain an instance of s2 (ignoring blanks and case)?
+ */
+
+const FcChar8 *
+FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
+{
+    while (*s1)
+    {
+       if (FcStrIsAtIgnoreBlanksAndCase (s1, s2))
+           return s1;
+       s1++;
+    }
+    return 0;
+}
+
+/*
+ * Is the head of s1 equal to s2?
+ */
+
+static FcBool
+FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
+{
+    FcChar8 c1, c2;
+    
+    for (;;) 
+    {
+       c1 = *s1++;
+       c2 = *s2++;
+       if (!c1 || (c1 != c2 && (c1 = FcToLower(c1)) != (c2 = FcToLower(c2))))
+           break;
+    }
+    return c1 == c2 || !c2;
+}
+
+/*
+ * Does s1 contain an instance of s2 (ignoring blanks and case)?
+ */
+
+const FcChar8 *
+FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
+{
+    while (*s1)
+    {
+       if (FcStrIsAtIgnoreCase (s1, s2))
+           return s1;
+       s1++;
+    }
+    return 0;
+}
+
 int
 FcUtf8ToUcs4 (const FcChar8 *src_orig,
              FcChar32      *dst,