emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs/src ftfont.c


From: Kenichi Handa
Subject: [Emacs-diffs] emacs/src ftfont.c
Date: Mon, 13 Apr 2009 12:33:13 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Kenichi Handa <handa>   09/04/13 12:33:13

Modified files:
        src            : ftfont.c 

Log message:
        (Qja, Qko): New variables.
        (fc_charset_table): Delete uniquifier data for iso8859-1.
        (ftfont_get_latin1_charset): New function.
        (get_adstyle_property): New function.
        (ftfont_pattern_entity): Set FONT_ADSTYLE_INDEX of entity for
        bitmap fonts.
        (ftfont_lookup_cache): Handle the case that KEY is a font-entity.
        Delete iso-8859-1 range from the charset of fonts whose adstyle is
        `ko' or `ja'.
        (ftfont_get_fc_charset): Call ftfont_lookup_cache with ENTITY.
        (ftfont_get_charset): For iso8859-1, call
        ftfont_get_latin1_charset.
        (ftfont_list): Don't refuse a font spec with non-nil `adstyle'
        property.
        (ftfont_open): Call ftfont_lookup_cache with ENTITY.
        (syms_of_ftfont): DEFSYM Qja and Qko.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/src/ftfont.c?cvsroot=emacs&r1=1.49&r2=1.50

Patches:
Index: ftfont.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/ftfont.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- ftfont.c    8 Apr 2009 01:30:55 -0000       1.49
+++ ftfont.c    13 Apr 2009 12:33:13 -0000      1.50
@@ -43,6 +43,9 @@
 /* Fontconfig's generic families and their aliases.  */
 static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
 
+/* Special ADSTYLE properties to avoid fonts used for Latin characters.  */
+static Lisp_Object Qja, Qko;
+
 /* Flag to tell if FcInit is already called or not.  */
 static int fc_initialized;
 
@@ -92,7 +95,7 @@
   /* set on demand */
   FcCharSet *fc_charset;
 } fc_charset_table[] =
-  { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
+  { { "iso8859-1", { } },      /* ftfont_get_latin1_charset handles it. */
     { "iso8859-2", { 0x00A0, 0x010E }},
     { "iso8859-3", { 0x00A0, 0x0108 }},
     { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
@@ -132,8 +135,71 @@
     { NULL }
   };
 
+/* Return a FcCharSet for iso8859-1 from fc_charset_table[0].  If the
+   charset is not yet ready, create it. */
+static FcCharSet *
+ftfont_get_latin1_charset ()
+{
+  FcCharSet *cs;
+  FcChar32 c;
+
+  if (fc_charset_table[0].fc_charset)
+    return fc_charset_table[0].fc_charset;
+  cs = FcCharSetCreate ();
+  if (! cs)
+    return NULL;
+  for (c = 33; c <= 0xFF; c++)
+    {
+      FcCharSetAddChar (cs, c);
+      if (c == 0x7E)
+       c = 0xA0;
+    }
+  fc_charset_table[0].fc_charset = cs;
+  return cs;
+}
+
 extern Lisp_Object Qc, Qm, Qp, Qd;
 
+/* Dirty hack for handing ADSTYLE property.
+
+   Fontconfig (actually the underlying FreeType) gives such ADSTYLE
+   font property of PCF/BDF fonts in FC_STYLE.  And, "Bold",
+   "Oblique", "Italic", or any non-normal SWIDTH property names
+   (e.g. SemiCondensed) are appended.  In addition, if there's no
+   ADSTYLE property nor non-normal WEIGHT/SLANT/SWIDTH properties,
+   "Regular" is used for FC_STYLE (see the function
+   pcf_interpret_style in src/pcf/pcfread.c of FreeType).
+
+   Unfortunately this behavior is not documented, so the following
+   code may fail if FreeType changes the behavior in the future.  */
+
+static Lisp_Object
+get_adstyle_property (FcPattern *p)
+{
+  char *str, *end;
+  Lisp_Object adstyle;
+
+  if (FcPatternGetString (p, FC_STYLE, 0, (FcChar8 **) &str) != FcResultMatch)
+    return Qnil;
+  for (end = str; *end && *end != ' '; end++);
+  if (*end)
+    {
+      char *p = alloca (end - str + 1);
+      memcpy (p, str, end - str);
+      p[end - str] = '\0';
+      str = p;
+    }
+  if (xstrcasecmp (str, "Regular") == 0
+      || xstrcasecmp (str, "Bold") == 0
+      || xstrcasecmp (str, "Oblique") == 0
+      || xstrcasecmp (str, "Italic") == 0)
+    return Qnil;
+  adstyle = font_intern_prop (str, end - str, 0);
+  if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
+    return Qnil;
+  return adstyle;
+}
+
 static Lisp_Object
 ftfont_pattern_entity (p, extra)
      FcPattern *p;
@@ -176,7 +242,14 @@
       FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
     }
   if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
+    {
+      Lisp_Object adstyle;
+
     ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
+      /* As this font has PIXEL_SIZE property, parhaps this is a BDF
+        or PCF font. */ 
+      ASET (entity, FONT_ADSTYLE_INDEX, get_adstyle_property (p));
+    }
   else
     ASET (entity, FONT_SIZE_INDEX, make_number (0));
   if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
@@ -265,9 +338,19 @@
      Lisp_Object key;
      int for_face;
 {
-  Lisp_Object cache, val;
+  Lisp_Object cache, val, entity;
   struct ftfont_cache_data *cache_data;
 
+  if (FONT_ENTITY_P (key))
+    {
+      entity = key;
+      val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
+      xassert (CONSP (val));
+      key = XCDR (val);
+    }
+  else
+    entity = Qnil;
+
   cache = assoc_no_quit (key, ft_face_cache);
   if (NILP (cache))
     {
@@ -301,24 +384,55 @@
        }
       else
        {
-         FcPattern *pat;
-         FcFontSet *fontset;
-         FcObjectSet *objset;
-         FcCharSet *charset;
+         FcPattern *pat = NULL;
+         FcFontSet *fontset = NULL;
+         FcObjectSet *objset = NULL;
+         FcCharSet *charset = NULL;
 
          pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename,
                                FC_INDEX, FcTypeInteger, index, NULL);
-         objset = FcObjectSetBuild (FC_CHARSET, NULL);
+         if (! pat)
+           goto finish;
+         objset = FcObjectSetBuild (FC_CHARSET, FC_STYLE, NULL);
+         if (! objset)
+           goto finish;
          fontset = FcFontList (NULL, pat, objset);
-         if (fontset && fontset->nfont > 0
-             && (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0,
+         if (! fontset)
+           goto finish;
+         if (fontset && fontset->nfont > 0)
+           {
+             if (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0,
                                       &charset)
-                 == FcResultMatch))
+                 == FcResultMatch)
+               {
+                 /* Dirty hack.  Fonts of "ja" and "ko" adstyle are
+                    not suitable for Latin characters.  */
+                 if (! NILP (entity)
+                     && (EQ (AREF (entity, FONT_ADSTYLE_INDEX), Qja)
+                         || EQ (AREF (entity, FONT_ADSTYLE_INDEX), Qko)))
+                   {
+                     FcCharSet *latin1 = ftfont_get_latin1_charset ();
+
+                     if (! latin1)
+                       goto finish;
+                     cache_data->fc_charset = FcCharSetSubtract (charset,
+                                                                 latin1);
+                   }
+                 else
            cache_data->fc_charset = FcCharSetCopy (charset);
+               }
+             else
+               cache_data->fc_charset = FcCharSetCreate ();
+           }
          else
            cache_data->fc_charset = FcCharSetCreate ();
+
+       finish:
+         if (fontset)
          FcFontSetDestroy (fontset);
+         if (objset)
          FcObjectSetDestroy (objset);
+         if (pat)
          FcPatternDestroy (pat);
        }
     }
@@ -332,10 +446,7 @@
   Lisp_Object val, cache;
   struct ftfont_cache_data *cache_data;
 
-  val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
-  xassert (CONSP (val));
-  val = XCDR (val);
-  cache = ftfont_lookup_cache (val, 0);
+  cache = ftfont_lookup_cache (entity, 0);
   val = XCDR (cache);
   cache_data = XSAVE_VALUE (val)->pointer;
   return cache_data->fc_charset;
@@ -470,6 +581,10 @@
     return -1;
   if (! fc_charset_table[i].fc_charset)
     {
+      if (i == 0)
+       ftfont_get_latin1_charset ();
+      else
+       {
       FcCharSet *charset = FcCharSetCreate ();
       int *uniquifier = fc_charset_table[i].uniquifier;
 
@@ -483,6 +598,7 @@
          }
       fc_charset_table[i].fc_charset = charset;
     }
+    }
   return i;
 }
 
@@ -602,10 +718,6 @@
   Lisp_Object registry;
   int fc_charset_idx;
 
-  if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))
-      && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0)
-    /* Fontconfig doesn't support adstyle property.  */
-    return NULL;
   if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
       && n < 100)
     /* Fontconfig doesn't support reverse-italic/obligue.  */
@@ -752,7 +864,7 @@
 ftfont_list (frame, spec)
      Lisp_Object frame, spec;
 {
-  Lisp_Object val = Qnil, family;
+  Lisp_Object val = Qnil, family, adstyle;
   int i;
   FcPattern *pattern;
   FcFontSet *fontset = NULL;
@@ -800,10 +912,12 @@
            goto err;
        }
     }
-
+  adstyle = AREF (spec, FONT_ADSTYLE_INDEX);
+  if (! NILP (adstyle) && SBYTES (SYMBOL_NAME (adstyle)) == 0)
+    adstyle = Qnil;
   objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
                             FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE,
-                            FC_FILE, FC_INDEX,
+                            FC_STYLE, FC_FILE, FC_INDEX,
 #ifdef FC_CAPABILITY
                             FC_CAPABILITY,
 #endif /* FC_CAPABILITY */
@@ -908,6 +1022,15 @@
          if (j == ASIZE (chars))
            continue;
        }
+      if (! NILP (adstyle))
+       {
+         Lisp_Object this_adstyle = get_adstyle_property (fontset->fonts[i]);
+
+         if (NILP (this_adstyle)
+             || xstrcasecmp (SDATA (SYMBOL_NAME (adstyle)),
+                             SDATA (SYMBOL_NAME (this_adstyle))) != 0)
+           continue;
+       }
       entity = ftfont_pattern_entity (fontset->fonts[i],
                                      AREF (spec, FONT_EXTRA_INDEX));
       if (! NILP (entity))
@@ -1046,7 +1169,7 @@
   if (! CONSP (val))
     return Qnil;
   val = XCDR (val);
-  cache = ftfont_lookup_cache (val, 1);
+  cache = ftfont_lookup_cache (entity, 1);
   if (NILP (cache))
     return Qnil;
   filename = XCAR (val);
@@ -2091,6 +2214,8 @@
   DEFSYM (Qmono, "mono");
   DEFSYM (Qsans, "sans");
   DEFSYM (Qsans__serif, "sans serif");
+  DEFSYM (Qja, "ja");
+  DEFSYM (Qko, "ko");
 
   staticpro (&freetype_font_cache);
   freetype_font_cache = Fcons (Qt, Qnil);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]