[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android dd4924ca90a 5/6: Update Android port
From: |
Po Lu |
Subject: |
feature/android dd4924ca90a 5/6: Update Android port |
Date: |
Mon, 27 Mar 2023 04:45:37 -0400 (EDT) |
branch: feature/android
commit dd4924ca90a8ada26bb10e5df4557ae32c0d6403
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Update Android port
* configure.ac (HAVE_OTF_GET_VARIATION_GLYPHS): Check for
`hb_font_set_var_named_instance'.
* src/sfnt.c (main): Update tests.
* src/sfntfont-android.c (Fandroid_enumerate_fonts): Blacklist
bad font.
* src/sfntfont.c (struct sfnt_font_tables, struct sfnt_font_desc)
(sfnt_decode_instance_name, sfnt_weight_descriptions)
(sfnt_enum_font_1, sfntfont_list_1, sfntfont_desc_to_entity)
(sfntfont_list, struct sfntfont_get_glyph_outline_dcontext)
(sfntfont_get_glyph, sfntfont_get_glyph_outline)
(struct sfnt_font_info, sfnt_close_tables, sfnt_open_tables)
(sfntfont_open, sfntfont_measure_pcm, sfntfont_close)
(sfntfont_draw, sfntfont_begin_hb_font, syms_of_sfntfont)
(mark_sfntfont): Handle variable fonts correctly.
---
configure.ac | 15 +-
src/sfnt.c | 4 +-
src/sfntfont-android.c | 7 +-
src/sfntfont.c | 405 +++++++++++++++++++++++++++++++++++++++++++------
4 files changed, 377 insertions(+), 54 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1097be48e26..760188bf369 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4586,14 +4586,19 @@ if test "${HAVE_X11}" = "yes" && test
"${HAVE_FREETYPE}" = "yes" \
|| test "$REALLY_ANDROID" = "yes"; then
if test "${with_harfbuzz}" != "no"; then
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
- if test "$HAVE_HARFBUZZ" = "yes"; then
+ AS_IF([test "$HAVE_HARFBUZZ" = "yes"],[
AC_DEFINE([HAVE_HARFBUZZ], [1], [Define to 1 if using HarfBuzz.])
### mingw32 and Cygwin-w32 don't use -lharfbuzz, since they load
### the library dynamically.
- if test "${HAVE_W32}" = "yes"; then
- HARFBUZZ_LIBS=
- fi
- fi
+ AS_IF([test "${HAVE_W32}" = "yes"], [HARFBUZZ_LIBS=])
+ ## Now check for `hb_font_set_var_named_instance'.
+ OLD_CFLAGS=$CFLAGS
+ CFLAGS="$HARFBUZZ_CFLAGS $CFLAGS"
+ EMACS_CHECK_LIB([harfbuzz], [hb_font_set_var_named_instance],
+ [AC_DEFINE([HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE], [1],
+ [Define to 1 if `hb_font_set_var_named_instance' is present.])],
+ [], [$HARFBUZZ_LIBS], [#include <hb.h>])
+ CFLAGS=$OLD_CFLAGS])
fi
fi
diff --git a/src/sfnt.c b/src/sfnt.c
index 9a1094a1ca9..99649698557 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -18922,8 +18922,8 @@ main (int argc, char **argv)
return 1;
}
-#define FANCY_PPEM 15
-#define EASY_PPEM 15
+#define FANCY_PPEM 40
+#define EASY_PPEM 40
interpreter = NULL;
head = sfnt_read_head_table (fd, font);
diff --git a/src/sfntfont-android.c b/src/sfntfont-android.c
index 37f43465097..5e4c8fc6c9f 100644
--- a/src/sfntfont-android.c
+++ b/src/sfntfont-android.c
@@ -713,8 +713,11 @@ loaded before character sets are made available. */)
/* If it contains (not ends with!) with .ttf or .ttc, then
enumerate it. */
- if (strstr (dirent->d_name, ".ttf")
- || strstr (dirent->d_name, ".ttc"))
+ if ((strstr (dirent->d_name, ".ttf")
+ || strstr (dirent->d_name, ".ttc"))
+ /* Ignore the non-variable Roboto font. */
+ && (i != 0 || strcmp (dirent->d_name,
+ "RobotoStatic-Regular.ttf")))
{
sprintf (name, "%s/%s", system_font_directories[i],
dirent->d_name);
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 346e145082a..808c8b7c629 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -69,6 +69,10 @@ struct sfnt_font_tables
struct sfnt_prep_table *prep;
struct sfnt_fpgm_table *fpgm;
struct sfnt_cvt_table *cvt;
+ struct sfnt_fvar_table *fvar;
+ struct sfnt_avar_table *avar;
+ struct sfnt_gvar_table *gvar;
+ struct sfnt_cvar_table *cvar;
/* The selected character map. */
struct sfnt_cmap_encoding_subtable_data *cmap_data;
@@ -118,6 +122,11 @@ struct sfnt_font_desc
/* Font registry that this font supports. */
Lisp_Object registry;
+ /* Vector of instances. Each element is another of the instance's
+ `style', `adstyle', and numeric width, weight, and slant. May be
+ nil. */
+ Lisp_Object instances;
+
/* Numeric width, weight, slant and spacing. */
int width, weight, slant, spacing;
@@ -360,6 +369,29 @@ sfnt_decode_foundry_name (struct sfnt_name_table *name)
designer_rec.length);
}
+/* Decode the name of the specified font INSTANCE using the given NAME
+ table. Return the name of that instance, or nil upon failure. */
+
+static Lisp_Object
+sfnt_decode_instance_name (struct sfnt_instance *instance,
+ struct sfnt_name_table *name)
+{
+ struct sfnt_name_record name_rec;
+ unsigned char *name_data;
+
+ name_data = sfnt_find_name (name, instance->name_id,
+ &name_rec);
+
+ if (!name_data)
+ return Qnil;
+
+ return sfnt_decode_font_string (name_data,
+ name_rec.platform_id,
+ name_rec.platform_specific_id,
+ name_rec.language_id,
+ name_rec.length);
+}
+
struct sfnt_style_desc
{
/* The C string to match against. */
@@ -375,6 +407,7 @@ static struct sfnt_style_desc sfnt_weight_descriptions[] =
{ "thin", 0, },
{ "extralight", 40, },
{ "ultralight", 40, },
+ { "light", 50, },
{ "demilight", 55, },
{ "semilight", 55, },
{ "book", 75, },
@@ -809,7 +842,10 @@ sfnt_enum_font_1 (int fd, const char *file,
struct sfnt_name_table *name;
struct sfnt_meta_table *meta;
struct sfnt_maxp_table *maxp;
- Lisp_Object family, style;
+ struct sfnt_fvar_table *fvar;
+ struct sfnt_font_desc temp;
+ Lisp_Object family, style, instance, style1;
+ int i;
/* Create the font desc and copy in the file name. */
desc = xzalloc (sizeof *desc + strlen (file) + 1);
@@ -842,6 +878,10 @@ sfnt_enum_font_1 (int fd, const char *file,
if (sfnt_decode_family_style (name, &family, &style))
goto bail4;
+ /* See if this is a distortable/variable/multiple master font (all
+ three terms mean the same time.) */
+ fvar = sfnt_read_fvar_table (fd, subtables);
+
/* Set the family. */
desc->family = family;
desc->designer = sfnt_decode_foundry_name (name);
@@ -877,6 +917,43 @@ sfnt_enum_font_1 (int fd, const char *file,
/* Figure out what registry this font is likely to support. */
sfnt_grok_registry (fd, desc, subtables);
+ if (fvar && fvar->instance_count)
+ {
+ /* If there is an fvar table with instances, then this is a font
+ which defines different axes along which the points in each
+ glyph can be changed.
+
+ Instead of enumerating the font itself, enumerate each
+ instance within, which specifies how to configure each axis
+ to achieve a specified style. */
+
+ desc->instances = make_vector (fvar->instance_count, Qnil);
+
+ for (i = 0; i < fvar->instance_count; ++i)
+ {
+ style1 = sfnt_decode_instance_name (&fvar->instance[i],
+ name);
+
+ if (!style1)
+ continue;
+
+ /* Now parse the style. */
+ temp.adstyle = Qnil;
+ sfnt_parse_style (style1, &temp);
+
+ /* Set each field of the vector. */
+ instance = make_vector (5, Qnil);
+ ASET (instance, 0, style1);
+ ASET (instance, 1, temp.adstyle);
+ ASET (instance, 2, make_fixnum (temp.width));
+ ASET (instance, 3, make_fixnum (temp.weight));
+ ASET (instance, 4, make_fixnum (temp.slant));
+
+ /* Place the vector in desc->instances. */
+ ASET (desc->instances, i, instance);
+ }
+ }
+
/* Set the style, link the desc onto system_fonts and return. */
desc->style = style;
desc->next = system_fonts;
@@ -898,6 +975,7 @@ sfnt_enum_font_1 (int fd, const char *file,
next = &prev->next;
}
+ xfree (fvar);
xfree (meta);
xfree (maxp);
xfree (name);
@@ -1346,15 +1424,23 @@ sfntfont_registries_compatible_p (Lisp_Object a,
Lisp_Object b)
}
/* Return whether or not the font description DESC satisfactorily
- matches the font specification FONT_SPEC. */
+ matches the font specification FONT_SPEC.
-static bool
-sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec)
+ Value is 0 if there is no match, -1 if there is a match against
+ DESC itself, and the number of matching instances if the style
+ matches one or more instances defined in in DESC. Return the index
+ of each matching instance in INSTANCES; it should be SIZE big. */
+
+static int
+sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec,
+ int *instances, int size)
{
Lisp_Object tem, extra, tail;
struct sfnt_cmap_encoding_subtable_data *cmap;
size_t i;
struct sfnt_cmap_encoding_subtable subtable;
+ int instance, num_instance;
+ Lisp_Object item;
/* cmap and subtable are caches for sfntfont_lookup_char. */
@@ -1388,7 +1474,9 @@ sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object
spec)
if (!NILP (tem) && NILP (Fstring_equal (SYMBOL_NAME (tem),
desc->family)))
- return false;
+ return 0;
+
+ instance = -1;
/* If a registry is set and wrong, then reject the font desc
immediately. This detects 50% of mismatches from fontset.c.
@@ -1399,33 +1487,82 @@ sfntfont_list_1 (struct sfnt_font_desc *desc,
Lisp_Object spec)
tem = AREF (spec, FONT_REGISTRY_INDEX);
if (!NILP (tem) && !NILP (desc->registry)
&& !sfntfont_registries_compatible_p (tem, desc->registry))
- return false;
+ return 0;
- /* Check that the adstyle specified matches. */
+ /* Check the style. If DESC is a fixed font, just check once.
+ Otherwise, check each instance. */
- tem = AREF (spec, FONT_ADSTYLE_INDEX);
- if (!NILP (tem) && NILP (Fequal (tem, desc->adstyle)))
- return false;
+ if (NILP (desc->instances))
+ {
+ tem = AREF (spec, FONT_ADSTYLE_INDEX);
+ if (!NILP (tem) && NILP (Fequal (tem, desc->adstyle)))
+ return 0;
- /* Check the style. */
+ if (FONT_WIDTH_NUMERIC (spec) != -1
+ && FONT_WIDTH_NUMERIC (spec) != desc->width)
+ return 0;
- if (FONT_WIDTH_NUMERIC (spec) != -1
- && FONT_WIDTH_NUMERIC (spec) != desc->width)
- return false;
+ if (FONT_WEIGHT_NUMERIC (spec) != -1
+ && FONT_WEIGHT_NUMERIC (spec) != desc->weight)
+ return 0;
- if (FONT_WEIGHT_NUMERIC (spec) != -1
- && FONT_WEIGHT_NUMERIC (spec) != desc->weight)
- return false;
+ if (FONT_SLANT_NUMERIC (spec) != -1
+ && FONT_SLANT_NUMERIC (spec) != desc->slant)
+ return 0;
+ }
+ else
+ {
+ num_instance = 0;
- if (FONT_SLANT_NUMERIC (spec) != -1
- && FONT_SLANT_NUMERIC (spec) != desc->slant)
- return false;
+ /* Find the indices of instances in this distortable font which
+ match the given font spec. */
+
+ for (i = 0; i < ASIZE (desc->instances); ++i)
+ {
+ item = AREF (desc->instances, i);
+
+ if (NILP (item))
+ continue;
+
+ /* Check that the adstyle specified matches. */
+
+ tem = AREF (spec, FONT_ADSTYLE_INDEX);
+ if (!NILP (tem) && NILP (Fequal (tem, AREF (item, 1))))
+ continue;
+
+ /* Check the style. */
+
+ if (FONT_WIDTH_NUMERIC (spec) != -1
+ && (FONT_WIDTH_NUMERIC (spec)
+ != XFIXNUM (AREF (item, 2))))
+ continue;
+
+ if (FONT_WEIGHT_NUMERIC (spec) != -1
+ && (FONT_WEIGHT_NUMERIC (spec)
+ != XFIXNUM (AREF (item, 3))))
+ continue;
+
+ if (FONT_SLANT_NUMERIC (spec) != -1
+ && (FONT_SLANT_NUMERIC (spec)
+ != XFIXNUM (AREF (item, 4))))
+ continue;
+
+ if (num_instance == size)
+ break;
+
+ /* A matching instance has been found. Set its index, then
+ go back to the rest of the font matching. */
+ instances[num_instance++] = i;
+ }
+
+ instance = num_instance;
+ }
/* Handle extras. */
extra = AREF (spec, FONT_EXTRA_INDEX);
if (NILP (extra))
- return true;
+ return instance;
tem = assq_no_quit (QCscript, extra);
cmap = NULL;
@@ -1490,12 +1627,12 @@ sfntfont_list_1 (struct sfnt_font_desc *desc,
Lisp_Object spec)
desc->subtable = subtable;
xfree (cmap);
- return true;
+ return instance;
fail:
/* The cmap might've been read in and require deallocation. */
xfree (cmap);
- return false;
+ return 0;
}
/* Type of font entities and font objects created. */
@@ -1546,12 +1683,14 @@ sfntfont_registry_for_desc (struct sfnt_font_desc *desc)
}
/* Return a font-entity that represents the font descriptor (unopened
- font) DESC. */
+ font) DESC. If INSTANCE is more than or equal to 1, then it is the
+ index of the instance in DESC that should be opened plus 1; in that
+ case, DESC must be a distortable font. */
static Lisp_Object
-sfntfont_desc_to_entity (struct sfnt_font_desc *desc)
+sfntfont_desc_to_entity (struct sfnt_font_desc *desc, int instance)
{
- Lisp_Object entity;
+ Lisp_Object entity, vector;
entity = font_make_entity ();
@@ -1572,19 +1711,40 @@ sfntfont_desc_to_entity (struct sfnt_font_desc *desc)
ASET (entity, FONT_SPACING_INDEX,
make_fixnum (desc->spacing));
- FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
- make_fixnum (desc->width));
- FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
- make_fixnum (desc->weight));
- FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
- make_fixnum (desc->slant));
+ if (instance >= 1)
+ {
+ if (NILP (desc->instances)
+ || instance > ASIZE (desc->instances))
+ emacs_abort ();
- ASET (entity, FONT_ADSTYLE_INDEX, Qnil);
+ vector = AREF (desc->instances, instance - 1);
+ FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
+ AREF (vector, 2));
+ FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
+ AREF (vector, 3));
+ FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
+ AREF (vector, 4));
+ ASET (entity, FONT_ADSTYLE_INDEX, AREF (vector, 1));
+ }
+ else
+ {
+ FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
+ make_fixnum (desc->width));
+ FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
+ make_fixnum (desc->weight));
+ FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
+ make_fixnum (desc->slant));
+ ASET (entity, FONT_ADSTYLE_INDEX, desc->adstyle);
+ }
/* Set FONT_EXTRA_INDEX to a pointer to the font description. Font
descriptions are never supposed to be freed. */
+
ASET (entity, FONT_EXTRA_INDEX,
- list1 (Fcons (Qfont_entity, make_mint_ptr (desc))));
+ (instance >= 1
+ ? list2 (Fcons (Qfont_entity, make_mint_ptr (desc)),
+ Fcons (Qfont_instance, make_fixnum (instance - 1)))
+ : list1 (Fcons (Qfont_entity, make_mint_ptr (desc)))));
return entity;
}
@@ -1597,6 +1757,7 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec)
{
Lisp_Object matching, tem;
struct sfnt_font_desc *desc;
+ int i, rc, instances[100];
matching = Qnil;
@@ -1612,10 +1773,24 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec)
}
/* Loop through known system fonts and add them one-by-one. */
+
for (desc = system_fonts; desc; desc = desc->next)
{
- if (sfntfont_list_1 (desc, font_spec))
- matching = Fcons (sfntfont_desc_to_entity (desc), matching);
+ rc = sfntfont_list_1 (desc, font_spec, instances,
+ ARRAYELTS (instances));
+
+ if (rc < 0)
+ matching = Fcons (sfntfont_desc_to_entity (desc, 0),
+ matching);
+ else if (rc)
+ {
+ /* Add each matching instance. */
+
+ for (i = 0; i < rc; ++i)
+ matching = Fcons (sfntfont_desc_to_entity (desc,
+ instances[i] + 1),
+ matching);
+ }
}
unblock_input ();
@@ -1688,23 +1863,45 @@ struct sfntfont_get_glyph_outline_dcontext
/* glyf table. */
struct sfnt_glyf_table *glyf;
+
+ /* Variation settings, or NULL. */
+ struct sfnt_blend *blend;
};
-/* Return the glyph identified by GLYPH from the glyf and loca table
- specified in DCONTEXT. Set *NEED_FREE to true. */
+/* Return the glyph identified by GLYPH_ID from the glyf and loca
+ table specified in DCONTEXT. Set *NEED_FREE to true. */
static struct sfnt_glyph *
-sfntfont_get_glyph (sfnt_glyph glyph, void *dcontext,
+sfntfont_get_glyph (sfnt_glyph glyph_id, void *dcontext,
bool *need_free)
{
struct sfntfont_get_glyph_outline_dcontext *tables;
+ struct sfnt_glyph *glyph;
+ struct sfnt_metrics_distortion distortion;
tables = dcontext;
*need_free = true;
- return sfnt_read_glyph (glyph, tables->glyf,
- tables->loca_short,
- tables->loca_long);
+ glyph = sfnt_read_glyph (glyph_id, tables->glyf,
+ tables->loca_short,
+ tables->loca_long);
+
+ if (!tables->blend || !glyph)
+ return glyph;
+
+ if ((glyph->simple
+ && sfnt_vary_simple_glyph (tables->blend, glyph_id,
+ glyph, &distortion))
+ || (!glyph->simple
+ && sfnt_vary_compound_glyph (tables->blend, glyph_id,
+ glyph, &distortion)))
+ {
+ sfnt_free_glyph (glyph);
+ return NULL;
+ }
+
+ /* Note that the distortion is not relevant for compound glyphs. */
+ return glyph;
}
/* Free the glyph identified by GLYPH. */
@@ -1734,6 +1931,8 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline
*outline)
HEAD. Keep *CACHE_SIZE updated with the number of elements in the
cache.
+ Distort the glyph using BLEND if INDEX is not -1.
+
Use the offset information in the long or short loca tables
LOCA_LONG and LOCA_SHORT, whichever is set.
@@ -1754,6 +1953,8 @@ static struct sfnt_glyph_outline *
sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
struct sfnt_outline_cache *cache,
sfnt_fixed scale, int *cache_size,
+ struct sfnt_blend *blend,
+ int index,
struct sfnt_glyf_table *glyf,
struct sfnt_head_table *head,
struct sfnt_hmtx_table *hmtx,
@@ -1772,8 +1973,10 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
struct sfnt_instructed_outline *value;
const char *error;
struct sfnt_glyph_metrics temp;
+ struct sfnt_metrics_distortion distortion;
start = cache->next;
+ distortion.advance = 0;
/* See if the outline is already cached. */
for (; start != cache; start = start->next)
@@ -1806,6 +2009,30 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
if (!glyph)
return NULL;
+ /* Distort the glyph if necessary. */
+
+ if (index != -1)
+ {
+ if (glyph->simple)
+ {
+ if (sfnt_vary_simple_glyph (blend, glyph_code,
+ glyph, &distortion))
+ {
+ sfnt_free_glyph (glyph);
+ return NULL;
+ }
+ }
+ else if (!glyph->simple)
+ {
+ if (sfnt_vary_compound_glyph (blend, glyph_code,
+ glyph, &distortion))
+ {
+ sfnt_free_glyph (glyph);
+ return NULL;
+ }
+ }
+ }
+
/* Try to instruct the glyph if INTERPRETER is specified. */
outline = NULL;
@@ -1813,6 +2040,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
dcontext.loca_long = loca_long;
dcontext.loca_short = loca_short;
dcontext.glyf = glyf;
+ dcontext.blend = (index != -1 ? blend : NULL);
/* Now load the glyph's unscaled metrics into TEMP. */
@@ -1820,6 +2048,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
head, maxp))
goto fail;
+ /* Add the advance width distortion. */
+ temp.advance += distortion.advance;
+
if (interpreter)
{
if (glyph->simple)
@@ -1878,6 +2109,13 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
if (!outline)
return NULL;
+ if (index != -1)
+ /* Finally, adjust the left side bearing of the glyph metrics by
+ the origin point of the outline, should a distortion have been
+ applied. The left side bearing is the distance from the origin
+ point to the left most point on the X axis. */
+ temp.lbearing = outline->xmin - outline->origin;
+
start = xmalloc (sizeof *start);
start->glyph = glyph_code;
start->outline = outline;
@@ -2125,6 +2363,13 @@ struct sfnt_font_info
/* Factor used to convert from em space to pixel space. */
sfnt_fixed scale;
+ /* The blend (configuration of this multiple master font). */
+ struct sfnt_blend blend;
+
+ /* The index of the named instance used to initialize BLEND.
+ -1 if BLEND is not initialized. */
+ int instance;
+
#ifdef HAVE_MMAP
/* Whether or not the glyph table has been mmapped. */
bool glyf_table_mapped;
@@ -2358,6 +2603,10 @@ sfnt_close_tables (struct sfnt_font_tables *tables)
xfree (tables->prep);
xfree (tables->fpgm);
xfree (tables->cvt);
+ xfree (tables->fvar);
+ xfree (tables->avar);
+ xfree (tables->gvar);
+ xfree (tables->cvar);
xfree (tables->cmap_data);
if (tables->uvs)
@@ -2524,6 +2773,15 @@ sfnt_open_tables (struct sfnt_font_desc *desc)
tables->fpgm = sfnt_read_fpgm_table (fd, subtable);
tables->cvt = sfnt_read_cvt_table (fd, subtable);
+ /* Read distortion related tables. These might not be present. */
+ tables->fvar = sfnt_read_fvar_table (fd, subtable);
+ tables->avar = sfnt_read_avar_table (fd, subtable);
+ tables->gvar = sfnt_read_gvar_table (fd, subtable);
+
+ if (tables->cvt && tables->fvar)
+ tables->cvar = sfnt_read_cvar_table (fd, subtable, tables->fvar,
+ tables->cvt);
+
return tables;
bail5:
@@ -2614,9 +2872,10 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
struct sfnt_font_desc *desc;
Lisp_Object font_object;
struct charset *charset;
- int point_size;
+ int point_size, instance, i;
Display_Info *dpyinfo;
struct sfnt_font_tables *tables;
+ Lisp_Object tem;
if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
@@ -2633,10 +2892,18 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
/* Now find the font description corresponding to FONT_ENTITY. */
- if (NILP (AREF (font_entity, FONT_EXTRA_INDEX)))
+ tem = AREF (font_entity, FONT_EXTRA_INDEX);
+ if (NILP (tem))
return Qnil;
- desc = xmint_pointer (XCDR (XCAR (AREF (font_entity, FONT_EXTRA_INDEX))));
+ desc = xmint_pointer (XCDR (XCAR (tem)));
+
+ /* Finally, see if a specific instance is associated with
+ FONT_ENTITY. */
+
+ instance = -1;
+ if (!NILP (XCDR (tem)))
+ instance = XFIXNUM (XCDR (XCAR (XCDR (tem))));
/* Build the font object. */
font_object = font_make_object (VECSIZE (struct sfnt_font_info),
@@ -2669,6 +2936,8 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
font_info->raster_cache_size = 0;
font_info->interpreter = NULL;
font_info->scale = 0;
+ font_info->instance = -1;
+ font_info->blend.coords = NULL;
#ifdef HAVE_MMAP
font_info->glyf_table_mapped = false;
#endif /* HAVE_MMAP */
@@ -2784,6 +3053,34 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
/ 2));
sfntfont_setup_interpreter (font_info, point_size);
+ /* If an instance was specified and the font is distortable, set up
+ the blend. */
+
+ if (instance != -1
+ && desc->tables->fvar && desc->tables->gvar
+ /* Make sure the instance is within range. */
+ && instance < desc->tables->fvar->instance_count)
+ {
+ sfnt_init_blend (&font_info->blend, desc->tables->fvar,
+ desc->tables->gvar, desc->tables->avar,
+ desc->tables->cvar);
+
+ /* Copy over the coordinates. */
+ for (i = 0; i < desc->tables->fvar->axis_count; ++i)
+ font_info->blend.coords[i]
+ = desc->tables->fvar->instance[instance].coords[i];
+
+ sfnt_normalize_blend (&font_info->blend);
+
+ /* If an interpreter was specified, distort it now. */
+
+ if (font_info->interpreter)
+ sfnt_vary_interpreter (font_info->interpreter,
+ &font_info->blend);
+
+ font_info->instance = instance;
+ }
+
#ifdef HAVE_HARFBUZZ
/* HarfBuzz will potentially read font tables after the font has
been opened by Emacs. Keep the font open, and record its offset
@@ -2855,6 +3152,8 @@ sfntfont_measure_pcm (struct sfnt_font_info *font,
sfnt_glyph glyph,
outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache,
font->scale,
&font->outline_cache_size,
+ &font->blend,
+ font->instance,
font->glyf, font->head,
font->hmtx, font->hhea,
font->maxp,
@@ -2960,6 +3259,11 @@ sfntfont_close (struct font *font)
info->interpreter = NULL;
info->uvs = NULL;
+ /* Deinitialize the blend. */
+ if (info->instance != -1 && info->blend.coords)
+ sfnt_free_blend (&info->blend);
+ info->instance = -1;
+
#ifdef HAVE_MMAP
/* Unlink INFO. */
@@ -3035,6 +3339,8 @@ sfntfont_draw (struct glyph_string *s, int from, int to,
&info->outline_cache,
info->scale,
&info->outline_cache_size,
+ &info->blend,
+ info->instance,
info->glyf, info->head,
info->hmtx, info->hhea,
info->maxp,
@@ -3362,6 +3668,13 @@ sfntfont_begin_hb_font (struct font *font, double
*position_unit)
hb_font_set_scale (info->hb_font, factor * 64, factor * 64);
hb_font_set_ppem (info->hb_font, factor, factor);
+#ifdef HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE
+ /* Set the instance if this is a distortable font. */
+ if (info->instance != -1)
+ hb_font_set_var_named_instance (info->hb_font,
+ info->instance);
+#endif /* HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE */
+
/* This is needed for HarfBuzz before 2.0.0; it is the default
in later versions. */
hb_ot_font_set_funcs (info->hb_font);
@@ -3396,6 +3709,7 @@ syms_of_sfntfont (void)
DEFSYM (Qzh, "zh");
DEFSYM (Qja, "ja");
DEFSYM (Qko, "ko");
+ DEFSYM (Qfont_instance, "font-instance");
/* Char-table purpose. */
DEFSYM (Qfont_lookup_cache, "font-lookup-cache");
@@ -3427,6 +3741,7 @@ mark_sfntfont (void)
mark_object (desc->family);
mark_object (desc->style);
mark_object (desc->adstyle);
+ mark_object (desc->instances);
mark_object (desc->languages);
mark_object (desc->registry);
mark_object (desc->char_cache);
- feature/android updated (d7457e1ce4e -> 54d79f37ae5), Po Lu, 2023/03/27
- feature/android 54d79f37ae5 6/6: Merge remote-tracking branch 'origin/master' into feature/android, Po Lu, 2023/03/27
- feature/android a1c5461edab 2/6: Merge remote-tracking branch 'origin/master' into feature/android, Po Lu, 2023/03/27
- feature/android c0873f2382f 1/6: Update Android port, Po Lu, 2023/03/27
- feature/android 67a325243c6 3/6: Refactor sfntfont.c, Po Lu, 2023/03/27
- feature/android dd4924ca90a 5/6: Update Android port,
Po Lu <=
- feature/android 18b34e9ca01 4/6: Refactor sfntfont.c, Po Lu, 2023/03/27