Наследование: IVwGraphics
Пример #1
0
		public void PaintParaBox()
		{
			AssembledStyles styles = new AssembledStyles();
			var clientRuns = new List<IClientRun>();
			BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000);
			clientRuns.Add(box0);
			BlockBox box1 = new BlockBox(styles, Color.Blue, 36000, 18000);
			clientRuns.Add(box1);
			BlockBox box2 = new BlockBox(styles, Color.Red, 24000, 18000);
			clientRuns.Add(box2);
			BlockBox box3 = new BlockBox(styles, Color.Red, 72000, 36000);
			clientRuns.Add(box3);
			BlockBox box4 = new BlockBox(styles, Color.Red, 36000, 36000);
			clientRuns.Add(box4);

			TextSource source = new TextSource(clientRuns, null);
			ParaBox para = new ParaBox(styles, source);
			RootBox root = new RootBox(styles);
			root.AddBox(para);

			MockGraphics graphics = new MockGraphics();
			LayoutInfo layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);
			root.Layout(layoutArgs);

			PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
			root.Paint(graphics, ptrans);
			Assert.AreEqual(5, graphics.RectanglesDrawn.Count);
			VerifyRect(2, 2, 96, 48, graphics, 0, Color.Red);
			VerifyRect(2, 48+2, 48, 24, graphics, 1, Color.Blue);
			VerifyRect(2+48, 48 + 2, 32, 24, graphics, 2, Color.Red);
			VerifyRect(2, 24 + 48 + 2, 96, 48, graphics, 3, Color.Red);
			VerifyRect(2, 48 + 24 + 48 + 2, 48, 48, graphics, 4, Color.Red);
		}
Пример #2
0
        private void VerifyPaint(RootBox root, Rectangle clipRect, int xScrollOffset, int yScrollOffset, Rectangle[] paintRects)
        {
            MockGraphics graphics = new MockGraphics();

            graphics.ClipRectangle = clipRect;
            PaintTransform ptrans = new PaintTransform(0, 0, 96, 96, xScrollOffset, yScrollOffset, 96, 96);

            root.Paint(graphics, ptrans);
            var drawActions = graphics.DrawActions;             // after the paint, it gets created when first rect added.

            if (paintRects == null || paintRects.Length == 0)
            {
                Assert.IsTrue(drawActions == null || drawActions.Count == 0);
                return;
            }
            Assert.That(drawActions, Has.Count.EqualTo(paintRects.Length * 2));
            int position = 0;

            // First all the blocks get drawn in their PaintBackground routine
            foreach (var rect in paintRects)
            {
                VerifyRect(drawActions, ref position, rect);
            }
            // Then we verify that the PaintForeground routines got called.
            for (; position < drawActions.Count; position++)
            {
                Assert.That(drawActions[position], Is.InstanceOf(typeof(FgBlockBox)));
            }
        }
Пример #3
0
		public void PaintBarBox()
		{
			AssembledStyles styles = new AssembledStyles();
			BlockBox box = new BlockBox(styles, Color.Red, 72000, 36000);

			RootBox root = new RootBox(styles);
			root.AddBox(box);
			LayoutInfo transform = MakeLayoutInfo();
			root.Layout(transform);

			PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
			MockGraphics graphics = new MockGraphics();
			root.Paint(graphics, ptrans);
			Assert.AreEqual(1, graphics.RectanglesDrawn.Count);
			Assert.AreEqual(new Rectangle(2, 2, 96, 48), graphics.RectanglesDrawn[0]);
			Assert.AreEqual((int)ColorUtil.ConvertColorToBGR(Color.Red), graphics.BackColor);
		}
Пример #4
0
        public void PaintPictureBox()
        {
            AssembledStyles styles = new AssembledStyles();
            Bitmap          bm     = new Bitmap(20, 30);
            ImageBox        box    = new ImageBox(styles.WithMargins(new Thickness(72.0 / 96.0 * 2.0))
                                                  .WithBorders(new Thickness(72.0 / 96.0 * 3.0))
                                                  .WithPads(new Thickness(72.0 / 96.0 * 7.0, 72.0 / 96.0 * 8.0, 72.0 / 96.0 * 11.0, 72.0 / 96.0 * 13.0)), bm);

            RootBox  root  = new RootBox(styles);
            BlockBox block = new BlockBox(styles, Color.Yellow, 2000, 4000);

            root.AddBox(block);
            root.AddBox(box);
            LayoutInfo transform = MakeLayoutInfo();

            root.Layout(transform);
            Assert.That(box.Height, Is.EqualTo(30 + 2 * 2 + 3 * 2 + 8 + 13));
            Assert.That(box.Width, Is.EqualTo(20 + 2 * 2 + 3 * 2 + 7 + 11));
            Assert.That(box.Ascent, Is.EqualTo(box.Height));

            PaintTransform ptrans   = new PaintTransform(2, 4, 96, 96, 10, 40, 96, 96);
            MockGraphics   graphics = new MockGraphics();

            root.Paint(graphics, ptrans);
            Assert.That(graphics.LastRenderPictureArgs, Is.Not.Null);
            Assert.That(graphics.LastRenderPictureArgs.Picture, Is.EqualTo(box.Picture));
            Assert.That(graphics.LastRenderPictureArgs.X, Is.EqualTo(2 - 10 + 2 + 3 + 7));
            Assert.That(graphics.LastRenderPictureArgs.Y, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8));
            Assert.That(graphics.LastRenderPictureArgs.Cx, Is.EqualTo(20));
            Assert.That(graphics.LastRenderPictureArgs.Cy, Is.EqualTo(30));
            int hmWidth  = box.Picture.Width;
            int hmHeight = box.Picture.Height;

            Assert.That(graphics.LastRenderPictureArgs.XSrc, Is.EqualTo(0));
            Assert.That(graphics.LastRenderPictureArgs.YSrc, Is.EqualTo(hmHeight));
            Assert.That(graphics.LastRenderPictureArgs.CxSrc, Is.EqualTo(hmWidth));
            Assert.That(graphics.LastRenderPictureArgs.CySrc, Is.EqualTo(-hmHeight));
            Assert.That(graphics.LastRenderPictureArgs.RcWBounds.left, Is.EqualTo(2 - 10 + 2 + 3 + 7));
            Assert.That(graphics.LastRenderPictureArgs.RcWBounds.top, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8));
            Assert.That(graphics.LastRenderPictureArgs.RcWBounds.right, Is.EqualTo(2 - 10 + 2 + 3 + 7 + 20));
            Assert.That(graphics.LastRenderPictureArgs.RcWBounds.bottom, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8 + 30));
        }
Пример #5
0
        public void PaintBarBox()
        {
            AssembledStyles styles = new AssembledStyles();
            BlockBox        box    = new BlockBox(styles, Color.Red, 72000, 36000);

            RootBox root = new RootBox(styles);

            root.AddBox(box);
            LayoutInfo transform = MakeLayoutInfo();

            root.Layout(transform);

            PaintTransform ptrans   = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
            MockGraphics   graphics = new MockGraphics();

            root.Paint(graphics, ptrans);
            Assert.AreEqual(1, graphics.RectanglesDrawn.Count);
            Assert.AreEqual(new Rectangle(2, 2, 96, 48), graphics.RectanglesDrawn[0]);
            Assert.AreEqual((int)ColorUtil.ConvertColorToBGR(Color.Red), graphics.BackColor);
        }
Пример #6
0
        public void PaintParaBox()
        {
            AssembledStyles styles     = new AssembledStyles();
            var             clientRuns = new List <IClientRun>();
            BlockBox        box0       = new BlockBox(styles, Color.Red, 72000, 36000);

            clientRuns.Add(box0);
            BlockBox box1 = new BlockBox(styles, Color.Blue, 36000, 18000);

            clientRuns.Add(box1);
            BlockBox box2 = new BlockBox(styles, Color.Red, 24000, 18000);

            clientRuns.Add(box2);
            BlockBox box3 = new BlockBox(styles, Color.Red, 72000, 36000);

            clientRuns.Add(box3);
            BlockBox box4 = new BlockBox(styles, Color.Red, 36000, 36000);

            clientRuns.Add(box4);

            TextSource source = new TextSource(clientRuns, null);
            ParaBox    para   = new ParaBox(styles, source);
            RootBox    root   = new RootBox(styles);

            root.AddBox(para);

            MockGraphics graphics   = new MockGraphics();
            LayoutInfo   layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);

            root.Layout(layoutArgs);

            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);

            root.Paint(graphics, ptrans);
            Assert.AreEqual(5, graphics.RectanglesDrawn.Count);
            VerifyRect(2, 2, 96, 48, graphics, 0, Color.Red);
            VerifyRect(2, 48 + 2, 48, 24, graphics, 1, Color.Blue);
            VerifyRect(2 + 48, 48 + 2, 32, 24, graphics, 2, Color.Red);
            VerifyRect(2, 24 + 48 + 2, 96, 48, graphics, 3, Color.Red);
            VerifyRect(2, 48 + 24 + 48 + 2, 48, 48, graphics, 4, Color.Red);
        }
Пример #7
0
        public void BackgroundAndUnderlinePainting()
        {
            var     styles = new AssembledStyles();
            RootBox root   = new RootBoxFdo(styles);

            SetupFakeRootSite(root);
            var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            root.RendererFactory = layoutInfo.RendererFactory;
            root.Builder.Show(
                Paragraph.Containing(
                    Display.Of("plain"),
                    Display.Of("underOnYellow").Underline(FwUnderlineType.kuntSingle).BackColor(Color.Yellow)
                    ),
                Paragraph.Containing(
                    Display.Of("doubleRedOnPink").Underline(FwUnderlineType.kuntDouble, Color.Red).BackColor(Color.Pink),
                    Display.Of("dotted").Underline(FwUnderlineType.kuntDotted),
                    Display.Of("dottedOnYellow").Underline(FwUnderlineType.kuntDotted).BackColor(Color.Yellow)
                    ),
                Paragraph.Containing(
                    Display.Of("dashed").Underline(FwUnderlineType.kuntDashed),
                    Display.Of("dashedRed").Underline(FwUnderlineType.kuntDashed).ForeColor(Color.Red),
                    Display.Of("squiggle").Underline(FwUnderlineType.kuntSquiggle)
                    )
                );
            root.Layout(layoutInfo);

            var para1      = (ParaBox)root.FirstBox;
            var stringBox1 = (StringBox)para1.FirstBox;
            var seg1       = (FakeSegment)stringBox1.Segment;
            // A convenient place to test that literals get Chrp with default user ws.
            LgCharRenderProps chrp;
            int ichMin, ichLim;

            para1.Source.GetCharProps(0, out chrp, out ichMin, out ichLim);
            Assert.That(chrp.ws, Is.EqualTo(layoutInfo.RendererFactory.UserWs));
            // This segment has just one chunk of underline, the second run.
            seg1.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 10 }, Rights = new[] { 20 }, Tops = new[] { 15 }
            });
            // Todo: add expectations for each run of underlining.

            var para2      = (ParaBox)para1.Next;
            var stringBox2 = (StringBox)para2.FirstBox;
            var seg2       = (FakeSegment)stringBox2.Segment;

            // For the double red underline, we'll pretend there are two line segments.
            seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 5, 15 }, Rights = new[] { 10, 20 }, Tops = new[] { 15, 16 }
            });
            seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 12 }, Rights = new[] { 22 }, Tops = new[] { 13 }
            });
            seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 30 }, Rights = new[] { 41 }, Tops = new[] { 12 }
            });

            var para3      = (ParaBox)para2.Next;
            var stringBox3 = (StringBox)para3.FirstBox;
            var seg3       = (FakeSegment)stringBox3.Segment;

            seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 0 }, Rights = new[] { 10 }, Tops = new[] { 11 }
            });
            seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 10 }, Rights = new[] { 20 }, Tops = new[] { 11 }
            });
            seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
            {
                Lefts = new[] { 30 }, Rights = new[] { 40 }, Tops = new[] { 11 }
            });

            // We want to keep track of the sequence of paint operations in all three segments.
            var drawActions = new List <object>();

            seg1.DrawActions = seg2.DrawActions = seg3.DrawActions = drawActions;
            var vg = new MockGraphics();

            vg.DrawActions = drawActions;

            var site = (MockSite)root.Site;

            root.Paint(vg, site.m_transform);
            var paintTrans = site.m_transform;

            // We should have asked about each run of distinct underlining.
            VerifyCharPlacementCall(seg1, 0, "plain".Length, "plain".Length + "underOnYellow".Length,
                                    paintTrans.SourceRect, paintTrans.DestRect, vg, 1);

            // para/seg 2
            Rect srcRect = paintTrans.SourceRect;

            srcRect.top    -= para1.Height;
            srcRect.bottom -= para1.Height;
            VerifyCharPlacementCall(seg2, 0, 0, "doubleRedOnPink".Length,
                                    srcRect, paintTrans.DestRect, vg, 2);
            VerifyCharPlacementCall(seg2, 0, "doubleRedOnPink".Length, "doubleRedOnPink".Length + "dotted".Length,
                                    srcRect, paintTrans.DestRect, vg, 1);
            VerifyCharPlacementCall(seg2, 0, "doubleRedOnPink".Length + "dotted".Length,
                                    "doubleRedOnPink".Length + "dotted".Length + "dottedOnYellow".Length,
                                    srcRect, paintTrans.DestRect, vg, 1);

            // para/seg 3
            srcRect.top    -= para2.Height;
            srcRect.bottom -= para2.Height;
            VerifyCharPlacementCall(seg3, 0, 0, "dashed".Length,
                                    srcRect, paintTrans.DestRect, vg, 1);
            VerifyCharPlacementCall(seg3, 0, "dashed".Length, "dashed".Length + "dashedRed".Length,
                                    srcRect, paintTrans.DestRect, vg, 1);
            VerifyCharPlacementCall(seg3, 0, "dashed".Length + "dashedRed".Length,
                                    "dashed".Length + "dashedRed".Length + "squiggle".Length,
                                    srcRect, paintTrans.DestRect, vg, 1);
            // Todo: eventually arrange a run where ichBase is non-zero, and check what happens.

            // We want to check a lot of things about the drawing.
            // - all the background color and underline drawing should happen before any of the text drawing.
            // - the right stuff should be drawn to construct the underlines
            // - in particular dotted, dashed, and squiggle underlines should have the gaps and alternations
            // aligned, even if in different segments.

            // Todo: check actual line segs drawn

            int position = 0;             // in drawActions

            // Normal calls to Draw have the effect of painting the background. All three backgrounds
            // should be painted before the foreground. First we paint seg1 with background, since it has some.
            VerifyDraw(drawActions, ref position, seg1);
            // Next we draw its one horizontal line of underline.
            VerifyHorzLine(drawActions, ref position, 10, 20, 15, 1, new int[] { int.MaxValue }, 10);

            // Then segment 2's background
            VerifyDraw(drawActions, ref position, seg2);
            // And various lots of underline: double takes 2 per segment
            VerifyHorzLine(drawActions, ref position, 5, 10, 17, 1, new int[] { int.MaxValue }, 5);
            VerifyHorzLine(drawActions, ref position, 5, 10, 15, 1, new int[] { int.MaxValue }, 5);
            VerifyHorzLine(drawActions, ref position, 15, 20, 18, 1, new int[] { int.MaxValue }, 15);
            VerifyHorzLine(drawActions, ref position, 15, 20, 16, 1, new int[] { int.MaxValue }, 15);
            // dotted has non-trivial array of dx values (2 pix each)
            VerifyHorzLine(drawActions, ref position, 12, 22, 13, 1, new int[] { 2, 2 }, 12);
            // dotted has non-trivial array of dx values (2 pix each)
            VerifyHorzLine(drawActions, ref position, 30, 41, 12, 1, new int[] { 2, 2 }, 30);
            // No background in para 3, doesn't get a draw background call.
            //VerifyDraw(drawActions, ref position, seg3);
            // But underlines still drawn in the background phase
            // Dashed line
            VerifyHorzLine(drawActions, ref position, 0, 10, 11, 1, new int[] { 6, 3 }, 0);
            VerifyHorzLine(drawActions, ref position, 10, 20, 11, 1, new int[] { 6, 3 }, 10);
            // Todo: verify line segs drawn for squiggle.
            VerifyLine(drawActions, ref position, 30, 12, 32, 10, ColorUtil.ConvertColorToBGR(Color.Black));
            VerifyLine(drawActions, ref position, 32, 10, 34, 12, ColorUtil.ConvertColorToBGR(Color.Black));
            VerifyLine(drawActions, ref position, 34, 12, 36, 10, ColorUtil.ConvertColorToBGR(Color.Black));
            VerifyLine(drawActions, ref position, 36, 10, 38, 12, ColorUtil.ConvertColorToBGR(Color.Black));
            VerifyLine(drawActions, ref position, 38, 12, 40, 10, ColorUtil.ConvertColorToBGR(Color.Black));
            VerifyNbDraw(drawActions, ref position, seg1);
            VerifyNbDraw(drawActions, ref position, seg2);
            VerifyDraw(drawActions, ref position, seg3);
        }
Пример #8
0
		public void DrawingBordersandBackground()
		{
			var root = new RootBoxFdo(new AssembledStyles());
			SetupFakeRootSite(root);
			var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);
			root.RendererFactory = layoutInfo.RendererFactory;
			var mock1 = new MockData1() {SimpleThree = "This is the first paragraph."};
			// The length of the second paragraph is found by experiment to be enough so that
			// despite its lacking borders it also breaks into 2 lines in the second step.
			var mock2 = new MockData1() {SimpleThree = "Here is another paragraph. It needs to be a bit longer."};
			root.Builder.Show(
				Paragraph.Containing(Display.Of(() => mock1.SimpleThree)).BackColor(Color.Red)
					.Margins(1.Points(), 2.Points(), 3.Points(), 4.Points())
					.Borders(5.Points(), 6.Points(), 7.Points(), 8.Points(), Color.Blue)
					.Pads(9.Points(), 10.Points(), 11.Points(), 12.Points()),
				Paragraph.Containing(Display.Of(() => mock2.SimpleThree)).BackColor(Color.Yellow)
					.Margins(1.Points(), 2.Points(), 3.Points(), 4.Points()));
			root.Layout(layoutInfo);
			// We want to keep track of the sequence of paint operations in all three segments.
			var drawActions = new List<object>();
			var vg = new MockGraphics();
			vg.DrawActions = drawActions;
			var para1 = (ParaBox)root.FirstBox;
			var stringbox1 = (StringBox)para1.FirstBox;
			var seg1 = (FakeSegment)stringbox1.Segment;
			seg1.DrawActions = drawActions;
			var para2 = (ParaBox)para1.Next;
			var stringbox2 = (StringBox)para2.FirstBox;
			var seg2 = (FakeSegment)stringbox2.Segment;
			seg2.DrawActions = drawActions;

			var site = (MockSite)root.Site;
			root.Paint(vg, site.m_transform);
			var paintTrans = site.m_transform;
			int position = 0;

			int red = (int)ColorUtil.ConvertColorToBGR(Color.Red);
			int margLeft = layoutInfo.MpToPixelsX(1000);
			Assert.That(margLeft, Is.EqualTo(1));
			int bordLeft = layoutInfo.MpToPixelsX(5000);
			Assert.That(bordLeft, Is.EqualTo(7));
			int xOffset = 2 - 100; // how far it is pushed over by the offsets of the layoutInfo
			int margTop = layoutInfo.MpToPixelsY(2000);
			Assert.That(margTop, Is.EqualTo(3));
			int bordTop = layoutInfo.MpToPixelsY(6000);
			Assert.That(bordTop, Is.EqualTo(8));
			int yOffset = 2 - 200; // how far it is pushed down by the offsets of the layoutInfo
			int padLeft = layoutInfo.MpToPixelsX(9000);
			Assert.That(padLeft, Is.EqualTo(12));
			int padRight = layoutInfo.MpToPixelsX(11000);
			Assert.That(padRight, Is.EqualTo(15));
			int padTop = layoutInfo.MpToPixelsY(10000);
			Assert.That(padTop, Is.EqualTo(13));
			int padBottom = layoutInfo.MpToPixelsY(12000);
			Assert.That(padBottom, Is.EqualTo(16));
			// First it should draw a background rectangle for the first paragraph.
			// It is indented by the left margin and the left border, and down by the top margin and border.
			// The other side is determined by the size of the embedded box and the two pads.
			VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
				margLeft + bordLeft + xOffset + stringbox1.Width + padLeft + padRight,
				margTop + bordTop + yOffset + stringbox1.Height + padTop + padBottom,
				red);
			int bordBottom = layoutInfo.MpToPixelsY(8000);
			Assert.That(bordBottom, Is.EqualTo(11));
			int blue = (int)ColorUtil.ConvertColorToBGR(Color.Blue);
			// It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
			// but in fact the current implementation draws the left border first.
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
				margLeft + bordLeft + xOffset,
				margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
				blue);
			int bordRight = layoutInfo.MpToPixelsX(7000);
			Assert.That(bordRight, Is.EqualTo(9));
			// Then the top border
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
				margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
				margTop + bordTop + yOffset,
				blue);
			// Then the right border
			VerifyRect(drawActions, ref position,
				margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight,
				margTop + yOffset,
				margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
				margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
				blue);
			// Then the bottom border
			VerifyRect(drawActions, ref position,
				margLeft + xOffset,
				margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom,
				margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
				margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
				blue);
			// Figure an adjusted y offset for the second paragraph. Everything is down by the height
			// of the first paragraph, except that the top and bottom margins overlap by the
			// height of the smaller.
			int yOffset2 = yOffset + para1.Height - margTop;
			int yellow = (int)ColorUtil.ConvertColorToBGR(Color.Yellow);
			// Next a background block for the second paragraph.
			// (Background color should be reset for the embedded string boxes, so they should not draw their own
			// background.)
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
				margLeft + xOffset + stringbox2.Width,
				margTop + yOffset2 + stringbox2.Height,
				yellow);
			// Verify the position where the text is drawn
			VerifyDraw(drawActions, ref position, seg1, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
			VerifyDraw(drawActions, ref position, seg2, margLeft + 2, para1.Height + 2); //margTop cancels out
			// And that should be all!
			Assert.That(position, Is.EqualTo(drawActions.Count));

			// Verify that multi-lines in a paragraph are appropriately laid out with margin etc.
			int maxWidth = para1.Width - FakeRenderEngine.SimulatedWidth("paragraph");
			// This maxWidth should force each paragraph to make two segments.
			layoutInfo = HookupTests.MakeLayoutInfo(maxWidth, m_gm.VwGraphics, 55);
			root.Layout(layoutInfo);
			drawActions.Clear();
			position = 0;
			var stringbox1a = (StringBox)para1.FirstBox;
			var seg1a = (FakeSegment)stringbox1a.Segment;
			seg1a.DrawActions = drawActions;
			var stringbox1b = (StringBox)stringbox1a.Next;
			var seg1b = (FakeSegment)stringbox1b.Segment;
			seg1b.DrawActions = drawActions;
			var stringbox2a = (StringBox)para2.FirstBox;
			var seg2a = (FakeSegment)stringbox2a.Segment;
			seg2a.DrawActions = drawActions;
			var stringbox2b = (StringBox)stringbox2a.Next;
			var seg2b = (FakeSegment)stringbox2b.Segment;
			seg2b.DrawActions = drawActions;

			root.Paint(vg, site.m_transform);
			int margRight = layoutInfo.MpToPixelsX(3000);
			Assert.That(margRight, Is.EqualTo(4));
			// First it should draw a background rectangle for the first paragraph.
			// It is indented by the left margin and the left border, and down by the top margin and border.
			// The other side is determined by maxWidth minus the right margin and border.
			int contentHeight1 = stringbox1a.Height + stringbox1b.Height;
			VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
				maxWidth - margRight - bordRight + xOffset,
				margTop + bordTop + yOffset + contentHeight1 + padTop + padBottom,
				red);
			// It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
			// but in fact the current implementation draws the left border first.
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
				margLeft + bordLeft + xOffset,
				margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
				blue);
			// Then the top border
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
				maxWidth - margRight + xOffset,
				margTop + bordTop + yOffset,
				blue);
			// Then the right border
			VerifyRect(drawActions, ref position,
				maxWidth - margRight - bordRight + xOffset,
				margTop + yOffset,
				maxWidth - margRight + xOffset,
				margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
				blue);
			// Then the bottom border
			VerifyRect(drawActions, ref position,
				margLeft + xOffset,
				margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom,
				maxWidth - margRight + xOffset,
				margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
				blue);
			// Figure an adjusted y offset for the second paragraph. Everything is down by the height
			// of the first paragraph, except that the top and bottom margins overlap by the
			// height of the smaller.
			yOffset2 = yOffset + para1.Height - margTop;
			// Next a background block for the second paragraph.
			// (Background color should be reset for the embedded string boxes, so they should not draw their own
			// background.)
			VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
				maxWidth - margRight + xOffset,
				margTop + yOffset2 + stringbox2a.Height + stringbox2b.Height,
				yellow);
			// Verify the position where the text is drawn
			VerifyDraw(drawActions, ref position, seg1a, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
			VerifyDraw(drawActions, ref position, seg1b, margLeft + bordLeft + padLeft + 2,
				margTop + bordTop + padTop + 2 + stringbox1a.Height);
			VerifyDraw(drawActions, ref position, seg2a, margLeft + 2, para1.Height + 2); //margTop cancels out
			VerifyDraw(drawActions, ref position, seg2b, margLeft + 2, para1.Height + 2 + stringbox2a.Height); //margTop cancels out
			// And that should be all!
			Assert.That(position, Is.EqualTo(drawActions.Count));

			// A quick check that Relayout puts things in the same places.
			drawActions.Clear();
			position = 0;
			var fixupMap = new Dictionary<Box, Rectangle>();
			fixupMap[para1] = new Rectangle(0, 0, 10, 10);
			var oldstring1aLeft = stringbox1a.Left;
			var oldstring1bTop = stringbox1b.Top;
			using (var lcb = new LayoutCallbacks(root))
				root.Relayout(layoutInfo, fixupMap, lcb);
			Assert.That(drawActions.Count, Is.EqualTo(0));
			Assert.That(para1.FirstBox.Left, Is.EqualTo(oldstring1aLeft));
			Assert.That(para1.FirstBox.Next.Top, Is.EqualTo(oldstring1bTop));
		}
Пример #9
0
		public void PileAndBlock()
		{
			var root = new RootBoxFdo(new AssembledStyles());
			SetupFakeRootSite(root);
			var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);
			root.RendererFactory = layoutInfo.RendererFactory;
			var mock1 = new MockData1() { SimpleThree = "This is the first paragraph." };
			// The length of the second paragraph is found by experiment to be enough so that
			// despite its lacking borders it also breaks into 2 lines in the second step.
			var mock2 = new MockData1() { SimpleThree = "Here is another paragraph. It needs to be a bit longer." };
			root.Builder.Show(
				Div.Containing(
					Display.Block(Color.Red, 25000, 18000).BackColor(Color.Purple)
						.Margins(3000, 3000, 3000, 3000)
						.Border(5000, Color.Blue)
						.Pads(4000, 4000, 4000, 4000),
					Display.Block(Color.Green, 25000, 18000)
					).BackColor(Color.Pink) // these apply to div.
						.Margins(1000, 1000, 1000, 1000)
						.Border(2000, Color.Gold)
						.Pads(6000, 6000, 6000, 6000));
			root.Layout(layoutInfo);
			// We want to keep track of the sequence of paint operations in all three segments.
			var drawActions = new List<object>();
			var vg = new MockGraphics();
			vg.DrawActions = drawActions;

			var site = (MockSite)root.Site;
			root.Paint(vg, site.m_transform);
			var paintTrans = site.m_transform;
			int position = 0;
			int xOffset = 2 - 100; // how far it is pushed over by the offsets of the layoutInfo
			int yOffset = 2 - 200; // how far it is pushed down by the offsets of the layoutInfo

			int red = (int)ColorUtil.ConvertColorToBGR(Color.Red);
			int pink = (int)ColorUtil.ConvertColorToBGR(Color.Pink);
			int purple = (int)ColorUtil.ConvertColorToBGR(Color.Purple);
			int blue = (int)ColorUtil.ConvertColorToBGR(Color.Blue);
			int green = (int)ColorUtil.ConvertColorToBGR(Color.Green);
			int gold = (int)ColorUtil.ConvertColorToBGR(Color.Gold);
			// Technically we could do different conversions in the two directions, but for this test both dpi are the same.
			int margPile = layoutInfo.MpToPixelsX(1000);
			int bordPile = layoutInfo.MpToPixelsX(2000);
			int padPile = layoutInfo.MpToPixelsX(6000);
			int blockWidth = layoutInfo.MpToPixelsX(25000);
			int blockHeight = layoutInfo.MpToPixelsX(18000);
			int margBlock = layoutInfo.MpToPixelsX(3000);
			int bordBlock = layoutInfo.MpToPixelsX(5000);
			int padBlock = layoutInfo.MpToPixelsX(4000);

			// First a background rectangle for the whole pile.
			var leftPilePad = margPile + bordPile + xOffset;
			var topPilePad = margPile + bordPile + yOffset;
			var rightPilePad = margPile + bordPile + 2 * padPile + blockWidth + 2 * margBlock + 2 * bordBlock + 2 * padBlock + xOffset;
			var bottomPilePad = margPile + bordPile + 2 * padPile + 2 * blockHeight + 2 * margBlock + 2 * bordBlock + 2 * padBlock + yOffset;
			VerifyRect(drawActions, ref position, leftPilePad, topPilePad, rightPilePad, bottomPilePad, pink);
			// Left border, whole pile
			VerifyRect(drawActions, ref position, leftPilePad - bordPile, topPilePad - bordPile,
				leftPilePad, bottomPilePad + bordPile, gold);
			// top border, whole pile
			VerifyRect(drawActions, ref position, leftPilePad - bordPile, topPilePad - bordPile,
				rightPilePad + bordPile, topPilePad, gold);
			// right border, whole pile
			VerifyRect(drawActions, ref position, rightPilePad, topPilePad - bordPile,
				rightPilePad + bordPile, bottomPilePad + bordPile, gold);
			// bottom border, whole pile
			VerifyRect(drawActions, ref position, leftPilePad - bordPile, bottomPilePad,
				rightPilePad + bordPile, bottomPilePad + bordPile, gold);

			// background and border for first block.
			var leftBlockPad = margPile + bordPile + padPile + margBlock + bordBlock + xOffset;
			var topBlockPad = margPile + bordPile + padPile + margBlock + bordBlock + yOffset;
			var rightBlockPad = margPile + bordPile + padPile + margBlock + bordBlock + 2 * padBlock + blockWidth + xOffset;
			var bottomBlockPad = margPile + bordPile + padPile + margBlock + bordBlock + 2 * padBlock + blockHeight + yOffset;
			VerifyRect(drawActions, ref position, leftBlockPad, topBlockPad, rightBlockPad, bottomBlockPad, purple);
			// Left border, whole pile
			VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, topBlockPad - bordBlock,
				leftBlockPad, bottomBlockPad + bordBlock, blue);
			// top border, whole pile
			VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, topBlockPad - bordBlock,
				rightBlockPad + bordBlock, topBlockPad, blue);
			// right border, whole pile
			VerifyRect(drawActions, ref position, rightBlockPad, topBlockPad - bordBlock,
				rightBlockPad + bordBlock, bottomBlockPad + bordBlock, blue);
			// bottom border, whole pile
			VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, bottomBlockPad,
				rightBlockPad + bordBlock, bottomBlockPad + bordBlock, blue);
			// The first block itself.
			VerifyRect(drawActions, ref position, leftBlockPad + padBlock, topBlockPad + padBlock,
				leftBlockPad + padBlock + blockWidth, topBlockPad + padBlock + blockHeight, red);
			// The second block itself.
			var topBlock2 = bottomBlockPad + bordBlock + margBlock;
			VerifyRect(drawActions, ref position, leftPilePad + padPile, topBlock2,
				leftPilePad + padPile + blockWidth, topBlock2 + blockHeight, green);
			// And that should be all!
			Assert.That(position, Is.EqualTo(drawActions.Count));

			// A quick check that Relayout puts things in the same places.
			drawActions.Clear();
			var fixupMap = new Dictionary<Box, Rectangle>();
			var div1 = (DivBox) root.FirstBox;
			var block1 = div1.FirstBox;
			fixupMap[div1] = new Rectangle(0, 0, 10, 10);
			fixupMap[block1] = new Rectangle(0, 0, 10, 10);
			var oldblock1Left = block1.Left;
			var oldblock1bTop = block1.Top;
			using (var lcb = new LayoutCallbacks(root))
				root.Relayout(layoutInfo, fixupMap, lcb);
			Assert.That(drawActions.Count, Is.EqualTo(0));
			Assert.That(div1.FirstBox.Left, Is.EqualTo(oldblock1Left));
			Assert.That(div1.FirstBox.Top, Is.EqualTo(oldblock1bTop));
		}
Пример #10
0
		void VerifyRect(int x, int y, int width, int height, MockGraphics graphics, int index, Color color)
		{
			Assert.AreEqual(new Rectangle(x, y, width, height), graphics.RectanglesDrawn[index]);
			Assert.AreEqual((int)ColorUtil.ConvertColorToBGR(color), graphics.RectColorsDrawn[index]);

		}
Пример #11
0
		public void ValidSelections()
		{
			AssembledStyles styles = new AssembledStyles();
			var clientRuns = new List<IClientRun>();
			var run0 = new StringClientRun("First run", styles);
			var run1 = new StringClientRun("Middle run", styles);
			BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000);
			var run2 = new StringClientRun("Last run", styles);
			clientRuns.Add(run0);
			clientRuns.Add(run1);
			clientRuns.Add(box0);
			clientRuns.Add(run2);
			TextSource source = new TextSource(clientRuns, null);
			ParaBox para0 = new ParaBox(styles, source);
			run0.Hookup = new LiteralStringParaHookup(para0, para0);
			run1.Hookup = new LiteralStringParaHookup(para0, para0);
			run2.Hookup = new LiteralStringParaHookup(para0, para0);
			DivBox div = new DivBox(styles);
			RootBox root = new RootBox(styles);
			para0.Container = div;
			MockGraphics graphics = new MockGraphics();
			LayoutInfo layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);
			root.Layout(layoutArgs);

			root.AddBox(div);
			var sel = para0.SelectAtStart();
			root.Selection = sel;

			Assert.That(!root.Selection.IsValid);

			div.AddBox(para0);
			root.RemoveBoxes(div, div);
			div.Container = root;

			Assert.That(!root.Selection.IsValid);

			root.AddBox(div);

			Assert.That(root.Selection.IsValid);

			(root.Selection as InsertionPoint).Hookup.ClientRunIndex = 4;

			Assert.That(!root.Selection.IsValid);

			(root.Selection as InsertionPoint).Hookup.ClientRunIndex = 2;

			Assert.That(!root.Selection.IsValid);

			(root.Selection as InsertionPoint).Hookup.ClientRunIndex = 0;
			(root.Selection as InsertionPoint).StringPosition = 10;

			Assert.That(!root.Selection.IsValid);

			(root.Selection as InsertionPoint).StringPosition = 0;
			run0.Hookup = null;

			Assert.That(!root.Selection.IsValid);

			run0.Hookup = new LiteralStringParaHookup(para0, para0);
			sel = para0.SelectAtStart();
			root.Selection = sel;

			Assert.That(root.Selection.IsValid);
		}
Пример #12
0
		public void BackgroundAndUnderlinePainting()
		{
			var styles = new AssembledStyles();
			RootBox root = new RootBoxFdo(styles);
			SetupFakeRootSite(root);
			var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);
			root.RendererFactory = layoutInfo.RendererFactory;
			root.Builder.Show(
				Paragraph.Containing(
					Display.Of("plain"),
					Display.Of("underOnYellow").Underline(FwUnderlineType.kuntSingle).BackColor(Color.Yellow)
					),
				Paragraph.Containing(
					Display.Of("doubleRedOnPink").Underline(FwUnderlineType.kuntDouble, Color.Red).BackColor(Color.Pink),
					Display.Of("dotted").Underline(FwUnderlineType.kuntDotted),
					Display.Of("dottedOnYellow").Underline(FwUnderlineType.kuntDotted).BackColor(Color.Yellow)
					),
				Paragraph.Containing(
					Display.Of("dashed").Underline(FwUnderlineType.kuntDashed),
					Display.Of("dashedRed").Underline(FwUnderlineType.kuntDashed).ForeColor(Color.Red),
					Display.Of("squiggle").Underline(FwUnderlineType.kuntSquiggle)
					)
				);
			root.Layout(layoutInfo);

			var para1 = (ParaBox)root.FirstBox;
			var stringBox1 = (StringBox)para1.FirstBox;
			var seg1 = (FakeSegment)stringBox1.Segment;
			// A convenient place to test that literals get Chrp with default user ws.
			LgCharRenderProps chrp;
			int ichMin, ichLim;
			para1.Source.GetCharProps(0, out chrp, out ichMin, out ichLim);
			Assert.That(chrp.ws, Is.EqualTo(layoutInfo.RendererFactory.UserWs));
			// This segment has just one chunk of underline, the second run.
			seg1.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
												{Lefts = new[] {10}, Rights = new[] {20}, Tops = new[] {15}});
			// Todo: add expectations for each run of underlining.

			var para2 = (ParaBox)para1.Next;
			var stringBox2 = (StringBox)para2.FirstBox;
			var seg2 = (FakeSegment)stringBox2.Segment;
			// For the double red underline, we'll pretend there are two line segments.
			seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 5, 15 }, Rights = new[] { 10, 20 }, Tops = new[] { 15, 16 } });
			seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 12 }, Rights = new[] { 22 }, Tops = new[] { 13 } });
			seg2.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 30 }, Rights = new[] { 41 }, Tops = new[] { 12 } });

			var para3 = (ParaBox)para2.Next;
			var stringBox3 = (StringBox)para3.FirstBox;
			var seg3 = (FakeSegment)stringBox3.Segment;
			seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 0 }, Rights = new[] { 10 }, Tops = new[] { 11 } });
			seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 10 }, Rights = new[] { 20 }, Tops = new[] { 11 } });
			seg3.NextCharPlacementResults.Add(new FakeSegment.CharPlacementResults()
				{ Lefts = new[] { 30 }, Rights = new[] { 40 }, Tops = new[] { 11 } });

			// We want to keep track of the sequence of paint operations in all three segments.
			var drawActions = new List<object>();
			seg1.DrawActions = seg2.DrawActions = seg3.DrawActions = drawActions;
			var vg = new MockGraphics();
			vg.DrawActions = drawActions;

			var site = (MockSite)root.Site;
			root.Paint(vg, site.m_transform);
			var paintTrans = site.m_transform;

			// We should have asked about each run of distinct underlining.
			VerifyCharPlacementCall(seg1, 0, "plain".Length, "plain".Length + "underOnYellow".Length,
				paintTrans.SourceRect, paintTrans.DestRect, vg, 1);

			// para/seg 2
			Rect srcRect = paintTrans.SourceRect;
			srcRect.top -= para1.Height;
			srcRect.bottom -= para1.Height;
			VerifyCharPlacementCall(seg2, 0, 0, "doubleRedOnPink".Length,
				srcRect, paintTrans.DestRect, vg, 2);
			VerifyCharPlacementCall(seg2, 0, "doubleRedOnPink".Length, "doubleRedOnPink".Length + "dotted".Length,
				srcRect, paintTrans.DestRect, vg, 1);
			VerifyCharPlacementCall(seg2, 0, "doubleRedOnPink".Length + "dotted".Length,
				"doubleRedOnPink".Length + "dotted".Length + "dottedOnYellow".Length,
				srcRect, paintTrans.DestRect, vg, 1);

			// para/seg 3
			srcRect.top -= para2.Height;
			srcRect.bottom -= para2.Height;
			VerifyCharPlacementCall(seg3, 0, 0, "dashed".Length,
				srcRect, paintTrans.DestRect, vg, 1);
			VerifyCharPlacementCall(seg3, 0, "dashed".Length, "dashed".Length + "dashedRed".Length,
				srcRect, paintTrans.DestRect, vg, 1);
			VerifyCharPlacementCall(seg3, 0, "dashed".Length + "dashedRed".Length,
				"dashed".Length + "dashedRed".Length + "squiggle".Length,
				srcRect, paintTrans.DestRect, vg, 1);
			// Todo: eventually arrange a run where ichBase is non-zero, and check what happens.

			// We want to check a lot of things about the drawing.
			// - all the background color and underline drawing should happen before any of the text drawing.
			// - the right stuff should be drawn to construct the underlines
			// - in particular dotted, dashed, and squiggle underlines should have the gaps and alternations
			// aligned, even if in different segments.

			// Todo: check actual line segs drawn

			int position = 0; // in drawActions
			// Normal calls to Draw have the effect of painting the background. All three backgrounds
			// should be painted before the foreground. First we paint seg1 with background, since it has some.
			VerifyDraw(drawActions, ref position, seg1);
			// Next we draw its one horizontal line of underline.
			VerifyHorzLine(drawActions, ref position, 10, 20, 15, 1, new int[] {int.MaxValue}, 10);

			// Then segment 2's background
			VerifyDraw(drawActions, ref position, seg2);
			// And various lots of underline: double takes 2 per segment
			VerifyHorzLine(drawActions, ref position, 5, 10, 17, 1, new int[] { int.MaxValue }, 5);
			VerifyHorzLine(drawActions, ref position, 5, 10, 15, 1, new int[] { int.MaxValue }, 5);
			VerifyHorzLine(drawActions, ref position, 15, 20, 18, 1, new int[] { int.MaxValue }, 15);
			VerifyHorzLine(drawActions, ref position, 15, 20, 16, 1, new int[] { int.MaxValue }, 15);
			// dotted has non-trivial array of dx values (2 pix each)
			VerifyHorzLine(drawActions, ref position, 12, 22, 13, 1, new int[] { 2, 2 }, 12);
			// dotted has non-trivial array of dx values (2 pix each)
			VerifyHorzLine(drawActions, ref position, 30, 41, 12, 1, new int[] { 2, 2 }, 30);
			// No background in para 3, doesn't get a draw background call.
			//VerifyDraw(drawActions, ref position, seg3);
			// But underlines still drawn in the background phase
			// Dashed line
			VerifyHorzLine(drawActions, ref position, 0, 10, 11, 1, new int[] { 6, 3 }, 0);
			VerifyHorzLine(drawActions, ref position, 10, 20, 11, 1, new int[] { 6, 3 }, 10);
			// Todo: verify line segs drawn for squiggle.
			VerifyLine(drawActions, ref position, 30, 12, 32, 10, ColorUtil.ConvertColorToBGR(Color.Black));
			VerifyLine(drawActions, ref position, 32, 10, 34, 12, ColorUtil.ConvertColorToBGR(Color.Black));
			VerifyLine(drawActions, ref position, 34, 12, 36, 10, ColorUtil.ConvertColorToBGR(Color.Black));
			VerifyLine(drawActions, ref position, 36, 10, 38, 12, ColorUtil.ConvertColorToBGR(Color.Black));
			VerifyLine(drawActions, ref position, 38, 12, 40, 10, ColorUtil.ConvertColorToBGR(Color.Black));
			VerifyNbDraw(drawActions, ref position, seg1);
			VerifyNbDraw(drawActions, ref position, seg2);
			VerifyDraw(drawActions, ref position, seg3);
		}
Пример #13
0
        public void DrawingBordersandBackground()
        {
            var root = new RootBoxFdo(new AssembledStyles());

            SetupFakeRootSite(root);
            var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            root.RendererFactory = layoutInfo.RendererFactory;
            var mock1 = new MockData1()
            {
                SimpleThree = "This is the first paragraph."
            };
            // The length of the second paragraph is found by experiment to be enough so that
            // despite its lacking borders it also breaks into 2 lines in the second step.
            var mock2 = new MockData1()
            {
                SimpleThree = "Here is another paragraph. It needs to be a bit longer."
            };

            root.Builder.Show(
                Paragraph.Containing(Display.Of(() => mock1.SimpleThree)).BackColor(Color.Red)
                .Margins(1.Points(), 2.Points(), 3.Points(), 4.Points())
                .Borders(5.Points(), 6.Points(), 7.Points(), 8.Points(), Color.Blue)
                .Pads(9.Points(), 10.Points(), 11.Points(), 12.Points()),
                Paragraph.Containing(Display.Of(() => mock2.SimpleThree)).BackColor(Color.Yellow)
                .Margins(1.Points(), 2.Points(), 3.Points(), 4.Points()));
            root.Layout(layoutInfo);
            // We want to keep track of the sequence of paint operations in all three segments.
            var drawActions = new List <object>();
            var vg          = new MockGraphics();

            vg.DrawActions = drawActions;
            var para1      = (ParaBox)root.FirstBox;
            var stringbox1 = (StringBox)para1.FirstBox;
            var seg1       = (FakeSegment)stringbox1.Segment;

            seg1.DrawActions = drawActions;
            var para2      = (ParaBox)para1.Next;
            var stringbox2 = (StringBox)para2.FirstBox;
            var seg2       = (FakeSegment)stringbox2.Segment;

            seg2.DrawActions = drawActions;

            var site = (MockSite)root.Site;

            root.Paint(vg, site.m_transform);
            var paintTrans = site.m_transform;
            int position   = 0;

            int red      = (int)ColorUtil.ConvertColorToBGR(Color.Red);
            int margLeft = layoutInfo.MpToPixelsX(1000);

            Assert.That(margLeft, Is.EqualTo(1));
            int bordLeft = layoutInfo.MpToPixelsX(5000);

            Assert.That(bordLeft, Is.EqualTo(7));
            int xOffset = 2 - 100;             // how far it is pushed over by the offsets of the layoutInfo
            int margTop = layoutInfo.MpToPixelsY(2000);

            Assert.That(margTop, Is.EqualTo(3));
            int bordTop = layoutInfo.MpToPixelsY(6000);

            Assert.That(bordTop, Is.EqualTo(8));
            int yOffset = 2 - 200;             // how far it is pushed down by the offsets of the layoutInfo
            int padLeft = layoutInfo.MpToPixelsX(9000);

            Assert.That(padLeft, Is.EqualTo(12));
            int padRight = layoutInfo.MpToPixelsX(11000);

            Assert.That(padRight, Is.EqualTo(15));
            int padTop = layoutInfo.MpToPixelsY(10000);

            Assert.That(padTop, Is.EqualTo(13));
            int padBottom = layoutInfo.MpToPixelsY(12000);

            Assert.That(padBottom, Is.EqualTo(16));
            // First it should draw a background rectangle for the first paragraph.
            // It is indented by the left margin and the left border, and down by the top margin and border.
            // The other side is determined by the size of the embedded box and the two pads.
            VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
                       margLeft + bordLeft + xOffset + stringbox1.Width + padLeft + padRight,
                       margTop + bordTop + yOffset + stringbox1.Height + padTop + padBottom,
                       red);
            int bordBottom = layoutInfo.MpToPixelsY(8000);

            Assert.That(bordBottom, Is.EqualTo(11));
            int blue = (int)ColorUtil.ConvertColorToBGR(Color.Blue);

            // It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
            // but in fact the current implementation draws the left border first.
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            int bordRight = layoutInfo.MpToPixelsX(7000);

            Assert.That(bordRight, Is.EqualTo(9));
            // Then the top border
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset,
                       blue);
            // Then the right border
            VerifyRect(drawActions, ref position,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight,
                       margTop + yOffset,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            // Then the bottom border
            VerifyRect(drawActions, ref position,
                       margLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom,
                       margLeft + bordLeft + xOffset + padLeft + stringbox1.Width + padRight + bordRight,
                       margTop + bordTop + yOffset + padTop + stringbox1.Height + padBottom + bordBottom,
                       blue);
            // Figure an adjusted y offset for the second paragraph. Everything is down by the height
            // of the first paragraph, except that the top and bottom margins overlap by the
            // height of the smaller.
            int yOffset2 = yOffset + para1.Height - margTop;
            int yellow   = (int)ColorUtil.ConvertColorToBGR(Color.Yellow);

            // Next a background block for the second paragraph.
            // (Background color should be reset for the embedded string boxes, so they should not draw their own
            // background.)
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
                       margLeft + xOffset + stringbox2.Width,
                       margTop + yOffset2 + stringbox2.Height,
                       yellow);
            // Verify the position where the text is drawn
            VerifyDraw(drawActions, ref position, seg1, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
            VerifyDraw(drawActions, ref position, seg2, margLeft + 2, para1.Height + 2);             //margTop cancels out
            // And that should be all!
            Assert.That(position, Is.EqualTo(drawActions.Count));

            // Verify that multi-lines in a paragraph are appropriately laid out with margin etc.
            int maxWidth = para1.Width - FakeRenderEngine.SimulatedWidth("paragraph");

            // This maxWidth should force each paragraph to make two segments.
            layoutInfo = HookupTests.MakeLayoutInfo(maxWidth, m_gm.VwGraphics, 55);
            root.Layout(layoutInfo);
            drawActions.Clear();
            position = 0;
            var stringbox1a = (StringBox)para1.FirstBox;
            var seg1a       = (FakeSegment)stringbox1a.Segment;

            seg1a.DrawActions = drawActions;
            var stringbox1b = (StringBox)stringbox1a.Next;
            var seg1b       = (FakeSegment)stringbox1b.Segment;

            seg1b.DrawActions = drawActions;
            var stringbox2a = (StringBox)para2.FirstBox;
            var seg2a       = (FakeSegment)stringbox2a.Segment;

            seg2a.DrawActions = drawActions;
            var stringbox2b = (StringBox)stringbox2a.Next;
            var seg2b       = (FakeSegment)stringbox2b.Segment;

            seg2b.DrawActions = drawActions;

            root.Paint(vg, site.m_transform);
            int margRight = layoutInfo.MpToPixelsX(3000);

            Assert.That(margRight, Is.EqualTo(4));
            // First it should draw a background rectangle for the first paragraph.
            // It is indented by the left margin and the left border, and down by the top margin and border.
            // The other side is determined by maxWidth minus the right margin and border.
            int contentHeight1 = stringbox1a.Height + stringbox1b.Height;

            VerifyRect(drawActions, ref position, margLeft + bordLeft + xOffset, margTop + bordTop + yOffset,
                       maxWidth - margRight - bordRight + xOffset,
                       margTop + bordTop + yOffset + contentHeight1 + padTop + padBottom,
                       red);
            // It's arbitrary what order we draw the borders, and I wish the test didn't specify it,
            // but in fact the current implementation draws the left border first.
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       margLeft + bordLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Then the top border
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset,
                       blue);
            // Then the right border
            VerifyRect(drawActions, ref position,
                       maxWidth - margRight - bordRight + xOffset,
                       margTop + yOffset,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Then the bottom border
            VerifyRect(drawActions, ref position,
                       margLeft + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom,
                       maxWidth - margRight + xOffset,
                       margTop + bordTop + yOffset + padTop + contentHeight1 + padBottom + bordBottom,
                       blue);
            // Figure an adjusted y offset for the second paragraph. Everything is down by the height
            // of the first paragraph, except that the top and bottom margins overlap by the
            // height of the smaller.
            yOffset2 = yOffset + para1.Height - margTop;
            // Next a background block for the second paragraph.
            // (Background color should be reset for the embedded string boxes, so they should not draw their own
            // background.)
            VerifyRect(drawActions, ref position, margLeft + xOffset, margTop + yOffset2,
                       maxWidth - margRight + xOffset,
                       margTop + yOffset2 + stringbox2a.Height + stringbox2b.Height,
                       yellow);
            // Verify the position where the text is drawn
            VerifyDraw(drawActions, ref position, seg1a, margLeft + bordLeft + padLeft + 2, margTop + bordTop + padTop + 2);
            VerifyDraw(drawActions, ref position, seg1b, margLeft + bordLeft + padLeft + 2,
                       margTop + bordTop + padTop + 2 + stringbox1a.Height);
            VerifyDraw(drawActions, ref position, seg2a, margLeft + 2, para1.Height + 2);                      //margTop cancels out
            VerifyDraw(drawActions, ref position, seg2b, margLeft + 2, para1.Height + 2 + stringbox2a.Height); //margTop cancels out
            // And that should be all!
            Assert.That(position, Is.EqualTo(drawActions.Count));

            // A quick check that Relayout puts things in the same places.
            drawActions.Clear();
            position = 0;
            var fixupMap = new Dictionary <Box, Rectangle>();

            fixupMap[para1] = new Rectangle(0, 0, 10, 10);
            var oldstring1aLeft = stringbox1a.Left;
            var oldstring1bTop  = stringbox1b.Top;

            using (var lcb = new LayoutCallbacks(root))
                root.Relayout(layoutInfo, fixupMap, lcb);
            Assert.That(drawActions.Count, Is.EqualTo(0));
            Assert.That(para1.FirstBox.Left, Is.EqualTo(oldstring1aLeft));
            Assert.That(para1.FirstBox.Next.Top, Is.EqualTo(oldstring1bTop));
        }
Пример #14
0
 void VerifyRect(int x, int y, int width, int height, MockGraphics graphics, int index, Color color)
 {
     Assert.AreEqual(new Rectangle(x, y, width, height), graphics.RectanglesDrawn[index]);
     Assert.AreEqual((int)ColorUtil.ConvertColorToBGR(color), graphics.RectColorsDrawn[index]);
 }
Пример #15
0
        public void FlashInsertionPoint()
        {
            AssembledStyles styles     = new AssembledStyles();
            var             clientRuns = new List <IClientRun>();
            BlockBox        box0       = new BlockBox(styles, Color.Red, 72000, 36000);

            clientRuns.Add(box0);
            TextSource source = new TextSource(clientRuns, null);
            ParaBox    para   = new ParaBox(styles, source);
            RootBox    root   = new RootBox(styles);

            root.AddBox(para);
            MockGraphics graphics   = new MockGraphics();
            LayoutInfo   layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);

            root.Layout(layoutArgs);

            var sel = new DummySelection();

            root.Selection = sel;

            PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);

            root.Paint(graphics, ptrans);

            Assert.AreEqual(graphics, sel.VgUsedToDraw);
            Assert.AreEqual(ptrans, sel.TransformUsedToDraw);

            sel.ClearResults();
            root.FlashInsertionPoint();

            Assert.IsFalse(sel.WasInvalidated, "flash IP should not cause range to be invalidated");

            var ip = new DummySelection();

            ip.SimulateIP  = true;
            root.Selection = ip;
            Assert.IsTrue(ip.WasInvalidated);

            // Initial paint after being installed should indeed paint the IP (so it appears at once)
            ip.ClearResults();
            root.Paint(graphics, ptrans);
            Assert.AreEqual(graphics, ip.VgUsedToDraw);
            Assert.AreEqual(ptrans, ip.TransformUsedToDraw);


            // Each flash should invalide it.
            sel.ClearResults();
            root.FlashInsertionPoint();
            Assert.IsTrue(ip.WasInvalidated);

            // The second paint should do nothing to the IP.
            ip.ClearResults();
            root.Paint(graphics, ptrans);
            Assert.AreEqual(null, ip.VgUsedToDraw);

            // One more flash
            ip.ClearResults();
            root.FlashInsertionPoint();
            Assert.IsTrue(ip.WasInvalidated);

            // And now back to drawing the IP.
            ip.ClearResults();
            root.Paint(graphics, ptrans);
            Assert.AreEqual(graphics, ip.VgUsedToDraw);
            Assert.AreEqual(ptrans, ip.TransformUsedToDraw);

            // range should get drawn even though IP was hidden.
            root.FlashInsertionPoint();       // back to hidden
            root.Selection = sel;             // back to range.
            sel.ClearResults();
            root.Paint(graphics, ptrans);
            Assert.AreEqual(graphics, sel.VgUsedToDraw);
            Assert.AreEqual(ptrans, sel.TransformUsedToDraw);
        }
Пример #16
0
        public void ValidSelections()
        {
            AssembledStyles styles     = new AssembledStyles();
            var             clientRuns = new List <IClientRun>();
            var             run0       = new StringClientRun("First run", styles);
            var             run1       = new StringClientRun("Middle run", styles);
            BlockBox        box0       = new BlockBox(styles, Color.Red, 72000, 36000);
            var             run2       = new StringClientRun("Last run", styles);

            clientRuns.Add(run0);
            clientRuns.Add(run1);
            clientRuns.Add(box0);
            clientRuns.Add(run2);
            TextSource source = new TextSource(clientRuns, null);
            ParaBox    para0  = new ParaBox(styles, source);

            run0.Hookup = new LiteralStringParaHookup(para0, para0);
            run1.Hookup = new LiteralStringParaHookup(para0, para0);
            run2.Hookup = new LiteralStringParaHookup(para0, para0);
            DivBox  div  = new DivBox(styles);
            RootBox root = new RootBox(styles);

            para0.Container = div;
            MockGraphics graphics   = new MockGraphics();
            LayoutInfo   layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);

            root.Layout(layoutArgs);

            root.AddBox(div);
            var sel = para0.SelectAtStart();

            root.Selection = sel;

            Assert.That(!root.Selection.IsValid);

            div.AddBox(para0);
            root.RemoveBoxes(div, div);
            div.Container = root;

            Assert.That(!root.Selection.IsValid);

            root.AddBox(div);

            Assert.That(root.Selection.IsValid);

            (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 4;

            Assert.That(!root.Selection.IsValid);

            (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 2;

            Assert.That(!root.Selection.IsValid);

            (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 0;
            (root.Selection as InsertionPoint).StringPosition        = 10;

            Assert.That(!root.Selection.IsValid);

            (root.Selection as InsertionPoint).StringPosition = 0;
            run0.Hookup = null;

            Assert.That(!root.Selection.IsValid);

            run0.Hookup    = new LiteralStringParaHookup(para0, para0);
            sel            = para0.SelectAtStart();
            root.Selection = sel;

            Assert.That(root.Selection.IsValid);
        }
Пример #17
0
		public void PaintPictureBox()
		{
			AssembledStyles styles = new AssembledStyles();
			Bitmap bm = new Bitmap(20, 30);
			ImageBox box = new ImageBox(styles.WithMargins(new Thickness(72.0 / 96.0 * 2.0))
				.WithBorders(new Thickness(72.0 / 96.0 * 3.0))
				.WithPads(new Thickness(72.0 / 96.0 * 7.0, 72.0 / 96.0 * 8.0, 72.0 / 96.0 * 11.0, 72.0 / 96.0 * 13.0)), bm);

			RootBox root = new RootBox(styles);
			BlockBox block = new BlockBox(styles, Color.Yellow, 2000, 4000);
			root.AddBox(block);
			root.AddBox(box);
			LayoutInfo transform = MakeLayoutInfo();
			root.Layout(transform);
			Assert.That(box.Height, Is.EqualTo(30 + 2*2+3*2+8+13));
			Assert.That(box.Width, Is.EqualTo(20 + 2*2 +3*2 + 7 + 11));
			Assert.That(box.Ascent, Is.EqualTo(box.Height));

			PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 10, 40, 96, 96);
			MockGraphics graphics = new MockGraphics();
			root.Paint(graphics, ptrans);
			Assert.That(graphics.LastRenderPictureArgs, Is.Not.Null);
			Assert.That(graphics.LastRenderPictureArgs.Picture, Is.EqualTo(box.Picture));
			Assert.That(graphics.LastRenderPictureArgs.X, Is.EqualTo(2-10 + 2 + 3 + 7));
			Assert.That(graphics.LastRenderPictureArgs.Y, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8));
			Assert.That(graphics.LastRenderPictureArgs.Cx, Is.EqualTo(20));
			Assert.That(graphics.LastRenderPictureArgs.Cy, Is.EqualTo(30));
			int hmWidth = box.Picture.Width;
			int hmHeight = box.Picture.Height;
			Assert.That(graphics.LastRenderPictureArgs.XSrc, Is.EqualTo(0));
			Assert.That(graphics.LastRenderPictureArgs.YSrc, Is.EqualTo(hmHeight));
			Assert.That(graphics.LastRenderPictureArgs.CxSrc, Is.EqualTo(hmWidth));
			Assert.That(graphics.LastRenderPictureArgs.CySrc, Is.EqualTo(-hmHeight));
			Assert.That(graphics.LastRenderPictureArgs.RcWBounds.left, Is.EqualTo(2 - 10 + 2 + 3 + 7));
			Assert.That(graphics.LastRenderPictureArgs.RcWBounds.top, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8));
			Assert.That(graphics.LastRenderPictureArgs.RcWBounds.right, Is.EqualTo(2 - 10 + 2 + 3 + 7 + 20));
			Assert.That(graphics.LastRenderPictureArgs.RcWBounds.bottom, Is.EqualTo(4 - 40 + block.Height + 2 + 3 + 8 + 30));
		}
Пример #18
0
		public void FlashInsertionPoint()
		{
			AssembledStyles styles = new AssembledStyles();
			var clientRuns = new List<IClientRun>();
			BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000);
			clientRuns.Add(box0);
			TextSource source = new TextSource(clientRuns, null);
			ParaBox para = new ParaBox(styles, source);
			RootBox root = new RootBox(styles);
			root.AddBox(para);
			MockGraphics graphics = new MockGraphics();
			LayoutInfo layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics);
			root.Layout(layoutArgs);

			var sel = new DummySelection();
			root.Selection = sel;

			PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96);
			root.Paint(graphics, ptrans);

			Assert.AreEqual(graphics, sel.VgUsedToDraw);
			Assert.AreEqual(ptrans, sel.TransformUsedToDraw);

			sel.ClearResults();
			root.FlashInsertionPoint();

			Assert.IsFalse(sel.WasInvalidated, "flash IP should not cause range to be invalidated");

			var ip = new DummySelection();
			ip.SimulateIP = true;
			root.Selection = ip;
			Assert.IsTrue(ip.WasInvalidated);

			// Initial paint after being installed should indeed paint the IP (so it appears at once)
			ip.ClearResults();
			root.Paint(graphics, ptrans);
			Assert.AreEqual(graphics, ip.VgUsedToDraw);
			Assert.AreEqual(ptrans, ip.TransformUsedToDraw);


			// Each flash should invalide it.
			sel.ClearResults();
			root.FlashInsertionPoint();
			Assert.IsTrue(ip.WasInvalidated);

			// The second paint should do nothing to the IP.
			ip.ClearResults();
			root.Paint(graphics, ptrans);
			Assert.AreEqual(null, ip.VgUsedToDraw);

			// One more flash
			ip.ClearResults();
			root.FlashInsertionPoint();
			Assert.IsTrue(ip.WasInvalidated);

			// And now back to drawing the IP.
			ip.ClearResults();
			root.Paint(graphics, ptrans);
			Assert.AreEqual(graphics, ip.VgUsedToDraw);
			Assert.AreEqual(ptrans, ip.TransformUsedToDraw);

			// range should get drawn even though IP was hidden.
			root.FlashInsertionPoint(); // back to hidden
			root.Selection = sel; // back to range.
			sel.ClearResults();
			root.Paint(graphics, ptrans);
			Assert.AreEqual(graphics, sel.VgUsedToDraw);
			Assert.AreEqual(ptrans, sel.TransformUsedToDraw);
		}
Пример #19
0
		private void VerifyPaint(RootBox root, Rectangle clipRect, int xScrollOffset, int yScrollOffset, Rectangle[] paintRects)
		{
			MockGraphics graphics = new MockGraphics();
			graphics.ClipRectangle = clipRect;
			PaintTransform ptrans = new PaintTransform(0, 0, 96, 96, xScrollOffset, yScrollOffset, 96, 96);
			root.Paint(graphics, ptrans);
			var drawActions = graphics.DrawActions; // after the paint, it gets created when first rect added.
			if (paintRects == null || paintRects.Length == 0)
			{
				Assert.IsTrue(drawActions == null || drawActions.Count == 0);
				return;
			}
			Assert.That(drawActions, Has.Count.EqualTo(paintRects.Length * 2));
			int position = 0;
			// First all the blocks get drawn in their PaintBackground routine
			foreach (var rect in paintRects)
			{
				VerifyRect(drawActions, ref position, rect);
			}
			// Then we verify that the PaintForeground routines got called.
			for (; position < drawActions.Count; position++)
				Assert.That(drawActions[position], Is.InstanceOf(typeof(FgBlockBox)));
		}
Пример #20
0
        public void PileAndBlock()
        {
            var root = new RootBoxFdo(new AssembledStyles());

            SetupFakeRootSite(root);
            var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55);

            root.RendererFactory = layoutInfo.RendererFactory;
            var mock1 = new MockData1()
            {
                SimpleThree = "This is the first paragraph."
            };
            // The length of the second paragraph is found by experiment to be enough so that
            // despite its lacking borders it also breaks into 2 lines in the second step.
            var mock2 = new MockData1()
            {
                SimpleThree = "Here is another paragraph. It needs to be a bit longer."
            };

            root.Builder.Show(
                Div.Containing(
                    Display.Block(Color.Red, 25000, 18000).BackColor(Color.Purple)
                    .Margins(3000, 3000, 3000, 3000)
                    .Border(5000, Color.Blue)
                    .Pads(4000, 4000, 4000, 4000),
                    Display.Block(Color.Green, 25000, 18000)
                    ).BackColor(Color.Pink)                     // these apply to div.
                .Margins(1000, 1000, 1000, 1000)
                .Border(2000, Color.Gold)
                .Pads(6000, 6000, 6000, 6000));
            root.Layout(layoutInfo);
            // We want to keep track of the sequence of paint operations in all three segments.
            var drawActions = new List <object>();
            var vg          = new MockGraphics();

            vg.DrawActions = drawActions;

            var site = (MockSite)root.Site;

            root.Paint(vg, site.m_transform);
            var paintTrans = site.m_transform;
            int position   = 0;
            int xOffset    = 2 - 100;          // how far it is pushed over by the offsets of the layoutInfo
            int yOffset    = 2 - 200;          // how far it is pushed down by the offsets of the layoutInfo

            int red    = (int)ColorUtil.ConvertColorToBGR(Color.Red);
            int pink   = (int)ColorUtil.ConvertColorToBGR(Color.Pink);
            int purple = (int)ColorUtil.ConvertColorToBGR(Color.Purple);
            int blue   = (int)ColorUtil.ConvertColorToBGR(Color.Blue);
            int green  = (int)ColorUtil.ConvertColorToBGR(Color.Green);
            int gold   = (int)ColorUtil.ConvertColorToBGR(Color.Gold);
            // Technically we could do different conversions in the two directions, but for this test both dpi are the same.
            int margPile    = layoutInfo.MpToPixelsX(1000);
            int bordPile    = layoutInfo.MpToPixelsX(2000);
            int padPile     = layoutInfo.MpToPixelsX(6000);
            int blockWidth  = layoutInfo.MpToPixelsX(25000);
            int blockHeight = layoutInfo.MpToPixelsX(18000);
            int margBlock   = layoutInfo.MpToPixelsX(3000);
            int bordBlock   = layoutInfo.MpToPixelsX(5000);
            int padBlock    = layoutInfo.MpToPixelsX(4000);

            // First a background rectangle for the whole pile.
            var leftPilePad   = margPile + bordPile + xOffset;
            var topPilePad    = margPile + bordPile + yOffset;
            var rightPilePad  = margPile + bordPile + 2 * padPile + blockWidth + 2 * margBlock + 2 * bordBlock + 2 * padBlock + xOffset;
            var bottomPilePad = margPile + bordPile + 2 * padPile + 2 * blockHeight + 2 * margBlock + 2 * bordBlock + 2 * padBlock + yOffset;

            VerifyRect(drawActions, ref position, leftPilePad, topPilePad, rightPilePad, bottomPilePad, pink);
            // Left border, whole pile
            VerifyRect(drawActions, ref position, leftPilePad - bordPile, topPilePad - bordPile,
                       leftPilePad, bottomPilePad + bordPile, gold);
            // top border, whole pile
            VerifyRect(drawActions, ref position, leftPilePad - bordPile, topPilePad - bordPile,
                       rightPilePad + bordPile, topPilePad, gold);
            // right border, whole pile
            VerifyRect(drawActions, ref position, rightPilePad, topPilePad - bordPile,
                       rightPilePad + bordPile, bottomPilePad + bordPile, gold);
            // bottom border, whole pile
            VerifyRect(drawActions, ref position, leftPilePad - bordPile, bottomPilePad,
                       rightPilePad + bordPile, bottomPilePad + bordPile, gold);

            // background and border for first block.
            var leftBlockPad   = margPile + bordPile + padPile + margBlock + bordBlock + xOffset;
            var topBlockPad    = margPile + bordPile + padPile + margBlock + bordBlock + yOffset;
            var rightBlockPad  = margPile + bordPile + padPile + margBlock + bordBlock + 2 * padBlock + blockWidth + xOffset;
            var bottomBlockPad = margPile + bordPile + padPile + margBlock + bordBlock + 2 * padBlock + blockHeight + yOffset;

            VerifyRect(drawActions, ref position, leftBlockPad, topBlockPad, rightBlockPad, bottomBlockPad, purple);
            // Left border, whole pile
            VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, topBlockPad - bordBlock,
                       leftBlockPad, bottomBlockPad + bordBlock, blue);
            // top border, whole pile
            VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, topBlockPad - bordBlock,
                       rightBlockPad + bordBlock, topBlockPad, blue);
            // right border, whole pile
            VerifyRect(drawActions, ref position, rightBlockPad, topBlockPad - bordBlock,
                       rightBlockPad + bordBlock, bottomBlockPad + bordBlock, blue);
            // bottom border, whole pile
            VerifyRect(drawActions, ref position, leftBlockPad - bordBlock, bottomBlockPad,
                       rightBlockPad + bordBlock, bottomBlockPad + bordBlock, blue);
            // The first block itself.
            VerifyRect(drawActions, ref position, leftBlockPad + padBlock, topBlockPad + padBlock,
                       leftBlockPad + padBlock + blockWidth, topBlockPad + padBlock + blockHeight, red);
            // The second block itself.
            var topBlock2 = bottomBlockPad + bordBlock + margBlock;

            VerifyRect(drawActions, ref position, leftPilePad + padPile, topBlock2,
                       leftPilePad + padPile + blockWidth, topBlock2 + blockHeight, green);
            // And that should be all!
            Assert.That(position, Is.EqualTo(drawActions.Count));

            // A quick check that Relayout puts things in the same places.
            drawActions.Clear();
            var fixupMap = new Dictionary <Box, Rectangle>();
            var div1     = (DivBox)root.FirstBox;
            var block1   = div1.FirstBox;

            fixupMap[div1]   = new Rectangle(0, 0, 10, 10);
            fixupMap[block1] = new Rectangle(0, 0, 10, 10);
            var oldblock1Left = block1.Left;
            var oldblock1bTop = block1.Top;

            using (var lcb = new LayoutCallbacks(root))
                root.Relayout(layoutInfo, fixupMap, lcb);
            Assert.That(drawActions.Count, Is.EqualTo(0));
            Assert.That(div1.FirstBox.Left, Is.EqualTo(oldblock1Left));
            Assert.That(div1.FirstBox.Top, Is.EqualTo(oldblock1bTop));
        }