public void PileOfBlocksLayout() { var styles = new AssembledStyles(); BlockBox box1 = new BlockBox(styles, Color.Red, 72000, 36000); BlockBox box2 = new BlockBox(styles, Color.Blue, 108000, 18000); BlockBox box3 = new BlockBox(styles, Color.Orange, 72000, 18000); RootBox root = new RootBox(styles); root.AddBox(box1); root.AddBox(box2); root.AddBox(box3); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24)); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(48)); Assert.That(box3.Top, Is.EqualTo(48 + 24)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(root.Width, Is.EqualTo(144)); }
public void InsertCharInEmptyLine() { string contents = ""; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var styles = new AssembledStyles().WithWs(34); var clientRuns = new List <IClientRun>(); var run = new StringClientRun(contents, styles); clientRuns.Add(run); var data1 = new MockData1(34, 35); data1.SimpleThree = contents; var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged, hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => data1.SimpleThree = newVal; run.Hookup = hookup; var root = new RootBox(styles); var block = new BlockBox(styles, Color.Red, 20000, 10000); root.AddBox(block); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(para.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); Assert.That(root.Width, Is.EqualTo(block.Width)); int simulatedWidth = FakeRenderEngine.SimulatedWidth("x"); Assert.That(root.Width, Is.GreaterThan(para.Width + simulatedWidth)); PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; var oldRootWidth = root.Width; var ip = root.SelectAtEnd(); ip.InsertText("x"); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(root.Width, Is.EqualTo(oldRootWidth)); Assert.That(para.Width, Is.EqualTo(simulatedWidth)); var expectedInvalidate = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin + block.Height, simulatedWidth + RootBox.InvalidateMargin * 2, 13 + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate)); }
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); }
private void InitRedBox() { AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBox(styles); BlockBox block = new BlockBox(styles, Color.Red, 72000, 36000); root.AddBox(block); theSharpView.Root = root; }
public void CommonContainerTests() { var styles = new AssembledStyles(); var columnWidths = new FixedColumnWidths(new[] { 10 }); var root1 = new RootBox(styles); var root2 = new RootBox(styles); VerifyCC(root1, root1, root1, root1, root1); VerifyCC(root2, root2, root2, root2, root2); var row1 = new RowBox(styles, columnWidths, false); var div1 = new DivBox(styles); root2.AddBox(row1); root1.AddBox(div1); VerifyCC(row1, row1, row1, row1, row1); VerifyCC(div1, div1, div1, div1, div1); VerifyCC(root1, div1, root1, root1, div1); VerifyCC(root2, row1, root2, root2, row1); var row2 = new RowBox(styles, columnWidths, false); var div2 = new DivBox(styles); root2.AddBox(row2); root1.AddBox(div2); VerifyCC(row1, row2, root2, row1, row2); VerifyCC(div1, div2, root1, div1, div2); var row3 = new RowBox(styles, columnWidths, false); var div3 = new DivBox(styles); row1.AddBox(row3); div1.AddBox(div3); VerifyCC(row1, row3, row1, row1, row3); VerifyCC(row2, row3, root2, row2, row1); VerifyCC(div1, div3, div1, div1, div3); VerifyCC(div2, div3, root1, div2, div1); var row4 = new RowBox(styles, columnWidths, false); var div4 = new DivBox(styles); row2.AddBox(row4); div2.AddBox(div4); VerifyCC(row3, row4, root2, row1, row2); VerifyCC(row1, row4, root2, row1, row2); VerifyCC(div3, div4, root1, div1, div2); VerifyCC(div1, div4, root1, div1, div2); }
public void NextAndPrevInSelectionSeq() { var styles = new AssembledStyles(); var root = new RootBox(styles); Assert.That(root.NextInSelectionSequence(true), Is.Null); Assert.That(root.PreviousInSelectionSequence, Is.Null); var block = new BlockBox(styles, Color.Red, 6000, 6000); root.AddBox(block); Assert.That(root.NextInSelectionSequence(true), Is.EqualTo(block)); Assert.That(block.PreviousInSelectionSequence, Is.EqualTo(root)); var div = new DivBox(styles); root.AddBox(div); Assert.That(block.NextInSelectionSequence(true), Is.EqualTo(div)); Assert.That(div.PreviousInSelectionSequence, Is.EqualTo(block)); var divChild = new DivBox(styles); div.AddBox(divChild); var block2 = new BlockBox(styles, Color.Red, 6000, 6000); divChild.AddBox(block2); var block3 = new BlockBox(styles, Color.Red, 6000, 6000); divChild.AddBox(block3); var block4 = new BlockBox(styles, Color.Red, 6000, 6000); div.AddBox(block4); // up and forward Assert.That(block3.NextInSelectionSequence(true), Is.EqualTo(block4)); Assert.That(block4.PreviousInSelectionSequence, Is.EqualTo(block3)); // Can go back from a box to a previous empty group var emptyDiv = new DivBox(styles); root.AddBox(emptyDiv); var block5 = new BlockBox(styles, Color.Red, 6000, 6000); root.AddBox(block5); Assert.That(emptyDiv.NextInSelectionSequence(true), Is.EqualTo(block5)); Assert.That(block5.PreviousInSelectionSequence, Is.EqualTo(emptyDiv)); Assert.That(div.NextInSelectionSequence(true), Is.EqualTo(divChild)); Assert.That(div.NextInSelectionSequence(false), Is.EqualTo(emptyDiv)); }
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)); }
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)); }
public void PileOfBlocksLayout() { var styles = new AssembledStyles(); BlockBox box1 = new BlockBox(styles, Color.Red, 72000, 36000); BlockBox box2 = new BlockBox(styles, Color.Blue, 108000, 18000); BlockBox box3 = new BlockBox(styles, Color.Orange, 72000, 18000); RootBox root = new RootBox(styles); root.AddBox(box1); root.AddBox(box2); root.AddBox(box3); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24) ); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(48)); Assert.That(box3.Top, Is.EqualTo(48 + 24)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(root.Width, Is.EqualTo(144)); }
ParaBox AddPara(string[] contents, AssembledStyles styles, RootBox root) { var clientRuns = new List <IClientRun>(); foreach (string item in contents) { var run = new StringClientRun(item, styles); clientRuns.Add(run); } var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); root.AddBox(para); return(para); }
public void MakeRootBox() { 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); Assert.AreEqual(48, box.Height); Assert.AreEqual(96, box.Width); Assert.AreEqual(48, root.Height); Assert.AreEqual(96, root.Width); }
private void InitSeveralBoxes() { AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBox(styles); var items = new List <ClientRun>(); items.Add(new BlockBox(styles, Color.Red, 72000, 36000)); items.Add(new BlockBox(styles, Color.Blue, 36000, 18000)); items.Add(new BlockBox(styles, Color.Orange, 18000, 36000)); items.Add(new BlockBox(styles, Color.Green, 72000, 18000)); items.Add(new BlockBox(styles, Color.Yellow, 72000, 36000)); TextSource source = new TextSource(items); ParaBox para = new ParaBox(styles, source); root.AddBox(para); theSharpView.Root = root; }
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); }
// Add to the root a text paragraph which reflects the SimpleText property. private void AddSimpleTextPara(AssembledStyles styles, int ws, RootBox root) { var items = new List <ClientRun>(); var run = new StringClientRun("This is the day that the Lord has made. We will rejoice and be glad in it", styles.WithWs(ws)); items.Add(run); TextSource source = new TextSource(items); ParaBox para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => this.SimpleText, hook => SimpleTextChanged += hook.StringPropChanged, hook => SimpleTextChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => SimpleText = newVal; run.Hookup = hookup; root.AddBox(para); }
public void OneBlockPara() { AssembledStyles styles = new AssembledStyles(); List<IClientRun> clientRuns = new List<IClientRun>(); BlockBox box = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns.Add(box); TextSource source = new TextSource(clientRuns, null); ParaBox para = new ParaBox(styles, source); RootBox root = new RootBox(styles); root.AddBox(para); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.AreEqual(48, box.Height); Assert.AreEqual(96, box.Width); Assert.AreEqual(48, root.Height); Assert.AreEqual(96, root.Width); }
private ParaBox MakePara(MockSequenceHookup hookup, AssembledStyles styles, MockData1 itemNew, string contents, RootBox root) { var newItemHookup = new ItemHookup(itemNew, null); hookup.InsertChildHookup(newItemHookup, 1); // Give that hookup a stringhookup child, connected to a paragraph and root box. var clientRuns = new List <IClientRun>(); itemNew.SimpleThree = contents; var run = new StringClientRun(contents, styles); clientRuns.Add(run); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); run.Hookup = new LiteralStringParaHookup(itemNew, para); newItemHookup.InsertChildHookup(run.Hookup, 0); root.AddBox(para); return(para); }
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); }
public void RowClippedPaint() { var styles = new AssembledStyles(); var box1 = new FgBlockBox(styles, Color.Red, 36000, 72000); var box2 = new FgBlockBox(styles, Color.Blue, 18000, 108000); var box3 = new FgBlockBox(styles, Color.Orange, 18000, 72000); var box4 = new FgBlockBox(styles, Color.Orange, 18000, 72000); var widths = new FixedColumnWidths(new[] { 34, 67, 99, 46 }); var row1 = new RowBox(styles, widths, false); row1.AddBox(box1); row1.AddBox(box2); row1.AddBox(box3); row1.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(row1); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); var rect1 = new Rectangle(0, 0, 48, 96); var rect2 = new Rectangle(0, 0, 24, 144); rect2.Offset(rect1.Right, 0); var rect3 = new Rectangle(0, 0, 24, 96); rect3.Offset(rect2.Right, 0); var rect4 = new Rectangle(0, 0, 24, 96); rect4.Offset(rect3.Right, 0); var paintRects = new[] { rect1, rect2, rect3, rect4 }; VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 2000), 0, 0, paintRects); // Clipping off the left part, but not the whole, of a box does not prevent drawing it. VerifyPaint(root, new Rectangle(10, -1000, -10 + rect4.Right - 10, 2000), 0, 0, paintRects); // Even clipping all but one pixel does not prevent drawing. VerifyPaint(root, new Rectangle(47, -1000, -47 + rect3.Right + 1, 2000), 0, 0, paintRects); // However if we clip a bit more we should draw less var middleTwo = new[] { rect2, rect3 }; VerifyPaint(root, new Rectangle(48, -1000, -48 + rect3.Right - 2, 2000), 0, 0, middleTwo); // If the clip covers just a bit of the first box we paint just that. var firstOne = new[] { rect1 }; VerifyPaint(root, new Rectangle(-1000, -1000, 1000 + 10, 2000), 0, 0, firstOne); // If the clip covers just a bit of the last box we paint just that. var lastOne = new[] { rect4 }; VerifyPaint(root, new Rectangle(rect4.Right - 2, -1000, 1000, 2000), 0, 0, lastOne); // If the clip is entirely above the pile we draw nothing. VerifyPaint(root, new Rectangle(-1000, -1000, 990, 2000), 0, 0, null); // Likewise if entirely below. VerifyPaint(root, new Rectangle(rect4.Right + 10, -1000, 10, 2000), 0, 0, null); // Now try with simulated scrolling. Use a normal clip rectangle, but pretend the first two // and a bit boxes are scrolled off. var offset = rect2.Right + 10; var rect3Offset = rect3; rect3Offset.Offset(-offset, 0); var rect4Offset = rect4; rect4Offset.Offset(-offset, 0); var lastTwoOffset = new[] { rect3Offset, rect4Offset }; VerifyPaint(root, new Rectangle(0, -1000, 200, 2000), offset, 0, lastTwoOffset); }
public void ContentChangeWrapping() { var styles = new AssembledStyles().WithWs(s_simpleStringWs); string contents1 = "This is a simple string. It has two sentences."; var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents1, styles)); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(30, m_gm.VwGraphics); }
public void FiveBlockPara() { 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); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); VerifyBox(box0, 96, 48, box1, para, "box0"); VerifyBox(box1, 48, 24, box2, para, "box1"); VerifyBox(box2, 32, 24, box3, para, "box2"); VerifyBox(box3, 96, 48, box4, para, "box3"); VerifyBox(box4, 48, 48, null, para, "box4"); VerifyGroup(para, 96 + 48 + 32 + 96 + 48, 48, null, root, box0, box4, "para"); VerifyGroup(root, 96 + 48 + 32 + 96 + 48, 48, null, null, para, para, "root"); VerifyParaLine(para, 0, box0, box4, 0, "para unlimited one line"); // Check multi-line layout (one line has room for two boxes). LayoutInfo layoutArgs2 = MakeLayoutInfo(100, m_gm.VwGraphics); root.Layout(layoutArgs2); Assert.AreEqual(4, para.Lines.Count, "para1 at 100 has four lines"); VerifyBox(box0, 96, 48, box1, para, "box0/100"); VerifyBox(box1, 48, 24, box2, para, "box1/100"); VerifyBox(box2, 32, 24, box3, para, "box2/100"); VerifyBox(box3, 96, 48, box4, para, "box3/100"); VerifyBox(box4, 48, 48, null, para, "box4/100"); VerifyParaLine(para, 0, box0, box0, 0, "para/100 first"); VerifyParaLine(para, 1, box1, box2, 48, "para/100 second"); VerifyParaLine(para, 2, box3, box3, 48 + 24, "para/100 third"); VerifyParaLine(para, 3, box4, box4, 48 + 24 + 48, "para/100 fourth"); // At 100 pixels wide, box0 goes on the first line, boxes 1 and 2 on the third, box 3 and box4 take the fourth and fifth. // Multiple lines means the paragraph occupies its full width. int height100 = 48 + 24 + 48 + 48; VerifyGroup(para, 100, height100, null, root, box0, box4, "para/100"); VerifyGroup(root, 100, height100, null, null, para, para, "root/100"); // Check layout when some boxes won't fit on a whole line. LayoutInfo layoutArgs3 = MakeLayoutInfo(50, m_gm.VwGraphics); root.Layout(layoutArgs3); Assert.AreEqual(5, para.Lines.Count, "para1 at 50 has five lines"); VerifyBox(box0, 96, 48, box1, para, "box0/50"); VerifyParaLine(para, 0, box0, box0, 0, "para/50 first"); VerifyParaLine(para, 1, box1, box1, 48, "para/50 second"); VerifyParaLine(para, 2, box2, box2, 48 + 24, "para/50 third"); VerifyParaLine(para, 3, box3, box3, 48 + 24 + 24, "para/50 fourth"); VerifyParaLine(para, 4, box4, box4, 48 + 24 + 24 +48, "para/50 fifth"); // At 100 pixels wide, box0 goes on the first line, boxes 1 and 2 on the third, box 3 and box4 take the fourth and fifth. // Multiple lines means the paragraph occupies its full width. int height50 = 48 + 24 + 24 + 48 + 48; VerifyGroup(para, 96, height50, null, root, box0, box4, "para/50"); VerifyGroup(root, 96, height50, null, null, para, para, "root/50"); }
/// <summary> /// This setup method for para builder is also useful for testing stuff related to the paragraph itself. /// For example, we take advantage of it for testing backspace at start of client run. /// </summary> internal static RootBox MakeTestParaThreeStrings(IVwGraphics vg, MockBreakOption breakOption, out ParaBox para) { var styles = new AssembledStyles().WithWs(s_simpleStringWs); var styles2 = new AssembledStyles().WithWs(s_secondGroupWs); string contents1 = AssembleStrings(s_firstGroupWords); string contents2 = AssembleStrings(s_secondGroupWords); string contents3 = AssembleStrings(s_thirdGroupWords); var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents1, styles)); clientRuns.Add(new StringClientRun(contents2, styles2)); clientRuns.Add(new StringClientRun(contents3, styles)); var source = new TextSource(clientRuns, null); para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, vg); int totalLength = contents1.Length + contents2.Length + contents3.Length; // Arrange the following line breaks. // First the builder will ask to break the whole string, it puts the first three words on a line and indicates it is full. SetupMockEngineForThreeStringsPara(s_firstGroupWords, s_secondGroupWords, s_thirdGroupWords, layoutArgs); root.Layout(layoutArgs); return root; }
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); }
public void MouseEvents() { var string1 = "This is the day that the Lord has made."; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var runStyle = new AssembledStyles().WithWs(34); var style = new AssembledStyles(); var root = new RootBox(style); var para1 = MakePara(style, runStyle, string1); root.AddBox(para1); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory); root.Layout(layoutArgs); var mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2, 5, 0); root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(0)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // In a different place, tests moving the selection and also getting AssociatePrevious true. int widthThis = FakeRenderEngine.SimulatedWidth("This"); var mouseArgs2 = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis - 1, 5, 0); root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.True); // A click in the same place should not make a new selection. var sel = root.Selection; root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans); // no change Assert.That(root.Selection, Is.EqualTo(sel)); // A shift-click close enough to the same place to be the same character position but difference AssocPrevious // should make the appropriate new IP, not a range. var mouseArgs2b = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis + 1, 5, 0); root.OnMouseDown(mouseArgs2b, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // A shift-click should make a range. root.OnMouseDown(mouseArgs, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection))); var anchor = ((RangeSelection)root.Selection).Anchor; var drag = ((RangeSelection)root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(0)); // shift-click further right: should move the drag end var mouseArgs3 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 5, 0); root.OnMouseDown(mouseArgs3, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection))); anchor = ((RangeSelection)root.Selection).Anchor; drag = ((RangeSelection)root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(1)); // mouse move, to a different position root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); sel = root.Selection; Assert.That(sel, Is.TypeOf(typeof(RangeSelection))); anchor = ((RangeSelection)root.Selection).Anchor; drag = ((RangeSelection)root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(0)); // mouse move to the same position: no new selection. root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); // no actual movement Assert.That(root.Selection, Is.EqualTo(sel)); Assert.That(((RangeSelection)root.Selection).DragEnd, Is.EqualTo(drag)); // mouse move to an IP at the anchor should return us to an IP root.OnMouseMove(mouseArgs2b, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // mouse down on next line makes a selection there. Confirm proper passing of srcRect for vertical offset var mouseArgs4 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 2 + 16, 0); root.OnMouseDown(mouseArgs4, Keys.None, m_gm.VwGraphics, ptrans); var paraBox = (ParaBox)root.FirstBox; var seg2 = ((StringBox)paraBox.FirstBox.Next).Segment as FakeSegment; Assert.That(seg2, Is.Not.Null); Assert.That(seg2.LastPointToCharArgs, Is.Not.Null); var topOfseg2 = paraBox.FirstBox.Height; Assert.That(seg2.LastPointToCharArgs.RcSrc, Is.EqualTo(new Rect(-2, -2 - topOfseg2, 94, 94 - topOfseg2))); }
public void NestedDivsLayout() { var styles = new AssembledStyles(); BlockBox box1 = new BlockBox(styles, Color.Red, 72000, 36000); BlockBox box2 = new BlockBox(styles, Color.Blue, 108000, 18000); BlockBox box3 = new BlockBox(styles, Color.Orange, 72000, 18000); BlockBox box4 = new BlockBox(styles, Color.Orange, 72000, 18000); var div1 = new DivBox(styles); var div2 = new DivBox(styles); div1.AddBox(box1); div1.AddBox(box2); div2.AddBox(box3); div2.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(div1); root.AddBox(div2); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24 + 24)); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(48)); Assert.That(div2.Top, Is.EqualTo(48 + 24)); Assert.That(box4.Top, Is.EqualTo(24)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(root.Width, Is.EqualTo(144)); // Now try changing the size of a block. MockSite site = new MockSite(); root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 120, 128); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; box2.UpdateSize(144000, 36000); Assert.That(box2.Width, Is.EqualTo(96 * 2)); Assert.That(box2.Height, Is.EqualTo(48)); Assert.That(div1.Height, Is.EqualTo(96)); // two children now both 48 high. Assert.That(root.Height, Is.EqualTo(48 + 48 + 24 + 24)); // new heights of 4 children. Assert.That(root.Width, Is.EqualTo(96 * 2)); // Since it got both wider and higher, we should invalidate at least the whole current size. var bigInvalidate = root.InvalidateRect; Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 36000); Assert.That(root.Height, Is.EqualTo(48 + 48 + 24 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144)); // narrower box2 still determines it // Got narrower, at least the whole old invalidate rectangle should be invalidated. Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24 + 24)); // new smaller value Assert.That(root.Width, Is.EqualTo(144)); // unchanged this time // It got shorter. We want an optimized invalidate rectangle that does not // include the top box. But it must include the space at the bottom that the root box used to occupy. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (its in the fixmap so its own Relayout does this); // the shrinkage area at the bottom of div2; // and the area computed because div2 moved. VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 48); // old box2 VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 24); // shrinkage of div1 // This is from the new top of div2 to its old bottom (old bottom was 48 + 48 + 24 + 24) VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 48 + 24); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 72000); Assert.That(root.Height, Is.EqualTo(48 + 96 + 24 + 24)); // new larger value Assert.That(root.Width, Is.EqualTo(144)); // unchanged this time // It got longer. We want an optimized invalidate rectangle that does not // include the top box. But it must include the space at the bottom where the root box grew. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it returns true from Relayout); // the growth area at the bottom of div2; // and the area computed because div2 moved. VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 96); // new box2 VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 - 24); // new part of div1 occupied by box2 // This is from the old top of div2 to its new bottom (48 + 96 + 24 + 24) VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 + 24); }
public void ComplexRangeDrawing() { var string1 = "This is the day that the Lord has made."; var string2 = "We will rejoice and be glad in it."; var string3 = "Love the Lord your God with all your heart."; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var runStyle = new AssembledStyles().WithWs(34); var lineHeightMp = 20000; var style = new AssembledStyles().WithLineHeight(lineHeightMp); var root = new RootBox(style); var para1 = MakePara(style, runStyle, string1); root.AddBox(para1); var div = new DivBox(style); root.AddBox(div); var para2 = MakePara(style, runStyle, string2); div.AddBox(para2); var para3 = MakePara(style, runStyle, string3); div.AddBox(para3); // This width makes each paragraph take three lines. var layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory); root.Layout(layoutArgs); var ip1 = para1.SelectAt(1, false); var ip2 = para1.SelectAt(3, true); var range1 = new RangeSelection(ip1, ip2); Assert.That(range1.EndBeforeAnchor, Is.False); Assert.That(range1.Start, Is.EqualTo(ip1)); Assert.That(range1.End, Is.EqualTo(ip2)); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var sbox1_1 = para1.FirstBox as StringBox; range1.Draw(m_gm.VwGraphics, ptrans); int topOffset = -2; // top of RcSrc for top of root box. int topYd = 2; // destination coord corresponding to top of root box. int leftXd = 2; // destination coord corresponding to left of root box. int bottomOfFirstLine = topYd + engine.SegmentHeight; int lineHeight = ptrans.MpToPixelsY(lineHeightMp); int bottomOfFirstHilite = bottomOfFirstLine + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para1, sbox1_1, range1, topOffset, topYd, bottomOfFirstHilite); var sbox1_2 = sbox1_1.Next as StringBox; int bottomOfSecondHilite = bottomOfFirstHilite + lineHeight; VerifyRangeSegmentDrawing(para1, sbox1_2, range1, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); var sbox1_3 = sbox1_2.Next as StringBox; int bottomOfThirddHilite = bottomOfSecondHilite + lineHeight - para1.Ascent; VerifyRangeSegmentDrawing(para1, sbox1_3, range1, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // A two-line selection has much the same results. var ip3 = para1.SelectAt(sbox1_2.IchMin + 2, true); var range2 = new RangeSelection(ip1, ip3); range2.Draw(m_gm.VwGraphics, ptrans); VerifyRangeSegmentDrawing(para1, sbox1_1, range2, topOffset, topYd, bottomOfFirstHilite); VerifyRangeSegmentDrawing(para1, sbox1_2, range2, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); VerifyRangeSegmentDrawing(para1, sbox1_3, range2, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // Try multi-para selection in paras in same div. var ip2_3 = para2.SelectAt(3, false); var ip3_4 = para3.SelectAt(4, true); var range3 = new RangeSelection(ip2_3, ip3_4); range3.Draw(m_gm.VwGraphics, ptrans); var sbox2_1 = para2.FirstBox as StringBox; int topOfPara2 = topYd + para1.Height; int bottomOfFirstLineP2 = topOfPara2 + engine.SegmentHeight; int bottomOfFirstHiliteP2 = bottomOfFirstLineP2 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para2, sbox2_1, range3, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); var sbox2_2 = sbox2_1.Next as StringBox; int bottomOfSecondHiliteP2 = bottomOfFirstHiliteP2 + lineHeight; VerifyRangeSegmentDrawing(para2, sbox2_2, range3, topOffset - para1.Height - lineHeight, bottomOfFirstHiliteP2, bottomOfSecondHiliteP2); var sbox2_3 = sbox2_2.Next as StringBox; int bottomOfThirddHiliteP2 = bottomOfSecondHiliteP2 + lineHeight - para2.Ascent; VerifyRangeSegmentDrawing(para2, sbox2_3, range3, topOffset - para1.Height - lineHeight * 2, bottomOfSecondHiliteP2, bottomOfThirddHiliteP2); var sbox3_1 = para3.FirstBox as StringBox; int topOfPara3 = topOfPara2 + para2.Height; var bottomOfFirstLineP3 = topOfPara3 + engine.SegmentHeight; var bottomOfFirstHiliteP3 = bottomOfFirstLineP3 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para3, sbox3_1, range3, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); // Currently the other two segments of para3 will also be asked to draw it, but we've already checked how tops and bottoms // are worked out, and we don't care if these beyond-the-end segments draw it or not. Better not to test, then we can // optimize freely. // Now try a range that is (backwards and) across a div boundary var range4 = new RangeSelection(ip3_4, ip2); Assert.That(range4.EndBeforeAnchor, Is.True); Assert.That(range4.Start.SameLocation(ip2), Is.True); Assert.That(range4.End.SameLocation(ip3_4), Is.True); ClearSegmentDrawing(sbox1_3); ClearSegmentDrawing(sbox2_1); ClearSegmentDrawing(sbox3_1); range4.Draw(m_gm.VwGraphics, ptrans); // Several others should get drawn as well, but I think it's sufficient to verify tha something gets done correct in each para. VerifyRangeSegmentDrawing(para1, sbox1_3, range4, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); VerifyRangeSegmentDrawing(para2, sbox2_1, range4, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); VerifyRangeSegmentDrawing(para3, sbox3_1, range4, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); var range5 = new RangeSelection(ip2, ip3_4); Assert.That(range5.EndBeforeAnchor, Is.False); Assert.That(range5.Start.SameLocation(ip2), Is.True); Assert.That(range5.End.SameLocation(ip3_4), Is.True); // While we've got these selections, it's a good chance to check out GetSelectionLocation // The first one is a simple rectangle in the first string box. SetSelectionLocation(sbox1_1, 15, 20); Assert.That(range1.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 20 - 15, bottomOfFirstHilite - topYd))); SetSelectionLocation(sbox1_2, 18, 25); Assert.That(range2.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 25 - 15, bottomOfSecondHilite - topYd))); SetSelectionLocation(sbox3_1, 22, 27); Assert.That(range4.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(leftXd, topYd, para2.Width, bottomOfFirstHiliteP3 - topYd))); }
public void DivClippedPaint() { var styles = new AssembledStyles(); var box1 = new FgBlockBox(styles, Color.Red, 72000, 36000); var box2 = new FgBlockBox(styles, Color.Blue, 108000, 18000); var box3 = new FgBlockBox(styles, Color.Orange, 72000, 18000); var box4 = new FgBlockBox(styles, Color.Orange, 72000, 18000); var div1 = new DivBox(styles); div1.AddBox(box1); div1.AddBox(box2); div1.AddBox(box3); div1.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(div1); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); var rect1 = new Rectangle(0, 0, 96, 48); var rect2 = new Rectangle(0, 0, 144, 24); rect2.Offset(0, rect1.Bottom); var rect3 = new Rectangle(0, 0, 96, 24); rect3.Offset(0, rect2.Bottom); var rect4 = new Rectangle(0, 0, 96, 24); rect4.Offset(0, rect3.Bottom); var paintRects = new[] { rect1, rect2, rect3, rect4 }; VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 2000), 0, 0, paintRects); // Clipping off the top part, but not the whole, of a box does not prevent drawing it. VerifyPaint(root, new Rectangle(-1000, 10, 2000, -10 + rect4.Bottom - 10), 0, 0, paintRects); // Even clipping all but one pixel does not prevent drawing. VerifyPaint(root, new Rectangle(-1000, 47, 2000, -47 + rect3.Bottom + 1), 0, 0, paintRects); // However if we clip a bit more we should draw less var middleTwo = new[] { rect2, rect3 }; VerifyPaint(root, new Rectangle(-1000, 48, 2000, -48 + rect3.Bottom - 2), 0, 0, middleTwo); // If the clip covers just a bit of the first box we paint just that. var firstOne = new[] { rect1 }; VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 1000 + 10), 0, 0, firstOne); // If the clip covers just a bit of the last box we paint just that. var lastOne = new[] { rect4 }; VerifyPaint(root, new Rectangle(-1000, rect4.Bottom - 2, 2000, 1000), 0, 0, lastOne); // If the clip is entirely above the pile we draw nothing. VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 990), 0, 0, null); // Likewise if entirely below. VerifyPaint(root, new Rectangle(-1000, rect4.Bottom + 10, 2000, 10), 0, 0, null); // Now try with simulated scrolling. Use a normal clip rectangle, but pretend the first two // and a bit boxes are scrolled off. var offset = rect2.Bottom + 10; var rect3Offset = rect3; rect3Offset.Offset(0, -offset); var rect4Offset = rect4; rect4Offset.Offset(0, -offset); var lastTwoOffset = new[] { rect3Offset, rect4Offset }; VerifyPaint(root, new Rectangle(-1000, 0, 2000, 200), 0, offset, lastTwoOffset); }
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); }
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); }
public void ComplexRangeDrawing() { var string1 = "This is the day that the Lord has made."; var string2 = "We will rejoice and be glad in it."; var string3 = "Love the Lord your God with all your heart."; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var runStyle = new AssembledStyles().WithWs(34); var lineHeightMp = 20000; var style = new AssembledStyles().WithLineHeight(lineHeightMp); var root = new RootBox(style); var para1 = MakePara(style, runStyle, string1); root.AddBox(para1); var div = new DivBox(style); root.AddBox(div); var para2 = MakePara(style, runStyle, string2); div.AddBox(para2); var para3 = MakePara(style, runStyle, string3); div.AddBox(para3); // This width makes each paragraph take three lines. var layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory); root.Layout(layoutArgs); var ip1 = para1.SelectAt(1, false); var ip2 = para1.SelectAt(3, true); var range1 = new RangeSelection(ip1, ip2); Assert.That(range1.EndBeforeAnchor, Is.False); Assert.That(range1.Start, Is.EqualTo(ip1)); Assert.That(range1.End, Is.EqualTo(ip2)); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var sbox1_1 = para1.FirstBox as StringBox; range1.Draw(m_gm.VwGraphics, ptrans); int topOffset = -2; // top of RcSrc for top of root box. int topYd = 2; // destination coord corresponding to top of root box. int leftXd = 2; // destination coord corresponding to left of root box. int bottomOfFirstLine = topYd + engine.SegmentHeight; int lineHeight = ptrans.MpToPixelsY(lineHeightMp); int bottomOfFirstHilite = bottomOfFirstLine + (lineHeight - engine.SegmentHeight)/2; VerifyRangeSegmentDrawing(para1, sbox1_1, range1, topOffset, topYd, bottomOfFirstHilite); var sbox1_2 = sbox1_1.Next as StringBox; int bottomOfSecondHilite = bottomOfFirstHilite + lineHeight; VerifyRangeSegmentDrawing(para1, sbox1_2, range1, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); var sbox1_3 = sbox1_2.Next as StringBox; int bottomOfThirddHilite = bottomOfSecondHilite + lineHeight - para1.Ascent; VerifyRangeSegmentDrawing(para1, sbox1_3, range1, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // A two-line selection has much the same results. var ip3 = para1.SelectAt(sbox1_2.IchMin + 2, true); var range2 = new RangeSelection(ip1, ip3); range2.Draw(m_gm.VwGraphics, ptrans); VerifyRangeSegmentDrawing(para1, sbox1_1, range2, topOffset, topYd, bottomOfFirstHilite); VerifyRangeSegmentDrawing(para1, sbox1_2, range2, topOffset - lineHeight, bottomOfFirstHilite, bottomOfSecondHilite); VerifyRangeSegmentDrawing(para1, sbox1_3, range2, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); // Try multi-para selection in paras in same div. var ip2_3 = para2.SelectAt(3, false); var ip3_4 = para3.SelectAt(4, true); var range3 = new RangeSelection(ip2_3, ip3_4); range3.Draw(m_gm.VwGraphics, ptrans); var sbox2_1 = para2.FirstBox as StringBox; int topOfPara2 = topYd + para1.Height; int bottomOfFirstLineP2 = topOfPara2 + engine.SegmentHeight; int bottomOfFirstHiliteP2 = bottomOfFirstLineP2 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para2, sbox2_1, range3, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); var sbox2_2 = sbox2_1.Next as StringBox; int bottomOfSecondHiliteP2 = bottomOfFirstHiliteP2 + lineHeight; VerifyRangeSegmentDrawing(para2, sbox2_2, range3, topOffset - para1.Height - lineHeight, bottomOfFirstHiliteP2, bottomOfSecondHiliteP2); var sbox2_3 = sbox2_2.Next as StringBox; int bottomOfThirddHiliteP2 = bottomOfSecondHiliteP2 + lineHeight - para2.Ascent; VerifyRangeSegmentDrawing(para2, sbox2_3, range3, topOffset - para1.Height - lineHeight * 2, bottomOfSecondHiliteP2, bottomOfThirddHiliteP2); var sbox3_1 = para3.FirstBox as StringBox; int topOfPara3 = topOfPara2 + para2.Height; var bottomOfFirstLineP3 = topOfPara3 + engine.SegmentHeight; var bottomOfFirstHiliteP3 = bottomOfFirstLineP3 + (lineHeight - engine.SegmentHeight) / 2; VerifyRangeSegmentDrawing(para3, sbox3_1, range3, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); // Currently the other two segments of para3 will also be asked to draw it, but we've already checked how tops and bottoms // are worked out, and we don't care if these beyond-the-end segments draw it or not. Better not to test, then we can // optimize freely. // Now try a range that is (backwards and) across a div boundary var range4 = new RangeSelection(ip3_4, ip2); Assert.That(range4.EndBeforeAnchor, Is.True); Assert.That(range4.Start.SameLocation(ip2), Is.True); Assert.That(range4.End.SameLocation(ip3_4), Is.True); ClearSegmentDrawing(sbox1_3); ClearSegmentDrawing(sbox2_1); ClearSegmentDrawing(sbox3_1); range4.Draw(m_gm.VwGraphics, ptrans); // Several others should get drawn as well, but I think it's sufficient to verify tha something gets done correct in each para. VerifyRangeSegmentDrawing(para1, sbox1_3, range4, topOffset - lineHeight * 2, bottomOfSecondHilite, bottomOfThirddHilite); VerifyRangeSegmentDrawing(para2, sbox2_1, range4, topOffset - para1.Height, topOfPara2, bottomOfFirstHiliteP2); VerifyRangeSegmentDrawing(para3, sbox3_1, range4, topOffset - para1.Height - para2.Height, topOfPara3, bottomOfFirstHiliteP3); var range5 = new RangeSelection(ip2, ip3_4); Assert.That(range5.EndBeforeAnchor, Is.False); Assert.That(range5.Start.SameLocation(ip2), Is.True); Assert.That(range5.End.SameLocation(ip3_4), Is.True); // While we've got these selections, it's a good chance to check out GetSelectionLocation // The first one is a simple rectangle in the first string box. SetSelectionLocation(sbox1_1, 15, 20); Assert.That(range1.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 20 - 15, bottomOfFirstHilite - topYd))); SetSelectionLocation(sbox1_2, 18, 25); Assert.That(range2.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(15, topYd, 25 - 15, bottomOfSecondHilite - topYd))); SetSelectionLocation(sbox3_1, 22, 27); Assert.That(range4.GetSelectionLocation(m_gm.VwGraphics, ptrans), Is.EqualTo( new Rectangle(leftXd, topYd, para2.Width, bottomOfFirstHiliteP3 - topYd))); }
public void InsertCharInEmptyLine() { string contents = ""; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var styles = new AssembledStyles().WithWs(34); var clientRuns = new List<IClientRun>(); var run = new StringClientRun(contents, styles); clientRuns.Add(run); var data1 = new MockData1(34, 35); data1.SimpleThree = contents; var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged, hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => data1.SimpleThree = newVal; run.Hookup = hookup; var root = new RootBox(styles); var block = new BlockBox(styles, Color.Red, 20000, 10000); root.AddBox(block); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(para.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); Assert.That(root.Width, Is.EqualTo(block.Width)); int simulatedWidth = FakeRenderEngine.SimulatedWidth("x"); Assert.That(root.Width, Is.GreaterThan(para.Width + simulatedWidth)); PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; var oldRootWidth = root.Width; var ip = root.SelectAtEnd(); ip.InsertText("x"); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(root.Width, Is.EqualTo(oldRootWidth)); Assert.That(para.Width, Is.EqualTo(simulatedWidth)); var expectedInvalidate = new Rectangle(-RootBox.InvalidateMargin, - RootBox.InvalidateMargin + block.Height, simulatedWidth + RootBox.InvalidateMargin * 2, 13 + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate)); }
public void NestedRowsLayout() { var styles = new AssembledStyles(); var box1 = new LayoutInfoRecorderBox(styles, Color.Red, 72000, 36000); var box2 = new LayoutInfoRecorderBox(styles, Color.Blue, 108000, 18000); var box3 = new LayoutInfoRecorderBox(styles, Color.Orange, 72000, 18000); var box4 = new LayoutInfoRecorderBox(styles, Color.Orange, 72000, 18000); var widths = new FixedColumnWidths(new[] { 34, 67, 99 }); // pass widths to RowBox constructor var row1 = new RowBox(styles, widths, false); var row2 = new RowBox(styles, widths, false); row1.AddBox(box1); row1.AddBox(box2); row2.AddBox(box3); row2.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(row1); root.AddBox(row2); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.LastLayoutInfo.MaxWidth, Is.EqualTo(34)); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(box3.Height, Is.EqualTo(24)); Assert.That(box4.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24)); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(96)); Assert.That(box3.Left, Is.EqualTo(0)); Assert.That(box4.Left, Is.EqualTo(96)); Assert.That(row1.Top, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(0)); Assert.That(row2.Top, Is.EqualTo(48)); Assert.That(box3.Top, Is.EqualTo(0)); Assert.That(box4.Top, Is.EqualTo(0)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(box3.Width, Is.EqualTo(96)); Assert.That(box4.Width, Is.EqualTo(96)); Assert.That(root.Width, Is.EqualTo(96 + 144)); // Now try changing the size of a block. MockSite site = new MockSite(); root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 120, 128); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; box2.UpdateSize(144000, 36000); Assert.That(box2.Width, Is.EqualTo(96 * 2)); Assert.That(box2.Height, Is.EqualTo(48)); Assert.That(row1.Height, Is.EqualTo(48)); Assert.That(root.Height, Is.EqualTo(72)); Assert.That(root.Width, Is.EqualTo(96 * 3)); // Since it got both wider and higher, we should invalidate at least the whole current size. var bigInvalidate = root.InvalidateRect; Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(96 + 144)); // narrower box2 still determines it // Got narrower, at least the whole old invalidate rectangle should be invalidated. Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(72000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144 + 48)); // new smaller value // It got thinner. We want an optimized invalidate rectangle that does not // include the left boxes. But it must include the space at the right that the root box used to occupy. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it's in the fixmap so its own Relayout does this); // the shrinkage area at the right of row2; // and the area computed because row2 moved. //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 48, 144); // old box2 //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 24); // shrinkage of row1 // This is from the new left of div2 to its old right (old right was 48 + 48 + 24 + 24) //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 48 + 24); site.RectsInvalidated.Clear(); box2.UpdateSize(144000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144 + 144)); // new larger value // It got wider. We want an optimized invalidate rectangle that does not // include the left boxes. But it must include the space at the right where the root box grew. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it returns true from Relayout); // the growth area at the right of div2; // and the area computed because div2 moved. //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 96); // new box2 //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 - 24); // new part of div1 occupied by box2 // This is from the old left of div2 to its new right (48 + 96 + 24 + 24) //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 + 24); }
public void EmptyString() { int ws = 1; AssembledStyles styles = new AssembledStyles().WithWs((ws)); var clientRuns = new List<IClientRun>(); StringClientRun clientRun = new StringClientRun("", styles); clientRuns.Add(clientRun); TextSource source = new TextSource(clientRuns, null); ParaBox para = new ParaBox(styles, source); RootBox root = new RootBox(styles); root.AddBox(para); LayoutInfo layoutArgs = MakeLayoutInfo(); var engine = layoutArgs.GetRenderer(1) as MockRenderEngine; engine.AddMockSeg(0, 0, 0, 0, ws, LgEndSegmentType.kestNoMore); root.Layout(layoutArgs); Assert.AreEqual(1, para.Lines.Count); Assert.IsTrue(root.Height > 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); }
/// <summary> /// The setup method for para builder is also useful for testing stuff related to the paragraph itself. /// </summary> /// <param name="vg"></param> /// <param name="para"></param> /// <returns></returns> internal static RootBox MakeTestParaSimpleString(IVwGraphics vg, MockBreakOption breakOption, out ParaBox para) { var styles = new AssembledStyles().WithWs(s_simpleStringWs); string contents = AssembleStrings(s_simpleStringWords); var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents, styles)); var source = new TextSource(clientRuns, null); para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, vg); var engine = layoutArgs.GetRenderer(1) as MockRenderEngine; switch (breakOption) { case MockBreakOption.ThreeOkayBreaks: // This option generates three lines as long as the width is sufficient because // Asked to break the whole string we answer a segment that has the first three words. engine.AddMockSeg(0, contents.Length, SumStringLengths(s_simpleStringWords, 0, 3), s_widthFirstMockSeg, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we answer a segment with the next three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 3), contents.Length, SumStringLengths(s_simpleStringWords, 3, 6), s_widthSecondMockSeg, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we answer a segment with the last three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 6), contents.Length, SumStringLengths(s_simpleStringWords, 6, 9), s_widthThirdMockSeg, s_simpleStringWs, LgEndSegmentType.kestNoMore); break; case MockBreakOption.FourSegsThreeLines: // Asked to break the whole string we answer a segment that has the first two words but allows more. engine.AddMockSeg(0, contents.Length, SumStringLengths(s_simpleStringWords, 0, 2), 50, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we give one more word and say it fills the line. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 2), contents.Length, SumStringLengths(s_simpleStringWords, 0, 3), 20, s_simpleStringWs, LgEndSegmentType.kestMoreLines); // Asked to break the rest of the line we answer a segment with the next three and say it fills the line. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 3), contents.Length, SumStringLengths(s_simpleStringWords, 3, 6), s_widthSecondMockSeg, s_simpleStringWs, LgEndSegmentType.kestMoreLines); // Asked to break the rest of the line we answer a segment with the last three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 6), contents.Length, SumStringLengths(s_simpleStringWords, 6, 9), s_widthThirdMockSeg, s_simpleStringWs, LgEndSegmentType.kestNoMore); // Asked to do anything else engine.OtherSegPolicy = UnexpectedSegments.MakeOneCharSeg; break; case MockBreakOption.ThreeFullLines: // Asked to break the whole string we answer a segment that has the first three words. SetupMockEngineForThreeLines(contents, engine, s_simpleStringWords); break; } root.Layout(layoutArgs); return root; }
ParaBox AddPara(string[] contents, AssembledStyles styles, RootBox root) { var clientRuns = new List<IClientRun>(); foreach (string item in contents) { var run = new StringClientRun(item, styles); clientRuns.Add(run); } var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); root.AddBox(para); return para; }
public void DivClippedPaint() { var styles = new AssembledStyles(); var box1 = new FgBlockBox(styles, Color.Red, 72000, 36000); var box2 = new FgBlockBox(styles, Color.Blue, 108000, 18000); var box3 = new FgBlockBox(styles, Color.Orange, 72000, 18000); var box4 = new FgBlockBox(styles, Color.Orange, 72000, 18000); var div1 = new DivBox(styles); div1.AddBox(box1); div1.AddBox(box2); div1.AddBox(box3); div1.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(div1); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); var rect1 = new Rectangle(0, 0, 96, 48); var rect2 = new Rectangle(0, 0, 144, 24); rect2.Offset(0, rect1.Bottom); var rect3 = new Rectangle(0, 0, 96, 24); rect3.Offset(0, rect2.Bottom); var rect4 = new Rectangle(0, 0, 96, 24); rect4.Offset(0, rect3.Bottom); var paintRects = new[] { rect1, rect2, rect3, rect4 }; VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 2000), 0, 0, paintRects); // Clipping off the top part, but not the whole, of a box does not prevent drawing it. VerifyPaint(root, new Rectangle(-1000, 10, 2000, -10 + rect4.Bottom - 10), 0, 0, paintRects); // Even clipping all but one pixel does not prevent drawing. VerifyPaint(root, new Rectangle(-1000, 47, 2000, -47 + rect3.Bottom + 1), 0, 0, paintRects); // However if we clip a bit more we should draw less var middleTwo = new[] {rect2, rect3}; VerifyPaint(root, new Rectangle(-1000, 48, 2000, -48 + rect3.Bottom - 2), 0, 0, middleTwo); // If the clip covers just a bit of the first box we paint just that. var firstOne = new[] {rect1}; VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 1000 + 10), 0, 0, firstOne); // If the clip covers just a bit of the last box we paint just that. var lastOne = new[] { rect4 }; VerifyPaint(root, new Rectangle(-1000, rect4.Bottom - 2, 2000, 1000), 0, 0, lastOne); // If the clip is entirely above the pile we draw nothing. VerifyPaint(root, new Rectangle(-1000, -1000, 2000, 990), 0, 0, null); // Likewise if entirely below. VerifyPaint(root, new Rectangle(-1000, rect4.Bottom + 10, 2000, 10), 0, 0, null); // Now try with simulated scrolling. Use a normal clip rectangle, but pretend the first two // and a bit boxes are scrolled off. var offset = rect2.Bottom + 10; var rect3Offset = rect3; rect3Offset.Offset(0, -offset); var rect4Offset = rect4; rect4Offset.Offset(0, -offset); var lastTwoOffset = new[] {rect3Offset, rect4Offset}; VerifyPaint(root, new Rectangle(-1000, 0, 2000, 200), 0, offset, lastTwoOffset); }
public void NestedDivsLayout() { var styles = new AssembledStyles(); BlockBox box1 = new BlockBox(styles, Color.Red, 72000, 36000); BlockBox box2 = new BlockBox(styles, Color.Blue, 108000, 18000); BlockBox box3 = new BlockBox(styles, Color.Orange, 72000, 18000); BlockBox box4 = new BlockBox(styles, Color.Orange, 72000, 18000); var div1 = new DivBox(styles); var div2 = new DivBox(styles); div1.AddBox(box1); div1.AddBox(box2); div2.AddBox(box3); div2.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(div1); root.AddBox(div2); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24 + 24)); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(48)); Assert.That(div2.Top, Is.EqualTo(48 + 24)); Assert.That(box4.Top, Is.EqualTo(24)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(root.Width, Is.EqualTo(144)); // Now try changing the size of a block. MockSite site = new MockSite(); root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 120, 128); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; box2.UpdateSize(144000, 36000); Assert.That(box2.Width, Is.EqualTo(96*2)); Assert.That(box2.Height, Is.EqualTo(48)); Assert.That(div1.Height, Is.EqualTo(96)); // two children now both 48 high. Assert.That(root.Height, Is.EqualTo(48 +48 + 24 + 24)); // new heights of 4 children. Assert.That(root.Width, Is.EqualTo(96*2)); // Since it got both wider and higher, we should invalidate at least the whole current size. var bigInvalidate = root.InvalidateRect; Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 36000); Assert.That(root.Height, Is.EqualTo(48 + 48 + 24 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144)); // narrower box2 still determines it // Got narrower, at least the whole old invalidate rectangle should be invalidated. Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24 + 24 + 24)); // new smaller value Assert.That(root.Width, Is.EqualTo(144)); // unchanged this time // It got shorter. We want an optimized invalidate rectangle that does not // include the top box. But it must include the space at the bottom that the root box used to occupy. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (its in the fixmap so its own Relayout does this); // the shrinkage area at the bottom of div2; // and the area computed because div2 moved. VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 48); // old box2 VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 24); // shrinkage of div1 // This is from the new top of div2 to its old bottom (old bottom was 48 + 48 + 24 + 24) VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 48 + 24); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 72000); Assert.That(root.Height, Is.EqualTo(48 + 96 + 24 + 24)); // new larger value Assert.That(root.Width, Is.EqualTo(144)); // unchanged this time // It got longer. We want an optimized invalidate rectangle that does not // include the top box. But it must include the space at the bottom where the root box grew. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it returns true from Relayout); // the growth area at the bottom of div2; // and the area computed because div2 moved. VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 96); // new box2 VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 - 24); // new part of div1 occupied by box2 // This is from the old top of div2 to its new bottom (48 + 96 + 24 + 24) VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 + 24); }
public void CommonContainerTests() { var styles = new AssembledStyles(); var columnWidths = new FixedColumnWidths(new[] {10}); var root1 = new RootBox(styles); var root2 = new RootBox(styles); VerifyCC(root1, root1, root1, root1, root1); VerifyCC(root2, root2, root2, root2, root2); var row1 = new RowBox(styles, columnWidths, false); var div1 = new DivBox(styles); root2.AddBox(row1); root1.AddBox(div1); VerifyCC(row1, row1, row1, row1, row1); VerifyCC(div1, div1, div1, div1, div1); VerifyCC(root1, div1, root1, root1, div1); VerifyCC(root2, row1, root2, root2, row1); var row2 = new RowBox(styles, columnWidths, false); var div2 = new DivBox(styles); root2.AddBox(row2); root1.AddBox(div2); VerifyCC(row1, row2, root2, row1, row2); VerifyCC(div1, div2, root1, div1, div2); var row3 = new RowBox(styles, columnWidths, false); var div3 = new DivBox(styles); row1.AddBox(row3); div1.AddBox(div3); VerifyCC(row1, row3, row1, row1, row3); VerifyCC(row2, row3, root2, row2, row1); VerifyCC(div1, div3, div1, div1, div3); VerifyCC(div2, div3, root1, div2, div1); var row4 = new RowBox(styles, columnWidths, false); var div4 = new DivBox(styles); row2.AddBox(row4); div2.AddBox(div4); VerifyCC(row3, row4, root2, row1, row2); VerifyCC(row1, row4, root2, row1, row2); VerifyCC(div3, div4, root1, div1, div2); VerifyCC(div1, div4, root1, div1, div2); }
public void NestedRowsLayout() { var styles = new AssembledStyles(); var box1 = new LayoutInfoRecorderBox(styles, Color.Red, 72000, 36000); var box2 = new LayoutInfoRecorderBox(styles, Color.Blue, 108000, 18000); var box3 = new LayoutInfoRecorderBox(styles, Color.Orange, 72000, 18000); var box4 = new LayoutInfoRecorderBox(styles, Color.Orange, 72000, 18000); var widths = new FixedColumnWidths(new[] {34, 67, 99}); // pass widths to RowBox constructor var row1 = new RowBox(styles, widths, false); var row2 = new RowBox(styles, widths, false); row1.AddBox(box1); row1.AddBox(box2); row2.AddBox(box3); row2.AddBox(box4); RootBox root = new RootBox(styles); root.AddBox(row1); root.AddBox(row2); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); Assert.That(box1.LastLayoutInfo.MaxWidth, Is.EqualTo(34)); Assert.That(box1.Height, Is.EqualTo(48)); Assert.That(box2.Height, Is.EqualTo(24)); Assert.That(box3.Height, Is.EqualTo(24)); Assert.That(box4.Height, Is.EqualTo(24)); Assert.That(root.Height, Is.EqualTo(48 + 24)); Assert.That(box1.Left, Is.EqualTo(0)); Assert.That(box2.Left, Is.EqualTo(96)); Assert.That(box3.Left, Is.EqualTo(0)); Assert.That(box4.Left, Is.EqualTo(96)); Assert.That(row1.Top, Is.EqualTo(0)); Assert.That(box1.Top, Is.EqualTo(0)); Assert.That(box2.Top, Is.EqualTo(0)); Assert.That(row2.Top, Is.EqualTo(48)); Assert.That(box3.Top, Is.EqualTo(0)); Assert.That(box4.Top, Is.EqualTo(0)); Assert.That(box1.Width, Is.EqualTo(96)); Assert.That(box2.Width, Is.EqualTo(144)); Assert.That(box3.Width, Is.EqualTo(96)); Assert.That(box4.Width, Is.EqualTo(96)); Assert.That(root.Width, Is.EqualTo(96 + 144)); // Now try changing the size of a block. MockSite site = new MockSite(); root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 120, 128); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; box2.UpdateSize(144000, 36000); Assert.That(box2.Width, Is.EqualTo(96 * 2)); Assert.That(box2.Height, Is.EqualTo(48)); Assert.That(row1.Height, Is.EqualTo(48)); Assert.That(root.Height, Is.EqualTo(72)); Assert.That(root.Width, Is.EqualTo(96 * 3)); // Since it got both wider and higher, we should invalidate at least the whole current size. var bigInvalidate = root.InvalidateRect; Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(108000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(96 + 144)); // narrower box2 still determines it // Got narrower, at least the whole old invalidate rectangle should be invalidated. Assert.That(site.RectsInvalidatedInRoot, Has.Member(bigInvalidate)); site.RectsInvalidated.Clear(); box2.UpdateSize(72000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144 + 48)); // new smaller value // It got thinner. We want an optimized invalidate rectangle that does not // include the left boxes. But it must include the space at the right that the root box used to occupy. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it's in the fixmap so its own Relayout does this); // the shrinkage area at the right of row2; // and the area computed because row2 moved. //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 48, 144); // old box2 //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 24); // shrinkage of row1 // This is from the new left of div2 to its old right (old right was 48 + 48 + 24 + 24) //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 48 + 24); site.RectsInvalidated.Clear(); box2.UpdateSize(144000, 18000); Assert.That(root.Height, Is.EqualTo(48 + 24)); // unchanged this time Assert.That(root.Width, Is.EqualTo(144 + 144)); // new larger value // It got wider. We want an optimized invalidate rectangle that does not // include the left boxes. But it must include the space at the right where the root box grew. // There are other possible implementations, but currently, we expect the old rectangle of box2 // to be invalidated (it returns true from Relayout); // the growth area at the right of div2; // and the area computed because div2 moved. //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48, 144, 96); // new box2 //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 - 24); // new part of div1 occupied by box2 // This is from the old left of div2 to its new right (48 + 96 + 24 + 24) //VerifyExpectedRectangle(site.RectsInvalidatedInRoot, 0, 48 + 24, 144, 96 + 24); }
public void MouseEvents() { var string1 = "This is the day that the Lord has made."; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var runStyle = new AssembledStyles().WithWs(34); var style = new AssembledStyles(); var root = new RootBox(style); var para1 = MakePara(style, runStyle, string1); root.AddBox(para1); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var layoutArgs = new LayoutInfo(2, 2, 96, 96, FakeRenderEngine.SimulatedWidth("This is the day "), m_gm.VwGraphics, factory); root.Layout(layoutArgs); var mouseArgs = new MouseEventArgs(MouseButtons.Left, 1, 2, 5, 0); root.OnMouseDown(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(0)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // In a different place, tests moving the selection and also getting AssociatePrevious true. int widthThis = FakeRenderEngine.SimulatedWidth("This"); var mouseArgs2 = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis - 1, 5, 0); root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.True); // A click in the same place should not make a new selection. var sel = root.Selection; root.OnMouseDown(mouseArgs2, Keys.None, m_gm.VwGraphics, ptrans); // no change Assert.That(root.Selection, Is.EqualTo(sel)); // A shift-click close enough to the same place to be the same character position but difference AssocPrevious // should make the appropriate new IP, not a range. var mouseArgs2b = new MouseEventArgs(MouseButtons.Left, 1, 2 + widthThis + 1, 5, 0); root.OnMouseDown(mouseArgs2b, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // A shift-click should make a range. root.OnMouseDown(mouseArgs, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection))); var anchor = ((RangeSelection) root.Selection).Anchor; var drag = ((RangeSelection) root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(0)); // shift-click further right: should move the drag end var mouseArgs3 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 5, 0); root.OnMouseDown(mouseArgs3, Keys.Shift, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(RangeSelection))); anchor = ((RangeSelection)root.Selection).Anchor; drag = ((RangeSelection)root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(1)); // mouse move, to a different position root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); sel = root.Selection; Assert.That(sel, Is.TypeOf(typeof(RangeSelection))); anchor = ((RangeSelection)root.Selection).Anchor; drag = ((RangeSelection)root.Selection).DragEnd; Assert.That(anchor.LogicalParaPosition, Is.EqualTo(4)); Assert.That(drag.LogicalParaPosition, Is.EqualTo(0)); // mouse move to the same position: no new selection. root.OnMouseMove(mouseArgs, Keys.None, m_gm.VwGraphics, ptrans); // no actual movement Assert.That(root.Selection, Is.EqualTo(sel)); Assert.That(((RangeSelection)root.Selection).DragEnd, Is.EqualTo(drag)); // mouse move to an IP at the anchor should return us to an IP root.OnMouseMove(mouseArgs2b, Keys.None, m_gm.VwGraphics, ptrans); Assert.That(root.Selection, Is.TypeOf(typeof(InsertionPoint))); Assert.That(((InsertionPoint)root.Selection).LogicalParaPosition, Is.EqualTo(4)); Assert.That(((InsertionPoint)root.Selection).AssociatePrevious, Is.False); // mouse down on next line makes a selection there. Confirm proper passing of srcRect for vertical offset var mouseArgs4 = new MouseEventArgs(MouseButtons.Left, 1, 2 + 4, 2 + 16, 0); root.OnMouseDown(mouseArgs4, Keys.None, m_gm.VwGraphics, ptrans); var paraBox = (ParaBox) root.FirstBox; var seg2 = ((StringBox) paraBox.FirstBox.Next).Segment as FakeSegment; Assert.That(seg2, Is.Not.Null); Assert.That(seg2.LastPointToCharArgs, Is.Not.Null); var topOfseg2 = paraBox.FirstBox.Height; Assert.That(seg2.LastPointToCharArgs.RcSrc, Is.EqualTo(new Rect(-2, -2 - topOfseg2, 94, 94-topOfseg2))); }