Mercurial > emacs
changeset 90441:d63258b13d84
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
font.c.
(ftfont_pattern_entity): New function.
(ftfont_get_cache): Assume that freetype_font_cache is already
initialized.
(ftfont_list): Handle the case that a file is specified in font
name. Use ftfont_pattern_entity to generate entities.
(ftfont_has_char): Check if the pattern contains FC_CHARSET.
(syms_of_ftfont): Initialize freetype_font_cache.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 09 Jun 2006 02:15:05 +0000 |
parents | 33277d7748f3 |
children | d6abf2344438 |
files | src/ftfont.c |
diffstat | 1 files changed, 122 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ftfont.c Fri Jun 09 02:14:49 2006 +0000 +++ b/src/ftfont.c Fri Jun 09 02:15:05 2006 +0000 @@ -40,15 +40,20 @@ #include "fontset.h" #include "font.h" +/* Symbolic type of this font-driver. */ Lisp_Object Qfreetype; +/* Flag to tell if FcInit is areadly called or not. */ static int fc_initialized; + +/* Handle to a FreeType library instance. */ static FT_Library ft_library; +/* Cache for FreeType fonts. */ static Lisp_Object freetype_font_cache; -static Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp; - +/* Fontconfig's charset used for finding fonts of registry + "iso8859-1". */ static FcCharSet *cs_iso8859_1; /* The actual structure for FreeType font that can be casted to struct @@ -77,6 +82,70 @@ return 0; } +Lisp_Object +ftfont_pattern_entity (p, frame, registry, name) + FcPattern *p; + Lisp_Object frame, registry, name; +{ + Lisp_Object entity; + FcChar8 *file; + FcCharSet *charset; + char *str; + int numeric; + double dbl; + + if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) + return Qnil; + if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) == FcResultMatch) + charset = NULL; + + entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); + + ASET (entity, FONT_TYPE_INDEX, Qfreetype); + ASET (entity, FONT_REGISTRY_INDEX, registry); + ASET (entity, FONT_FRAME_INDEX, frame); + ASET (entity, FONT_OBJLIST_INDEX, Qnil); + + if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) + ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str))); + if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) + ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str))); + if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) + ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); + if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) + ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); + if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) + ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); + if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) + ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); + else + ASET (entity, FONT_SIZE_INDEX, make_number (0)); + + if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) + numeric = FC_MONO; + file = FcStrCopy (file); + if (! file) + return Qnil; + + p = FcPatternCreate (); + if (! p) + return Qnil; + + if (FcPatternAddString (p, FC_FILE, file) == FcFalse + || (charset && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse) + || FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse + || (! NILP (name) + && (FcPatternAddString (p, FC_FILE, (FcChar8 *) SDATA (name)) + == FcFalse))) + { + FcPatternDestroy (p); + return Qnil; + } + ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0)); + return entity; +} + + static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object)); static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); @@ -135,8 +204,6 @@ ftfont_get_cache (frame) Lisp_Object frame; { - if (NILP (freetype_font_cache)) - freetype_font_cache = Fcons (Qt, Qnil); return freetype_font_cache; } @@ -180,14 +247,14 @@ ftfont_list (frame, spec) Lisp_Object frame, spec; { - Lisp_Object val, tmp, extra, font_name; + Lisp_Object val, tmp, extra, font_name, file_name; int i; FcPattern *pattern = NULL; FcCharSet *charset = NULL; FcLangSet *langset = NULL; FcFontSet *fontset = NULL; FcObjectSet *objset = NULL; - Lisp_Object registry = Qnil; + Lisp_Object registry = Qunicode_bmp; val = null_vector; @@ -208,12 +275,13 @@ && ftfont_build_basic_charsets () < 0) goto err; charset = cs_iso8859_1; - registry = Qnil; } + else if (! EQ (registry, Qiso10646_1) && ! EQ (registry, Qunicode_bmp)) + goto finish; } extra = AREF (spec, FONT_EXTRA_INDEX); - font_name = Qnil; + font_name = file_name = Qnil; if (CONSP (extra)) { tmp = Fassq (QCotf, extra); @@ -242,7 +310,11 @@ } tmp = Fassq (QCname, extra); if (CONSP (tmp)) - font_name = XCDR (tmp); + { + font_name = XCDR (tmp); + if (SDATA (font_name)[0] == ':') + file_name = font_name, font_name = Qnil; + } tmp = Fassq (QCscript, extra); if (CONSP (tmp) && ! charset) { @@ -263,12 +335,9 @@ } } - if (! NILP (registry) && ! charset) - goto finish; - if (STRINGP (font_name)) { - if (! isalpha (SDATA (font_name)[0])) + if (SDATA (font_name)[0] == '-') goto finish; pattern = FcNameParse (SDATA (font_name)); if (! pattern) @@ -276,7 +345,13 @@ } else { - pattern = FcPatternCreate (); + if (! NILP (file_name)) + { + pattern = FcNameParse (SDATA (file_name)); + FcPatternDel (pattern, FC_PIXEL_SIZE); + } + else + pattern = FcPatternCreate (); if (! pattern) goto err; @@ -311,68 +386,42 @@ if (langset && ! FcPatternAddLangSet (pattern, FC_LANG, langset)) goto err; - objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, - FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, - FC_CHARSET, FC_FILE, NULL); - if (! objset) - goto err; - BLOCK_INPUT; - fontset = FcFontList (NULL, pattern, objset); - UNBLOCK_INPUT; - if (! fontset) - goto err; - val = Qnil; - for (i = 0; i < fontset->nfont; i++) + if (STRINGP (font_name)) { - FcPattern *p = fontset->fonts[i]; - FcChar8 *str, *file; - - if (FcPatternGetString (p, FC_FILE, 0, &file) == FcResultMatch - && FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) == FcResultMatch) - { - Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), - null_string); - int numeric; - double dbl; - FcPattern *p0; - - ASET (entity, FONT_TYPE_INDEX, Qfreetype); - ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); - ASET (entity, FONT_FRAME_INDEX, frame); - ASET (entity, FONT_OBJLIST_INDEX, Qnil); + FcPattern *pat; + FcResult result; + Lisp_Object entity; - if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) - ASET (entity, FONT_FOUNDRY_INDEX, - intern_downcase ((char *) str, strlen ((char *) str))); - if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) - ASET (entity, FONT_FAMILY_INDEX, - intern_downcase ((char *) str, strlen ((char *) str))); - if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) - ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); - if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) - ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); - if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) - ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); - if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) - ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); - else - ASET (entity, FONT_SIZE_INDEX, make_number (0)); + FcConfigSubstitute (NULL, pattern, FcMatchPattern); + FcDefaultSubstitute (pattern); + pat = FcFontMatch (NULL, pattern, &result); + entity = ftfont_pattern_entity (pat, frame, registry, font_name); + FcPatternDestroy (pat); + if (! NILP (entity)) + val = Fmake_vector (make_number (1), entity); + } + else + { + objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, + FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, + FC_CHARSET, FC_FILE, NULL); + if (! objset) + goto err; - if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) - numeric = FC_MONO; - p0 = FcPatternCreate (); - if (! p0 - || FcPatternAddString (p0, FC_FILE, file) == FcFalse - || FcPatternAddCharSet (p0, FC_CHARSET, charset) == FcFalse - || FcPatternAddInteger (p0, FC_SPACING, numeric) == FcFalse) - break; - ASET (entity, FONT_EXTRA_INDEX, make_save_value (p0, 0)); - - val = Fcons (entity, val); + fontset = FcFontList (NULL, pattern, objset); + if (! fontset) + goto err; + val = Qnil; + for (i = 0; i < fontset->nfont; i++) + { + Lisp_Object entity = ftfont_pattern_entity (fontset->fonts[i], + frame, registry, Qnil); + if (! NILP (entity)) + val = Fcons (entity, val); } + val = Fvconcat (1, &val); } - val = Fvconcat (1, &val); goto finish; err: @@ -586,8 +635,8 @@ val = AREF (entity, FONT_EXTRA_INDEX); pattern = XSAVE_VALUE (val)->pointer; - FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset); - + if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) + return -1; return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); } @@ -719,12 +768,9 @@ syms_of_ftfont () { staticpro (&freetype_font_cache); - freetype_font_cache = Qnil; + freetype_font_cache = Fcons (Qt, Qnil); DEFSYM (Qfreetype, "freetype"); - DEFSYM (Qiso8859_1, "iso8859-1"); - DEFSYM (Qiso10646_1, "iso10646-1"); - DEFSYM (Qunicode_bmp, "unicode-bmp"); ftfont_driver.type = Qfreetype; register_font_driver (&ftfont_driver, NULL);