using Azimuth; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using UnitTestSharp; namespace Glass.UnitTests { public class RendererTests : TestFixture { public class TestRenderer : Renderer { public struct RenderArguments { public int context; public Material material; public Rect rect; public AffineMatrix transform; public override string ToString() { return $"context: {context}, material: {material}, rect: {rect}, transform: {transform}"; } } public List renderCalls = new List(); public override void Render(int context, SpriteMaterial material, Rect rect, AffineMatrix transform) { renderCalls.Add(new RenderArguments { context = context, material = material, rect = rect, transform = transform, }); } } public void RenderBaseMaterial() { var renderer = new TestRenderer(); CheckThrow(typeof(ArgumentException)); renderer.Render(7, new Material(), new Rect(), new AffineMatrix(0, Vector.Zero)); } public void RenderSpriteMaterial() { var spriteMaterial = new SpriteMaterial(new Point(3, 4)); var renderer = new TestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, spriteMaterial, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = spriteMaterial, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } public class RenderControlTests : TestFixture { public void Basic() { var control = new Panel(); var spriteMaterial = new SpriteMaterial(new Point(3, 4)); control.Material = spriteMaterial; var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11), }; control.Bounds = rect; var renderer = new TestRenderer(); renderer.Render(7, control); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = spriteMaterial, rect = rect, transform = AffineMatrix.Identity, }, }; CheckEqual(expected, renderer.renderCalls); } public void WithTransform() { var control = new Panel(); var spriteMaterial = new SpriteMaterial(new Point(3, 4)); control.Material = spriteMaterial; var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11), }; control.Bounds = rect; var renderer = new TestRenderer(); renderer.Render(7, control, AffineMatrix.BuildFromTranslation(new Vector(-3, -4))); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = spriteMaterial, rect = rect, transform = AffineMatrix.BuildFromTranslation(new Vector(-3, -4)), }, }; CheckEqual(expected, renderer.renderCalls); } public void WithChildren() { var parent = new Panel(); parent.Material = new SpriteMaterial(new Point(-3, -4)); var parentRect = new Rect { Size = new Vector(58, 39), Position = new Vector(-11, 15), }; parent.Bounds = parentRect; var child = parent.ChildControls.NewChild(); var childRect = new Rect { Size = new Vector(3, 4), Position = new Vector(15, 29), }; child.Bounds = childRect; child.Material = new SpriteMaterial(new Point(3, 4)); var renderer = new TestRenderer(); renderer.Render(7, parent, AffineMatrix.BuildFromTranslation(new Vector(7, 11))); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = (SpriteMaterial)parent.Material, rect = parentRect, transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)), }, new TestRenderer.RenderArguments { context = 7, material = (SpriteMaterial)child.Material, rect = childRect, transform = AffineMatrix.BuildFromTranslation(new Vector(-4, 26)), }, }; CheckEqual(expected, renderer.renderCalls); } } public class RenderControlContainer : TestFixture { public void ControlContainerRendersInReverseOrder() { var control1 = new Panel(); var spriteMaterial1 = new SpriteMaterial(new Point(3, 4)); control1.Material = spriteMaterial1; var rect1 = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11), }; control1.Bounds = rect1; var control2 = new Panel(); var spriteMaterial2 = new SpriteMaterial(new Point(-3, -4)); control2.Material = spriteMaterial2; var rect2 = new Rect { Size = new Vector(-3, -4), Position = new Vector(-7, -11), }; control2.Bounds = rect2; var container = new ControlContainer(); container.Add(control1); container.Add(control2); var renderer = new TestRenderer(); renderer.Render(7, container); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = spriteMaterial2, rect = rect2, transform = AffineMatrix.Identity, }, new TestRenderer.RenderArguments { context = 7, material = spriteMaterial1, rect = rect1, transform = AffineMatrix.Identity, }, }; CheckEqual(expected, renderer.renderCalls); } public class ParentMaterial : Material { public SpriteMaterial child; public override IList ChildMaterials => new[] { child }; } public void RecursesIntoGrandchildren() { var control1 = new Panel(); var spriteMaterial1 = new SpriteMaterial(new Point(3, 4)); control1.Material = spriteMaterial1; var rect1 = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11), }; control1.Bounds = rect1; var control2 = new Panel(); var spriteMaterial2 = new SpriteMaterial(new Point(-3, -4)); control2.Material = spriteMaterial2; var rect2 = new Rect { Size = new Vector(-3, -4), Position = new Vector(-7, -11), }; control2.Bounds = rect2; var parentControl = new Panel(); parentControl.ChildControls.Add(control1); parentControl.ChildControls.Add(control2); var parentMaterial = new SpriteMaterial(new Point(3, 4)); parentControl.Material = parentMaterial; var rectParent = new Rect { Size = new Vector(-100, -200), Position = new Vector(15, 48), }; parentControl.Bounds = rectParent; var container = new ControlContainer(); container.Add(parentControl); var renderer = new TestRenderer(); renderer.Render(7, container); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = parentMaterial, rect = rectParent, transform = AffineMatrix.Identity, }, new TestRenderer.RenderArguments { context = 7, material = spriteMaterial2, rect = rect2, transform = AffineMatrix.BuildFromTranslation(new Vector(15, 48)), }, new TestRenderer.RenderArguments { context = 7, material = spriteMaterial1, rect = rect1, transform = AffineMatrix.BuildFromTranslation(new Vector(15, 48)), }, }; CheckEqual(expected, renderer.renderCalls); } public void WithTransform() { var control1 = new Panel(); var spriteMaterial1 = new SpriteMaterial(new Point(3, 4)); control1.Material = spriteMaterial1; var rect1 = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11), }; control1.Bounds = rect1; var control2 = new Panel(); var spriteMaterial2 = new SpriteMaterial(new Point(-3, -4)); control2.Material = spriteMaterial2; var rect2 = new Rect { Size = new Vector(-3, -4), Position = new Vector(-7, -11), }; control2.Bounds = rect2; var container = new ControlContainer(); container.Add(control1); container.Add(control2); var renderer = new TestRenderer(); renderer.Render(7, container, AffineMatrix.BuildFromTranslation(new Vector(100, 200))); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = spriteMaterial2, rect = rect2, transform = AffineMatrix.BuildFromTranslation(new Vector(100, 200)), }, new TestRenderer.RenderArguments { context = 7, material = spriteMaterial1, rect = rect1, transform = AffineMatrix.BuildFromTranslation(new Vector(100, 200)), }, }; CheckEqual(expected, renderer.renderCalls); } } public class RenderDispatchTable : TestFixture { public void ToSpriteMaterial() { Material spriteMaterial = new SpriteMaterial(new Point(3, 4)); var renderer = new TestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, spriteMaterial, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = (SpriteMaterial)spriteMaterial, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } public class ThreeWideTestRenderer : TestRenderer { public override void Render(int context, ThreeWideMaterial material, Rect rect, AffineMatrix transform) { renderCalls.Add(new RenderArguments { context = context, material = material, rect = rect, transform = transform, }); } } public void ToThreeWideMaterial() { Material material = new ThreeWideMaterial(); var renderer = new ThreeWideTestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, material, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = material, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } public class NineSliceTestRenderer : TestRenderer { public override void Render(int context, NineSliceMaterial material, Rect rect, AffineMatrix transform) { renderCalls.Add(new RenderArguments { context = context, material = material, rect = rect, transform = transform, }); } } public void ToNineSliceMaterial() { Material material = new NineSliceMaterial(); var renderer = new NineSliceTestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, material, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = material, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } public class CustomMaterialTestRenderer : TestRenderer { public class CustomMaterial : Material { } public void Render(int context, CustomMaterial material, Rect rect, AffineMatrix transform) { renderCalls.Add(new RenderArguments { context = context, material = material, rect = rect, transform = transform, }); } } public void ToCustomMaterial() { Material material = new CustomMaterialTestRenderer.CustomMaterial(); var renderer = new CustomMaterialTestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, material, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = material, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } public class NullTestRenderer : TestRenderer { public override void NullRenderer(int context, Rect rect, AffineMatrix transform) { renderCalls.Add(new RenderArguments { context = context, material = null, rect = rect, transform = transform, }); } } public void NullMaterial() { Material material = null; var renderer = new NullTestRenderer(); var rect = new Rect { Size = new Vector(3, 4), Position = new Vector(7, 11) }; var transform = new AffineMatrix(0, new Vector(13, 17)); renderer.Render(7, material, rect, transform); var expected = new TestRenderer.RenderArguments[] { new TestRenderer.RenderArguments { context = 7, material = null, rect = rect, transform = transform, }, }; CheckEqual(expected, renderer.renderCalls); } } public void RenderNull() { var renderer = new TestRenderer(); CheckThrow(typeof(NotImplementedException)); renderer.NullRenderer(7, new Rect{}, AffineMatrix.Identity); } public class RenderThreeWide : TestFixture { public void MaterialsWithNoNaturalWidthOnlyDrawCenterMaterial() { var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(20, 30), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(1, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 1) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(new Point(3, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckNull(renderer.renderCalls[0].material.NaturalWidth); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[0].transform); CheckEqual(threeWideRect, renderer.renderCalls[0].rect); } public void MaterialsWithNaturalWidthFromSpriteSheetDrawAllThreeMaterials() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(100, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(7, renderer.renderCalls[1].context); CheckEqual(7, renderer.renderCalls[2].context); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(10, renderer.renderCalls[0].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[1].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[2].material.NaturalWidth); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[0].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[1].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[2].transform); var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(190, 200), Size = new Vector(10, 10), }; var midRect = new Rect { Position = new Vector(110, 200), Size = new Vector(80, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(midRect, renderer.renderCalls[1].rect); CheckEqual(rightRect, renderer.renderCalls[2].rect); } public void NaturalHeightTooLargeDrawsWithRectHeight() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 20, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(100, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(7, renderer.renderCalls[1].context); CheckEqual(7, renderer.renderCalls[2].context); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(10, renderer.renderCalls[0].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[1].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[2].material.NaturalWidth); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[0].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[1].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[2].transform); var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(190, 200), Size = new Vector(10, 10), }; var midRect = new Rect { Position = new Vector(110, 200), Size = new Vector(80, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(midRect, renderer.renderCalls[1].rect); CheckEqual(rightRect, renderer.renderCalls[2].rect); } public void NaturalHeightTooSmallDrawsWithRectHeight() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 5, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(100, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(7, renderer.renderCalls[1].context); CheckEqual(7, renderer.renderCalls[2].context); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(10, renderer.renderCalls[0].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[1].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[2].material.NaturalWidth); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[0].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[1].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[2].transform); var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(190, 200), Size = new Vector(10, 10), }; var midRect = new Rect { Position = new Vector(110, 200), Size = new Vector(80, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(midRect, renderer.renderCalls[1].rect); CheckEqual(rightRect, renderer.renderCalls[2].rect); } public void NaturalHeightUnevenDrawsWithRectHeight() { SpriteSheetAttribute spriteSheet0 = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 5, borderSize: 0, "foo1"); SpriteSheetAttribute spriteSheet1 = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo2"); SpriteSheetAttribute spriteSheet2 = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 20, borderSize: 0, "foo3"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); ((SpriteMaterial)material.Materials[0]).SpriteSheet = spriteSheet0; ((SpriteMaterial)material.Materials[1]).SpriteSheet = spriteSheet1; ((SpriteMaterial)material.Materials[2]).SpriteSheet = spriteSheet2; var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(100, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(7, renderer.renderCalls[1].context); CheckEqual(7, renderer.renderCalls[2].context); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(10, renderer.renderCalls[0].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[1].material.NaturalWidth); CheckEqual(10, renderer.renderCalls[2].material.NaturalWidth); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[0].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[1].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(3, 4)), renderer.renderCalls[2].transform); var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(190, 200), Size = new Vector(10, 10), }; var midRect = new Rect { Position = new Vector(110, 200), Size = new Vector(80, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(midRect, renderer.renderCalls[1].rect); CheckEqual(rightRect, renderer.renderCalls[2].rect); } public void CenterShrinksWhenRectTooNarrow() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(25, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var midRect = new Rect { Position = new Vector(110, 200), Size = new Vector(5, 10), }; var rightRect = new Rect { Position = new Vector(115, 200), Size = new Vector(10, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(midRect, renderer.renderCalls[1].rect); CheckEqual(rightRect, renderer.renderCalls[2].rect); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); } public void CenterNotDrawnWhenRectTooNarrow() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(20, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(2, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 2) { return; } var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(110, 200), Size = new Vector(10, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(rightRect, renderer.renderCalls[1].rect); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); } public void RightTruncatesWhenRectTooNarrow() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(15, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(2, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 2) { return; } var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; var rightRect = new Rect { Position = new Vector(110, 200), Size = new Vector(5, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(rightRect, renderer.renderCalls[1].rect); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); } public void OnlyLeftDrawnWhenRectTooNarrow() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(1, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 1) { return; } var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); } public void LeftTruncatesWhenRectTooNarrow() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(5, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(1, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 1) { return; } var leftRect = new Rect { Position = new Vector(100, 200), Size = new Vector(5, 10), }; CheckEqual(leftRect, renderer.renderCalls[0].rect); CheckEqual(new Point(2, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); } public void NothingDrawnWhenZeroWidth() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(0, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(0, renderer.renderCalls.Count); } public void NothingDrawWhenZeroHeight() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 0), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(0, renderer.renderCalls.Count); } public void NothingDrawnWhenNegativeWidth() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(-1, 10), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(0, renderer.renderCalls.Count); } public void NothingDrawWhenNegativeHeight() { SpriteSheetAttribute spriteSheet = new SpriteSheetAttribute( spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var material = SpriteMaterial.CreateThreeWide(new Point(3, 4)); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(3, 4)); var threeWideRect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, -1), }; renderer.Render(7, material, threeWideRect, transform); CheckEqual(0, renderer.renderCalls.Count); } } public class RenderNineSliceTests : TestFixture { public void MaterialsWithNoNaturalSizeOnlyDrawCenterMaterial() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(20, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(1, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 1) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(new Point(3, 4), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckNull(renderer.renderCalls[0].material.NaturalWidth); CheckNull(renderer.renderCalls[0].material.NaturalHeight); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[0].transform); CheckEqual(rect, renderer.renderCalls[0].rect); } public void MaterialsWithNaturalSizeDrawEveryMaterialIfThereIsRoom() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[6].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 5), (renderer.renderCalls[7].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[8].material as SpriteMaterial)?.CellLocation); var size = new Vector(10, 10); CheckEqual(new Rect { Position = new Vector(100, 200), Size = size }, renderer.renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = size }, renderer.renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = size }, renderer.renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = size }, renderer.renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = size }, renderer.renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = size }, renderer.renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = size }, renderer.renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = size }, renderer.renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(120, 220), Size = size }, renderer.renderCalls[8].rect); } public void ContextIsPassedToAllChildren() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); renderer.Render(7, material, new Rect{ Size = new Vector(30, 30) }, AffineMatrix.Identity); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } CheckEqual(7, renderer.renderCalls[0].context); CheckEqual(7, renderer.renderCalls[1].context); CheckEqual(7, renderer.renderCalls[2].context); CheckEqual(7, renderer.renderCalls[3].context); CheckEqual(7, renderer.renderCalls[4].context); CheckEqual(7, renderer.renderCalls[5].context); CheckEqual(7, renderer.renderCalls[6].context); CheckEqual(7, renderer.renderCalls[7].context); CheckEqual(7, renderer.renderCalls[8].context); } public void TransformIsPassedToAllChildren() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[0].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[1].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[2].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[3].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[4].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[5].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[6].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[7].transform); CheckEqual(AffineMatrix.BuildFromTranslation(new Vector(7, 11)), renderer.renderCalls[8].transform); } public void LeftColumnUsesMaxNaturalWidth() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetBig = new SpriteSheetAttribute(spriteSizeX: 20, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetSmall = new SpriteSheetAttribute(spriteSizeX: 5, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); ((SpriteMaterial)material.MiddleLeftMaterial).SpriteSheet = spriteSheetBig; ((SpriteMaterial)material.BottomLeftMaterial).SpriteSheet = spriteSheetSmall; var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(40, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } var size = new Vector(10, 10); var leftSize = new Vector(20, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = leftSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = size }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(130, 200), Size = size }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = leftSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = size }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(130, 210), Size = size }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = leftSize }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(120, 220), Size = size }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(130, 220), Size = size }, renderCalls[8].rect); } public void RightColumnMaxNaturalWidth() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetBig = new SpriteSheetAttribute(spriteSizeX: 20, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetSmall = new SpriteSheetAttribute(spriteSizeX: 5, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); ((SpriteMaterial)material.MiddleRightMaterial).SpriteSheet = spriteSheetBig; ((SpriteMaterial)material.BottomRightMaterial).SpriteSheet = spriteSheetSmall; var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(40, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } var size = new Vector(10, 10); var rightSize = new Vector(20, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = size }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = size }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = rightSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = size }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = size }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = rightSize }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = size }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = size }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(120, 220), Size = rightSize }, renderCalls[8].rect); } public void TopRowUsesMaxOfNaturalHeight() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetBig = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 20, borderSize: 0, "foo"); var spriteSheetSmall = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 5, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); ((SpriteMaterial)material.UpperMiddleMaterial).SpriteSheet = spriteSheetBig; ((SpriteMaterial)material.UpperRightMaterial).SpriteSheet = spriteSheetSmall; var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 40), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } var size = new Vector(10, 10); var topSize = new Vector(10, 20); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = topSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = topSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = topSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = size }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = size }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 220), Size = size }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 230), Size = size }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 230), Size = size }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(120, 230), Size = size }, renderCalls[8].rect); } public void BottomRowUsesMaxOfNaturalHeight() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); var spriteSheetBig = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 20, borderSize: 0, "foo"); var spriteSheetSmall = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 5, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); ((SpriteMaterial)material.BottomMiddleMaterial).SpriteSheet = spriteSheetBig; ((SpriteMaterial)material.BottomRightMaterial).SpriteSheet = spriteSheetSmall; var renderer = new TestRenderer(); var transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 40), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } var size = new Vector(10, 10); var bottomSize = new Vector(10, 20); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = size }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = size }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = size }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = size }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = size }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = size }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = bottomSize }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = bottomSize }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(120, 220), Size = bottomSize }, renderCalls[8].rect); } public void DoesNotRenderToZeroWidthRect() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(0, 40), }; renderer.Render(7, material, rect, AffineMatrix.Identity); CheckEqual(0, renderer.renderCalls.Count); } public void DoesNotRenderToNegativeWidthRect() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(-1, 40), }; renderer.Render(7, material, rect, AffineMatrix.Identity); CheckEqual(0, renderer.renderCalls.Count); } public void DoesNotRenderToZeroHeightRect() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(40, 0), }; renderer.Render(7, material, rect, AffineMatrix.Identity); CheckEqual(0, renderer.renderCalls.Count); } public void DoesNotRenderToNegativeHeightRect() { var material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); var spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(40, -1), }; renderer.Render(7, material, rect, AffineMatrix.Identity); CheckEqual(0, renderer.renderCalls.Count); } public class ColumnShrinkingBehaviorTests : TestFixture { NineSliceMaterial material; SpriteSheetAttribute spriteSheet; AffineMatrix transform; Vector position; public override void TestSetup() { material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); position = new Vector(100, 200); } public void MiddleColumnShrinksIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(25, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[6].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 5), (renderer.renderCalls[7].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[8].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var centerSize = new Vector(5, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = centerSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(115, 200), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = normalSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = centerSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(115, 210), Size = normalSize }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = normalSize }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = centerSize }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(115, 220), Size = normalSize }, renderCalls[8].rect); } public void MiddleColumnDoesNotRenderIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(20, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(6, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 6) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = normalSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = normalSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = normalSize }, renderCalls[5].rect); } public void RightColumnTruncatesIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(15, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(6, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 6) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var rightSize = new Vector(5, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = rightSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = rightSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = normalSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(110, 220), Size = rightSize }, renderCalls[5].rect); } public void RightColumnDoesNotRenderIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(10, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = normalSize }, renderCalls[2].rect); } public void LeftColumnTruncatesIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(5, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); var leftSize = new Vector(5, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = leftSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = leftSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(100, 220), Size = leftSize }, renderCalls[2].rect); } public void NothingRendersIfNotWideEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(0, 30), }; renderer.Render(7, material, rect, transform); CheckEqual(0, renderer.renderCalls.Count); } } public class RowShrinkingBehaviorTests : TestFixture { NineSliceMaterial material; SpriteSheetAttribute spriteSheet; AffineMatrix transform; Vector position; public override void TestSetup() { material = SpriteMaterial.CreateNineSlice(new Point(3, 4)); spriteSheet = new SpriteSheetAttribute(spriteSizeX: 10, spriteSizeY: 10, borderSize: 0, "foo"); SpriteMaterial.InitializeMaterial(material, spriteSheet); transform = AffineMatrix.BuildFromTranslation(new Vector(7, 11)); position = new Vector(100, 200); } public void MiddleRowShrinksIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 25), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(9, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 9) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 4), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 4), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 4), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[6].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 5), (renderer.renderCalls[7].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[8].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var centerSize = new Vector(10, 5); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = centerSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = centerSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = centerSize }, renderCalls[5].rect); CheckEqual(new Rect { Position = new Vector(100, 215), Size = normalSize }, renderCalls[6].rect); CheckEqual(new Rect { Position = new Vector(110, 215), Size = normalSize }, renderCalls[7].rect); CheckEqual(new Rect { Position = new Vector(120, 215), Size = normalSize }, renderCalls[8].rect); } public void MiddleRowDoesNotRenderIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 20), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(6, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 6) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 5), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = normalSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = normalSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = normalSize }, renderCalls[5].rect); } public void BottomRowTruncatesIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 15), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(6, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 6) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(2, 5), (renderer.renderCalls[3].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 5), (renderer.renderCalls[4].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 5), (renderer.renderCalls[5].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var bottomSize = new Vector(10, 5); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = normalSize }, renderCalls[2].rect); CheckEqual(new Rect { Position = new Vector(100, 210), Size = bottomSize }, renderCalls[3].rect); CheckEqual(new Rect { Position = new Vector(110, 210), Size = bottomSize }, renderCalls[4].rect); CheckEqual(new Rect { Position = new Vector(120, 210), Size = bottomSize }, renderCalls[5].rect); } public void BottomRowDoesNotRenderIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 10), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 10); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = normalSize }, renderCalls[2].rect); } public void TopRowTruncatesIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 5), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(3, renderer.renderCalls.Count); if (renderer.renderCalls.Count != 3) { return; } CheckEqual(new Point(2, 3), (renderer.renderCalls[0].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(3, 3), (renderer.renderCalls[1].material as SpriteMaterial)?.CellLocation); CheckEqual(new Point(4, 3), (renderer.renderCalls[2].material as SpriteMaterial)?.CellLocation); var normalSize = new Vector(10, 5); var renderCalls = renderer.renderCalls; CheckEqual(new Rect { Position = new Vector(100, 200), Size = normalSize }, renderCalls[0].rect); CheckEqual(new Rect { Position = new Vector(110, 200), Size = normalSize }, renderCalls[1].rect); CheckEqual(new Rect { Position = new Vector(120, 200), Size = normalSize }, renderCalls[2].rect); } public void NothingRendersIfNotTallEnough() { var renderer = new TestRenderer(); var rect = new Rect { Position = new Vector(100, 200), Size = new Vector(30, 0), }; renderer.Render(context: 7, material, rect, transform); CheckEqual(0, renderer.renderCalls.Count); } } } } }