Skip to content

Commit e8b7074

Browse files
Fix obvious interpreter issues
1 parent 47c8d2b commit e8b7074

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

src/SixLabors.Fonts/Tables/TrueType/Hinting/TrueTypeInterpreter.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,32 @@
77
namespace SixLabors.Fonts.Tables.TrueType.Hinting;
88

99
/// <summary>
10-
/// Code adapted from <see href="https://github.com/MikePopoloski/SharpFont/blob/b28555e8fae94c57f1b5ccd809cdd1260f0eb55f/SharpFont/FontFace.cs"/>
11-
/// For further information
12-
/// <see href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM05/Chap5.html"/>
13-
/// <see href="https://learn.microsoft.com/en-us/typography/cleartype/truetypecleartype"/>
14-
/// <see href="https://freetype.org/freetype2/docs/hinting/subpixel-hinting.html"/>
10+
/// Code adapted from
11+
/// <see href="https://github.com/MikePopoloski/SharpFont/blob/b28555e8fae94c57f1b5ccd809cdd1260f0eb55f/SharpFont/Internal/Interpreter.cs"/>.
12+
///
13+
/// Reference material:
14+
/// <see href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM05/Chap5.html"/> –
15+
/// the original TrueType instruction set and execution model.
16+
/// <see href="https://learn.microsoft.com/en-us/typography/cleartype/truetypecleartype"/> –
17+
/// details on how Microsoft's ClearType rasterizer interprets TrueType hints.
18+
/// <see href="https://freetype.org/freetype2/docs/hinting/subpixel-hinting.html"/> –
19+
/// documentation of FreeType's subpixel hinting engines, including the v40 "minimal" interpreter.
20+
///
21+
/// <para>
22+
/// This implementation matches the behavior of FreeType's v40 subpixel hinting interpreter,
23+
/// with horizontal hinting disabled and full vertical TrueType instruction processing preserved.
24+
/// It follows the v40 model in which outlines are adjusted primarily along the Y-axis and
25+
/// instructions operate without backward compatibility constraints. This corresponds to
26+
/// FreeType's configuration where <c>TT_CONFIG_OPTION_SUBPIXEL_HINTING</c> selects the
27+
/// minimal (v40) engine and <c>backward_compatibility</c> is forced to zero.
28+
/// </para>
29+
///
30+
/// <para>
31+
/// Modern ClearType-hinted fonts are designed for this style of processing and will render
32+
/// consistently under this interpreter. Legacy CRT-era fonts such as Arial or Times New Roman
33+
/// also render cleanly under v40 semantics, though without legacy bi-level horizontal snapping,
34+
/// which v40 intentionally omits.
35+
/// </para>
1536
/// </summary>
1637
internal class TrueTypeInterpreter
1738
{
@@ -567,7 +588,7 @@ private void Execute(StackInstructionStream stream, bool inFunction, bool allowF
567588
continue;
568589
}
569590

570-
this.points.Current[i].OnCurve ^= true;
591+
this.points.Current[index].OnCurve ^= true;
571592
}
572593

573594
this.state.Loop = 1;
@@ -852,7 +873,7 @@ private void Execute(StackInstructionStream stream, bool inFunction, bool allowF
852873
}
853874
else
854875
{
855-
this.iupYCalled = true;
876+
this.iupXCalled = true;
856877
touchMask = TouchState.X;
857878
current = (byte*)&currentPtr->Point.X;
858879
original = (byte*)&originalPtr->Point.X;
@@ -1565,7 +1586,7 @@ private void SetVectorToLine(int mode, bool dual)
15651586
if (dual)
15661587
{
15671588
p1 = this.zp2.GetOriginal(index1);
1568-
p2 = this.zp2.GetOriginal(index2);
1589+
p2 = this.zp1.GetOriginal(index2);
15691590
line = p2 - p1;
15701591

15711592
if (line.LengthSquared() == 0)
@@ -1803,7 +1824,7 @@ private void ShiftPoints(Vector2 displacement)
18031824
bool postIUP = this.iupXCalled && this.iupYCalled;
18041825
bool composite = this.isComposite;
18051826
ControlPoint[] current = this.zp2.Current;
1806-
bool inTwilight = this.zp0.IsTwilight && this.zp1.IsTwilight && this.zp2.IsTwilight;
1827+
bool inTwilight = this.zp0.IsTwilight || this.zp1.IsTwilight || this.zp2.IsTwilight;
18071828

18081829
for (int i = 0; i < this.state.Loop; i++)
18091830
{

0 commit comments

Comments
 (0)