]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcfreetype.c
Set spacing to mono if every encoded glyph is the same width
[fontconfig.git] / src / fcfreetype.c
index d8799fc6e8ea2b6c32fa724f88e4a8bbf698d45a..7a9e32d2a4dca301be6c48fc2ca60ad1708e29ad 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * $XFree86: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
+ * $RCSId: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
  *
- * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ * 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
@@ -121,12 +121,14 @@ FcFreeTypeQuery (const FcChar8    *file,
     FcPattern      *pat;
     int                    slant;
     int                    weight;
+    int                    width = -1;
     int                    i;
     FcCharSet      *cs;
     FcLangSet      *ls;
     FT_Library     ftLibrary;
     FcChar8        *family;
     FcChar8        *style;
+    int                    spacing;
     TT_OS2         *os2;
     TT_Header      *head;
     const FcChar8   *exclusiveLang = 0;
@@ -162,16 +164,11 @@ FcFreeTypeQuery (const FcChar8    *file,
     if (face->style_flags & FT_STYLE_FLAG_ITALIC)
        slant = FC_SLANT_ITALIC;
 
-    if (!FcPatternAddInteger (pat, FC_SLANT, slant))
-       goto bail1;
 
     weight = FC_WEIGHT_MEDIUM;
     if (face->style_flags & FT_STYLE_FLAG_BOLD)
        weight = FC_WEIGHT_BOLD;
 
-    if (!FcPatternAddInteger (pat, FC_WEIGHT, weight))
-       goto bail1;
-
     /*
      * Grub through the name table looking for family
      * and style names.  FreeType makes quite a hash
@@ -530,10 +527,58 @@ 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)
+           weight = FC_WEIGHT_EXTRALIGHT;
+       else if (os2->usWeightClass < 350)
+           weight = FC_WEIGHT_LIGHT;
+       else if (os2->usWeightClass < 450)
+           weight = FC_WEIGHT_REGULAR;
+       else if (os2->usWeightClass < 550)
+           weight = FC_WEIGHT_MEDIUM;
+       else if (os2->usWeightClass < 650)
+           weight = FC_WEIGHT_SEMIBOLD;
+       else if (os2->usWeightClass < 750)
+           weight = FC_WEIGHT_BOLD;
+       else if (os2->usWeightClass < 850)
+           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;
+       case 2: width = FC_WIDTH_EXTRACONDENSED; break;
+       case 3: width = FC_WIDTH_CONDENSED; break;
+       case 4: width = FC_WIDTH_SEMICONDENSED; break;
+       case 5: width = FC_WIDTH_NORMAL; break;
+       case 6: width = FC_WIDTH_SEMIEXPANDED; break;
+       case 7: width = FC_WIDTH_EXPANDED; break;
+       case 8: width = FC_WIDTH_EXTRAEXPANDED; break;
+       case 9: width = FC_WIDTH_ULTRAEXPANDED; break;
+       }
+    }
+    
+    if (!FcPatternAddInteger (pat, FC_SLANT, slant))
+       goto bail1;
+
+    if (!FcPatternAddInteger (pat, FC_WEIGHT, weight))
+       goto bail1;
+
+    if (width != -1)
+       if (!FcPatternAddInteger (pat, FC_WIDTH, width))
+           goto bail1;
+
     /*
      * Compute the unicode coverage for the font
      */
-    cs = FcFreeTypeCharSet (face, blanks);
+    cs = FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
     if (!cs)
        goto bail1;
 
@@ -557,6 +602,10 @@ FcFreeTypeQuery (const FcChar8     *file,
     if (!FcPatternAddLangSet (pat, FC_LANG, ls))
        goto bail2;
 
+    if (spacing != FC_PROPORTIONAL)
+       if (!FcPatternAddInteger (pat, FC_SPACING, spacing))
+           goto bail2;
+
     /*
      * Drop our reference to the charset
      */
@@ -1173,7 +1222,8 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
 
 static FcBool
 FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, 
-                     FT_UInt glyph, FcBlanks *blanks)
+                     FT_UInt glyph, FcBlanks *blanks,
+                     FT_Pos *advance)
 {
     FT_Int         load_flags = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
     FT_GlyphSlot    slot;
@@ -1195,6 +1245,8 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
     if (!glyph)
        return FcFalse;
     
+    *advance = slot->metrics.horiAdvance;
+
     switch (slot->format) {
     case ft_glyph_format_bitmap:
        /*
@@ -1225,7 +1277,7 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
 }
 
 FcCharSet *
-FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
 {
     FcChar32       page, off, max, ucs4;
 #ifdef CHECK
@@ -1237,6 +1289,8 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
     int                    o;
     int                    i;
     FT_UInt        glyph;
+    FT_Pos         advance, all_advance = 0;
+    FcBool         has_advance = FcFalse, fixed_advance = FcTrue;
 
     fcs = FcCharSetCreate ();
     if (!fcs)
@@ -1257,8 +1311,16 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
            {
                ucs4 = map->ent[i].bmp;
                glyph = FT_Get_Char_Index (face, map->ent[i].encode);
-               if (glyph && FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks))
+               if (glyph && 
+                   FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
                {
+                   if (!has_advance)
+                   {
+                       has_advance = FcTrue;
+                       all_advance = advance;
+                   }
+                   else if (advance != all_advance)
+                       fixed_advance = FcFalse;
                    leaf = FcCharSetFindLeafCreate (fcs, ucs4);
                    if (!leaf)
                        goto bail1;
@@ -1298,8 +1360,15 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
                {
                    glyph = FT_Get_Char_Index (face, ucs4);
                    if (glyph && FcFreeTypeCheckGlyph (face, ucs4, 
-                                                      glyph, blanks))
+                                                      glyph, blanks, &advance))
                    {
+                       if (!has_advance)
+                       {
+                           has_advance = FcTrue;
+                           all_advance = advance;
+                       }
+                       else if (advance != all_advance)
+                           fixed_advance = FcFalse;
                        if (!leaf)
                        {
                            leaf = FcCharSetFindLeafCreate (fcs, ucs4);
@@ -1347,6 +1416,10 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
            printf ("Bitmap extra char 0x%x\n", ucs4);
     }
 #endif
+    if (fixed_advance)
+       *spacing = FC_MONO;
+    else
+       *spacing = FC_PROPORTIONAL;
     return fcs;
 bail1:
     FcCharSetDestroy (fcs);
@@ -1354,3 +1427,10 @@ bail0:
     return 0;
 }
 
+FcCharSet *
+FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
+{
+    int spacing;
+
+    return FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
+}