Mercurial > emacs
changeset 96559:34bb8a9f2b7f
(font_make_object): New arg entity and pixelsize.
(font_check_otf_features, font_check_otf): New functions.
(font_match_p): Check :lang, :script, and :otf properties.
(font_open_entity): Set the member vertical_centering of struct
font.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 09 Jul 2008 00:30:18 +0000 |
parents | 2d344e7d113a |
children | d87a9f1b9378 |
files | src/font.c |
diffstat | 1 files changed, 166 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/src/font.c Wed Jul 09 00:29:47 2008 +0000 +++ b/src/font.c Wed Jul 09 00:30:18 2008 +0000 @@ -189,15 +189,32 @@ return font_entity; } +/* Create a font-object whose structure size is SIZE. If ENTITY is + not nil, copy properties from ENTITY to the font-object. If + PIXELSIZE is positive, set the `size' property to PIXELSIZE. */ Lisp_Object -font_make_object (size) +font_make_object (size, entity, pixelsize) int size; + Lisp_Object entity; + int pixelsize; { Lisp_Object font_object; struct font *font = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT); + int i; + XSETFONT (font_object, font); + if (! NILP (entity)) + { + for (i = 1; i < FONT_SPEC_MAX; i++) + font->props[i] = AREF (entity, i); + if (! NILP (AREF (entity, FONT_EXTRA_INDEX))) + font->props[FONT_EXTRA_INDEX] + = Fcopy_sequence (AREF (entity, FONT_EXTRA_INDEX)); + } + if (size > 0) + font->props[FONT_SIZE_INDEX] = make_number (pixelsize); return font_object; } @@ -2184,10 +2201,7 @@ /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. The return value indicates how different ENTITY is compared with - SPEC_PROP. - - ALTERNATE_FAMILIES, if non-nil, is a pre-calculated list of - alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */ + SPEC_PROP. */ static unsigned font_score (entity, spec_prop) @@ -2351,32 +2365,155 @@ } } - -/* Check if ENTITY matches with the font specification SPEC. */ +static int +font_check_otf_features (script, langsys, features, table) + Lisp_Object script, langsys, features, table; +{ + Lisp_Object val; + int negative; + + table = assq_no_quit (script, table); + if (NILP (table)) + return 0; + table = XCDR (table); + if (! NILP (langsys)) + { + table = assq_no_quit (langsys, table); + if (NILP (table)) + return 0; + } + else + { + val = assq_no_quit (Qnil, table); + if (NILP (val)) + table = XCAR (table); + else + table = val; + } + table = XCDR (table); + for (negative = 0; CONSP (features); features = XCDR (features)) + { + if (NILP (XCAR (features))) + negative = 1; + if (NILP (Fmemq (XCAR (features), table)) != negative) + return 0; + } + return 1; +} + +/* Check if OTF_CAPABILITY satisfies SPEC (otf-spec). */ + +static int +font_check_otf (spec, otf_capability) +{ + Lisp_Object script, langsys = Qnil, gsub = Qnil, gpos = Qnil; + + script = XCAR (spec); + spec = XCDR (spec); + if (! NILP (spec)) + { + langsys = XCAR (spec); + spec = XCDR (spec); + if (! NILP (spec)) + { + gsub = XCAR (spec); + spec = XCDR (spec); + if (! NILP (spec)) + gpos = XCAR (spec); + } + } + + if (! NILP (gsub) && ! font_check_otf_features (script, langsys, gsub, + XCAR (otf_capability))) + return 0; + if (! NILP (gpos) && ! font_check_otf_features (script, langsys, gpos, + XCDR (otf_capability))) + return 0; + return 1; +} + + + +/* Check if FONT (font-entity or font-object) matches with the font + specification SPEC. */ int -font_match_p (spec, entity) - Lisp_Object spec, entity; +font_match_p (spec, font) + Lisp_Object spec, font; { - Lisp_Object prefer_prop[FONT_SPEC_MAX]; - Lisp_Object alternate_families = Qnil; + Lisp_Object prop[FONT_SPEC_MAX], *props; + Lisp_Object extra, font_extra; int i; - for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) - prefer_prop[i] = AREF (spec, i); - if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) - prefer_prop[FONT_SIZE_INDEX] - = make_number (font_pixel_size (XFRAME (selected_frame), spec)); - if (! NILP (prefer_prop[FONT_FAMILY_INDEX])) + for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) + if (! NILP (AREF (spec, i)) + && ! NILP (AREF (font, i)) + && ! EQ (AREF (spec, i), AREF (font, i))) + return 0; + props = XFONT_SPEC (spec)->props; + if (FLOATP (props[FONT_SIZE_INDEX])) + { + for (i = FONT_FOUNDRY_INDEX; i < FONT_SIZE_INDEX; i++) + prop[i] = AREF (spec, i); + prop[FONT_SIZE_INDEX] + = make_number (font_pixel_size (XFRAME (selected_frame), spec)); + props = prop; + } + + if (font_score (font, props) > 0) + return 0; + extra = AREF (spec, FONT_EXTRA_INDEX); + font_extra = AREF (font, FONT_EXTRA_INDEX); + for (; CONSP (extra); extra = XCDR (extra)) { - alternate_families - = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX], - Vface_alternative_font_family_alist, Qt); - if (CONSP (alternate_families)) - alternate_families = XCDR (alternate_families); + Lisp_Object key = XCAR (XCAR (extra)); + Lisp_Object val = XCDR (XCAR (extra)), val2; + + if (EQ (key, QClang)) + { + val2 = assq_no_quit (key, font_extra); + if (NILP (val2)) + return 0; + val2 = XCDR (val2); + if (CONSP (val)) + { + if (! CONSP (val2)) + return 0; + while (CONSP (val)) + if (NILP (Fmemq (val, val2))) + return 0; + } + else + if (CONSP (val2) + ? NILP (Fmemq (val, XCDR (val2))) + : ! EQ (val, val2)) + return 0; + } + else if (EQ (key, QCscript)) + { + val2 = assq_no_quit (val, Vscript_representative_chars); + if (! NILP (val2)) + for (val2 = XCDR (val2); CONSP (val2); val2 = XCDR (val2)) + if (font_encode_char (font, XINT (XCAR (val2))) + == FONT_INVALID_CODE) + return 0; + } + else if (EQ (key, QCotf)) + { + struct font *fontp; + + if (! FONT_OBJECT_P (font)) + return 0; + fontp = XFONT_OBJECT (font); + if (! fontp->driver->otf_capability) + return 0; + val2 = fontp->driver->otf_capability (fontp); + if (NILP (val2) || ! font_check_otf (val, val2)) + return 0; + } } - return (font_score (entity, prefer_prop) == 0); + return 1; } @@ -2711,6 +2848,12 @@ return Qnil; font_object = driver_list->driver->open (f, entity, pixel_size); + if (STRINGP (AREF (font_object, FONT_FULLNAME_INDEX)) + && STRINGP (Vvertical_centering_font_regexp)) + XFONT_OBJECT (font_object)->vertical_centering + = (fast_string_match_ignore_case + (Vvertical_centering_font_regexp, + (AREF (font_object, FONT_FULLNAME_INDEX))) >= 0); font_add_log ("open", entity, font_object); if (NILP (font_object)) return Qnil;