summaryrefslogtreecommitdiff
path: root/src/sfnt.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-12-11 11:28:34 +0800
committerPo Lu <luangruo@yahoo.com>2023-12-11 11:28:34 +0800
commit1ec8e76bcf9aa9ec31718c9a2bb80f89219383e4 (patch)
tree67eedfc9613022ee823672c1ddc705ebb008f5bd /src/sfnt.c
parent64cdcf7f51f1428c40d8c2a902c76b9877e2ff8d (diff)
downloademacs-1ec8e76bcf9aa9ec31718c9a2bb80f89219383e4.tar.gz
emacs-1ec8e76bcf9aa9ec31718c9a2bb80f89219383e4.tar.bz2
emacs-1ec8e76bcf9aa9ec31718c9a2bb80f89219383e4.zip
Correct implementation of UTP
* src/sfnt.c (sfnt_interpret_utp): Derive which flags to reset from the freedom vector.
Diffstat (limited to 'src/sfnt.c')
-rw-r--r--src/sfnt.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 44906b12ce9..f9ffc86da58 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -7450,6 +7450,8 @@ static void
sfnt_interpret_utp (struct sfnt_interpreter *interpreter,
uint32_t p)
{
+ unsigned char mask;
+
if (!interpreter->state.zp0)
{
if (p >= interpreter->twilight_zone_size)
@@ -7463,7 +7465,31 @@ sfnt_interpret_utp (struct sfnt_interpreter *interpreter,
|| p >= interpreter->glyph_zone->num_points)
TRAP ("UTP[] p lies outside glyph zone");
- interpreter->glyph_zone->flags[p] &= ~SFNT_POINT_TOUCHED_X;
+ /* The flags unset by UTP are subject to which axes in the freedom
+ vector are significant, as stated in the TrueType reference
+ manual by this needless mouthful:
+
+ A point may be touched in the x-direction, the y-direction, or
+ in both the x and y-directions. The position of the freedom
+ vector determines whether the point is untouched in the
+ x-direction, the y-direction, or both. If the vector is set to
+ the x-axis, the point will be untouched in the x-direction. If
+ the vector is set to the y-axis, the point will be untouched in
+ the y-direction. Otherwise the point will be untouched in both
+ directions.
+
+ A points that is marked as untouched will be moved by an IUP[]
+ instruction even if the point was previously touched. */
+
+ mask = 0xff;
+
+ if (interpreter->state.freedom_vector.x)
+ mask &= ~SFNT_POINT_TOUCHED_X;
+
+ if (interpreter->state.freedom_vector.y)
+ mask &= ~SFNT_POINT_TOUCHED_Y;
+
+ interpreter->glyph_zone->flags[p] &= mask;
}
/* Save the specified unit VECTOR into INTERPRETER's graphics state as