Bug 319808 – Patch to let pango support artifical italic, bold and bold
authorBehdad Esfahbod <behdad@gnome.org>
Wed, 13 Dec 2006 21:02:00 +0000 (21:02 +0000)
committerBehdad Esfahbod <behdad@src.gnome.org>
Wed, 13 Dec 2006 21:02:00 +0000 (21:02 +0000)
2006-12-13  Behdad Esfahbod  <behdad@gnome.org>

        Bug 319808 – Patch to let pango support artifical italic, bold and
        bold italic styles for the fonts which don't have these styles.
        Patch from James Su

        * pango/pangofc-fontmap.c (pango_fc_face_describe), (create_face),
        (pango_fc_family_list_faces): Create fake Bold, Italic, and Bold
        Italic faces for fonts that do not have one.

ChangeLog
pango/pangofc-fontmap.c

index 4713d91..8dab0c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-12-13  Behdad Esfahbod  <behdad@gnome.org>
+
+       Bug 319808 – Patch to let pango support artifical italic, bold and
+       bold italic styles for the fonts which don't have these styles.
+       Patch from James Su
+
+       * pango/pangofc-fontmap.c (pango_fc_face_describe), (create_face),
+       (pango_fc_family_list_faces): Create fake Bold, Italic, and Bold
+       Italic faces for fonts that do not have one.
+
 2006-12-13  Gwenole Beauchesne  <gbeauchesne@mandriva.com>
 
        Bug 385478 – Fix tests on OPD platform
index 2baa4e4..9a34387 100644 (file)
@@ -86,6 +86,8 @@ struct _PangoFcFace
 
   PangoFcFamily *family;
   char *style;
+
+  guint fake : 1;
 };
 
 struct _PangoFcFamily
@@ -1684,7 +1686,7 @@ pango_fc_face_describe (PangoFontFace *face)
   FcPattern *match_pattern;
   FcPattern *result_pattern;
 
-  if (is_alias_family (fcfamily->family_name))
+  if (fcface->fake)
     {
       if (strcmp (fcface->style, "Regular") == 0)
        return make_alias_description (fcfamily, FALSE, FALSE);
@@ -1869,11 +1871,13 @@ pango_fc_face_get_type (void)
  */
 static PangoFcFace *
 create_face (PangoFcFamily *fcfamily,
-            const char     *style)
+            const char     *style,
+            gboolean       fake)
 {
   PangoFcFace *face = g_object_new (PANGO_FC_TYPE_FACE, NULL);
   face->style = g_strdup (style);
   face->family = fcfamily;
+  face->fake = fake;
 
   return face;
 }
@@ -1898,37 +1902,98 @@ pango_fc_family_list_faces (PangoFontFamily  *family,
          fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces);
 
          i = 0;
-         fcfamily->faces[i++] = create_face (fcfamily, "Regular");
-         fcfamily->faces[i++] = create_face (fcfamily, "Bold");
-         fcfamily->faces[i++] = create_face (fcfamily, "Italic");
-         fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic");
+         fcfamily->faces[i++] = create_face (fcfamily, "Regular", TRUE);
+         fcfamily->faces[i++] = create_face (fcfamily, "Bold", TRUE);
+         fcfamily->faces[i++] = create_face (fcfamily, "Italic", TRUE);
+         fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic", TRUE);
        }
       else
        {
-         FcObjectSet *os = FcObjectSetBuild (FC_STYLE, NULL);
+         FcObjectSet *os = FcObjectSetBuild (FC_STYLE, FC_WEIGHT, FC_SLANT, NULL);
          FcPattern *pat = FcPatternBuild (NULL, 
                                           FC_FAMILY, FcTypeString, fcfamily->family_name,
                                           NULL);
-      
+
+         enum {
+           REGULAR,
+           ITALIC,
+           BOLD,
+           BOLD_ITALIC
+         };
+         /* Regular, Italic, Bold, Bold Italic */
+         gboolean has_face [4] = { FALSE, FALSE, FALSE, FALSE };
+         PangoFcFace **faces;
+         gint num = 0;
+
          fontset = FcFontList (NULL, pat, os);
-      
+
          FcPatternDestroy (pat);
          FcObjectSetDestroy (os);
-      
-         fcfamily->n_faces = fontset->nfont;
-         fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces);
-         
+
+         /* at most we have 3 additional artifical faces */
+         faces = g_new (PangoFcFace *, fontset->nfont + 3);
+
          for (i = 0; i < fontset->nfont; i++)
            {
-             FcChar8 *s;
-             FcResult res;
+             FcChar8 *style, *font_style = NULL;
+             int weight, slant;
+
+             if (FcPatternGetInteger(fontset->fonts[i], FC_WEIGHT, 0, &weight) != FcResultMatch)
+               weight = FC_WEIGHT_MEDIUM;
+
+             if (FcPatternGetInteger(fontset->fonts[i], FC_SLANT, 0, &slant) != FcResultMatch)
+               slant = FC_SLANT_ROMAN;
+
+             if (FcPatternGetString (fontset->fonts[i], FC_STYLE, 0, &font_style) != FcResultMatch)
+               font_style = NULL;
+
+             if (weight <= FC_WEIGHT_MEDIUM)
+               {
+                 if (slant == FC_SLANT_ROMAN)
+                   {
+                     has_face[REGULAR] = TRUE;
+                     style = "Regular";
+                   }
+                 else
+                   {
+                     has_face[ITALIC] = TRUE;
+                     style = "Italic";
+                   }
+               }
+             else
+               {
+                 if (slant == FC_SLANT_ROMAN)
+                   {
+                     has_face[BOLD] = TRUE;
+                     style = "Bold";
+                   }
+                 else
+                   {
+                     has_face[BOLD_ITALIC] = TRUE;
+                     style = "Bold Italic";
+                   }
+               }
+
+             if (!font_style)
+               font_style = style;
+             faces[num++] = create_face (fcfamily, font_style, FALSE);
+           }
 
-             res = FcPatternGetString (fontset->fonts[i], FC_STYLE, 0, &s);
-             if (res != FcResultMatch)
-               s = "Regular";
+         if (has_face[REGULAR])
+           {
+             if (!has_face[ITALIC])
+               faces[num++] = create_face (fcfamily, "Italic", TRUE);
+             if (!has_face[BOLD])
+               faces[num++] = create_face (fcfamily, "Bold", TRUE);
 
-             fcfamily->faces[i] = create_face (fcfamily, s);
            }
+         if ((has_face[REGULAR] || has_face[ITALIC] || has_face[BOLD]) && !has_face[BOLD_ITALIC])
+           faces[num++] = create_face (fcfamily, "Bold Italic", TRUE);
+
+         faces = g_renew (PangoFcFace *, faces, num);
+
+         fcfamily->n_faces = num;
+         fcfamily->faces = faces;
 
          FcFontSetDestroy (fontset);
        }