/* xfont.c -- X core font driver.
- Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Copyright (C) 2006-2015 Free Software Foundation, Inc.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
static void xfont_prepare_face (struct frame *, struct face *);
static int xfont_has_char (Lisp_Object, int);
static unsigned xfont_encode_char (struct font *, int);
-static int xfont_text_extents (struct font *, unsigned *, int,
- struct font_metrics *);
+static void xfont_text_extents (struct font *, unsigned *, int,
+ struct font_metrics *);
static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
static int xfont_check (struct frame *, struct font *);
struct font_driver xfont_driver =
{
LISP_INITIALLY_ZERO, /* Qx */
- 0, /* case insensitive */
+ false, /* case insensitive */
xfont_get_cache,
xfont_list,
xfont_match,
xfont_encode_char,
xfont_text_extents,
xfont_draw,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
xfont_check,
NULL, /* get_variation_glyphs */
NULL, /* filter_properties */
}
return (i >= 0);
}
- return 0;
+ return false;
}
/* A hash table recoding which font supports which scripts. Each key
{
char **indices = alloca (sizeof (char *) * num_fonts);
Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
- Lisp_Object scripts = Qnil;
+ Lisp_Object scripts = Qnil, entity = Qnil;
for (i = 0; i < ASIZE (xfont_scratch_props); i++)
ASET (xfont_scratch_props, i, Qnil);
indices[i] = names[i];
qsort (indices, num_fonts, sizeof (char *), compare_font_names);
- for (i = 0; i < num_fonts; i++)
- {
- ptrdiff_t len;
- Lisp_Object entity;
+ /* Take one or two passes over the font list. Do the second
+ pass only if we really need it, i.e., only if the first pass
+ found no fonts and skipped some scalable fonts. */
+ bool skipped_some_scalable_fonts = false;
+ for (int i_pass = 0;
+ (i_pass == 0
+ || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
+ i_pass++)
+ for (i = 0; i < num_fonts; i++)
+ {
+ ptrdiff_t len;
+
+ if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
+ continue;
+ if (NILP (entity))
+ entity = font_make_entity ();
+ len = xfont_decode_coding_xlfd (indices[i], -1, buf);
+ if (font_parse_xlfd (buf, len, entity) < 0)
+ continue;
+ ASET (entity, FONT_TYPE_INDEX, Qx);
+ /* Avoid auto-scaled fonts. */
+ if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
+ && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
+ && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
+ && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
+ continue;
+ /* Avoid not-allowed scalable fonts. */
+ if (NILP (Vscalable_fonts_allowed))
+ {
+ int size = 0;
- if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
- continue;
- entity = font_make_entity ();
- len = xfont_decode_coding_xlfd (indices[i], -1, buf);
- if (font_parse_xlfd (buf, len, entity) < 0)
- continue;
- ASET (entity, FONT_TYPE_INDEX, Qx);
- /* Avoid auto-scaled fonts. */
- if (INTEGERP (AREF (entity, FONT_DPI_INDEX))
- && INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
- && XINT (AREF (entity, FONT_DPI_INDEX)) != 0
- && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
- continue;
- /* Avoid not-allowed scalable fonts. */
- if (NILP (Vscalable_fonts_allowed))
- {
- int size = 0;
+ if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XINT (AREF (entity, FONT_SIZE_INDEX));
+ else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
+ size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
+ if (size == 0 && i_pass == 0)
+ {
+ skipped_some_scalable_fonts = true;
+ continue;
+ }
+ }
+ else if (CONSP (Vscalable_fonts_allowed))
+ {
+ Lisp_Object tail;
- if (INTEGERP (AREF (entity, FONT_SIZE_INDEX)))
- size = XINT (AREF (entity, FONT_SIZE_INDEX));
- else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
- size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
- if (size == 0)
- continue;
- }
- else if (CONSP (Vscalable_fonts_allowed))
- {
- Lisp_Object tail, elt;
-
- for (tail = Vscalable_fonts_allowed; CONSP (tail);
- tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (STRINGP (elt)
- && fast_c_string_match_ignore_case (elt, indices[i],
- len) >= 0)
- break;
- }
- if (! CONSP (tail))
- continue;
- }
+ for (tail = Vscalable_fonts_allowed; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ Lisp_Object elt = XCAR (tail);
+ if (STRINGP (elt)
+ && (fast_c_string_match_ignore_case (elt, indices[i],
+ len)
+ >= 0))
+ break;
+ }
+ if (! CONSP (tail))
+ continue;
+ }
- /* Avoid fonts of invalid registry. */
- if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
- continue;
+ /* Avoid fonts of invalid registry. */
+ if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
+ continue;
- /* Update encoding and repertory if necessary. */
- if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
- {
- registry = AREF (entity, FONT_REGISTRY_INDEX);
- if (font_registry_charsets (registry, &encoding, &repertory) < 0)
- encoding = NULL;
- }
- if (! encoding)
- /* Unknown REGISTRY, not supported. */
- continue;
- if (repertory)
- {
- if (NILP (script)
- || xfont_chars_supported (chars, NULL, encoding, repertory))
- list = Fcons (entity, list);
+ /* Update encoding and repertory if necessary. */
+ if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
+ {
+ registry = AREF (entity, FONT_REGISTRY_INDEX);
+ if (font_registry_charsets (registry, &encoding, &repertory) < 0)
+ encoding = NULL;
+ }
+ if (! encoding)
+ /* Unknown REGISTRY, not supported. */
continue;
- }
- if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
- word_size * 7)
- || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
- {
- vcopy (xfont_scratch_props, 0,
- aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
- ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
- scripts = xfont_supported_scripts (display, indices[i],
- xfont_scratch_props, encoding);
- }
- if (NILP (script)
- || ! NILP (Fmemq (script, scripts)))
- list = Fcons (entity, list);
- }
+ if (repertory)
+ {
+ if (NILP (script)
+ || xfont_chars_supported (chars, NULL, encoding, repertory))
+ list = Fcons (entity, list), entity = Qnil;
+ continue;
+ }
+ if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
+ word_size * 7)
+ || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
+ {
+ vcopy (xfont_scratch_props, 0,
+ aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
+ ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
+ scripts = xfont_supported_scripts (display, indices[i],
+ xfont_scratch_props,
+ encoding);
+ }
+ if (NILP (script)
+ || ! NILP (Fmemq (script, scripts)))
+ list = Fcons (entity, list), entity = Qnil;
+ }
XFreeFontNames (names);
}
if (STRINGP (XCAR (alter))
&& ((r - name) + SBYTES (XCAR (alter))) < 256)
{
- strcpy (r, SSDATA (XCAR (alter)));
+ lispstpcpy (r, XCAR (alter));
list = xfont_list_pattern (display, name, registry, script);
if (! NILP (list))
break;
ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
}
ASET (font_object, FONT_FULLNAME_INDEX, fullname);
- ASET (font_object, FONT_FILE_INDEX, Qnil);
- ASET (font_object, FONT_FORMAT_INDEX, Qx);
font = XFONT_OBJECT (font_object);
((struct xfont_info *) font)->xfont = xfont;
((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
}
-static int
-xfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics)
+static void
+xfont_text_extents (struct font *font, unsigned int *code,
+ int nglyphs, struct font_metrics *metrics)
{
XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
- int width = 0;
- int i, first;
+ int i, width = 0;
+ bool first;
- if (metrics)
- memset (metrics, 0, sizeof (struct font_metrics));
- for (i = 0, first = 1; i < nglyphs; i++)
+ for (i = 0, first = true; i < nglyphs; i++)
{
XChar2b char2b;
static XCharStruct *pcm;
continue;
if (first)
{
- if (metrics)
- {
- metrics->lbearing = pcm->lbearing;
- metrics->rbearing = pcm->rbearing;
- metrics->ascent = pcm->ascent;
- metrics->descent = pcm->descent;
- }
- first = 0;
+ metrics->lbearing = pcm->lbearing;
+ metrics->rbearing = pcm->rbearing;
+ metrics->ascent = pcm->ascent;
+ metrics->descent = pcm->descent;
+ first = false;
}
else
{
- if (metrics)
- {
- if (metrics->lbearing > width + pcm->lbearing)
- metrics->lbearing = width + pcm->lbearing;
- if (metrics->rbearing < width + pcm->rbearing)
- metrics->rbearing = width + pcm->rbearing;
- if (metrics->ascent < pcm->ascent)
- metrics->ascent = pcm->ascent;
- if (metrics->descent < pcm->descent)
- metrics->descent = pcm->descent;
- }
+ if (metrics->lbearing > width + pcm->lbearing)
+ metrics->lbearing = width + pcm->lbearing;
+ if (metrics->rbearing < width + pcm->rbearing)
+ metrics->rbearing = width + pcm->rbearing;
+ if (metrics->ascent < pcm->ascent)
+ metrics->ascent = pcm->ascent;
+ if (metrics->descent < pcm->descent)
+ metrics->descent = pcm->descent;
}
width += pcm->width;
}
- if (metrics)
- metrics->width = width;
- return width;
+
+ metrics->width = width;
}
static int
syms_of_xfont (void)
{
staticpro (&xfont_scripts_cache);
- { /* Here we rely on the fact that syms_of_xfont (via syms_of_font)
- is called fairly late, when QCtest and Qequal are known to be set. */
- Lisp_Object args[2];
- args[0] = QCtest;
- args[1] = Qequal;
- xfont_scripts_cache = Fmake_hash_table (2, args);
- }
+ xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
staticpro (&xfont_scratch_props);
xfont_scratch_props = Fmake_vector (make_number (8), Qnil);
xfont_driver.type = Qx;