[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android 89a30637b32 1/3: Update Android port
From: |
Po Lu |
Subject: |
feature/android 89a30637b32 1/3: Update Android port |
Date: |
Wed, 29 Mar 2023 23:31:04 -0400 (EDT) |
branch: feature/android
commit 89a30637b32edea461746023717f77bd87bb4b10
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Update Android port
* src/sfnt.c (sfnt_make_interpreter): New argument `fvar'. Set
axis count.
(SCANCTRL): Implement selector bit 8.
(GXAXIS): New instruction.
(SFVTPV): Validate graphics state after changing freedom vector.
(sfnt_line_to_vector): Implement `original'.
(sfnt_move): Remove redundant division.
(sfnt_interpret_run): Implement distortable font related GXAXIS
instruction (0x91).
(sfnt_vary_interpreter): Set naxis and norm_coords.
(sfnt_make_test_interpreter, pushb_test_args, pushw_test_args)
(sfnt_name_instruction, main): Adjust accordingly.
* src/sfnt.h (struct sfnt_interpreter, PROTOTYPE):
* src/sfntfont.c (sfntfont_setup_interpreter, sfntfont_open):
Set up distortion information.
---
src/sfnt.c | 111 ++++++++++++++++++++++++++++++++++++++++++++-------------
src/sfnt.h | 7 ++++
src/sfntfont.c | 6 ++--
3 files changed, 98 insertions(+), 26 deletions(-)
diff --git a/src/sfnt.c b/src/sfnt.c
index 4da0997751d..564f5d883bd 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -5445,10 +5445,10 @@ sfnt_init_graphics_state (struct sfnt_graphics_state
*state)
}
/* Set up an interpreter to be used with a font. Use the resource
- limits specified in the MAXP table, the values specified in the CVT
- and HEAD tables, the pixel size PIXEL_SIZE, and the point size
- POINT_SIZE. CVT may be NULL, in which case the interpreter will
- not have access to a control value table.
+ limits specified in the MAXP table, the values specified in the
+ CVT, HEAD and FVAR tables, the pixel size PIXEL_SIZE, and the point
+ size POINT_SIZE. CVT may be NULL, in which case the interpreter
+ will not have access to a control value table.
POINT_SIZE should be PIXEL_SIZE, converted to 1/72ths of an inch.
@@ -5459,6 +5459,7 @@ TEST_STATIC struct sfnt_interpreter *
sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
struct sfnt_cvt_table *cvt,
struct sfnt_head_table *head,
+ struct sfnt_fvar_table *fvar,
int pixel_size, int point_size)
{
size_t size, temp, i, storage_size, pad;
@@ -5613,6 +5614,18 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
/* Fill in the current call depth. */
interpreter->call_depth = 0;
+ /* Clear variation axes. They will be set upon a call to
+ `sfnt_vary_interpreter'. */
+ interpreter->n_axis = 0;
+ interpreter->norm_coords = NULL;
+
+ /* Set n_axis now if a fvar table was provided. This way, GXAXIS
+ pushes the correct number of values even if no blend is
+ provided. */
+
+ if (fvar)
+ interpreter->n_axis = fvar->axis_count;
+
/* Return the interpreter. */
return interpreter;
}
@@ -6483,16 +6496,25 @@ sfnt_interpret_trap (struct sfnt_interpreter
*interpreter,
interpreter->state.scan_control = value; \
}
+/* Selector bit 8 is undocumented, but present in the Macintosh
+ rasterizer. 02000 is returned if there is a variation axis in
+ use. */
+
#define GETINFO() \
{ \
- uint32_t selector; \
+ uint32_t selector, k; \
\
selector = POP (); \
\
+ k = 0; \
+ \
if (selector & 1) \
- PUSH_UNCHECKED (2) \
- else \
- PUSH_UNCHECKED (0) \
+ k |= 02; \
+ \
+ if (selector & 8 && interpreter->n_axis) \
+ k |= 02000; \
+ \
+ PUSH_UNCHECKED (k); \
}
#define IDEF() \
@@ -6563,6 +6585,25 @@ sfnt_interpret_trap (struct sfnt_interpreter
*interpreter,
|= (1 << s); \
}
+/* GXAXIS is undocumented. It seems to return each axis in shortFrac
+ format. */
+
+#define GXAXIS() \
+ { \
+ uint32_t v; \
+ int i; \
+ \
+ for (i = 0; i < interpreter->n_axis; ++i) \
+ { \
+ if (interpreter->norm_coords) \
+ v = interpreter->norm_coords[i] / 4; \
+ else \
+ v = 0; \
+ \
+ PUSH (v); \
+ } \
+ }
+
#define PUSHB() \
{ \
int b, nbytes, IP; \
@@ -6943,6 +6984,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
{ \
interpreter->state.freedom_vector \
= interpreter->state.projection_vector; \
+ \
+ sfnt_validate_gs (&interpreter->state); \
}
#define ISECT() \
@@ -8231,6 +8274,16 @@ sfnt_line_to_vector (struct sfnt_interpreter
*interpreter,
sfnt_address_zp1 (interpreter, p1, &x1, &y1, &original_x1,
&original_y1);
+ /* Use original coordinates if specified. */
+
+ if (original)
+ {
+ x2 = original_x2;
+ y2 = original_y2;
+ x1 = original_x1;
+ y1 = original_y1;
+ }
+
/* Calculate the vector between X2, Y2, and X1, Y1. */
a = sfnt_sub (x1, x2);
b = sfnt_sub (y1, y2);
@@ -9392,7 +9445,7 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6
*restrict y,
size_t n, struct sfnt_interpreter *interpreter,
sfnt_f26dot6 distance, unsigned char *flags)
{
- sfnt_f26dot6 versor;
+ sfnt_f26dot6 versor, k;
sfnt_f2dot14 dot_product;
size_t num;
@@ -9412,12 +9465,13 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6
*restrict y,
/* Move along X axis, converting the distance to the freedom
vector. */
num = n;
+ k = sfnt_multiply_divide_signed (distance,
+ versor,
+ dot_product);
while (num--)
{
- *x = sfnt_add (*x, sfnt_multiply_divide_signed (distance,
- versor,
- dot_product));
+ *x = sfnt_add (*x, k);
x++;
if (flags)
@@ -9432,12 +9486,13 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6
*restrict y,
/* Move along X axis, converting the distance to the freedom
vector. */
num = n;
+ k = sfnt_multiply_divide_signed (distance,
+ versor,
+ dot_product);
while (num--)
{
- *y = sfnt_add (*y, sfnt_multiply_divide_signed (distance,
- versor,
- dot_product));
+ *y = sfnt_add (*y, k);
y++;
if (flags)
@@ -10747,6 +10802,10 @@ sfnt_interpret_run (struct sfnt_interpreter
*interpreter,
NOT_IMPLEMENTED ();
break;
+ case 0x91: /* GXAXIS */
+ GXAXIS ();
+ break;
+
default:
if (opcode >= 0xE0) /* MIRP */
{
@@ -14895,7 +14954,8 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend,
sfnt_glyph id,
}
/* Vary the specified INTERPRETER's control value table using the
- variations in BLEND's CVT variations table.
+ variations in BLEND's CVT variations table, then record the blend's
+ normalized coordinates and axis count in the interpreter.
The CVT table used to create INTERPRETER must be the same used
to read BLEND->cvar. If not, behavior is undefined. */
@@ -14953,6 +15013,9 @@ sfnt_vary_interpreter (struct sfnt_interpreter
*interpreter,
interpreter->cvt[i] += delta;
}
}
+
+ interpreter->n_axis = blend->fvar->axis_count;
+ interpreter->norm_coords = blend->norm_coords;
}
@@ -15443,7 +15506,7 @@ sfnt_make_test_interpreter (void)
return sfnt_make_interpreter (&test_interpreter_profile,
&test_interpreter_cvt,
&test_interpreter_head,
- 17, 17);
+ NULL, 17, 17);
}
struct sfnt_interpreter_test
@@ -15938,7 +16001,7 @@ static struct sfnt_generic_test_args npushw_test_args =
static struct sfnt_generic_test_args pushb_test_args =
{
(uint32_t []) { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U,
- 1U, },
+ 1U, },
9,
true,
11,
@@ -15947,7 +16010,7 @@ static struct sfnt_generic_test_args pushb_test_args =
static struct sfnt_generic_test_args pushw_test_args =
{
(uint32_t []) { 0x203U, 0x204U, 0x205U, 0x206U, 0x207U, 0x208U,
- 0x909U, 0x909U, (uint32_t) -1, },
+ 0x909U, 0x909U, (uint32_t) -1, },
9,
true,
20,
@@ -18347,7 +18410,7 @@ sfnt_name_instruction (unsigned char opcode)
"7 INS_$8F",
"7 INS_$90",
- "7 INS_$91",
+ "7 GXAXIS",
"7 INS_$92",
"7 INS_$93",
"7 INS_$94",
@@ -18924,8 +18987,8 @@ main (int argc, char **argv)
return 1;
}
-#define FANCY_PPEM 36
-#define EASY_PPEM 36
+#define FANCY_PPEM 19
+#define EASY_PPEM 19
interpreter = NULL;
head = sfnt_read_head_table (fd, font);
@@ -19085,7 +19148,7 @@ main (int argc, char **argv)
loca_short->num_offsets);
}
- interpreter = sfnt_make_interpreter (maxp, cvt, head,
+ interpreter = sfnt_make_interpreter (maxp, cvt, head, fvar,
FANCY_PPEM, FANCY_PPEM);
if (instance && gvar)
sfnt_vary_interpreter (interpreter, &blend);
@@ -19296,7 +19359,7 @@ main (int argc, char **argv)
cvt ? cvt->num_elements : 0ul);
interpreter = sfnt_make_interpreter (maxp, cvt, head,
- FANCY_PPEM,
+ fvar, FANCY_PPEM,
FANCY_PPEM);
state = interpreter->state;
diff --git a/src/sfnt.h b/src/sfnt.h
index 30c82ad3795..58a6de060f4 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -1860,6 +1860,12 @@ struct sfnt_interpreter
/* What was the trap. */
const char *trap_reason;
+ /* Number of variation axes provided by this distortable font. */
+ int n_axis;
+
+ /* Normalized axis coordinates set for this distortable font. */
+ sfnt_fixed *norm_coords;
+
#ifdef TEST
/* If non-NULL, function called before each instruction is
executed. */
@@ -1918,6 +1924,7 @@ extern struct sfnt_prep_table *sfnt_read_prep_table
(PROTOTYPE);
#define PROTOTYPE \
struct sfnt_maxp_table *, \
struct sfnt_cvt_table *, \
+ struct sfnt_fvar_table *, \
struct sfnt_head_table *, \
int, int
diff --git a/src/sfntfont.c b/src/sfntfont.c
index c9d48f640af..960abe0d270 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -2532,7 +2532,7 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info)
/* Initialize the instruction interpreter for INFO. Load the font and
preprogram for the pixel size in INFO and its corresponding point
- size POINT_SIZE.
+ size POINT_SIZE. Use the FVAR table in DESC.
The font tables in INFO must already have been initialized.
@@ -2541,6 +2541,7 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info)
static void
sfntfont_setup_interpreter (struct sfnt_font_info *info,
+ struct sfnt_font_desc *desc,
int point_size)
{
struct sfnt_cvt_table *cvt;
@@ -2575,6 +2576,7 @@ sfntfont_setup_interpreter (struct sfnt_font_info *info,
info->head. CVT can be NULL. */
interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head,
+ desc->tables->fvar,
info->font.pixel_size,
point_size);
@@ -3110,7 +3112,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx
* dpyinfo->resy
/ 2));
- sfntfont_setup_interpreter (font_info, point_size);
+ sfntfont_setup_interpreter (font_info, desc, point_size);
/* If an instance was specified and the font is distortable, set up
the blend. */