aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2009-04-13 12:33:13 +0000
committerKenichi Handa2009-04-13 12:33:13 +0000
commit99c4d65db7400d28b56494fd3671471a43acb76d (patch)
treebad63641cc7d73546acf172a390c6960db4572bf /src
parent7395a3b3278acf50a66294d2f799a9e62b146b2d (diff)
downloademacs-99c4d65db7400d28b56494fd3671471a43acb76d.tar.gz
emacs-99c4d65db7400d28b56494fd3671471a43acb76d.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/ftfont.c199
1 files changed, 162 insertions, 37 deletions
diff --git a/src/ftfont.c b/src/ftfont.c
index 0be985e30f2..6865478bd20 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -43,6 +43,9 @@ Lisp_Object Qfreetype;
43/* Fontconfig's generic families and their aliases. */ 43/* Fontconfig's generic families and their aliases. */
44static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif; 44static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
45 45
46/* Special ADSTYLE properties to avoid fonts used for Latin characters. */
47static Lisp_Object Qja, Qko;
48
46/* Flag to tell if FcInit is already called or not. */ 49/* Flag to tell if FcInit is already called or not. */
47static int fc_initialized; 50static int fc_initialized;
48 51
@@ -92,7 +95,7 @@ static struct
92 /* set on demand */ 95 /* set on demand */
93 FcCharSet *fc_charset; 96 FcCharSet *fc_charset;
94} fc_charset_table[] = 97} fc_charset_table[] =
95 { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } }, 98 { { "iso8859-1", { } }, /* ftfont_get_latin1_charset handles it. */
96 { "iso8859-2", { 0x00A0, 0x010E }}, 99 { "iso8859-2", { 0x00A0, 0x010E }},
97 { "iso8859-3", { 0x00A0, 0x0108 }}, 100 { "iso8859-3", { 0x00A0, 0x0108 }},
98 { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }}, 101 { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
@@ -132,8 +135,71 @@ static struct
132 { NULL } 135 { NULL }
133 }; 136 };
134 137
138/* Return a FcCharSet for iso8859-1 from fc_charset_table[0]. If the
139 charset is not yet ready, create it. */
140static FcCharSet *
141ftfont_get_latin1_charset ()
142{
143 FcCharSet *cs;
144 FcChar32 c;
145
146 if (fc_charset_table[0].fc_charset)
147 return fc_charset_table[0].fc_charset;
148 cs = FcCharSetCreate ();
149 if (! cs)
150 return NULL;
151 for (c = 33; c <= 0xFF; c++)
152 {
153 FcCharSetAddChar (cs, c);
154 if (c == 0x7E)
155 c = 0xA0;
156 }
157 fc_charset_table[0].fc_charset = cs;
158 return cs;
159}
160
135extern Lisp_Object Qc, Qm, Qp, Qd; 161extern Lisp_Object Qc, Qm, Qp, Qd;
136 162
163/* Dirty hack for handing ADSTYLE property.
164
165 Fontconfig (actually the underlying FreeType) gives such ADSTYLE
166 font property of PCF/BDF fonts in FC_STYLE. And, "Bold",
167 "Oblique", "Italic", or any non-normal SWIDTH property names
168 (e.g. SemiCondensed) are appended. In addition, if there's no
169 ADSTYLE property nor non-normal WEIGHT/SLANT/SWIDTH properties,
170 "Regular" is used for FC_STYLE (see the function
171 pcf_interpret_style in src/pcf/pcfread.c of FreeType).
172
173 Unfortunately this behavior is not documented, so the following
174 code may fail if FreeType changes the behavior in the future. */
175
176static Lisp_Object
177get_adstyle_property (FcPattern *p)
178{
179 char *str, *end;
180 Lisp_Object adstyle;
181
182 if (FcPatternGetString (p, FC_STYLE, 0, (FcChar8 **) &str) != FcResultMatch)
183 return Qnil;
184 for (end = str; *end && *end != ' '; end++);
185 if (*end)
186 {
187 char *p = alloca (end - str + 1);
188 memcpy (p, str, end - str);
189 p[end - str] = '\0';
190 str = p;
191 }
192 if (xstrcasecmp (str, "Regular") == 0
193 || xstrcasecmp (str, "Bold") == 0
194 || xstrcasecmp (str, "Oblique") == 0
195 || xstrcasecmp (str, "Italic") == 0)
196 return Qnil;
197 adstyle = font_intern_prop (str, end - str, 0);
198 if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
199 return Qnil;
200 return adstyle;
201}
202
137static Lisp_Object 203static Lisp_Object
138ftfont_pattern_entity (p, extra) 204ftfont_pattern_entity (p, extra)
139 FcPattern *p; 205 FcPattern *p;
@@ -176,7 +242,14 @@ ftfont_pattern_entity (p, extra)
176 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric)); 242 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
177 } 243 }
178 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) 244 if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
179 ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); 245 {
246 Lisp_Object adstyle;
247
248 ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
249 /* As this font has PIXEL_SIZE property, parhaps this is a BDF
250 or PCF font. */
251 ASET (entity, FONT_ADSTYLE_INDEX, get_adstyle_property (p));
252 }
180 else 253 else
181 ASET (entity, FONT_SIZE_INDEX, make_number (0)); 254 ASET (entity, FONT_SIZE_INDEX, make_number (0));
182 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch) 255 if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
@@ -265,9 +338,19 @@ ftfont_lookup_cache (key, for_face)
265 Lisp_Object key; 338 Lisp_Object key;
266 int for_face; 339 int for_face;
267{ 340{
268 Lisp_Object cache, val; 341 Lisp_Object cache, val, entity;
269 struct ftfont_cache_data *cache_data; 342 struct ftfont_cache_data *cache_data;
270 343
344 if (FONT_ENTITY_P (key))
345 {
346 entity = key;
347 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
348 xassert (CONSP (val));
349 key = XCDR (val);
350 }
351 else
352 entity = Qnil;
353
271 cache = assoc_no_quit (key, ft_face_cache); 354 cache = assoc_no_quit (key, ft_face_cache);
272 if (NILP (cache)) 355 if (NILP (cache))
273 { 356 {
@@ -301,25 +384,56 @@ ftfont_lookup_cache (key, for_face)
301 } 384 }
302 else 385 else
303 { 386 {
304 FcPattern *pat; 387 FcPattern *pat = NULL;
305 FcFontSet *fontset; 388 FcFontSet *fontset = NULL;
306 FcObjectSet *objset; 389 FcObjectSet *objset = NULL;
307 FcCharSet *charset; 390 FcCharSet *charset = NULL;
308 391
309 pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename, 392 pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename,
310 FC_INDEX, FcTypeInteger, index, NULL); 393 FC_INDEX, FcTypeInteger, index, NULL);
311 objset = FcObjectSetBuild (FC_CHARSET, NULL); 394 if (! pat)
395 goto finish;
396 objset = FcObjectSetBuild (FC_CHARSET, FC_STYLE, NULL);
397 if (! objset)
398 goto finish;
312 fontset = FcFontList (NULL, pat, objset); 399 fontset = FcFontList (NULL, pat, objset);
313 if (fontset && fontset->nfont > 0 400 if (! fontset)
314 && (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0, 401 goto finish;
402 if (fontset && fontset->nfont > 0)
403 {
404 if (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0,
315 &charset) 405 &charset)
316 == FcResultMatch)) 406 == FcResultMatch)
317 cache_data->fc_charset = FcCharSetCopy (charset); 407 {
408 /* Dirty hack. Fonts of "ja" and "ko" adstyle are
409 not suitable for Latin characters. */
410 if (! NILP (entity)
411 && (EQ (AREF (entity, FONT_ADSTYLE_INDEX), Qja)
412 || EQ (AREF (entity, FONT_ADSTYLE_INDEX), Qko)))
413 {
414 FcCharSet *latin1 = ftfont_get_latin1_charset ();
415
416 if (! latin1)
417 goto finish;
418 cache_data->fc_charset = FcCharSetSubtract (charset,
419 latin1);
420 }
421 else
422 cache_data->fc_charset = FcCharSetCopy (charset);
423 }
424 else
425 cache_data->fc_charset = FcCharSetCreate ();
426 }
318 else 427 else
319 cache_data->fc_charset = FcCharSetCreate (); 428 cache_data->fc_charset = FcCharSetCreate ();
320 FcFontSetDestroy (fontset); 429
321 FcObjectSetDestroy (objset); 430 finish:
322 FcPatternDestroy (pat); 431 if (fontset)
432 FcFontSetDestroy (fontset);
433 if (objset)
434 FcObjectSetDestroy (objset);
435 if (pat)
436 FcPatternDestroy (pat);
323 } 437 }
324 } 438 }
325 return cache; 439 return cache;
@@ -332,10 +446,7 @@ ftfont_get_fc_charset (entity)
332 Lisp_Object val, cache; 446 Lisp_Object val, cache;
333 struct ftfont_cache_data *cache_data; 447 struct ftfont_cache_data *cache_data;
334 448
335 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); 449 cache = ftfont_lookup_cache (entity, 0);
336 xassert (CONSP (val));
337 val = XCDR (val);
338 cache = ftfont_lookup_cache (val, 0);
339 val = XCDR (cache); 450 val = XCDR (cache);
340 cache_data = XSAVE_VALUE (val)->pointer; 451 cache_data = XSAVE_VALUE (val)->pointer;
341 return cache_data->fc_charset; 452 return cache_data->fc_charset;
@@ -470,18 +581,23 @@ ftfont_get_charset (registry)
470 return -1; 581 return -1;
471 if (! fc_charset_table[i].fc_charset) 582 if (! fc_charset_table[i].fc_charset)
472 { 583 {
473 FcCharSet *charset = FcCharSetCreate (); 584 if (i == 0)
474 int *uniquifier = fc_charset_table[i].uniquifier; 585 ftfont_get_latin1_charset ();
586 else
587 {
588 FcCharSet *charset = FcCharSetCreate ();
589 int *uniquifier = fc_charset_table[i].uniquifier;
475 590
476 if (! charset) 591 if (! charset)
477 return -1;
478 for (j = 0; uniquifier[j]; j++)
479 if (! FcCharSetAddChar (charset, uniquifier[j]))
480 {
481 FcCharSetDestroy (charset);
482 return -1; 592 return -1;
483 } 593 for (j = 0; uniquifier[j]; j++)
484 fc_charset_table[i].fc_charset = charset; 594 if (! FcCharSetAddChar (charset, uniquifier[j]))
595 {
596 FcCharSetDestroy (charset);
597 return -1;
598 }
599 fc_charset_table[i].fc_charset = charset;
600 }
485 } 601 }
486 return i; 602 return i;
487} 603}
@@ -602,10 +718,6 @@ ftfont_spec_pattern (spec, otlayout, otspec)
602 Lisp_Object registry; 718 Lisp_Object registry;
603 int fc_charset_idx; 719 int fc_charset_idx;
604 720
605 if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX))
606 && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0)
607 /* Fontconfig doesn't support adstyle property. */
608 return NULL;
609 if ((n = FONT_SLANT_NUMERIC (spec)) >= 0 721 if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
610 && n < 100) 722 && n < 100)
611 /* Fontconfig doesn't support reverse-italic/obligue. */ 723 /* Fontconfig doesn't support reverse-italic/obligue. */
@@ -752,7 +864,7 @@ static Lisp_Object
752ftfont_list (frame, spec) 864ftfont_list (frame, spec)
753 Lisp_Object frame, spec; 865 Lisp_Object frame, spec;
754{ 866{
755 Lisp_Object val = Qnil, family; 867 Lisp_Object val = Qnil, family, adstyle;
756 int i; 868 int i;
757 FcPattern *pattern; 869 FcPattern *pattern;
758 FcFontSet *fontset = NULL; 870 FcFontSet *fontset = NULL;
@@ -800,10 +912,12 @@ ftfont_list (frame, spec)
800 goto err; 912 goto err;
801 } 913 }
802 } 914 }
803 915 adstyle = AREF (spec, FONT_ADSTYLE_INDEX);
916 if (! NILP (adstyle) && SBYTES (SYMBOL_NAME (adstyle)) == 0)
917 adstyle = Qnil;
804 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, 918 objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
805 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE, 919 FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE,
806 FC_FILE, FC_INDEX, 920 FC_STYLE, FC_FILE, FC_INDEX,
807#ifdef FC_CAPABILITY 921#ifdef FC_CAPABILITY
808 FC_CAPABILITY, 922 FC_CAPABILITY,
809#endif /* FC_CAPABILITY */ 923#endif /* FC_CAPABILITY */
@@ -908,6 +1022,15 @@ ftfont_list (frame, spec)
908 if (j == ASIZE (chars)) 1022 if (j == ASIZE (chars))
909 continue; 1023 continue;
910 } 1024 }
1025 if (! NILP (adstyle))
1026 {
1027 Lisp_Object this_adstyle = get_adstyle_property (fontset->fonts[i]);
1028
1029 if (NILP (this_adstyle)
1030 || xstrcasecmp (SDATA (SYMBOL_NAME (adstyle)),
1031 SDATA (SYMBOL_NAME (this_adstyle))) != 0)
1032 continue;
1033 }
911 entity = ftfont_pattern_entity (fontset->fonts[i], 1034 entity = ftfont_pattern_entity (fontset->fonts[i],
912 AREF (spec, FONT_EXTRA_INDEX)); 1035 AREF (spec, FONT_EXTRA_INDEX));
913 if (! NILP (entity)) 1036 if (! NILP (entity))
@@ -1046,7 +1169,7 @@ ftfont_open (f, entity, pixel_size)
1046 if (! CONSP (val)) 1169 if (! CONSP (val))
1047 return Qnil; 1170 return Qnil;
1048 val = XCDR (val); 1171 val = XCDR (val);
1049 cache = ftfont_lookup_cache (val, 1); 1172 cache = ftfont_lookup_cache (entity, 1);
1050 if (NILP (cache)) 1173 if (NILP (cache))
1051 return Qnil; 1174 return Qnil;
1052 filename = XCAR (val); 1175 filename = XCAR (val);
@@ -2091,6 +2214,8 @@ syms_of_ftfont ()
2091 DEFSYM (Qmono, "mono"); 2214 DEFSYM (Qmono, "mono");
2092 DEFSYM (Qsans, "sans"); 2215 DEFSYM (Qsans, "sans");
2093 DEFSYM (Qsans__serif, "sans serif"); 2216 DEFSYM (Qsans__serif, "sans serif");
2217 DEFSYM (Qja, "ja");
2218 DEFSYM (Qko, "ko");
2094 2219
2095 staticpro (&freetype_font_cache); 2220 staticpro (&freetype_font_cache);
2096 freetype_font_cache = Fcons (Qt, Qnil); 2221 freetype_font_cache = Fcons (Qt, Qnil);