X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/7815fe1985833c57457882b415a29358991dabdc..13a547c6792935558a306bec264e0bad575cec87:/src/font.c diff --git a/src/font.c b/src/font.c index 4b59d89b88..a9a381a828 100644 --- a/src/font.c +++ b/src/font.c @@ -1,8 +1,9 @@ /* font.c -- "Font" primitives. - Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - Copyright (C) 2006, 2007, 2008, 2009, 2010 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H13PRO009 + +Copyright (C) 2006-2011 Free Software Foundation, Inc. +Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 + National Institute of Advanced Industrial Science and Technology (AIST) + Registration Number H13PRO009 This file is part of GNU Emacs. @@ -21,7 +22,6 @@ along with GNU Emacs. If not, see . */ #include #include -#include #include #include @@ -62,8 +62,6 @@ static Lisp_Object QCf; font_driver *)->list when a specified font is not found. */ static Lisp_Object null_vector; -static Lisp_Object Vfont_weight_table, Vfont_slant_table, Vfont_width_table; - /* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */ static Lisp_Object font_style_table; @@ -123,7 +121,8 @@ static const struct table_entry width_table[] = { 200, { "ultra-expanded", "ultraexpanded", "wide" }} }; -Lisp_Object QCfoundry, QCadstyle, QCregistry; +Lisp_Object QCfoundry; +static Lisp_Object QCadstyle, QCregistry; /* Symbols representing keys of font extra info. */ Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth; Lisp_Object QCantialias, QCfont_entity, QCfc_unknown_spec; @@ -135,8 +134,6 @@ Lisp_Object Qja, Qko; Lisp_Object QCuser_spec; -Lisp_Object Vfont_encoding_alist; - /* Alist of font registry symbol and the corresponding charsets information. The information is retrieved from Vfont_encoding_alist on demand. @@ -164,7 +161,7 @@ static struct font_driver_list *font_driver_list; /* Creaters of font-related Lisp object. */ -Lisp_Object +static Lisp_Object font_make_spec (void) { Lisp_Object font_spec; @@ -220,6 +217,7 @@ static int font_pixel_size (FRAME_PTR f, Lisp_Object); static Lisp_Object font_open_entity (FRAME_PTR, Lisp_Object, int); static Lisp_Object font_matching_entity (FRAME_PTR, Lisp_Object *, Lisp_Object); +static unsigned font_encode_char (Lisp_Object, int); /* Number of registered font drivers. */ static int num_font_drivers; @@ -232,12 +230,12 @@ static int num_font_drivers; STR. */ Lisp_Object -font_intern_prop (char *str, int len, int force_symbol) +font_intern_prop (const char *str, int len, int force_symbol) { int i; Lisp_Object tem; Lisp_Object obarray; - int nbytes, nchars; + EMACS_INT nbytes, nchars; if (len == 1 && *str == '*') return Qnil; @@ -313,11 +311,11 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror { Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); int len = ASIZE (table); - int i, j; if (SYMBOLP (val)) { - unsigned char *s; + int i, j; + char *s; Lisp_Object args[2], elt; /* At first try exact match. */ @@ -327,12 +325,12 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror return ((XINT (AREF (AREF (table, i), 0)) << 8) | (i << 4) | (j - 1)); /* Try also with case-folding match. */ - s = SDATA (SYMBOL_NAME (val)); + s = SSDATA (SYMBOL_NAME (val)); for (i = 0; i < len; i++) for (j = 1; j < ASIZE (AREF (table, i)); j++) { elt = AREF (AREF (table, i), j); - if (xstrcasecmp (s, SDATA (SYMBOL_NAME (elt))) == 0) + if (xstrcasecmp (s, SSDATA (SYMBOL_NAME (elt))) == 0) return ((XINT (AREF (AREF (table, i), 0)) << 8) | (i << 4) | (j - 1)); } @@ -502,10 +500,9 @@ font_prop_validate_style (Lisp_Object style, Lisp_Object val) enum font_property_index prop = (EQ (style, QCweight) ? FONT_WEIGHT_INDEX : EQ (style, QCslant) ? FONT_SLANT_INDEX : FONT_WIDTH_INDEX); - int n; if (INTEGERP (val)) { - n = XINT (val); + int n = XINT (val); if (((n >> 4) & 0xF) >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX))) val = Qerror; @@ -699,7 +696,7 @@ font_put_extra (Lisp_Object font, Lisp_Object prop, Lisp_Object val) /* Font name parser and unparser */ -static int parse_matrix (char *); +static int parse_matrix (const char *); static int font_expand_wildcards (Lisp_Object *, int); static int font_parse_name (char *, Lisp_Object); @@ -758,7 +755,7 @@ enum xlfd_field_mask -1. */ static int -parse_matrix (char *p) +parse_matrix (const char *p) { double matrix[4]; char *end; @@ -1165,7 +1162,8 @@ font_parse_xlfd (char *name, Lisp_Object font) int font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) { - char *f[XLFD_REGISTRY_INDEX + 1]; + char *p; + const char *f[XLFD_REGISTRY_INDEX + 1]; Lisp_Object val; int i, j, len = 0; @@ -1191,24 +1189,24 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) if (SYMBOLP (val)) val = SYMBOL_NAME (val); if (j == XLFD_REGISTRY_INDEX - && ! strchr ((char *) SDATA (val), '-')) + && ! strchr (SSDATA (val), '-')) { /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */ if (SDATA (val)[SBYTES (val) - 1] == '*') { - f[j] = alloca (SBYTES (val) + 3); - sprintf (f[j], "%s-*", SDATA (val)); + f[j] = p = alloca (SBYTES (val) + 3); + sprintf (p, "%s-*", SDATA (val)); len += SBYTES (val) + 3; } else { - f[j] = alloca (SBYTES (val) + 4); - sprintf (f[j], "%s*-*", SDATA (val)); + f[j] = p = alloca (SBYTES (val) + 4); + sprintf (p, "%s*-*", SDATA (val)); len += SBYTES (val) + 4; } } else - f[j] = (char *) SDATA (val), len += SBYTES (val) + 1; + f[j] = SSDATA (val), len += SBYTES (val) + 1; } } @@ -1221,7 +1219,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) else { val = SYMBOL_NAME (val); - f[j] = (char *) SDATA (val), len += SBYTES (val) + 1; + f[j] = SSDATA (val), len += SBYTES (val) + 1; } } @@ -1234,8 +1232,8 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) i = pixel_size; if (i > 0) { - f[XLFD_PIXEL_INDEX] = alloca (22); - len += sprintf (f[XLFD_PIXEL_INDEX], "%d-*", i) + 1; + f[XLFD_PIXEL_INDEX] = p = alloca (22); + len += sprintf (p, "%d-*", i) + 1; } else f[XLFD_PIXEL_INDEX] = "*-*", len += 4; @@ -1243,8 +1241,8 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) else if (FLOATP (val)) { i = XFLOAT_DATA (val) * 10; - f[XLFD_PIXEL_INDEX] = alloca (12); - len += sprintf (f[XLFD_PIXEL_INDEX], "*-%d", i) + 1; + f[XLFD_PIXEL_INDEX] = p = alloca (12); + len += sprintf (p, "*-%d", i) + 1; } else f[XLFD_PIXEL_INDEX] = "*-*", len += 4; @@ -1252,9 +1250,8 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) if (INTEGERP (AREF (font, FONT_DPI_INDEX))) { i = XINT (AREF (font, FONT_DPI_INDEX)); - f[XLFD_RESX_INDEX] = alloca (22); - len += sprintf (f[XLFD_RESX_INDEX], - "%d-%d", i, i) + 1; + f[XLFD_RESX_INDEX] = p = alloca (22); + len += sprintf (p, "%d-%d", i, i) + 1; } else f[XLFD_RESX_INDEX] = "*-*", len += 4; @@ -1272,8 +1269,8 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) f[XLFD_SPACING_INDEX] = "*", len += 2; if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) { - f[XLFD_AVGWIDTH_INDEX] = alloca (11); - len += sprintf (f[XLFD_AVGWIDTH_INDEX], "%ld", + f[XLFD_AVGWIDTH_INDEX] = p = alloca (11); + len += sprintf (p, "%ld", (long) XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1; } else @@ -1305,7 +1302,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) This function tries to guess which format it is. */ -int +static int font_parse_fcname (char *name, Lisp_Object font) { char *p, *q; @@ -1382,25 +1379,26 @@ font_parse_fcname (char *name, Lisp_Object font) word_len = q - p; val = font_intern_prop (p, q - p, 1); -#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0) +#define PROP_MATCH(STR) (word_len == strlen (STR) \ + && memcmp (p, STR, strlen (STR)) == 0) - if (PROP_MATCH ("light", 5) - || PROP_MATCH ("medium", 6) - || PROP_MATCH ("demibold", 8) - || PROP_MATCH ("bold", 4) - || PROP_MATCH ("black", 5)) + if (PROP_MATCH ("light") + || PROP_MATCH ("medium") + || PROP_MATCH ("demibold") + || PROP_MATCH ("bold") + || PROP_MATCH ("black")) FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, val); - else if (PROP_MATCH ("roman", 5) - || PROP_MATCH ("italic", 6) - || PROP_MATCH ("oblique", 7)) + else if (PROP_MATCH ("roman") + || PROP_MATCH ("italic") + || PROP_MATCH ("oblique")) FONT_SET_STYLE (font, FONT_SLANT_INDEX, val); - else if (PROP_MATCH ("charcell", 8)) + else if (PROP_MATCH ("charcell")) ASET (font, FONT_SPACING_INDEX, make_number (FONT_SPACING_CHARCELL)); - else if (PROP_MATCH ("mono", 4)) + else if (PROP_MATCH ("mono")) ASET (font, FONT_SPACING_INDEX, make_number (FONT_SPACING_MONO)); - else if (PROP_MATCH ("proportional", 12)) + else if (PROP_MATCH ("proportional")) ASET (font, FONT_SPACING_INDEX, make_number (FONT_SPACING_PROPORTIONAL)); #undef PROP_MATCH @@ -1449,110 +1447,84 @@ font_parse_fcname (char *name, Lisp_Object font) { /* Either a fontconfig-style name with no size and property data, or a GTK-style name. */ - Lisp_Object prop; - int word_len, prop_found = 0; + Lisp_Object weight = Qnil, slant = Qnil; + Lisp_Object width = Qnil, size = Qnil; + char *word_start; + int word_len; + + /* Scan backwards from the end, looking for a size. */ + for (p = name + len - 1; p >= name; p--) + if (!isdigit (*p)) + break; + + if ((p < name + len - 1) && ((p + 1 == name) || *p == ' ')) + /* Found a font size. */ + size = make_float (strtod (p + 1, NULL)); + else + p = name + len; - for (p = name; *p; p = *q ? q + 1 : q) + /* Now P points to the termination of the string, sans size. + Scan backwards, looking for font properties. */ + for (; p > name; p = q) { - if (isdigit (*p)) + for (q = p - 1; q >= name; q--) { - int size_found = 1; - - for (q = p + 1; *q && *q != ' '; q++) - if (! isdigit (*q) && *q != '.') - { - size_found = 0; - break; - } - if (size_found) - { - double point_size = strtod (p, &q); - ASET (font, FONT_SIZE_INDEX, make_float (point_size)); - continue; - } + if (q > name && *(q-1) == '\\') + --q; /* Skip quoting backslashes. */ + else if (*q == ' ') + break; } - for (q = p + 1; *q && *q != ' '; q++) - if (*q == '\\' && q[1]) - q++; - word_len = q - p; - -#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0) - - if (PROP_MATCH ("Ultra-Light", 11)) - { - prop_found = 1; - prop = font_intern_prop ("ultra-light", 11, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Light", 5)) - { - prop_found = 1; - prop = font_intern_prop ("light", 5, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Book", 4)) - { - prop_found = 1; - prop = font_intern_prop ("book", 4, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Medium", 6)) - { - prop_found = 1; - prop = font_intern_prop ("medium", 6, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Semi-Bold", 9)) - { - prop_found = 1; - prop = font_intern_prop ("semi-bold", 9, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Bold", 4)) - { - prop_found = 1; - prop = font_intern_prop ("bold", 4, 1); - FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop); - } - else if (PROP_MATCH ("Italic", 6)) - { - prop_found = 1; - prop = font_intern_prop ("italic", 4, 1); - FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop); - } - else if (PROP_MATCH ("Oblique", 7)) - { - prop_found = 1; - prop = font_intern_prop ("oblique", 7, 1); - FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop); - } - else if (PROP_MATCH ("Semi-Condensed", 14)) - { - prop_found = 1; - prop = font_intern_prop ("semi-condensed", 14, 1); - FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop); - } - else if (PROP_MATCH ("Condensed", 9)) + word_start = q + 1; + word_len = p - word_start; + +#define PROP_MATCH(STR) \ + (word_len == strlen (STR) \ + && memcmp (word_start, STR, strlen (STR)) == 0) +#define PROP_SAVE(VAR, STR) \ + (VAR = NILP (VAR) ? font_intern_prop (STR, strlen (STR), 1) : VAR) + + if (PROP_MATCH ("Ultra-Light")) + PROP_SAVE (weight, "ultra-light"); + else if (PROP_MATCH ("Light")) + PROP_SAVE (weight, "light"); + else if (PROP_MATCH ("Book")) + PROP_SAVE (weight, "book"); + else if (PROP_MATCH ("Medium")) + PROP_SAVE (weight, "medium"); + else if (PROP_MATCH ("Semi-Bold")) + PROP_SAVE (weight, "semi-bold"); + else if (PROP_MATCH ("Bold")) + PROP_SAVE (weight, "bold"); + else if (PROP_MATCH ("Italic")) + PROP_SAVE (slant, "italic"); + else if (PROP_MATCH ("Oblique")) + PROP_SAVE (slant, "oblique"); + else if (PROP_MATCH ("Semi-Condensed")) + PROP_SAVE (width, "semi-condensed"); + else if (PROP_MATCH ("Condensed")) + PROP_SAVE (width, "condensed"); + /* An unknown word must be part of the font name. */ + else { - prop_found = 1; - prop = font_intern_prop ("condensed", 9, 1); - FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop); + family_end = p; + break; } - else { - if (prop_found) - return -1; /* Unknown property in GTK-style font name. */ - family_end = q; - } } #undef PROP_MATCH +#undef PROP_SAVE if (family_end) - { - Lisp_Object family; - family = font_intern_prop (name, family_end - name, 1); - ASET (font, FONT_FAMILY_INDEX, family); - } + ASET (font, FONT_FAMILY_INDEX, + font_intern_prop (name, family_end - name, 1)); + if (!NILP (size)) + ASET (font, FONT_SIZE_INDEX, size); + if (!NILP (weight)) + FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, weight); + if (!NILP (slant)) + FONT_SET_STYLE (font, FONT_SLANT_INDEX, slant); + if (!NILP (width)) + FONT_SET_STYLE (font, FONT_WIDTH_INDEX, width); } return 0; @@ -1571,7 +1543,7 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) int i, len = 1; char *p; Lisp_Object styles[3]; - char *style_names[3] = { "weight", "slant", "width" }; + const char *style_names[3] = { "weight", "slant", "width" }; char work[256]; family = AREF (font, FONT_FAMILY_INDEX); @@ -1629,15 +1601,15 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) len += strlen (":scalable=false"); /* or ":scalable=true" */ for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) { - Lisp_Object key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); + Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail)); len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */ - if (STRINGP (val)) - len += SBYTES (val); - else if (INTEGERP (val)) - len += sprintf (work, "%ld", (long) XINT (val)); - else if (SYMBOLP (val)) - len += (NILP (val) ? 5 : 4); /* for "false" or "true" */ + if (STRINGP (value)) + len += SBYTES (value); + else if (INTEGERP (value)) + len += sprintf (work, "%ld", (long) XINT (value)); + else if (SYMBOLP (value)) + len += (NILP (value) ? 5 : 4); /* for "false" or "true" */ } if (len > nbytes) @@ -1676,90 +1648,6 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) return (p - name); } -/* Store GTK-style font name of FONT (font-spec or font-entity) in - NAME (NBYTES length), and return the name length. F is the frame - on which the font is displayed; it is used to calculate the point - size. */ - -int -font_unparse_gtkname (Lisp_Object font, struct frame *f, char *name, int nbytes) -{ - char *p; - int len = 1; - Lisp_Object family, weight, slant, size; - int point_size = -1; - - family = AREF (font, FONT_FAMILY_INDEX); - if (! NILP (family)) - { - if (! SYMBOLP (family)) - return -1; - family = SYMBOL_NAME (family); - len += SBYTES (family); - } - - weight = font_style_symbolic (font, FONT_WEIGHT_INDEX, 0); - if (EQ (weight, Qnormal)) - weight = Qnil; - else if (! NILP (weight)) - { - weight = SYMBOL_NAME (weight); - len += SBYTES (weight); - } - - slant = font_style_symbolic (font, FONT_SLANT_INDEX, 0); - if (EQ (slant, Qnormal)) - slant = Qnil; - else if (! NILP (slant)) - { - slant = SYMBOL_NAME (slant); - len += SBYTES (slant); - } - - size = AREF (font, FONT_SIZE_INDEX); - /* Convert pixel size to point size. */ - if (INTEGERP (size)) - { - Lisp_Object font_dpi = AREF (font, FONT_DPI_INDEX); - int dpi = 75; - if (INTEGERP (font_dpi)) - dpi = XINT (font_dpi); - else if (f) - dpi = f->resy; - point_size = PIXEL_TO_POINT (XINT (size), dpi); - len += 11; - } - else if (FLOATP (size)) - { - point_size = (int) XFLOAT_DATA (size); - len += 11; - } - - if (len > nbytes) - return -1; - - p = name + sprintf (name, "%s", SDATA (family)); - - if (! NILP (weight)) - { - char *q = p; - p += sprintf (p, " %s", SDATA (weight)); - q[1] = toupper (q[1]); - } - - if (! NILP (slant)) - { - char *q = p; - p += sprintf (p, " %s", SDATA (slant)); - q[1] = toupper (q[1]); - } - - if (point_size > 0) - p += sprintf (p, " %d", point_size); - - return (p - name); -} - /* Parse NAME (null terminated) and store information in FONT (font-spec or font-entity). If NAME is successfully parsed, return 0. Otherwise return -1. */ @@ -1788,7 +1676,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec { CHECK_STRING (family); len = SBYTES (family); - p0 = (char *) SDATA (family); + p0 = SSDATA (family); p1 = strchr (p0, '-'); if (p1) { @@ -1807,7 +1695,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec /* Convert "XXX" and "XXX*" to "XXX*-*". */ CHECK_STRING (registry); len = SBYTES (registry); - p0 = (char *) SDATA (registry); + p0 = SSDATA (registry); p1 = strchr (p0, '-'); if (! p1) { @@ -1940,7 +1828,7 @@ otf_open (file) otf = XSAVE_VALUE (XCDR (val))->pointer; else { - otf = STRINGP (file) ? OTF_open ((char *) SDATA (file)) : NULL; + otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; val = make_save_value (otf, 0); otf_list = Fcons (Fcons (file, val), otf_list); } @@ -2711,7 +2599,7 @@ static Lisp_Object scratch_font_spec, scratch_font_prefer; (2) doesn't match with any regexps in Vface_ignored_fonts (if non-nil). */ -Lisp_Object +static Lisp_Object font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) { Lisp_Object entity, val; @@ -2915,7 +2803,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size) Lisp_Object objlist, size, val, font_object; struct font *font; int min_width, height; - int scaled_pixel_size; + int scaled_pixel_size = pixel_size; font_assert (FONT_ENTITY_P (entity)); size = AREF (entity, FONT_SIZE_INDEX); @@ -3039,7 +2927,7 @@ font_has_char (FRAME_PTR f, Lisp_Object font, int c) /* Return the glyph ID of FONT_OBJECT for character C. */ -unsigned +static unsigned font_encode_char (Lisp_Object font_object, int c) { struct font *font; @@ -3060,22 +2948,6 @@ font_get_name (Lisp_Object font_object) } -/* Return the specification of FONT_OBJECT. */ - -Lisp_Object -font_get_spec (Lisp_Object font_object) -{ - Lisp_Object spec = font_make_spec (); - int i; - - for (i = 0; i < FONT_SIZE_INDEX; i++) - ASET (spec, i, AREF (font_object, i)); - ASET (spec, FONT_SIZE_INDEX, - make_number (XFONT_OBJECT (font_object)->pixel_size)); - return spec; -} - - /* Create a new font spec from FONT_NAME, and return it. If FONT_NAME could not be parsed by font_parse_name, return Qnil. */ @@ -3085,7 +2957,7 @@ font_spec_from_name (Lisp_Object font_name) Lisp_Object spec = Ffont_spec (0, NULL); CHECK_STRING (font_name); - if (font_parse_name ((char *) SDATA (font_name), spec) == -1) + if (font_parse_name (SSDATA (font_name), spec) == -1) return Qnil; font_put_extra (spec, QCname, font_name); font_put_extra (spec, QCuser_spec, font_name); @@ -3144,50 +3016,6 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop) attrs[LFACE_FONT_INDEX] = font; } -void -font_update_lface (FRAME_PTR f, Lisp_Object *attrs) -{ - Lisp_Object spec; - - spec = attrs[LFACE_FONT_INDEX]; - if (! FONT_SPEC_P (spec)) - return; - - if (! NILP (AREF (spec, FONT_FOUNDRY_INDEX))) - attrs[LFACE_FOUNDRY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FOUNDRY_INDEX)); - if (! NILP (AREF (spec, FONT_FAMILY_INDEX))) - attrs[LFACE_FAMILY_INDEX] = SYMBOL_NAME (AREF (spec, FONT_FAMILY_INDEX)); - if (! NILP (AREF (spec, FONT_WEIGHT_INDEX))) - attrs[LFACE_WEIGHT_INDEX] = FONT_WEIGHT_FOR_FACE (spec); - if (! NILP (AREF (spec, FONT_SLANT_INDEX))) - attrs[LFACE_SLANT_INDEX] = FONT_SLANT_FOR_FACE (spec); - if (! NILP (AREF (spec, FONT_WIDTH_INDEX))) - attrs[LFACE_SWIDTH_INDEX] = FONT_WIDTH_FOR_FACE (spec); - if (! NILP (AREF (spec, FONT_SIZE_INDEX))) - { - int point; - - if (INTEGERP (AREF (spec, FONT_SIZE_INDEX))) - { - Lisp_Object val; - int dpi = f->resy; - - val = Ffont_get (spec, QCdpi); - if (! NILP (val)) - dpi = XINT (val); - point = PIXEL_TO_POINT (XINT (AREF (spec, FONT_SIZE_INDEX)) * 10, - dpi); - attrs[LFACE_HEIGHT_INDEX] = make_number (point); - } - else if (FLOATP (AREF (spec, FONT_SIZE_INDEX))) - { - point = XFLOAT_DATA (AREF (spec, FONT_SIZE_INDEX)) * 10; - attrs[LFACE_HEIGHT_INDEX] = make_number (point); - } - } -} - - /* Selecte a font from ENTITIES (list of font-entity vectors) that supports C and matches best with ATTRS and PIXEL_SIZE. */ @@ -3274,7 +3102,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) XSETFRAME (frame, f); size = AREF (spec, FONT_SIZE_INDEX); pixel_size = font_pixel_size (f, spec); - if (pixel_size == 0) + if (pixel_size == 0 && INTEGERP (attrs[LFACE_HEIGHT_INDEX])) { double pt = XINT (attrs[LFACE_HEIGHT_INDEX]); @@ -3287,7 +3115,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) else if (STRINGP (attrs[LFACE_FOUNDRY_INDEX])) { val = attrs[LFACE_FOUNDRY_INDEX]; - foundry[0] = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1); + foundry[0] = font_intern_prop (SSDATA (val), SBYTES (val), 1); foundry[1] = Qnil; foundry[2] = null_vector; } @@ -3318,7 +3146,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c) if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX])) { val = attrs[LFACE_FAMILY_INDEX]; - val = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1); + val = font_intern_prop (SSDATA (val), SBYTES (val), 1); } if (NILP (val)) { @@ -3444,7 +3272,7 @@ font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec) if (NILP (entity)) return Qnil; } - /* Don't loose the original name that was put in initially. We need + /* Don't lose the original name that was put in initially. We need it to re-apply the font when font parameters (like hinting or dpi) have changed. */ entity = font_open_for_lface (f, entity, attrs, spec); @@ -3506,7 +3334,7 @@ font_open_by_spec (FRAME_PTR f, Lisp_Object spec) found, return Qnil. */ Lisp_Object -font_open_by_name (FRAME_PTR f, char *name) +font_open_by_name (FRAME_PTR f, const char *name) { Lisp_Object args[2]; Lisp_Object spec, ret; @@ -3515,7 +3343,7 @@ font_open_by_name (FRAME_PTR f, char *name) args[1] = make_unibyte_string (name, strlen (name)); spec = Ffont_spec (2, args); ret = font_open_by_spec (f, spec); - /* Do not loose name originally put in. */ + /* Do not lose name originally put in. */ if (!NILP (ret)) font_put_extra (ret, QCuser_spec, args[1]); @@ -3589,14 +3417,13 @@ Lisp_Object font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers) { Lisp_Object active_drivers = Qnil; - struct font_driver *driver; struct font_driver_list *list; /* At first, turn off non-requested drivers, and turn on requested drivers. */ for (list = f->font_driver_list; list; list = list->next) { - driver = list->driver; + struct font_driver *driver = list->driver; if ((EQ (new_drivers, Qt) || ! NILP (Fmemq (driver->type, new_drivers))) != list->on) { @@ -3724,20 +3551,73 @@ font_get_frame_data (FRAME_PTR f, struct font_driver *driver) } +/* Sets attributes on a font. Any properties that appear in ALIST and + BOOLEAN_PROPERTIES or NON_BOOLEAN_PROPERTIES are set on the font. + BOOLEAN_PROPERTIES and NON_BOOLEAN_PROPERTIES are NULL-terminated + arrays of strings. This function is intended for use by the font + drivers to implement their specific font_filter_properties. */ +void +font_filter_properties (Lisp_Object font, + Lisp_Object alist, + const char *const boolean_properties[], + const char *const non_boolean_properties[]) +{ + Lisp_Object it; + int i; + + /* Set boolean values to Qt or Qnil */ + for (i = 0; boolean_properties[i] != NULL; ++i) + for (it = alist; ! NILP (it); it = XCDR (it)) + { + Lisp_Object key = XCAR (XCAR (it)); + Lisp_Object val = XCDR (XCAR (it)); + char *keystr = SSDATA (SYMBOL_NAME (key)); + + if (strcmp (boolean_properties[i], keystr) == 0) + { + const char *str = INTEGERP (val) ? (XINT (val) ? "true" : "false") + : SYMBOLP (val) ? SSDATA (SYMBOL_NAME (val)) + : "true"; + + if (strcmp ("false", str) == 0 || strcmp ("False", str) == 0 + || strcmp ("FALSE", str) == 0 || strcmp ("FcFalse", str) == 0 + || strcmp ("off", str) == 0 || strcmp ("OFF", str) == 0 + || strcmp ("Off", str) == 0) + val = Qnil; + else + val = Qt; + + Ffont_put (font, key, val); + } + } + + for (i = 0; non_boolean_properties[i] != NULL; ++i) + for (it = alist; ! NILP (it); it = XCDR (it)) + { + Lisp_Object key = XCAR (XCAR (it)); + Lisp_Object val = XCDR (XCAR (it)); + char *keystr = SSDATA (SYMBOL_NAME (key)); + if (strcmp (non_boolean_properties[i], keystr) == 0) + Ffont_put (font, key, val); + } +} + + /* Return the font used to draw character C by FACE at buffer position POS in window W. If STRING is non-nil, it is a string containing C at index POS. If C is negative, get C from the current buffer or STRING. */ -Lisp_Object -font_at (int c, EMACS_INT pos, struct face *face, struct window *w, Lisp_Object string) +static Lisp_Object +font_at (int c, EMACS_INT pos, struct face *face, struct window *w, + Lisp_Object string) { FRAME_PTR f; int multibyte; Lisp_Object font_object; multibyte = (NILP (string) - ? ! NILP (current_buffer->enable_multibyte_characters) + ? ! NILP (BVAR (current_buffer, enable_multibyte_characters)) : STRING_MULTIBYTE (string)); if (c < 0) { @@ -3966,7 +3846,7 @@ usage: (font-spec ARGS...) */) if (EQ (key, QCname)) { CHECK_STRING (val); - font_parse_name ((char *) SDATA (val), spec); + font_parse_name (SSDATA (val), spec); font_put_extra (spec, key, val); } else @@ -4082,7 +3962,6 @@ Layout tags. */) val = fontp->driver->otf_capability (fontp); else val = Fcons (Qnil, Qnil); - font_put_extra (font, QCotf, val); } else val = Fcdr (val); @@ -4326,7 +4205,7 @@ the consecutive wildcards are folded to one. */) { if (NILP (fold_wildcards)) return font_name; - strcpy (name, (char *) SDATA (font_name)); + strcpy (name, SSDATA (font_name)); goto done; } pixel_size = XFONT_OBJECT (font)->pixel_size; @@ -4487,7 +4366,7 @@ DEFUN ("font-variation-glyphs", Ffont_variation_glyphs, Sfont_variation_glyphs, doc: /* Return a list of variation glyphs for CHAR in FONT-OBJECT. Each element of the value is a cons (VARIATION-SELECTOR . GLYPH-ID), where - VARIATION-SELECTOR is a chracter code of variation selection + VARIATION-SELECTOR is a character code of variation selection (#xFE00..#xFE0F or #xE0100..#xE01EF) GLYPH-ID is a glyph code of the corresponding variation glyph. */) (Lisp_Object font_object, Lisp_Object character) @@ -4770,7 +4649,7 @@ the corresponding element is nil. */) Lisp_Object object) { struct font *font; - int i, len, c; + int i, len; Lisp_Object *chars, vec; USE_SAFE_ALLOCA; @@ -4788,6 +4667,7 @@ the corresponding element is nil. */) bytepos = CHAR_TO_BYTE (charpos); for (i = 0; charpos < XFASTINT (to); i++) { + int c; FETCH_CHAR_ADVANCE (c, charpos, bytepos); chars[i] = make_number (c); } @@ -4809,7 +4689,7 @@ the corresponding element is nil. */) if (STRING_MULTIBYTE (object)) for (i = 0; i < len; i++) { - c = STRING_CHAR_ADVANCE (p); + int c = STRING_CHAR_ADVANCE (p); chars[i] = make_number (c); } else @@ -4989,7 +4869,7 @@ If the named font is not yet loaded, return nil. */) if (fontset >= 0) name = fontset_ascii (fontset); - font_object = font_open_by_name (f, (char *) SDATA (name)); + font_object = font_open_by_name (f, SSDATA (name)); } else if (FONT_OBJECT_P (name)) font_object = name; @@ -5048,8 +4928,6 @@ build_style_table (const struct table_entry *entry, int nelement) return table; } -Lisp_Object Vfont_log; - /* The deferred font-log data of the form [ACTION ARG RESULT]. If ACTION is not nil, that is added to the log when font_add_log is called next time. At that time, ACTION is set back to nil. */ @@ -5060,16 +4938,16 @@ static Lisp_Object Vfont_log_deferred; opening), ARG is the argument for the action, and RESULT is the result of the action. */ void -font_add_log (char *action, Lisp_Object arg, Lisp_Object result) +font_add_log (const char *action, Lisp_Object arg, Lisp_Object result) { - Lisp_Object tail, val; + Lisp_Object val; int i; if (EQ (Vfont_log, Qt)) return; if (STRINGP (AREF (Vfont_log_deferred, 0))) { - char *str = (char *) SDATA (AREF (Vfont_log_deferred, 0)); + char *str = SSDATA (AREF (Vfont_log_deferred, 0)); ASET (Vfont_log_deferred, 0, Qnil); font_add_log (str, AREF (Vfont_log_deferred, 1), @@ -5118,6 +4996,7 @@ font_add_log (char *action, Lisp_Object arg, Lisp_Object result) } else if (CONSP (result)) { + Lisp_Object tail; result = Fcopy_sequence (result); for (tail = result; CONSP (tail); tail = XCDR (tail)) { @@ -5146,7 +5025,7 @@ font_add_log (char *action, Lisp_Object arg, Lisp_Object result) as font_add_log. */ void -font_deferred_log (char *action, Lisp_Object arg, Lisp_Object result) +font_deferred_log (const char *action, Lisp_Object arg, Lisp_Object result) { if (EQ (Vfont_log, Qt)) return; @@ -5255,7 +5134,7 @@ syms_of_font (void) defsubr (&Sfont_info); #endif - DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, + DEFVAR_LISP ("font-encoding-alist", Vfont_encoding_alist, doc: /* Alist of fontname patterns vs the corresponding encoding and repertory info. Each element looks like (REGEXP . (ENCODING . REPERTORY)), @@ -5282,7 +5161,7 @@ gets the repertory information by an opened font and ENCODING. */); table used by the font display code. So we make them read-only, to avoid this confusing situation. */ - DEFVAR_LISP_NOPRO ("font-weight-table", &Vfont_weight_table, + DEFVAR_LISP_NOPRO ("font-weight-table", Vfont_weight_table, doc: /* Vector of valid font weight values. Each element has the form: [NUMERIC-VALUE SYMBOLIC-NAME ALIAS-NAME ...] @@ -5290,13 +5169,13 @@ NUMERIC-VALUE is an integer, and SYMBOLIC-NAME and ALIAS-NAME are symbols. */); Vfont_weight_table = BUILD_STYLE_TABLE (weight_table); XSYMBOL (intern_c_string ("font-weight-table"))->constant = 1; - DEFVAR_LISP_NOPRO ("font-slant-table", &Vfont_slant_table, + DEFVAR_LISP_NOPRO ("font-slant-table", Vfont_slant_table, doc: /* Vector of font slant symbols vs the corresponding numeric values. See `font-weight-table' for the format of the vector. */); Vfont_slant_table = BUILD_STYLE_TABLE (slant_table); XSYMBOL (intern_c_string ("font-slant-table"))->constant = 1; - DEFVAR_LISP_NOPRO ("font-width-table", &Vfont_width_table, + DEFVAR_LISP_NOPRO ("font-width-table", Vfont_width_table, doc: /* Alist of font width symbols vs the corresponding numeric values. See `font-weight-table' for the format of the vector. */); Vfont_width_table = BUILD_STYLE_TABLE (width_table); @@ -5308,7 +5187,7 @@ See `font-weight-table' for the format of the vector. */); ASET (font_style_table, 1, Vfont_slant_table); ASET (font_style_table, 2, Vfont_width_table); - DEFVAR_LISP ("font-log", &Vfont_log, doc: /* + DEFVAR_LISP ("font-log", Vfont_log, doc: /* *Logging list of font related actions and results. The value t means to suppress the logging. The initial value is set to nil if the environment variable @@ -5347,6 +5226,3 @@ init_font (void) { Vfont_log = egetenv ("EMACS_FONT_LOG") ? Qnil : Qt; } - -/* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846 - (do not change this comment) */