diff options
| author | Kenichi Handa | 2008-07-09 00:31:42 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-07-09 00:31:42 +0000 |
| commit | e302a2919ee03d7236bbe6a55970df574c59cf26 (patch) | |
| tree | f5b9101001fba78e1899648f7ff457a81c204327 /src | |
| parent | 947eecfbc93d502cc8fd1f01053bf3e118ddb74a (diff) | |
| download | emacs-e302a2919ee03d7236bbe6a55970df574c59cf26.tar.gz emacs-e302a2919ee03d7236bbe6a55970df574c59cf26.zip | |
(struct ftfont_info): New member index, delete member
fc_charset_idx. Make the member order compatible with struct
xftfont_info.
(fc_charset_table): Change charset names to registry names.
(ftfont_pattern_entity): Delete the args registry and
fc_charset_idx. Change the value of :font-entity property
to (FONTNAME . INDEX). Always set :registry property to
`iso10646-1'.
(struct ftfont_cache_data): New struct.
(ftfont_lookup_cache): New arg for_face.
(ftfont_get_fc_charset, ftfont_get_otf): New functions.
(ftfont_driver): Set the member otf_capability.
(ftfont_get_charset): Adjust it for the change of
fc_charset_table.
(OTF_TAG_SYM): New macro.
(ftfont_spec_pattern): Delete the arg fc_charset_idx. Adjust it
for the change of fc_charset_table.
(ftfont_list): Adjust it for the change of ftfont_spec_pattern and
ftfont_pattern_entity. Add FC_INDEX to objset.
(ftfont_match): Adjust it for the change of ftfont_spec_pattern
and ftfont_pattern_entity.
(ftfont_open): Adjust it for the change of ftfont_lookup_cache,
font_make_object, struct ftfont_info.
(ftfont_has_char): Use ftfont_get_fc_charset.
(ftfont_otf_features, ftfont_otf_capability): New functions.
(ftfont_shape): Use ftfont_get_otf.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ftfont.c | 416 |
1 files changed, 273 insertions, 143 deletions
diff --git a/src/ftfont.c b/src/ftfont.c index 62bbb9bca4c..ba157119936 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -51,7 +51,7 @@ static FT_Library ft_library; | |||
| 51 | /* Cache for FreeType fonts. */ | 51 | /* Cache for FreeType fonts. */ |
| 52 | static Lisp_Object freetype_font_cache; | 52 | static Lisp_Object freetype_font_cache; |
| 53 | 53 | ||
| 54 | /* Cache for FT_Face */ | 54 | /* Cache for FT_Face and FcCharSet. */ |
| 55 | static Lisp_Object ft_face_cache; | 55 | static Lisp_Object ft_face_cache; |
| 56 | 56 | ||
| 57 | /* The actual structure for FreeType font that can be casted to struct | 57 | /* The actual structure for FreeType font that can be casted to struct |
| @@ -60,96 +60,99 @@ static Lisp_Object ft_face_cache; | |||
| 60 | struct ftfont_info | 60 | struct ftfont_info |
| 61 | { | 61 | { |
| 62 | struct font font; | 62 | struct font font; |
| 63 | FT_Size ft_size; | ||
| 64 | int fc_charset_idx; | ||
| 65 | #ifdef HAVE_LIBOTF | 63 | #ifdef HAVE_LIBOTF |
| 64 | /* The following three members must be here in this order to be | ||
| 65 | compatible with struct xftfont_info (in xftfont.c). */ | ||
| 66 | int maybe_otf; /* Flag to tell if this may be OTF or not. */ | 66 | int maybe_otf; /* Flag to tell if this may be OTF or not. */ |
| 67 | OTF *otf; | 67 | OTF *otf; |
| 68 | #endif /* HAVE_LIBOTF */ | 68 | #endif /* HAVE_LIBOTF */ |
| 69 | FT_Size ft_size; | ||
| 70 | int index; | ||
| 69 | }; | 71 | }; |
| 70 | 72 | ||
| 71 | static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object, | 73 | static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object)); |
| 72 | Lisp_Object, int)); | ||
| 73 | 74 | ||
| 74 | static Lisp_Object ftfont_resolve_generic_family P_ ((Lisp_Object, | 75 | static Lisp_Object ftfont_resolve_generic_family P_ ((Lisp_Object, |
| 75 | FcPattern *)); | 76 | FcPattern *)); |
| 77 | static Lisp_Object ftfont_lookup_cache P_ ((Lisp_Object, int)); | ||
| 78 | |||
| 76 | Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); | 79 | Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object)); |
| 77 | 80 | ||
| 78 | #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) | 81 | #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) |
| 79 | 82 | ||
| 80 | static struct | 83 | static struct |
| 81 | { | 84 | { |
| 82 | /* charset name */ | 85 | /* registry name */ |
| 83 | char *name; | 86 | char *name; |
| 84 | /* characters to distinguish the charset from the others */ | 87 | /* characters to distinguish the charset from the others */ |
| 85 | int uniquifier[6]; | 88 | int uniquifier[6]; |
| 86 | /* additional constraint by language */ | 89 | /* additional constraint by language */ |
| 87 | char *lang; | 90 | char *lang; |
| 88 | /* set in syms_of_ftfont */ | ||
| 89 | int charset_id; | ||
| 90 | /* set on demand */ | 91 | /* set on demand */ |
| 91 | FcCharSet *fc_charset; | 92 | FcCharSet *fc_charset; |
| 92 | } fc_charset_table[] = | 93 | } fc_charset_table[] = |
| 93 | { { "iso-8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 }, "en", -1 }, | 94 | { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } }, |
| 94 | { "iso-8859-2", { 0x00A0, 0x010E }}, | 95 | { "iso8859-2", { 0x00A0, 0x010E }}, |
| 95 | { "iso-8859-3", { 0x00A0, 0x0108 }}, | 96 | { "iso8859-3", { 0x00A0, 0x0108 }}, |
| 96 | { "iso-8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }}, | 97 | { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }}, |
| 97 | { "iso-8859-5", { 0x00A0, 0x0401 }}, | 98 | { "iso8859-5", { 0x00A0, 0x0401 }}, |
| 98 | { "iso-8859-6", { 0x00A0, 0x060C }}, | 99 | { "iso8859-6", { 0x00A0, 0x060C }}, |
| 99 | { "iso-8859-7", { 0x00A0, 0x0384 }}, | 100 | { "iso8859-7", { 0x00A0, 0x0384 }}, |
| 100 | { "iso-8859-8", { 0x00A0, 0x05D0 }}, | 101 | { "iso8859-8", { 0x00A0, 0x05D0 }}, |
| 101 | { "iso-8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }}, | 102 | { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }}, |
| 102 | { "iso-8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }}, | 103 | { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }}, |
| 103 | { "iso-8859-11", { 0x00A0, 0x0E01 }}, | 104 | { "iso8859-11", { 0x00A0, 0x0E01 }}, |
| 104 | { "iso-8859-13", { 0x00A0, 0x201C }}, | 105 | { "iso8859-13", { 0x00A0, 0x201C }}, |
| 105 | { "iso-8859-14", { 0x00A0, 0x0174 }}, | 106 | { "iso8859-14", { 0x00A0, 0x0174 }}, |
| 106 | { "iso-8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }}, | 107 | { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }}, |
| 107 | { "iso-8859-16", { 0x00A0, 0x0218}}, | 108 | { "iso8859-16", { 0x00A0, 0x0218}}, |
| 108 | { "chinese-gb2312", { 0x4E13 }, "zh-cn"}, | 109 | { "gb2312.1980-0", { 0x4E13 }, "zh-cn"}, |
| 109 | { "big5", { 0xF6B1 }, "zh-tw" }, | 110 | { "big5-0", { 0xF6B1 }, "zh-tw" }, |
| 110 | { "japanese-jisx0208", { 0x4E55 }, "ja"}, | 111 | { "jisx0208.1983-0", { 0x4E55 }, "ja"}, |
| 111 | { "korean-ksc5601", { 0xAC00 }, "ko"}, | 112 | { "ksc5601.1985-0", { 0xAC00 }, "ko"}, |
| 112 | { "chinese-cns11643-1", { 0xFE32 }, "zh-tw"}, | 113 | { "cns11643.1992-1", { 0xFE32 }, "zh-tw"}, |
| 113 | { "chinese-cns11643-2", { 0x4E33, 0x7934 }}, | 114 | { "cns11643.1992-2", { 0x4E33, 0x7934 }}, |
| 114 | { "chinese-cns11643-3", { 0x201A9 }}, | 115 | { "cns11643.1992-3", { 0x201A9 }}, |
| 115 | { "chinese-cns11643-4", { 0x20057 }}, | 116 | { "cns11643.1992-4", { 0x20057 }}, |
| 116 | { "chinese-cns11643-5", { 0x20000 }}, | 117 | { "cns11643.1992-5", { 0x20000 }}, |
| 117 | { "chinese-cns11643-6", { 0x20003 }}, | 118 | { "cns11643.1992-6", { 0x20003 }}, |
| 118 | { "chinese-cns11643-7", { 0x20055 }}, | 119 | { "cns11643.1992-7", { 0x20055 }}, |
| 119 | { "chinese-gbk", { 0x4E06 }, "zh-cn"}, | 120 | { "gbk-0", { 0x4E06 }, "zh-cn"}, |
| 120 | { "japanese-jisx0212", { 0x4E44 }}, | 121 | { "jisx0212.1990-0", { 0x4E44 }}, |
| 121 | { "japanese-jisx0213-1", { 0xFA10 }, "ja"}, | 122 | { "jisx0213.2000-1", { 0xFA10 }, "ja"}, |
| 122 | { "japanese-jisx0213-2", { 0xFA49 }}, | 123 | { "jisx0213.2000-2", { 0xFA49 }}, |
| 123 | { "japanese-jisx0213.2004-1", { 0x20B9F }}, | 124 | { "jisx0213.2004-1", { 0x20B9F }}, |
| 124 | { "viscii", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"}, | 125 | { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"}, |
| 125 | { "tis620", { 0x0E01 }, "th"}, | 126 | { "tis620.2529-1", { 0x0E01 }, "th"}, |
| 126 | { "windows-1251", { 0x0401, 0x0490 }, "ru"}, | 127 | { "windows-1251", { 0x0401, 0x0490 }, "ru"}, |
| 127 | { "koi8-r", { 0x0401, 0x2219 }, "ru"}, | 128 | { "koi8-r", { 0x0401, 0x2219 }, "ru"}, |
| 128 | { "mule-lao", { 0x0E81 }, "lo"}, | 129 | { "mulelao-1", { 0x0E81 }, "lo"}, |
| 129 | { NULL } | 130 | { NULL } |
| 130 | }; | 131 | }; |
| 131 | 132 | ||
| 132 | extern Lisp_Object Qc, Qm, Qp, Qd; | 133 | extern Lisp_Object Qc, Qm, Qp, Qd; |
| 133 | 134 | ||
| 134 | static Lisp_Object | 135 | static Lisp_Object |
| 135 | ftfont_pattern_entity (p, registry, extra, fc_charset_idx) | 136 | ftfont_pattern_entity (p, extra) |
| 136 | FcPattern *p; | 137 | FcPattern *p; |
| 137 | Lisp_Object registry, extra; | 138 | Lisp_Object extra; |
| 138 | int fc_charset_idx; | ||
| 139 | { | 139 | { |
| 140 | Lisp_Object entity; | 140 | Lisp_Object entity; |
| 141 | char *file, *str; | 141 | char *file, *str; |
| 142 | int index; | ||
| 142 | int numeric; | 143 | int numeric; |
| 143 | double dbl; | 144 | double dbl; |
| 144 | FcBool b; | 145 | FcBool b; |
| 145 | 146 | ||
| 146 | if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch) | 147 | if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch) |
| 147 | return Qnil; | 148 | return Qnil; |
| 149 | if (FcPatternGetInteger (p, FC_INDEX, 0, &index) != FcResultMatch) | ||
| 150 | return Qnil; | ||
| 148 | 151 | ||
| 149 | entity = font_make_entity (); | 152 | entity = font_make_entity (); |
| 150 | 153 | ||
| 151 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); | 154 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); |
| 152 | ASET (entity, FONT_REGISTRY_INDEX, registry); | 155 | ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); |
| 153 | 156 | ||
| 154 | if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) | 157 | if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) |
| 155 | ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str), 1)); | 158 | ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str), 1)); |
| @@ -189,7 +192,7 @@ ftfont_pattern_entity (p, registry, extra, fc_charset_idx) | |||
| 189 | font_put_extra (entity, QCfont_entity, | 192 | font_put_extra (entity, QCfont_entity, |
| 190 | Fcons (make_unibyte_string ((char *) file, | 193 | Fcons (make_unibyte_string ((char *) file, |
| 191 | strlen ((char *) file)), | 194 | strlen ((char *) file)), |
| 192 | make_number (fc_charset_idx))); | 195 | make_number (index))); |
| 193 | return entity; | 196 | return entity; |
| 194 | } | 197 | } |
| 195 | 198 | ||
| @@ -239,35 +242,116 @@ ftfont_resolve_generic_family (family, pattern) | |||
| 239 | return family; | 242 | return family; |
| 240 | } | 243 | } |
| 241 | 244 | ||
| 242 | Lisp_Object | 245 | struct ftfont_cache_data |
| 243 | ftfont_lookup_cache (filename) | 246 | { |
| 244 | Lisp_Object filename; | 247 | FT_Face ft_face; |
| 248 | FcCharSet *fc_charset; | ||
| 249 | }; | ||
| 250 | |||
| 251 | static Lisp_Object | ||
| 252 | ftfont_lookup_cache (key, for_face) | ||
| 253 | Lisp_Object key; | ||
| 254 | int for_face; | ||
| 245 | { | 255 | { |
| 246 | Lisp_Object cache, val; | 256 | Lisp_Object cache, val; |
| 257 | struct ftfont_cache_data *cache_data; | ||
| 247 | 258 | ||
| 248 | cache = assoc_no_quit (filename, ft_face_cache); | 259 | cache = assoc_no_quit (key, ft_face_cache); |
| 249 | if (NILP (cache)) | 260 | if (NILP (cache)) |
| 250 | { | 261 | { |
| 262 | cache_data = xmalloc (sizeof (struct ftfont_cache_data)); | ||
| 263 | cache_data->ft_face = NULL; | ||
| 264 | cache_data->fc_charset = NULL; | ||
| 251 | val = make_save_value (NULL, 0); | 265 | val = make_save_value (NULL, 0); |
| 252 | cache = Fcons (filename, val); | 266 | XSAVE_VALUE (val)->integer = 0; |
| 267 | XSAVE_VALUE (val)->pointer = cache_data; | ||
| 268 | cache = Fcons (key, val); | ||
| 253 | ft_face_cache = Fcons (cache, ft_face_cache); | 269 | ft_face_cache = Fcons (cache, ft_face_cache); |
| 254 | } | 270 | } |
| 255 | else | 271 | else |
| 256 | val = XCDR (cache); | ||
| 257 | if (! XSAVE_VALUE (val)->pointer) | ||
| 258 | { | 272 | { |
| 259 | FT_Face ft_face; | 273 | val = XCDR (cache); |
| 274 | cache_data = XSAVE_VALUE (val)->pointer; | ||
| 275 | } | ||
| 276 | if (for_face ? ! cache_data->ft_face : ! cache_data->fc_charset) | ||
| 277 | { | ||
| 278 | char *filename = (char *) SDATA (XCAR (key)); | ||
| 279 | int index = XINT (XCDR (key)); | ||
| 260 | 280 | ||
| 261 | if (! ft_library | 281 | if (for_face) |
| 262 | && FT_Init_FreeType (&ft_library) != 0) | 282 | { |
| 263 | return Qnil; | 283 | if (! ft_library |
| 264 | if (FT_New_Face (ft_library, (char *) SDATA (filename), 0, &ft_face) != 0) | 284 | && FT_Init_FreeType (&ft_library) != 0) |
| 265 | return Qnil; | 285 | return Qnil; |
| 266 | XSAVE_VALUE (val)->pointer = ft_face; | 286 | if (FT_New_Face (ft_library, filename, index, &cache_data->ft_face) |
| 287 | != 0) | ||
| 288 | return Qnil; | ||
| 289 | } | ||
| 290 | else | ||
| 291 | { | ||
| 292 | FcPattern *pat; | ||
| 293 | FcFontSet *fontset; | ||
| 294 | FcObjectSet *objset; | ||
| 295 | FcCharSet *charset; | ||
| 296 | |||
| 297 | pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename, | ||
| 298 | FC_INDEX, FcTypeInteger, index, NULL); | ||
| 299 | objset = FcObjectSetBuild (FC_CHARSET, NULL); | ||
| 300 | fontset = FcFontList (NULL, pat, objset); | ||
| 301 | xassert (fontset && fontset->nfont > 0); | ||
| 302 | if (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0, &charset) | ||
| 303 | == FcResultMatch) | ||
| 304 | cache_data->fc_charset = FcCharSetCopy (charset); | ||
| 305 | else | ||
| 306 | cache_data->fc_charset = FcCharSetCreate (); | ||
| 307 | FcFontSetDestroy (fontset); | ||
| 308 | FcObjectSetDestroy (objset); | ||
| 309 | FcPatternDestroy (pat); | ||
| 310 | } | ||
| 267 | } | 311 | } |
| 268 | return cache; | 312 | return cache; |
| 269 | } | 313 | } |
| 270 | 314 | ||
| 315 | FcCharSet * | ||
| 316 | ftfont_get_fc_charset (entity) | ||
| 317 | Lisp_Object entity; | ||
| 318 | { | ||
| 319 | Lisp_Object val, cache; | ||
| 320 | struct ftfont_cache_data *cache_data; | ||
| 321 | |||
| 322 | val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); | ||
| 323 | xassert (CONSP (val)); | ||
| 324 | val = XCDR (val); | ||
| 325 | cache = ftfont_lookup_cache (val, 0); | ||
| 326 | val = XCDR (cache); | ||
| 327 | cache_data = XSAVE_VALUE (val)->pointer; | ||
| 328 | return cache_data->fc_charset; | ||
| 329 | } | ||
| 330 | |||
| 331 | #ifdef HAVE_LIBOTF | ||
| 332 | static OTF * | ||
| 333 | ftfont_get_otf (ftfont_info) | ||
| 334 | struct ftfont_info *ftfont_info; | ||
| 335 | { | ||
| 336 | OTF *otf; | ||
| 337 | |||
| 338 | if (ftfont_info->otf) | ||
| 339 | return ftfont_info->otf; | ||
| 340 | if (! ftfont_info->maybe_otf) | ||
| 341 | return NULL; | ||
| 342 | otf = OTF_open_ft_face (ftfont_info->ft_size->face); | ||
| 343 | if (! otf || OTF_get_table (otf, "head") < 0) | ||
| 344 | { | ||
| 345 | if (otf) | ||
| 346 | OTF_close (otf); | ||
| 347 | ftfont_info->maybe_otf = 0; | ||
| 348 | return NULL; | ||
| 349 | } | ||
| 350 | ftfont_info->otf = otf; | ||
| 351 | return otf; | ||
| 352 | } | ||
| 353 | #endif /* HAVE_LIBOTF */ | ||
| 354 | |||
| 271 | static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR)); | 355 | static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR)); |
| 272 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); | 356 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); |
| 273 | static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object)); | 357 | static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object)); |
| @@ -282,6 +366,7 @@ static int ftfont_get_bitmap P_ ((struct font *, unsigned, | |||
| 282 | struct font_bitmap *, int)); | 366 | struct font_bitmap *, int)); |
| 283 | static int ftfont_anchor_point P_ ((struct font *, unsigned, int, | 367 | static int ftfont_anchor_point P_ ((struct font *, unsigned, int, |
| 284 | int *, int *)); | 368 | int *, int *)); |
| 369 | static Lisp_Object ftfont_otf_capability P_ ((struct font *)); | ||
| 285 | static Lisp_Object ftfont_shape P_ ((Lisp_Object)); | 370 | static Lisp_Object ftfont_shape P_ ((Lisp_Object)); |
| 286 | 371 | ||
| 287 | struct font_driver ftfont_driver = | 372 | struct font_driver ftfont_driver = |
| @@ -308,7 +393,11 @@ struct font_driver ftfont_driver = | |||
| 308 | NULL, | 393 | NULL, |
| 309 | NULL, | 394 | NULL, |
| 310 | ftfont_anchor_point, | 395 | ftfont_anchor_point, |
| 396 | #ifdef HAVE_LIBOTF | ||
| 397 | ftfont_otf_capability, | ||
| 398 | #else /* not HAVE_LIBOTF */ | ||
| 311 | NULL, | 399 | NULL, |
| 400 | #endif /* not HAVE_LIBOTF */ | ||
| 312 | NULL, | 401 | NULL, |
| 313 | NULL, | 402 | NULL, |
| 314 | NULL, | 403 | NULL, |
| @@ -332,25 +421,25 @@ static int | |||
| 332 | ftfont_get_charset (registry) | 421 | ftfont_get_charset (registry) |
| 333 | Lisp_Object registry; | 422 | Lisp_Object registry; |
| 334 | { | 423 | { |
| 335 | struct charset *encoding; | 424 | char *str = (char *) SDATA (SYMBOL_NAME (registry)); |
| 425 | char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1); | ||
| 426 | Lisp_Object regexp; | ||
| 336 | int i, j; | 427 | int i, j; |
| 337 | 428 | ||
| 338 | if (font_registry_charsets (registry, &encoding, NULL) < 0) | 429 | for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++) |
| 339 | return -1; | 430 | { |
| 340 | if (fc_charset_table[0].charset_id < 0) | 431 | if (str[i] == '.') |
| 341 | /* Setup charset_id field of all elements. */ | 432 | re[j++] = '\\'; |
| 342 | for (i = 0; fc_charset_table[i].name; i++) | 433 | else if (str[i] == '*') |
| 343 | { | 434 | re[j++] = '.'; |
| 344 | Lisp_Object sym = intern (fc_charset_table[i].name); | 435 | re[j] = str[i]; |
| 345 | 436 | if (re[j] == '?') | |
| 346 | if (CHARSETP (sym)) | 437 | re[j] = '.'; |
| 347 | fc_charset_table[i].charset_id = XINT (CHARSET_SYMBOL_ID (sym)); | 438 | } |
| 348 | else | 439 | re[j] = '\0'; |
| 349 | fc_charset_table[i].charset_id = -1; | 440 | regexp = make_unibyte_string (re, j); |
| 350 | } | ||
| 351 | |||
| 352 | for (i = 0; fc_charset_table[i].name; i++) | 441 | for (i = 0; fc_charset_table[i].name; i++) |
| 353 | if (encoding->id == fc_charset_table[i].charset_id) | 442 | if (fast_c_string_match_ignore_case (regexp, fc_charset_table[i].name) >= 0) |
| 354 | break; | 443 | break; |
| 355 | if (! fc_charset_table[i].name) | 444 | if (! fc_charset_table[i].name) |
| 356 | return -1; | 445 | return -1; |
| @@ -395,6 +484,15 @@ struct OpenTypeSpec | |||
| 395 | (P)[4] = '\0'; \ | 484 | (P)[4] = '\0'; \ |
| 396 | } while (0) | 485 | } while (0) |
| 397 | 486 | ||
| 487 | #define OTF_TAG_SYM(SYM, TAG) \ | ||
| 488 | do { \ | ||
| 489 | char str[5]; \ | ||
| 490 | \ | ||
| 491 | OTF_TAG_STR (TAG, str); \ | ||
| 492 | (SYM) = font_intern_prop (str, 4, 1); \ | ||
| 493 | } while (0) | ||
| 494 | |||
| 495 | |||
| 398 | static struct OpenTypeSpec * | 496 | static struct OpenTypeSpec * |
| 399 | ftfont_get_open_type_spec (Lisp_Object otf_spec) | 497 | ftfont_get_open_type_spec (Lisp_Object otf_spec) |
| 400 | { | 498 | { |
| @@ -459,13 +557,12 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec) | |||
| 459 | return spec; | 557 | return spec; |
| 460 | } | 558 | } |
| 461 | 559 | ||
| 462 | static FcPattern *ftfont_spec_pattern P_ ((Lisp_Object, int *, char *, | 560 | static FcPattern *ftfont_spec_pattern P_ ((Lisp_Object, char *, |
| 463 | struct OpenTypeSpec **)); | 561 | struct OpenTypeSpec **)); |
| 464 | 562 | ||
| 465 | static FcPattern * | 563 | static FcPattern * |
| 466 | ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec) | 564 | ftfont_spec_pattern (spec, otlayout, otspec) |
| 467 | Lisp_Object spec; | 565 | Lisp_Object spec; |
| 468 | int *fc_charset_idx; | ||
| 469 | char *otlayout; | 566 | char *otlayout; |
| 470 | struct OpenTypeSpec **otspec; | 567 | struct OpenTypeSpec **otspec; |
| 471 | { | 568 | { |
| @@ -478,6 +575,7 @@ ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec) | |||
| 478 | int scalable = -1; | 575 | int scalable = -1; |
| 479 | Lisp_Object script = Qnil; | 576 | Lisp_Object script = Qnil; |
| 480 | Lisp_Object registry; | 577 | Lisp_Object registry; |
| 578 | int fc_charset_idx; | ||
| 481 | 579 | ||
| 482 | if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) | 580 | if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) |
| 483 | && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0) | 581 | && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0) |
| @@ -500,16 +598,16 @@ ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec) | |||
| 500 | || EQ (registry, Qiso10646_1) | 598 | || EQ (registry, Qiso10646_1) |
| 501 | || EQ (registry, Qunicode_bmp) | 599 | || EQ (registry, Qunicode_bmp) |
| 502 | || EQ (registry, Qunicode_sip)) | 600 | || EQ (registry, Qunicode_sip)) |
| 503 | *fc_charset_idx = -1; | 601 | fc_charset_idx = -1; |
| 504 | else | 602 | else |
| 505 | { | 603 | { |
| 506 | FcChar8 *lang; | 604 | FcChar8 *lang; |
| 507 | 605 | ||
| 508 | *fc_charset_idx = ftfont_get_charset (registry); | 606 | fc_charset_idx = ftfont_get_charset (registry); |
| 509 | if (*fc_charset_idx < 0) | 607 | if (fc_charset_idx < 0) |
| 510 | return NULL; | 608 | return NULL; |
| 511 | charset = fc_charset_table[*fc_charset_idx].fc_charset; | 609 | charset = fc_charset_table[fc_charset_idx].fc_charset; |
| 512 | lang = (FcChar8 *) fc_charset_table[*fc_charset_idx].lang; | 610 | lang = (FcChar8 *) fc_charset_table[fc_charset_idx].lang; |
| 513 | if (lang) | 611 | if (lang) |
| 514 | { | 612 | { |
| 515 | langset = FcLangSetCreate (); | 613 | langset = FcLangSetCreate (); |
| @@ -622,7 +720,7 @@ ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec) | |||
| 622 | 720 | ||
| 623 | finish: | 721 | finish: |
| 624 | if (langset) FcLangSetDestroy (langset); | 722 | if (langset) FcLangSetDestroy (langset); |
| 625 | if (charset && *fc_charset_idx < 0) FcCharSetDestroy (charset); | 723 | if (charset && fc_charset_idx < 0) FcCharSetDestroy (charset); |
| 626 | return pattern; | 724 | return pattern; |
| 627 | } | 725 | } |
| 628 | 726 | ||
| @@ -630,12 +728,11 @@ static Lisp_Object | |||
| 630 | ftfont_list (frame, spec) | 728 | ftfont_list (frame, spec) |
| 631 | Lisp_Object frame, spec; | 729 | Lisp_Object frame, spec; |
| 632 | { | 730 | { |
| 633 | Lisp_Object val = Qnil, registry, family; | 731 | Lisp_Object val = Qnil, family; |
| 634 | int i; | 732 | int i; |
| 635 | FcPattern *pattern; | 733 | FcPattern *pattern; |
| 636 | FcFontSet *fontset = NULL; | 734 | FcFontSet *fontset = NULL; |
| 637 | FcObjectSet *objset = NULL; | 735 | FcObjectSet *objset = NULL; |
| 638 | int fc_charset_idx; | ||
| 639 | char otlayout[15]; /* For "otlayout:XXXX" */ | 736 | char otlayout[15]; /* For "otlayout:XXXX" */ |
| 640 | struct OpenTypeSpec *otspec = NULL; | 737 | struct OpenTypeSpec *otspec = NULL; |
| 641 | int spacing = -1; | 738 | int spacing = -1; |
| @@ -646,12 +743,11 @@ ftfont_list (frame, spec) | |||
| 646 | fc_initialized = 1; | 743 | fc_initialized = 1; |
| 647 | } | 744 | } |
| 648 | 745 | ||
| 649 | pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec); | 746 | pattern = ftfont_spec_pattern (spec, otlayout, &otspec); |
| 650 | if (! pattern) | 747 | if (! pattern) |
| 651 | return Qnil; | 748 | return Qnil; |
| 652 | if (INTEGERP (AREF (spec, FONT_SPACING_INDEX))) | 749 | if (INTEGERP (AREF (spec, FONT_SPACING_INDEX))) |
| 653 | spacing = XINT (AREF (spec, FONT_SPACING_INDEX)); | 750 | spacing = XINT (AREF (spec, FONT_SPACING_INDEX)); |
| 654 | registry = AREF (spec, FONT_REGISTRY_INDEX); | ||
| 655 | family = AREF (spec, FONT_FAMILY_INDEX); | 751 | family = AREF (spec, FONT_FAMILY_INDEX); |
| 656 | if (! NILP (family)) | 752 | if (! NILP (family)) |
| 657 | { | 753 | { |
| @@ -669,7 +765,7 @@ ftfont_list (frame, spec) | |||
| 669 | 765 | ||
| 670 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, | 766 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, |
| 671 | FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE, | 767 | FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE, |
| 672 | FC_FILE, | 768 | FC_FILE, FC_INDEX, |
| 673 | #ifdef FC_CAPABILITY | 769 | #ifdef FC_CAPABILITY |
| 674 | FC_CAPABILITY, | 770 | FC_CAPABILITY, |
| 675 | #endif /* FC_CAPABILITY */ | 771 | #endif /* FC_CAPABILITY */ |
| @@ -758,9 +854,8 @@ ftfont_list (frame, spec) | |||
| 758 | continue; | 854 | continue; |
| 759 | } | 855 | } |
| 760 | #endif /* HAVE_LIBOTF */ | 856 | #endif /* HAVE_LIBOTF */ |
| 761 | entity = ftfont_pattern_entity (fontset->fonts[i], registry, | 857 | entity = ftfont_pattern_entity (fontset->fonts[i], |
| 762 | AREF (spec, FONT_EXTRA_INDEX), | 858 | AREF (spec, FONT_EXTRA_INDEX)); |
| 763 | fc_charset_idx); | ||
| 764 | if (! NILP (entity)) | 859 | if (! NILP (entity)) |
| 765 | val = Fcons (entity, val); | 860 | val = Fcons (entity, val); |
| 766 | } | 861 | } |
| @@ -788,7 +883,6 @@ ftfont_match (frame, spec) | |||
| 788 | FcResult result; | 883 | FcResult result; |
| 789 | char otlayout[15]; /* For "otlayout:XXXX" */ | 884 | char otlayout[15]; /* For "otlayout:XXXX" */ |
| 790 | struct OpenTypeSpec *otspec = NULL; | 885 | struct OpenTypeSpec *otspec = NULL; |
| 791 | int fc_charset_idx; | ||
| 792 | 886 | ||
| 793 | if (! fc_initialized) | 887 | if (! fc_initialized) |
| 794 | { | 888 | { |
| @@ -796,7 +890,7 @@ ftfont_match (frame, spec) | |||
| 796 | fc_initialized = 1; | 890 | fc_initialized = 1; |
| 797 | } | 891 | } |
| 798 | 892 | ||
| 799 | pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec); | 893 | pattern = ftfont_spec_pattern (spec, otlayout, &otspec); |
| 800 | if (! pattern) | 894 | if (! pattern) |
| 801 | return Qnil; | 895 | return Qnil; |
| 802 | 896 | ||
| @@ -814,9 +908,7 @@ ftfont_match (frame, spec) | |||
| 814 | match = FcFontMatch (NULL, pattern, &result); | 908 | match = FcFontMatch (NULL, pattern, &result); |
| 815 | if (match) | 909 | if (match) |
| 816 | { | 910 | { |
| 817 | entity = ftfont_pattern_entity (match, Qunicode_bmp, | 911 | entity = ftfont_pattern_entity (match, AREF (spec, FONT_EXTRA_INDEX)); |
| 818 | AREF (spec, FONT_EXTRA_INDEX), | ||
| 819 | fc_charset_idx); | ||
| 820 | FcPatternDestroy (match); | 912 | FcPatternDestroy (match); |
| 821 | if (! NILP (AREF (spec, FONT_FAMILY_INDEX)) | 913 | if (! NILP (AREF (spec, FONT_FAMILY_INDEX)) |
| 822 | && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX), | 914 | && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX), |
| @@ -885,12 +977,11 @@ ftfont_open (f, entity, pixel_size) | |||
| 885 | { | 977 | { |
| 886 | struct ftfont_info *ftfont_info; | 978 | struct ftfont_info *ftfont_info; |
| 887 | struct font *font; | 979 | struct font *font; |
| 980 | struct ftfont_cache_data *cache_data; | ||
| 888 | FT_Face ft_face; | 981 | FT_Face ft_face; |
| 889 | FT_Size ft_size; | 982 | FT_Size ft_size; |
| 890 | FT_UInt size; | 983 | FT_UInt size; |
| 891 | Lisp_Object val, filename, cache, font_object; | 984 | Lisp_Object val, filename, index, cache, font_object; |
| 892 | int fc_charset_idx; | ||
| 893 | FcPattern *pattern; | ||
| 894 | int scalable; | 985 | int scalable; |
| 895 | int spacing; | 986 | int spacing; |
| 896 | char name[256]; | 987 | char name[256]; |
| @@ -901,14 +992,14 @@ ftfont_open (f, entity, pixel_size) | |||
| 901 | if (! CONSP (val)) | 992 | if (! CONSP (val)) |
| 902 | return Qnil; | 993 | return Qnil; |
| 903 | val = XCDR (val); | 994 | val = XCDR (val); |
| 904 | filename = XCAR (val); | 995 | cache = ftfont_lookup_cache (val, 1); |
| 905 | fc_charset_idx = XINT (XCDR (val)); | ||
| 906 | cache = ftfont_lookup_cache (filename); | ||
| 907 | if (NILP (cache)) | 996 | if (NILP (cache)) |
| 908 | return Qnil; | 997 | return Qnil; |
| 909 | filename = XCAR (cache); | 998 | filename = XCAR (val); |
| 999 | index = XCDR (val); | ||
| 910 | val = XCDR (cache); | 1000 | val = XCDR (cache); |
| 911 | ft_face = XSAVE_VALUE (val)->pointer; | 1001 | cache_data = XSAVE_VALUE (XCDR (cache))->pointer; |
| 1002 | ft_face = cache_data->ft_face; | ||
| 912 | if (XSAVE_VALUE (val)->integer > 0) | 1003 | if (XSAVE_VALUE (val)->integer > 0) |
| 913 | { | 1004 | { |
| 914 | /* FT_Face in this cache is already used by the different size. */ | 1005 | /* FT_Face in this cache is already used by the different size. */ |
| @@ -931,11 +1022,8 @@ ftfont_open (f, entity, pixel_size) | |||
| 931 | return Qnil; | 1022 | return Qnil; |
| 932 | } | 1023 | } |
| 933 | 1024 | ||
| 934 | font_object = font_make_object (VECSIZE (struct ftfont_info)); | 1025 | font_object = font_make_object (VECSIZE (struct ftfont_info), entity, size); |
| 935 | ASET (font_object, FONT_TYPE_INDEX, Qfreetype); | 1026 | ASET (font_object, FONT_TYPE_INDEX, Qfreetype); |
| 936 | for (i = 1;i < FONT_ENTITY_MAX; i++) | ||
| 937 | ASET (font_object, i, AREF (entity, i)); | ||
| 938 | ASET (font_object, FONT_SIZE_INDEX, make_number (size)); | ||
| 939 | len = font_unparse_xlfd (entity, size, name, 256); | 1027 | len = font_unparse_xlfd (entity, size, name, 256); |
| 940 | if (len > 0) | 1028 | if (len > 0) |
| 941 | ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len)); | 1029 | ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len)); |
| @@ -950,7 +1038,7 @@ ftfont_open (f, entity, pixel_size) | |||
| 950 | font = XFONT_OBJECT (font_object); | 1038 | font = XFONT_OBJECT (font_object); |
| 951 | ftfont_info = (struct ftfont_info *) font; | 1039 | ftfont_info = (struct ftfont_info *) font; |
| 952 | ftfont_info->ft_size = ft_face->size; | 1040 | ftfont_info->ft_size = ft_face->size; |
| 953 | ftfont_info->fc_charset_idx = fc_charset_idx; | 1041 | ftfont_info->index = XINT (index); |
| 954 | #ifdef HAVE_LIBOTF | 1042 | #ifdef HAVE_LIBOTF |
| 955 | ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; | 1043 | ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; |
| 956 | ftfont_info->otf = NULL; | 1044 | ftfont_info->otf = NULL; |
| @@ -1030,19 +1118,21 @@ ftfont_close (f, font) | |||
| 1030 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | 1118 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; |
| 1031 | Lisp_Object val, cache; | 1119 | Lisp_Object val, cache; |
| 1032 | 1120 | ||
| 1033 | cache = ftfont_lookup_cache (font->props[FONT_FILE_INDEX]); | 1121 | val = Fcons (font->props[FONT_FILE_INDEX], make_number (ftfont_info->index)); |
| 1122 | cache = ftfont_lookup_cache (val, 1); | ||
| 1123 | xassert (CONSP (cache)); | ||
| 1034 | val = XCDR (cache); | 1124 | val = XCDR (cache); |
| 1035 | (XSAVE_VALUE (val)->integer)--; | 1125 | (XSAVE_VALUE (val)->integer)--; |
| 1036 | if (XSAVE_VALUE (val)->integer == 0) | 1126 | if (XSAVE_VALUE (val)->integer == 0) |
| 1037 | { | 1127 | { |
| 1038 | FT_Face ft_face = XSAVE_VALUE (val)->pointer; | 1128 | struct ftfont_cache_data *cache_data = XSAVE_VALUE (val)->pointer; |
| 1039 | 1129 | ||
| 1040 | FT_Done_Face (ft_face); | 1130 | FT_Done_Face (cache_data->ft_face); |
| 1041 | #ifdef HAVE_LIBOTF | 1131 | #ifdef HAVE_LIBOTF |
| 1042 | if (ftfont_info->otf) | 1132 | if (ftfont_info->otf) |
| 1043 | OTF_close (ftfont_info->otf); | 1133 | OTF_close (ftfont_info->otf); |
| 1044 | #endif | 1134 | #endif |
| 1045 | XSAVE_VALUE (val)->pointer = NULL; | 1135 | cache_data->ft_face = NULL; |
| 1046 | } | 1136 | } |
| 1047 | else | 1137 | else |
| 1048 | FT_Done_Size (ftfont_info->ft_size); | 1138 | FT_Done_Size (ftfont_info->ft_size); |
| @@ -1053,16 +1143,9 @@ ftfont_has_char (entity, c) | |||
| 1053 | Lisp_Object entity; | 1143 | Lisp_Object entity; |
| 1054 | int c; | 1144 | int c; |
| 1055 | { | 1145 | { |
| 1056 | Lisp_Object val; | 1146 | FcCharSet *charset = ftfont_get_fc_charset (entity); |
| 1057 | int fc_charset_idx; | ||
| 1058 | struct charset *charset; | ||
| 1059 | 1147 | ||
| 1060 | val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); | 1148 | return (FcCharSetHasChar (charset, c) == FcTrue); |
| 1061 | fc_charset_idx = XINT (XCDR (XCDR (val))); | ||
| 1062 | if (fc_charset_idx < 0) | ||
| 1063 | return -1; | ||
| 1064 | charset = CHARSET_FROM_ID (fc_charset_table[fc_charset_idx].charset_id); | ||
| 1065 | return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)); | ||
| 1066 | } | 1149 | } |
| 1067 | 1150 | ||
| 1068 | static unsigned | 1151 | static unsigned |
| @@ -1198,6 +1281,67 @@ ftfont_anchor_point (font, code, index, x, y) | |||
| 1198 | } | 1281 | } |
| 1199 | 1282 | ||
| 1200 | #ifdef HAVE_LIBOTF | 1283 | #ifdef HAVE_LIBOTF |
| 1284 | |||
| 1285 | static Lisp_Object | ||
| 1286 | ftfont_otf_features (gsub_gpos) | ||
| 1287 | OTF_GSUB_GPOS *gsub_gpos; | ||
| 1288 | { | ||
| 1289 | Lisp_Object scripts, langsyses, features, sym; | ||
| 1290 | int i, j, k; | ||
| 1291 | |||
| 1292 | for (scripts = Qnil, i = gsub_gpos->ScriptList.ScriptCount - 1; i >= 0; i--) | ||
| 1293 | { | ||
| 1294 | OTF_Script *otf_script = gsub_gpos->ScriptList.Script + i; | ||
| 1295 | |||
| 1296 | for (langsyses = Qnil, j = otf_script->LangSysCount - 1; j >= -1; j--) | ||
| 1297 | { | ||
| 1298 | OTF_LangSys *otf_langsys; | ||
| 1299 | |||
| 1300 | if (j >= 0) | ||
| 1301 | otf_langsys = otf_script->LangSys + j; | ||
| 1302 | else if (otf_script->DefaultLangSysOffset) | ||
| 1303 | otf_langsys = &otf_script->DefaultLangSys; | ||
| 1304 | else | ||
| 1305 | break; | ||
| 1306 | |||
| 1307 | for (features = Qnil, k = otf_langsys->FeatureCount - 1; k >= 0; k--) | ||
| 1308 | { | ||
| 1309 | OTF_TAG_SYM (sym, gsub_gpos->FeatureList.Feature[k].FeatureTag); | ||
| 1310 | features = Fcons (sym, features); | ||
| 1311 | } | ||
| 1312 | if (j >= 0) | ||
| 1313 | OTF_TAG_SYM (sym, otf_script->LangSysRecord[j].LangSysTag); | ||
| 1314 | else | ||
| 1315 | sym = Qnil; | ||
| 1316 | langsyses = Fcons (Fcons (sym, features), langsyses); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | OTF_TAG_SYM (sym, gsub_gpos->ScriptList.Script[i].ScriptTag); | ||
| 1320 | scripts = Fcons (Fcons (sym, langsyses), scripts); | ||
| 1321 | } | ||
| 1322 | return scripts; | ||
| 1323 | |||
| 1324 | } | ||
| 1325 | |||
| 1326 | |||
| 1327 | static Lisp_Object | ||
| 1328 | ftfont_otf_capability (font) | ||
| 1329 | struct font *font; | ||
| 1330 | { | ||
| 1331 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | ||
| 1332 | OTF *otf = ftfont_get_otf (ftfont_info); | ||
| 1333 | Lisp_Object gsub_gpos; | ||
| 1334 | |||
| 1335 | if (! otf) | ||
| 1336 | return Qnil; | ||
| 1337 | gsub_gpos = Fcons (Qnil, Qnil); | ||
| 1338 | if (OTF_get_table (otf, "GSUB") == 0) | ||
| 1339 | XSETCAR (gsub_gpos, ftfont_otf_features (otf->gsub)); | ||
| 1340 | if (OTF_get_table (otf, "GPOS") == 0) | ||
| 1341 | XSETCDR (gsub_gpos, ftfont_otf_features (otf->gpos)); | ||
| 1342 | return gsub_gpos; | ||
| 1343 | } | ||
| 1344 | |||
| 1201 | #ifdef HAVE_M17N_FLT | 1345 | #ifdef HAVE_M17N_FLT |
| 1202 | 1346 | ||
| 1203 | struct MFLTFontFT | 1347 | struct MFLTFontFT |
| @@ -1720,28 +1864,14 @@ ftfont_shape (lgstring) | |||
| 1720 | { | 1864 | { |
| 1721 | struct font *font; | 1865 | struct font *font; |
| 1722 | struct ftfont_info *ftfont_info; | 1866 | struct ftfont_info *ftfont_info; |
| 1867 | OTF *otf; | ||
| 1723 | 1868 | ||
| 1724 | CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font); | 1869 | CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font); |
| 1725 | ftfont_info = (struct ftfont_info *) font; | 1870 | ftfont_info = (struct ftfont_info *) font; |
| 1726 | if (! ftfont_info->maybe_otf) | 1871 | otf = ftfont_get_otf (ftfont_info); |
| 1872 | if (! otf) | ||
| 1727 | return make_number (0); | 1873 | return make_number (0); |
| 1728 | if (! ftfont_info->otf) | 1874 | return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, otf); |
| 1729 | { | ||
| 1730 | OTF *otf = OTF_open_ft_face (ftfont_info->ft_size->face); | ||
| 1731 | |||
| 1732 | if (! otf || OTF_get_table (otf, "head") < 0) | ||
| 1733 | { | ||
| 1734 | if (otf) | ||
| 1735 | OTF_close (otf); | ||
| 1736 | ftfont_info->maybe_otf = 0; | ||
| 1737 | return make_number (0); | ||
| 1738 | } | ||
| 1739 | |||
| 1740 | ftfont_info->otf = otf; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, | ||
| 1744 | ftfont_info->otf); | ||
| 1745 | } | 1875 | } |
| 1746 | 1876 | ||
| 1747 | #endif /* HAVE_M17N_FLT */ | 1877 | #endif /* HAVE_M17N_FLT */ |