using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnitTestSharp; namespace Glass.UnitTests { public class SpriteFontDefinitionTests : TestFixture { static SpriteFontDefinition MakeFont(char glyph, int xAdvance) { var font = new SpriteFontDefinition(); font.GlyphDefinitions[glyph] = new SpriteFontDefinition.GlyphDefinition { XAdvance = xAdvance }; return font; } public class HasGlyphTests : TestFixture { public void GlyphInTheFont_IsTrue() { CheckTrue(MakeFont('A', xAdvance: 7).HasGlyph('A')); } public void GlyphNotInTheFont_IsFalse() { CheckFalse(MakeFont('B', xAdvance: 7).HasGlyph('A')); } public void ZeroAdvanceGlyph_IsStillPresent() { CheckTrue(MakeFont('A', xAdvance: 0).HasGlyph('A')); } public void InvalidGlyphFallback_DoesNotCountAsPresent() { var font = MakeFont('A', xAdvance: 7); font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7 }; CheckFalse(font.HasGlyph('B')); } public void WhitespaceSubstitution_DoesNotCountAsPresent() { CheckFalse(MakeFont(' ', xAdvance: 7).HasGlyph('\t')); } } public class GlyphForTests : TestFixture { public void GlyphInTheFont_IsReturned() { var font = new SpriteFontDefinition(); var glyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7 }; font.GlyphDefinitions['A'] = glyph; CheckEqual(glyph, font.GlyphFor('A')); } public void GlyphNotInTheFont_FallsBackToTheInvalidGlyph() { var font = MakeFont('B', xAdvance: 7); var placeholder = new SpriteFontDefinition.GlyphDefinition { XAdvance = 3 }; font.InvalidGlyph = placeholder; CheckEqual(placeholder, font.GlyphFor('A')); } public void GlyphNotInTheFontAndNoInvalidGlyph_IsNull() { CheckNull(MakeFont('B', xAdvance: 7).GlyphFor('A')); } public void GlyphInTheFont_IsPreferredOverTheInvalidGlyph() { var font = new SpriteFontDefinition(); var glyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7 }; font.GlyphDefinitions['A'] = glyph; font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 3 }; CheckEqual(glyph, font.GlyphFor('A')); } public void WhitespaceNotInTheFont_FallsBackToTheSpaceGlyph() { var font = new SpriteFontDefinition(); var space = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; font.GlyphDefinitions[' '] = space; font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 9 }; CheckEqual(space, font.GlyphFor('\t')); } public void WhitespaceInTheFont_IsPreferredOverTheSpaceGlyph() { var font = new SpriteFontDefinition(); var tab = new SpriteFontDefinition.GlyphDefinition { XAdvance = 20 }; font.GlyphDefinitions['\t'] = tab; font.GlyphDefinitions[' '] = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; CheckEqual(tab, font.GlyphFor('\t')); } public void NonBreakingSpace_FallsBackToTheSpaceGlyph() { var font = new SpriteFontDefinition(); var space = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; font.GlyphDefinitions[' '] = space; CheckEqual(space, font.GlyphFor('\u00A0')); } public void UnicodeSpaceSeparator_FallsBackToTheSpaceGlyph() { var font = new SpriteFontDefinition(); var space = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; font.GlyphDefinitions[' '] = space; CheckEqual(space, font.GlyphFor('\u2003')); } public void WhitespaceNotInTheFontAndNoSpaceGlyph_FallsBackToTheInvalidGlyph() { var font = MakeFont('A', xAdvance: 7); var placeholder = new SpriteFontDefinition.GlyphDefinition { XAdvance = 9 }; font.InvalidGlyph = placeholder; CheckEqual(placeholder, font.GlyphFor('\t')); } public void NonWhitespaceNotInTheFont_DoesNotUseTheSpaceGlyph() { var font = new SpriteFontDefinition(); font.GlyphDefinitions[' '] = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; var placeholder = new SpriteFontDefinition.GlyphDefinition { XAdvance = 9 }; font.InvalidGlyph = placeholder; CheckEqual(placeholder, font.GlyphFor('\u0001')); } } public class GlyphWidthTests : TestFixture { public void GlyphInTheFont_ReturnsItsXAdvance() { var font = MakeFont('A', xAdvance: 7); CheckEqual(7, font.GlyphWidth('A')); } public void MissingGlyph_MeasuresTheInvalidGlyph() { var font = MakeFont('B', xAdvance: 7); font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 3 }; CheckEqual(3, font.GlyphWidth('A')); } public void MissingGlyphAndNoInvalidGlyph_IsZero() { CheckEqual(0, MakeFont('B', xAdvance: 7).GlyphWidth('A')); } public void MissingWhitespace_MeasuresTheSpaceGlyph() { var font = MakeFont(' ', xAdvance: 4); font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 9 }; CheckEqual(4, font.GlyphWidth('\t')); } public void ZeroAdvanceInvalidGlyph_MeasuresZeroRatherThanFallingThrough() { var font = MakeFont('B', xAdvance: 7); font.InvalidGlyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 0 }; CheckEqual(0, font.GlyphWidth('A')); } public void XAdvanceIsMeasuredRatherThanSizeX() { var font = new SpriteFontDefinition(); font.GlyphDefinitions['A'] = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7, Size = new Point(99, 99) }; CheckEqual(7, font.GlyphWidth('A')); } } public class SpaceBetweenGlyphsTests : TestFixture { public void SpaceBetweenGlyphsReturnsKerning() { var font = new SpriteFontDefinition(); font.Kernings[((short)'A', (short)'V')] = -2; CheckEqual(-2, font.SpaceBetweenGlyphs('A', 'V')); } public void SpaceBetweenGlyphsIsZeroWithNoKerningEntry() { var font = new SpriteFontDefinition(); CheckEqual(0, font.SpaceBetweenGlyphs('A', 'V')); } public void SpaceBetweenGlyphsIsZeroWhenLeftGlyphIsNull() { var font = new SpriteFontDefinition(); font.Kernings[((short)'A', (short)'V')] = -2; CheckEqual(0, font.SpaceBetweenGlyphs(null, 'V')); } public void SpaceBetweenGlyphsIsZeroWhenRightGlyphIsNull() { var font = new SpriteFontDefinition(); font.Kernings[((short)'A', (short)'V')] = -2; CheckEqual(0, font.SpaceBetweenGlyphs('A', null)); } public void SpaceBetweenGlyphsIsZeroWhenBothGlyphsAreNull() { var font = new SpriteFontDefinition(); CheckEqual(0, font.SpaceBetweenGlyphs(null, null)); } public void SpaceBetweenGlyphsIsDirectional() { var font = new SpriteFontDefinition(); font.Kernings[((short)'A', (short)'V')] = -2; // No entry for (V, A), so only one direction has kerning. CheckEqual(-2, font.SpaceBetweenGlyphs('A', 'V')); CheckEqual(0, font.SpaceBetweenGlyphs('V', 'A')); } } } public class GlyphDefinitionTests : TestFixture { public class ToStringTests : TestFixture { public void NoChannel_ReportsAdvanceSizeOriginAndOffset() { var glyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7, Size = new Point(3, 4), Origin = new Point(1, 2), Offset = new Point(-1, 5), }; CheckEqual("advance 7, 3x4 at (1, 2), offset (-1, 5)", glyph.ToString()); } public void Channel_IsAppended() { var glyph = new SpriteFontDefinition.GlyphDefinition { XAdvance = 7, Channel = 2 }; CheckEqual("advance 7, 0x0 at (0, 0), offset (0, 0), channel 2", glyph.ToString()); } public void TwoGlyphsDifferingOnlyInAdvance_ReadDifferently() { var wide = new SpriteFontDefinition.GlyphDefinition { XAdvance = 9 }; var narrow = new SpriteFontDefinition.GlyphDefinition { XAdvance = 4 }; CheckFalse(wide.ToString() == narrow.ToString()); } } } }