Commit 03feb937 authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu

Make Cairo build obey hint-style font setting (Bug#35781)

* src/ftfont.h (ftfont_open2): Remove extern.
(ftfont_fix_match, ftfont_add_rendering_parameters)
(ftfont_entity_pattern): Add externs.
(struct font_info): Remove member bitmap_strike_index.
(struct font_info) [USE_CAIRO]: Remove member ft_size_draw.  All uses removed.
Add member bitmap_position_unit.

* src/xftfont.c (xftfont_fix_match, xftfont_add_rendering_parameters): Move
functions from here ...
* src/ftfont.c (ftfont_fix_match, ftfont_add_rendering_parameters): ... to
here.  All uses changed.
* src/xftfont.c (xftfont_open): Extract FcPattern creation from font entity
from here ...
* src/ftfont.c (ftfont_entity_pattern):	... to here.
* src/xftfont.c (syms_of_xftfont): Move DEFSYMs for Fontconfig's rendering
parameters from here ...
* src/ftfont.c (syms_of_ftfont): ... to here.

* src/ftfont.c (ftfont_open, ftfont_open2): Undo introduction of
bitmap_strike_index.  Merge functions into ftfont_open.

* src/ftcrfont.c (ftcrfont_open): Align code with xftfont_open rather than
ftfont_open.
(ftcrfont_close): Likewise.
(ftcrfont_has_char, ftcrfont_encode_char):
(ftcrfont_otf_capability) [HAVE_LIBOTF]:
(ftcrfont_variation_glyphs) [HAVE_OTF_GET_VARIATION_GLYPHS]: New functions.
(ftcrfont_driver): Register them.
(ftcrfont_get_bitmap, ftcrfont_anchor_point):
(ftcrfont_shape) [HAVE_M17N_FLT && HAVE_LIBOTF]: Use bitmap_position_unit
instead of bitmap_strike_index to screen bitmap fonts.
(ftcrfont_get_bitmap, ftcrfont_anchor_point):
(ftcrfont_otf_capability) [HAVE_LIBOTF]:
(ftcrfont_shape) [HAVE_M17N_FLT && HAVE_LIBOTF]:
(ftcrfont_variation_glyphs) [HAVE_OTF_GET_VARIATION_GLYPHS]: Temporarily
assign ftcrfont_info->ft_size and call corresponding ftfont functions.
(ftcrfont_draw): Don't flush cairo surface when exporting.
parent 72047556
Pipeline #1777 failed with stage
in 64 minutes and 12 seconds
......@@ -79,7 +79,6 @@ ftcrfont_glyph_extents (struct font *font,
cairo_glyph_t cr_glyph = {.index = glyph};
cairo_text_extents_t extents;
FT_Activate_Size (ftcrfont_info->ft_size_draw);
cairo_scaled_font_glyph_extents (ftcrfont_info->cr_scaled_font,
&cr_glyph, 1, &extents);
cache->lbearing = floor (extents.x_bearing);
......@@ -118,103 +117,159 @@ ftcrfont_match (struct frame *f, Lisp_Object spec)
static Lisp_Object
ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
Lisp_Object font_object;
FT_UInt size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
FcResult result;
Lisp_Object val, filename, font_object;
FcPattern *pat, *match;
struct font_info *ftcrfont_info;
struct font *font;
double size = 0;
cairo_font_face_t *font_face;
cairo_font_extents_t extents;
FT_Face ft_face;
FcMatrix *matrix;
val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
if (! CONSP (val))
return Qnil;
val = XCDR (val);
filename = XCAR (val);
size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
if (size == 0)
size = pixel_size;
block_input ();
pat = ftfont_entity_pattern (entity, pixel_size);
FcConfigSubstitute (NULL, pat, FcMatchPattern);
FcDefaultSubstitute (pat);
match = FcFontMatch (NULL, pat, &result);
ftfont_fix_match (pat, match);
FcPatternDestroy (pat);
font_face = cairo_ft_font_face_create_for_pattern (match);
if (!font_face)
{
unblock_input ();
FcPatternDestroy (match);
return Qnil;
}
cairo_matrix_t font_matrix, ctm;
cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
cairo_matrix_init_identity (&ctm);
cairo_font_options_t *options = cairo_font_options_create ();
cairo_scaled_font_t *scaled_font
= cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
cairo_font_face_destroy (font_face);
cairo_font_options_destroy (options);
unblock_input ();
font_object = font_build_object (VECSIZE (struct font_info),
Qftcr, entity, size);
ASET (font_object, FONT_FILE_INDEX, filename);
font = XFONT_OBJECT (font_object);
font->pixel_size = size;
font->driver = &ftcrfont_driver;
font->encoding_charset = font->repertory_charset = -1;
ftcrfont_info = (struct font_info *) font;
ftcrfont_info->cr_scaled_font = scaled_font;
/* This means that there's no need of transformation. */
ftcrfont_info->matrix.xx = 0;
if (FcPatternGetMatrix (match, FC_MATRIX, 0, &matrix) == FcResultMatch)
{
ftcrfont_info->matrix.xx = 0x10000L * matrix->xx;
ftcrfont_info->matrix.yy = 0x10000L * matrix->yy;
ftcrfont_info->matrix.xy = 0x10000L * matrix->xy;
ftcrfont_info->matrix.yx = 0x10000L * matrix->yx;
}
ftcrfont_info->metrics = NULL;
ftcrfont_info->metrics_nrows = 0;
block_input ();
font_object = ftfont_open2 (f, entity, pixel_size, font_object);
if (FONT_OBJECT_P (font_object))
cairo_glyph_t stack_glyph;
int n = 0;
font->min_width = font->average_width = font->space_width = 0;
for (char c = 32; c < 127; c++)
{
struct font *font = XFONT_OBJECT (font_object);
struct font_info *ftcrfont_info = (struct font_info *) font;
FT_Face ft_face = ftcrfont_info->ft_size->face;
font->driver = &ftcrfont_driver;
FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw);
FT_Activate_Size (ftcrfont_info->ft_size_draw);
if (ftcrfont_info->bitmap_strike_index < 0)
FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
else
FT_Select_Size (ft_face, ftcrfont_info->bitmap_strike_index);
cairo_font_face_t *font_face =
cairo_ft_font_face_create_for_ft_face (ft_face, 0);
cairo_matrix_t font_matrix, ctm;
cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
cairo_matrix_init_identity (&ctm);
cairo_font_options_t *options = cairo_font_options_create ();
ftcrfont_info->cr_scaled_font =
cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
cairo_font_face_destroy (font_face);
cairo_font_options_destroy (options);
ftcrfont_info->metrics = NULL;
ftcrfont_info->metrics_nrows = 0;
if (ftcrfont_info->bitmap_strike_index >= 0)
cairo_glyph_t *glyphs = &stack_glyph;
int num_glyphs = 1;
cairo_status_t status =
cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
0, 0, &c, 1, &glyphs, &num_glyphs,
NULL, NULL, NULL);
if (status == CAIRO_STATUS_SUCCESS)
{
/* Several members of struct font/font_info set by
ftfont_open2 are bogus. Recalculate them with cairo
scaled font functions. */
cairo_font_extents_t extents;
cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
font->ascent = lround (extents.ascent);
Lisp_Object val = assq_no_quit (QCminspace,
AREF (entity, FONT_EXTRA_INDEX));
if (!(CONSP (val) && NILP (XCDR (val))))
{
font->descent = lround (extents.descent);
font->height = font->ascent + font->descent;
}
else
if (glyphs != &stack_glyph)
cairo_glyph_free (glyphs);
else if (stack_glyph.index)
{
font->height = lround (extents.height);
font->descent = font->height - font->ascent;
int this_width = ftcrfont_glyph_extents (font, stack_glyph.index,
NULL);
if (this_width > 0
&& (! font->min_width
|| font->min_width > this_width))
font->min_width = this_width;
if (c == 32)
font->space_width = this_width;
font->average_width += this_width;
n++;
}
}
}
if (n > 0)
font->average_width /= n;
cairo_glyph_t stack_glyph;
int n = 0;
font->min_width = font->average_width = font->space_width = 0;
for (char c = 32; c < 127; c++)
{
cairo_glyph_t *glyphs = &stack_glyph;
int num_glyphs = 1;
cairo_status_t status =
cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
0, 0, &c, 1,
&glyphs, &num_glyphs,
NULL, NULL, NULL);
if (status == CAIRO_STATUS_SUCCESS)
{
if (glyphs != &stack_glyph)
cairo_glyph_free (glyphs);
else if (stack_glyph.index)
{
int this_width =
ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
if (this_width > 0
&& (! font->min_width
|| font->min_width > this_width))
font->min_width = this_width;
if (c == 32)
font->space_width = this_width;
font->average_width += this_width;
n++;
}
}
}
if (n > 0)
font->average_width /= n;
cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
font->ascent = lround (extents.ascent);
val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
if (!(CONSP (val) && NILP (XCDR (val))))
{
font->descent = lround (extents.descent);
font->height = font->ascent + font->descent;
}
else
{
font->height = lround (extents.height);
font->descent = font->height - font->ascent;
}
font->underline_position = -1;
font->underline_thickness = 0;
}
ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) == 0)
{
int upEM = ft_face->units_per_EM;
font->underline_position = -ft_face->underline_position * size / upEM;
font->underline_thickness = ft_face->underline_thickness * size / upEM;
if (font->underline_thickness > 2)
font->underline_position -= font->underline_thickness / 2;
}
else
{
font->underline_position = -1;
font->underline_thickness = 0;
}
#ifdef HAVE_LIBOTF
ftcrfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
ftcrfont_info->otf = NULL;
#endif /* HAVE_LIBOTF */
if (ft_face->units_per_EM)
ftcrfont_info->bitmap_position_unit = 0;
else
ftcrfont_info->bitmap_position_unit = (extents.height
/ ft_face->size->metrics.height);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
unblock_input ();
font->baseline_offset = 0;
font->relative_compose = 0;
font->default_ascent = 0;
font->vertical_centering = false;
return font_object;
}
......@@ -225,19 +280,58 @@ ftcrfont_close (struct font *font)
return;
struct font_info *ftcrfont_info = (struct font_info *) font;
int i;
block_input ();
for (i = 0; i < ftcrfont_info->metrics_nrows; i++)
#ifdef HAVE_LIBOTF
if (ftcrfont_info->otf)
{
OTF_close (ftcrfont_info->otf);
ftcrfont_info->otf = NULL;
}
#endif
for (int i = 0; i < ftcrfont_info->metrics_nrows; i++)
if (ftcrfont_info->metrics[i])
xfree (ftcrfont_info->metrics[i]);
if (ftcrfont_info->metrics)
xfree (ftcrfont_info->metrics);
FT_Done_Size (ftcrfont_info->ft_size_draw);
cairo_scaled_font_destroy (ftcrfont_info->cr_scaled_font);
unblock_input ();
}
static int
ftcrfont_has_char (Lisp_Object font, int c)
{
if (FONT_ENTITY_P (font))
return ftfont_has_char (font, c);
ftfont_close (font);
return -1;
}
static unsigned
ftcrfont_encode_char (struct font *font, int c)
{
struct font_info *ftcrfont_info = (struct font_info *) font;
unsigned code = FONT_INVALID_CODE;
unsigned char utf8[MAX_MULTIBYTE_LENGTH];
unsigned char *p = utf8;
cairo_glyph_t stack_glyph;
cairo_glyph_t *glyphs = &stack_glyph;
int num_glyphs = 1;
CHAR_STRING_ADVANCE (c, p);
if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
(char *) utf8, p - utf8,
&glyphs, &num_glyphs,
NULL, NULL, NULL)
== CAIRO_STATUS_SUCCESS)
{
if (glyphs != &stack_glyph)
cairo_glyph_free (glyphs);
else if (stack_glyph.index)
code = stack_glyph.index;
}
return code;
}
static void
......@@ -280,10 +374,18 @@ ftcrfont_get_bitmap (struct font *font, unsigned int code,
{
struct font_info *ftcrfont_info = (struct font_info *) font;
if (ftcrfont_info->bitmap_strike_index < 0)
return ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
if (ftcrfont_info->bitmap_position_unit)
return -1;
return -1;
cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
ftcrfont_info->ft_size = ft_face->size;
int result = ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
return result;
}
static int
......@@ -292,25 +394,75 @@ ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
{
struct font_info *ftcrfont_info = (struct font_info *) font;
if (ftcrfont_info->bitmap_strike_index < 0)
return ftfont_anchor_point (font, code, idx, x, y);
if (ftcrfont_info->bitmap_position_unit)
return -1;
return -1;
cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
ftcrfont_info->ft_size = ft_face->size;
int result = ftfont_anchor_point (font, code, idx, x, y);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
return result;
}
#ifdef HAVE_LIBOTF
static Lisp_Object
ftcrfont_shape (Lisp_Object lgstring)
ftcrfont_otf_capability (struct font *font)
{
struct font_info *ftcrfont_info = (struct font_info *) font;
cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
ftcrfont_info->ft_size = ft_face->size;
Lisp_Object result = ftfont_otf_capability (font);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
return result;
}
#endif
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
static Lisp_Object
ftcrfont_shape (Lisp_Object lgstring)
{
struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
struct font_info *ftcrfont_info = (struct font_info *) font;
if (ftcrfont_info->bitmap_strike_index < 0)
return ftfont_shape (lgstring);
if (ftcrfont_info->bitmap_position_unit)
return make_fixnum (0);
cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
ftcrfont_info->ft_size = ft_face->size;
Lisp_Object result = ftfont_shape (lgstring);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
return result;
}
#endif
return make_fixnum (0);
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
static int
ftcrfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
{
struct font_info *ftcrfont_info = (struct font_info *) font;
cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
ftcrfont_info->ft_size = ft_face->size;
int result = ftfont_variation_glyphs (font, c, variations);
cairo_ft_scaled_font_unlock_face (scaled_font);
ftcrfont_info->ft_size = NULL;
return result;
}
#endif /* HAVE_OTF_GET_VARIATION_GLYPHS */
static int
ftcrfont_draw (struct glyph_string *s,
......@@ -321,8 +473,6 @@ ftcrfont_draw (struct glyph_string *s,
struct font_info *ftcrfont_info = (struct font_info *) s->font;
cairo_t *cr;
cairo_glyph_t *glyphs;
cairo_surface_t *surface;
cairo_surface_type_t surface_type;
int len = to - from;
int i;
......@@ -351,17 +501,7 @@ ftcrfont_draw (struct glyph_string *s,
x_set_cr_source_with_gc_foreground (f, s->gc);
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
FT_Activate_Size (ftcrfont_info->ft_size_draw);
cairo_show_glyphs (cr, glyphs, len);
surface = cairo_get_target (cr);
/* XXX: It used to be necessary to flush when exporting. It might
be the case that this is no longer necessary. */
surface_type = cairo_surface_get_type (surface);
if (surface_type != CAIRO_SURFACE_TYPE_XLIB
&& (surface_type != CAIRO_SURFACE_TYPE_IMAGE
|| cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32))
cairo_surface_flush (surface);
x_end_cr_clip (f);
......@@ -383,18 +523,20 @@ struct font_driver const ftcrfont_driver =
.list_family = ftfont_list_family,
.open = ftcrfont_open,
.close = ftcrfont_close,
.has_char = ftfont_has_char,
.encode_char = ftfont_encode_char,
.has_char = ftcrfont_has_char,
.encode_char = ftcrfont_encode_char,
.text_extents = ftcrfont_text_extents,
.draw = ftcrfont_draw,
.get_bitmap = ftcrfont_get_bitmap,
.anchor_point = ftcrfont_anchor_point,
#ifdef HAVE_LIBOTF
.otf_capability = ftfont_otf_capability,
.otf_capability = ftcrfont_otf_capability,
#endif
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
.shape = ftcrfont_shape,
#endif
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
.get_variation_glyphs = ftfont_variation_glyphs,
.get_variation_glyphs = ftcrfont_variation_glyphs,
#endif
.filter_properties = ftfont_filter_properties,
.combining_capability = ftfont_combining_capability,
......
......@@ -1079,12 +1079,159 @@ ftfont_list_family (struct frame *f)
return list;
}
void
ftfont_fix_match (FcPattern *pat, FcPattern *match)
{
/* These values are not used for matching (except antialias), but for
rendering, so make sure they are carried over to the match.
We also put antialias here because most fonts are antialiased, so
the match will have antialias true. */
FcBool b = FcTrue;
int i;
double dpi;
FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
if (! b)
{
FcPatternDel (match, FC_ANTIALIAS);
FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
}
FcPatternGetBool (pat, FC_HINTING, 0, &b);
if (! b)
{
FcPatternDel (match, FC_HINTING);
FcPatternAddBool (match, FC_HINTING, FcFalse);
}
#ifndef FC_HINT_STYLE
# define FC_HINT_STYLE "hintstyle"
#endif
if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
{
FcPatternDel (match, FC_HINT_STYLE);
FcPatternAddInteger (match, FC_HINT_STYLE, i);
}
#ifndef FC_LCD_FILTER
/* Older fontconfig versions don't have FC_LCD_FILTER. */
#define FC_LCD_FILTER "lcdfilter"
#endif
if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
{
FcPatternDel (match, FC_LCD_FILTER);
FcPatternAddInteger (match, FC_LCD_FILTER, i);
}
if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
{
FcPatternDel (match, FC_RGBA);
FcPatternAddInteger (match, FC_RGBA, i);
}
if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
{
FcPatternDel (match, FC_DPI);
FcPatternAddDouble (match, FC_DPI, dpi);
}
}
void
ftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
{
Lisp_Object tail;
int ival;
for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
{
Lisp_Object key = XCAR (XCAR (tail));
Lisp_Object val = XCDR (XCAR (tail));
if (EQ (key, QCantialias))
FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
else if (EQ (key, QChinting))
FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
else if (EQ (key, QCautohint))
FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
else if (EQ (key, QChintstyle))
{
if (FIXNUMP (val))
FcPatternAddInteger (pat, FC_HINT_STYLE, XFIXNUM (val));
else if (SYMBOLP (val)
&& FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
}
else if (EQ (key, QCrgba))
{
if (FIXNUMP (val))
FcPatternAddInteger (pat, FC_RGBA, XFIXNUM (val));
else if (SYMBOLP (val)
&& FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
FcPatternAddInteger (pat, FC_RGBA, ival);
}
else if (EQ (key, QClcdfilter))
{
if (FIXNUMP (val))
FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XFIXNUM (val));
else if (SYMBOLP (val)
&& FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
}
#ifdef FC_EMBOLDEN
else if (EQ (key, QCembolden))
FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
#endif
}
}
FcPattern *
ftfont_entity_pattern (Lisp_Object entity, int pixel_size)
{
Lisp_Object val, filename, idx;
FcPattern *pat;
int i;
val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
eassert (CONSP (val));
val = XCDR (val);
filename = XCAR (val);
idx = XCDR (val);
pat = FcPatternCreate ();
FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
i = FONT_SLANT_NUMERIC (entity) - 100;
if (i < 0) i = 0;
FcPatternAddInteger (pat, FC_SLANT, i);
FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
val = AREF (entity, FONT_FAMILY_INDEX);
if (! NILP (val))
FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
val = AREF (entity, FONT_FOUNDRY_INDEX);
if (! NILP (val))
FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
val = AREF (entity, FONT_SPACING_INDEX);
if (! NILP (val))
FcPatternAddInteger (pat, FC_SPACING, XFIXNUM (val));
val = AREF (entity, FONT_DPI_INDEX);
if (! NILP (val))
{
double dbl = XFIXNUM (val);
FcPatternAddDouble (pat, FC_DPI, dbl);
}
val = AREF (entity, FONT_AVGWIDTH_INDEX);
if (FIXNUMP (val) && XFIXNUM (val) == 0)
FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
/* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
over 10x20-ISO8859-1.pcf.gz). */
FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
ftfont_add_rendering_parameters (pat, entity);