using Glass.Typesetting; using UnitTestSharp; namespace Glass.UnitTests.Typesetting { public class FacedPenTests : TestFixture { private static FaceRuns Runs(params (int start, int end, IFontMetrics font)[] runs) { return FacedMeasuringTests.Runs(FacedMeasuringTests.Kerned, runs); } public class StepTests : TestFixture { public void FirstGlyph_HasNothingToKernAgainst() { var pen = new FacedPen(Runs()); int position = 0; CheckTrue(pen.Step("ab", ref position, 2, out int kerning, out int width)); CheckEqual(0, kerning); CheckEqual(10, width); CheckEqual(1, position); } public void GlyphAfterOneInTheSameFont_KernsAgainstIt() { var pen = new FacedPen(Runs()); int position = 0; pen.Step("ab", ref position, 2, out _, out _); pen.Step("ab", ref position, 2, out int kerning, out int width); CheckEqual(-1, kerning); CheckEqual(10, width); } public void GlyphInAnotherFont_KernsAsAtTheStartOfALine() { var pen = new FacedPen(Runs((1, 2, FacedMeasuringTests.KernedWide))); int position = 0; pen.Step("ab", ref position, 2, out _, out _); pen.Step("ab", ref position, 2, out int kerning, out int width); CheckEqual(0, kerning); CheckEqual(14, width); } public void GlyphAfterOneInTheSameOtherFont_KernsWithThatFontsTable() { var pen = new FacedPen(Runs((0, 2, FacedMeasuringTests.KernedWide))); int position = 0; pen.Step("ab", ref position, 2, out _, out _); pen.Step("ab", ref position, 2, out int kerning, out int width); CheckEqual(-3, kerning); CheckEqual(14, width); } public void GlyphBackInTheBaseFont_KernsAsAtTheStartOfALine() { var pen = new FacedPen(Runs((0, 1, FacedMeasuringTests.KernedWide))); int position = 0; pen.Step("ab", ref position, 2, out _, out _); pen.Step("ab", ref position, 2, out int kerning, out _); CheckEqual(0, kerning); } public void CodePointThatDrawsNothing_ReturnsFalseAndStepsOverIt() { var pen = new FacedPen(Runs()); string text = "­a"; int position = 0; CheckFalse(pen.Step(text, ref position, 2, out int kerning, out int width)); CheckEqual(1, position); CheckEqual(0, kerning); CheckEqual(0, width); } public void CodePointThatDrawsNothing_LeavesTheKerningAlone() { var pen = new FacedPen(Runs((1, 2, FacedMeasuringTests.KernedWide))); string text = "a­b"; int position = 0; pen.Step(text, ref position, 3, out _, out _); pen.Step(text, ref position, 3, out _, out _); pen.Step(text, ref position, 3, out int kerning, out _); CheckEqual(-1, kerning); } public void SurrogatePair_IsOneGlyphOfTheInvalidGlyphsWidth() { var pen = new FacedPen(Runs()); string text = WordMeasurerTests.Emoji; int position = 0; CheckTrue(pen.Step(text, ref position, 2, out _, out int width)); CheckEqual(2, position); CheckEqual(WordMeasurerTests.InvalidGlyphWidth, width); } public void GlyphIsMeasuredInTheFontAtItsFirstCodeUnit() { var pen = new FacedPen(Runs((1, 2, FacedMeasuringTests.KernedWide))); string text = "a" + WordMeasurerTests.Emoji; int position = 1; pen.Step(text, ref position, 3, out _, out int width); CheckEqual(3, position); CheckEqual(9, width); } public void End_StopsASurrogatePairThatWouldStraddleIt() { var pen = new FacedPen(Runs()); string text = WordMeasurerTests.Emoji; int position = 0; CheckTrue(pen.Step(text, ref position, 1, out _, out int width)); CheckEqual(1, position); CheckEqual(WordMeasurerTests.InvalidGlyphWidth, width); } } public class StepOverTests : TestFixture { public void ReturnsTheKerningAgainstTheGlyphBefore() { IFontMetrics narrow = FacedMeasuringTests.Kerned; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['a']); CheckEqual(-1, pen.StepOver(narrow, narrow.MetricsTable['b'])); } public void InAnotherFont_ReturnsNoKerning() { var pen = new FacedPen(Runs()); pen.StepOver(FacedMeasuringTests.Kerned, FacedMeasuringTests.Kerned.MetricsTable['a']); CheckEqual(0, pen.StepOver(FacedMeasuringTests.KernedWide, FacedMeasuringTests.KernedWide.MetricsTable['b'])); } public void RemembersTheGlyphForTheNextOne() { IFontMetrics wide = FacedMeasuringTests.KernedWide; var pen = new FacedPen(Runs()); pen.StepOver(wide, wide.MetricsTable['a']); CheckEqual(-3, pen.StepOver(wide, wide.MetricsTable['b'])); } } public class KerningIntoTests : TestFixture { public void ReturnsTheKerningWithoutSteppingOver() { IFontMetrics narrow = FacedMeasuringTests.Kerned; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['a']); CheckEqual(-1, pen.KerningInto(narrow, narrow.MetricsTable['b'])); CheckEqual(-1, pen.KerningInto(narrow, narrow.MetricsTable['b'])); } public void InAnotherFont_IsNone() { IFontMetrics narrow = FacedMeasuringTests.Kerned; IFontMetrics wide = FacedMeasuringTests.KernedWide; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['a']); CheckEqual(0, pen.KerningInto(wide, wide.MetricsTable['b'])); } } public class RestartTests : TestFixture { public void ForgetsTheGlyphBefore() { IFontMetrics narrow = FacedMeasuringTests.Kerned; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['a']); pen.Restart(); CheckEqual(0, pen.StepOver(narrow, narrow.MetricsTable['b'])); } } public class RowTests : TestFixture { public void StartsAtTheStartOfALine() { CheckEqual(0, new FacedPen(Runs()).Row); } public void IsTheLastGlyphsKerningRow() { IFontMetrics narrow = FacedMeasuringTests.Kerned; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['b']); CheckEqual(narrow.MetricsTable['b'].LeftKerningRow, pen.Row); } public void AfterRestarting_IsTheStartOfALine() { IFontMetrics narrow = FacedMeasuringTests.Kerned; var pen = new FacedPen(Runs()); pen.StepOver(narrow, narrow.MetricsTable['b']); pen.Restart(); CheckEqual(0, pen.Row); } } public class FaceAtTests : TestFixture { public void IsTheFontTheRunsSetTheCharacterIn() { var pen = new FacedPen(Runs((2, 4, FacedMeasuringTests.KernedWide))); CheckTrue(ReferenceEquals(FacedMeasuringTests.Kerned, pen.FaceAt(1))); CheckTrue(ReferenceEquals(FacedMeasuringTests.KernedWide, pen.FaceAt(3))); CheckTrue(ReferenceEquals(FacedMeasuringTests.Kerned, pen.FaceAt(0))); } } } }