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); }
void TestDeriverEffect <T>(AssembledStyles astyles, T defVal, T newVal, T otherVal, PropReader <T> reader, StyleDeriver <T> deriver, string label, HashSet <AssembledStyles> outputStyles) { Assert.AreEqual(defVal, reader(astyles), "default " + label + " should be normal"); AssembledStyles derivedStyles = deriver(astyles, newVal); int oldCount = outputStyles.Count; outputStyles.Add(derivedStyles); Assert.AreEqual(oldCount + 1, outputStyles.Count, "new derived styles should not be equal to any earlier one"); Assert.AreEqual(newVal, reader(derivedStyles), "derived AS should have " + label + " property set"); Assert.AreEqual(defVal, reader(astyles), "original AS should not be changed by With... - " + label); Assert.AreNotEqual(astyles, derivedStyles, "two different AS's should not be equal"); AssembledStyles derivedStyles2 = deriver(astyles, newVal); Assert.IsTrue(Object.ReferenceEquals(derivedStyles2, derivedStyles), "two astyles derived the same way should be the same object - " + label); AssembledStyles derivedStyles3 = deriver(derivedStyles2, otherVal); AssembledStyles derivedStyles4 = deriver(astyles, otherVal); Assert.IsTrue(Object.ReferenceEquals(derivedStyles3, derivedStyles4), "two equivalent astyles derived differently should be the same object - " + label); var rawDerived = new AssembledStyles(derivedStyles2); Assert.AreEqual(newVal, reader(rawDerived), "copy consructor should copy " + label + " property"); }
public void DrawIPMultiRunPara() { var styles = new AssembledStyles(); RootBox root = new RootBoxFdo(styles); root.Builder.Show(Paragraph.Containing( Display.Of("first"), Display.Of("second"), Display.Of("third"))); SetupFakeRootSite(root); var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 55); root.Layout(layoutInfo); InsertionPoint ip = root.SelectAtEnd(); ip.Install(); var para = (ParaBox) root.FirstBox; Assert.AreEqual(ip, root.Selection); Assert.AreEqual(para, ip.Para, "IP should know about the paragraph it is in"); Assert.AreEqual("third".Length, ip.StringPosition, "IP position is relative to run"); Assert.AreEqual(true, ip.AssociatePrevious, "selection at end should always associate previous in non-empty para"); StringBox sbox = para.FirstBox as StringBox; Assert.That(sbox, Is.EqualTo(para.LastBox), "uniform text in infinite width should make one string box"); var seg = sbox.Segment as FakeSegment; Assert.IsNotNull(seg); PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, -10, 120, 128); ip.Draw(m_gm.VwGraphics, ptrans); VerifySegmentDrawing(para, sbox, seg.LastDrawIpCall, -4); seg.NextPosIpResult = new MockSegment.PositionsOfIpResults(); seg.NextPosIpResult.RectPrimary = new Rect(5, 6, 7, 9); seg.NextPosIpResult.PrimaryHere = true; Rectangle selRect = ip.GetSelectionLocation(m_gm.VwGraphics, ptrans); VerifySelLocation(para, sbox, seg.LastPosIpCall, -4); Assert.AreEqual(new Rectangle(5, 6, 2, 3), selRect); }
public Flow Borders(int mpLeading, int mpTop, int mpTrailing, int mpBottom, Color borderColor) { AddSetter(AssembledStyles.BordersSetter( new Thickness(mpLeading / 1000.0, mpTop / 1000.0, mpTrailing / 1000.0, mpBottom / 1000.0))); AddSetter(AssembledStyles.BorderColorSetter(borderColor)); return(this); }
public void DiffRuns() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "new stuff"; var mock2 = new MockData1(23, 23); mock2.SimpleThree = "old contents"; var mock3 = new MockData1(23, 23); mock3.SimpleThree = "different things"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Paragraph.Containing(Display.Of(() => mock1.SimpleThree, 23), Display.Of(() => mock2.SimpleThree, 23), Display.Of(() => mock3.SimpleThree, 23))); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; int x = FakeRenderEngine.SimulatedWidth("new stuf") + 2; var location = new Point(x, 8); EventArgs e = new EventArgs(); MouseEventArgs m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("stuff")); x = FakeRenderEngine.SimulatedWidth("new stuff") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old ")); x = FakeRenderEngine.SimulatedWidth("new stuff old contents") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("different ")); }
public void Relayout() { var styles = new AssembledStyles(); var box = new MockBox(styles); var fixMap = new Dictionary <Box, Rectangle>(); var layoutInfo = ParaBuilderTests.MakeLayoutInfo(100, m_gm.VwGraphics); var site = new MockSite(); var root = new RootBox(styles); root.Site = site; using (var lcb = new LayoutCallbacks(root)) { Assert.IsFalse(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box never laid out should return false (can't have old loc)"); } Assert.AreEqual(layoutInfo, box.LastLayoutTransform, "Relayout of box never laid out should call Layout() with same transform"); Assert.AreEqual(0, site.RectsInvalidated.Count, "Relayout of box never laid out should not invalidate anything"); box.LastLayoutTransform = null; using (var lcb = new LayoutCallbacks(root)) Assert.IsFalse(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box not in map should return false"); Assert.IsNull(box.LastLayoutTransform, "Relayout of box not in map should not call Layout()"); Assert.AreEqual(0, site.RectsInvalidated.Count, "Relayout of box not in map should not invalidate anything"); fixMap[box] = new Rectangle(2, 3, 4, 7); using (var lcb = new LayoutCallbacks(root)) Assert.IsTrue(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box in map should return true"); Assert.AreEqual(layoutInfo, box.LastLayoutTransform, "Relayout of box in map should call Layout() with same transform"); Assert.AreEqual(1, site.RectsInvalidatedInRoot.Count, "Relayout of box in map should invalidate rect from map"); Assert.AreEqual(new Rectangle(2, 3, 4, 7), site.RectsInvalidatedInRoot[0], "Relayout of box in map should invalidate proper rect"); }
public void PrepareRowFixupMap() { var styles = new AssembledStyles(); var row = new FixedSizeRow(styles, new FixedColumnWidths(new[] { 12 }), 27, 37); var root = new FixedSizeRoot(styles, 49, 59); var block = new BlockBox(styles, Color.Red, 6000, 8000); row.AddBox(block); root.AddBox(row); row.Left = 5; row.Top = 7; block.Left = 10; block.Top = 20; var transform = new LayoutInfo(0, 0, 72, 72, 1000, m_gm.VwGraphics, new MockRendererFactory()); block.Layout(transform); //Assert.AreEqual(6, block.Width); // sanity check: we made it 4000 mp wide at 72 dpi, that's 4 points at one point per dot var map = block.PrepareFixupMap(); var invalidRect = map[block]; Assert.AreEqual(new Rectangle(5 + 10 - 2, 7 + 20 - 2, 6 + 4, 8 + 4), invalidRect); invalidRect = map[row]; Assert.AreEqual(new Rectangle(5 - 2, 7 - 2, 27 + 4, 37 + 4), invalidRect); invalidRect = map[root]; Assert.AreEqual(new Rectangle(-2, -2, 49 + 4, 59 + 4), invalidRect); }
private void InitLongText() { var stylesheet = SetupStyles(); var styles = new AssembledStyles(stylesheet); RootBox root = new RootBoxFdo(styles.WithLineHeight(12500)); var owner = new ParagraphOwnerDemo(); var words = "This is a bit of text from which we can extract substrings of increasing length to populate various paragraphs in different ways" .Split(' '); string sb = ""; int ws = 1; // arbitrary with default renderer factory. for (int i = 0; i < 20; i++) { if (i < words.Length) { sb += (words[i]); } if (i < words.Length) { sb += (" "); } var para = ApplyTsStringStyle(sb, "Normal", ws); owner.InsertParagraph(0, para); } root.Builder.Show(Div.Containing(Div.Containing(Display.Of(() => owner.Paragraphs).Using( (builder, para) => builder.Show(Paragraph.Containing(Display.Of(() => para.TsContents)).Style(para.ParaStyle))) .EditParagraphsUsing(new ParagraphOpsDemo(owner))).Border(1500).Pads(3000, 3000, 3000, 3000)).Border(2500).Pads(1000, 1000, 1000, 1000)); styleChooser.Visible = true; theSharpView.Root = root; root.SelectAtStart().Install(); theSharpView.Focus(); }
void StartupMultiLingualStrings() { var stylesheet = SetupStyles(); var styles = new AssembledStyles(stylesheet); RootBox root = new RootBoxFdo(styles); var owner = new ParagraphOwnerDemo(); var paraDemo = new ParagraphDemo { ParaStyle = "Left" }; paraDemo.MlsContents = m_mlsOwner.MyMultiString; owner.InsertParagraph(0, paraDemo); root.Builder.Show(Display.Of(() => owner.Paragraphs).Using( (builder, para) => builder.Show(Paragraph.Containing(Display.Of(() => para.MlsContents, Ws2)).Style(para.ParaStyle))), Display.Of(() => owner.Paragraphs).Using( (builder, para) => builder.Show(Paragraph.Containing(Display.Of(() => para.MlsContents, Ws1)).Style(para.ParaStyle)))) .EditParagraphsUsing(new ParagraphOpsDemo(owner)); wsSelector1.SelectedItem = wsSelector1.Items[Ws1 - 1]; wsSelector2.SelectedItem = wsSelector2.Items[Ws2 - 1]; theSharpView.Root = root; root.SelectAtStart().Install(); theSharpView.Focus(); }
private void InitTextWithPrompts() { var styles = new AssembledStyles(); RootBox root = new RootBoxFdo(styles); root.RendererFactory = theSharpView.RendererFactory; var obj0 = new ParagraphDemo { Contents = "one" }; var obj1 = new ParagraphDemo { Contents = "" }; var obj2 = new ParagraphDemo { Contents = "three" }; int ws = 1; // arbitrary with default renderer factory. root.Builder.Show( Paragraph.Containing( Display.Of(() => obj0.Contents, ws).WhenEmpty("prompt", ws), Display.Of(" "), Display.Of(() => obj1.Contents, ws).WhenEmpty("prompt", ws), Display.Of(" "), Display.Of(() => obj2.Contents, ws).WhenEmpty("prompt", ws) ) ); theSharpView.Root = root; root.SelectAtStart().Install(); theSharpView.Focus(); }
public SubstituteMapRun(int logical, IClientRun clientRun, int render, string substitute, AssembledStyles substituteStyle) : base(logical, clientRun, render, 0, substitute.Length) { Debug.Assert(clientRun.Length == 0); m_substitute = substitute; m_substituteStyle = substituteStyle; }
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)); }
void GetFontsForAssembledStyle(AssembledStyles styles, Dictionary <string, int> fonts, ref int nextId) { int ws = styles.Ws; string fontName = styles.FaceName; if (ws != 0) { var chrp = styles.Chrp; var wsFactory = Anchor.Para.Source.GetWsFactory(); if (wsFactory != null) // paranoia { var writingSystem = wsFactory.get_EngineOrNull(ws); if (writingSystem != null) { writingSystem.InterpretChrp(ref chrp); fontName = AssembledStyles.FaceNameFromChrp(chrp); } } } int id; if (fonts.TryGetValue(fontName, out id)) { return; } fonts[fontName] = nextId++; }
/// <summary> /// Add a group box to the current box. Make it the current destination for the duration /// of calling AddContents, then restore the current destination. /// </summary> public ViewBuilder AddGroupBox(GroupBox box, Action <ViewBuilder> addContents) { var oldDest = m_destination; var oldNestedBoxStyles = m_nestedBoxStyles; if (box is RunBox) { // allow the new contents to add to the current box, but override the default nested styles. m_nestedBoxStyles = box.Style; addContents(this); } else { // Let nested styles be obtained as needed from the new destination box. // No need to compute them if they are not used. m_nestedBoxStyles = null; InsertBox(box); var oldInsertAfter = m_insertAfter; m_destination = box; // in case we aren't making hookups, insert at start of new destination m_insertAfter = null; m_insertRunAt = 0; addContents(this); m_insertAfter = oldInsertAfter; } m_destination = oldDest; m_nestedBoxStyles = oldNestedBoxStyles; return(this); }
private void InitStyleSheetChooser() { var stylesheet = SetupStyles(); int ws = 1; // arbitrary with default renderer factory. var styles = new AssembledStyles(stylesheet); RootBox root = new RootBoxFdo(styles); root.RendererFactory = theSharpView.RendererFactory; var obj0 = ApplyTsStringStyle("plain, ", "Normal", ws); var obj1 = ApplyTsStringStyle("bold, ", "Bold", ws); var obj2 = ApplyTsStringStyle("italic, ", "Italic", ws); var obj3 = ApplyTsStringStyle("bold italic, ", "Bold Italic", ws); var obj4 = ApplyTsStringStyle("red on yellow", "Red on Yellow", ws); root.Builder.Show(Paragraph.Containing(Display.Of(() => obj0.TsContents), Display.Of(() => obj1.TsContents), Display.Of(() => obj2.TsContents), Display.Of(() => obj3.TsContents), Display.Of(() => obj4.TsContents))); styleChooser.Visible = true; theSharpView.Root = root; root.SelectAtStart().Install(); theSharpView.Focus(); }
public void Relayout() { var styles = new AssembledStyles(); var box = new MockBox(styles); var fixMap = new Dictionary<Box, Rectangle>(); var layoutInfo = ParaBuilderTests.MakeLayoutInfo(100, m_gm.VwGraphics); var site = new MockSite(); var root = new RootBox(styles); root.Site = site; using (var lcb = new LayoutCallbacks(root)) { Assert.IsFalse(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box never laid out should return false (can't have old loc)"); } Assert.AreEqual(layoutInfo, box.LastLayoutTransform, "Relayout of box never laid out should call Layout() with same transform"); Assert.AreEqual(0, site.RectsInvalidated.Count, "Relayout of box never laid out should not invalidate anything"); box.LastLayoutTransform = null; using (var lcb = new LayoutCallbacks(root)) Assert.IsFalse(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box not in map should return false"); Assert.IsNull(box.LastLayoutTransform, "Relayout of box not in map should not call Layout()"); Assert.AreEqual(0, site.RectsInvalidated.Count, "Relayout of box not in map should not invalidate anything"); fixMap[box] = new Rectangle(2,3,4,7); using (var lcb = new LayoutCallbacks(root)) Assert.IsTrue(box.Relayout(layoutInfo, fixMap, lcb), "Relayout of box in map should return true"); Assert.AreEqual(layoutInfo, box.LastLayoutTransform, "Relayout of box in map should call Layout() with same transform"); Assert.AreEqual(1, site.RectsInvalidatedInRoot.Count, "Relayout of box in map should invalidate rect from map"); Assert.AreEqual(new Rectangle(2, 3, 4, 7), site.RectsInvalidatedInRoot[0], "Relayout of box in map should invalidate proper rect"); }
private void InitLongText() { AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBox(styles); var owner = new ParagraphOwnerDemo(); var words = "This is a bit of text from which we can extract substrings of increasing length to populate various paragraphs in different ways".Split(' '); var sb = new StringBuilder(); for (int i = 0; i < 20; i++) { var para = new ParagraphDemo(); if (i < words.Length) { sb.Append(words[i]); } para.Contents = sb.ToString(); if (i < words.Length) { sb.Append(" "); } owner.InsertParagraph(0, para); } int ws = 1; // arbitrary with default renderer factory. root.Builder.Show(Display.Of(() => owner.Paragraphs).Using( (builder, para) => builder.AddString(() => para.Contents, ws)) .EditParagraphsUsing(new ParagraphOpsDemo(owner))); theSharpView.Root = root; root.SelectAtEnd().Install(); theSharpView.Focus(); }
public void InterpretChrp(ref LgCharRenderProps chrp) { if (AssembledStyles.FaceNameFromChrp(chrp) == AssembledStyles.DefaultFontName) { AssembledStyles.SetFaceName(ref chrp, "MockFont"); } }
public void OrcBoxRun() { // Run 0 string part0 = "abc"; string part1 = "\xfffc"; string part2 = "defg"; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun0 = new StringClientRun(part0 + part1 + part2, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); BlockBox box = new BlockBox(styles.WithWs(wsFrn), Color.Red, 72000, 36000); TextSource source = new TextSource(clientRuns, (run, offset) => box); MapRun[] runs = source.Runs; Assert.AreEqual(3, runs.Length); VerifyRun(0, clientRun0, 0, 0, part0, runs[0], "first run of complex source with box"); int len = part0.Length; VerifyRun(len, box, len, part0.Length, part1, runs[1], "2nd run of complex source with box"); len += 1; VerifyRun(len, clientRun0, len, part0.Length + 1, part2, runs[2], "3rd run of complex source with box"); len += part2.Length; Assert.AreEqual(len, source.Length, "length of complex source with box"); VerifyCharProps(source, part0.Length, wsFrn, part0.Length, part0.Length + 1, "props of box"); }
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)); }
private void InitStyledText() { AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBox(styles); root.RendererFactory = theSharpView.RendererFactory; var obj0 = new ParagraphDemo() { Contents = "plain " }; var obj1 = new ParagraphDemo() { Contents = "bold " }; var obj2 = new ParagraphDemo() { Contents = "italic " }; var obj3 = new ParagraphDemo() { Contents = "bold italic " }; var obj4 = new ParagraphDemo() { Contents = "red on yellow" }; int ws = 1; // arbitrary with default renderer factory. root.Builder.Show( Paragraph.Containing( Display.Of(() => obj0.Contents, ws).FaceName("Times New Roman"), Display.Of(() => obj1.Contents, ws).FaceName("Times New Roman").Bold, Display.Of(() => obj2.Contents, ws).FaceName("Times New Roman").Italic, Display.Of(() => obj3.Contents, ws).FaceName("Times New Roman").Bold.Italic, Display.Of(() => obj4.Contents, ws).ForeColor(Color.Red).BackColor(Color.Yellow) ).Border(1.Points(), Color.Red).Pads(2.Points(), 3.Points(), 2.Points(), 3.Points()) ); root.Builder.Show( Paragraph.Containing( Display.Of("plain"), Display.Of("underOnYellow").Underline(FwUnderlineType.kuntSingle).BackColor(Color.Yellow).FaceName("Times New Roman") ).Margins(3.Points(), 2.Points(), 5.Points(), 2.Points()) .Borders(1.Points(), 2.Points(), 3.Points(), 4.Points(), Color.Green) .BackColor(Color.Pink).Pads(2.Points(), 2.Points(), 2.Points(), 2.Points()), 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, Color.Red) ) ); theSharpView.Root = root; root.SelectAtEnd().Install(); theSharpView.Focus(); }
public void Select() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "new old contents"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; int x = FakeRenderEngine.SimulatedWidth("new ") + 2; var location = new Point(x, 8); EventArgs e = new EventArgs(); MouseEventArgs m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old ")); mock1.SimpleThree = "new old:contents"; x = FakeRenderEngine.SimulatedWidth("new o") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old")); mock1.SimpleThree = "new(old contents"; x = FakeRenderEngine.SimulatedWidth("new ol") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old ")); mock1.SimpleThree = "newo1dcontents"; x = FakeRenderEngine.SimulatedWidth("new o1d") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("newo1dcontents")); }
/// <summary> /// Fluent language: return this, but the contents of the flow have the specified style. /// </summary> public Flow Style(string name) { if (name == null) { name = ""; } AddSetter(AssembledStyles.StyleSetter(name)); return(this); }
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 StringsInSource() { ITsString tss = tsf.MakeString("abc def", wsEn); AssembledStyles styles = new AssembledStyles(); TssClientRun clientRun = new TssClientRun(tss, styles); var clientRuns = new List<IClientRun>(); clientRuns.Add(clientRun); TextSource ts = new TextSource(clientRuns); }
public TssClientRun(ITsString tss, AssembledStyles style) { if (tss == null) { throw new ArgumentNullException("tss", "Cannot create TssClientRun with null TsString"); } Tss = tss; Style = style; }
public void MultiParaCopy() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var owner = new MockData1(23, 23); var mock1 = new MockData1(23, 23); var mock2 = new MockData1(23, 23); var mock3 = new MockData1(23, 23); owner.InsertIntoObjSeq1(0, mock1); owner.InsertIntoObjSeq1(1, mock2); owner.InsertIntoObjSeq1(2, mock3); mock1.SimpleThree = "This is the"; mock2.SimpleThree = "day that the"; mock3.SimpleThree = "Lord has made"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); var layoutInfo = HookupTests.MakeLayoutInfo(int.MaxValue / 2, m_gm.VwGraphics, 23); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; var po = new MockReceiveParagraphOperations(); root.Builder.Show(Display.Of(() => owner.ObjSeq1).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 23)) .EditParagraphsUsing(po)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); int x = FakeRenderEngine.SimulatedWidth("This ") + 2; var location = new Point(x, 8); Clipboard.SetDataObject(""); MouseEventArgs e = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(e, Keys.None, site.m_vwGraphics, site.m_transform); Assert.That(root.CanCopy(), Is.EqualTo(false), "Should not be able to copy"); x = FakeRenderEngine.SimulatedWidth("Lord") + 2; location = new Point(x, 29); e = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseMove(e, Keys.None, site.m_vwGraphics, site.m_transform); Assert.That(root.CanCopy(), Is.EqualTo(true), "Should be able to copy"); root.OnEditCopy(); Assert.That(owner.ObjSeq1[0].SimpleThree + owner.ObjSeq1[1].SimpleThree + owner.ObjSeq1[2].SimpleThree, Is.EqualTo("This is the" + "day that the" + "Lord has made")); Assert.That(Clipboard.GetDataObject().GetData(DataFormats.StringFormat), Is.EqualTo("is the\r\nday that the\r\nLord"), "Selected String should be \"is the\nday that the\nLord \""); }
public void StringsInSource() { ITsString tss = tsf.MakeString("abc def", wsEn); AssembledStyles styles = new AssembledStyles(); TssClientRun clientRun = new TssClientRun(tss, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun); TextSource ts = new TextSource(clientRuns); }
/// <summary> /// Add to the builder the box that wraps your content. /// </summary> public GroupBox MakeBox(AssembledStyles baseStyles) { var derivedStyles = baseStyles.WithProperties(m_propSetter); if (BoxMaker == null) { return(new RunBox(derivedStyles)); } return(BoxMaker(derivedStyles)); }
public void MakeBlockBox() { AssembledStyles styles = new AssembledStyles(); BlockBox box = new BlockBox(styles, Color.Red, 72000, 36000); LayoutInfo transform = MakeLayoutInfo(); box.Layout(transform); Assert.AreEqual(48, box.Height); Assert.AreEqual(96, box.Width); }
public void BasicDrop() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "old contents"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; var dataObj = new DataObject(DataFormats.StringFormat, "new "); int x = FakeRenderEngine.SimulatedWidth("old ") + 2; var location = new Point(x, 8); // A drag to where we can drop, allowing both copy and move, no keys held var dragArgs = new DragEventArgs(dataObj, (int) DragDropKeyStates.None, 200,300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Move)); Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere)); root.OnDragLeave(); Assert.That(root.DragState, Is.EqualTo(WindowDragState.None)); // Though other factors would favor move, only copy is allowed here. dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200,300, DragDropEffects.Copy, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Copy)); // Though otherwise we could copy, there is no text data in the data object. dragArgs = new DragEventArgs(new DataObject(), (int)DragDropKeyStates.None, 200,300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None)); dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.ControlKey, 200,300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Copy)); root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(mock1.SimpleThree, Is.EqualTo("old new contents")); }
private void InitSimpleTextPara() { AssembledStyles styles = new AssembledStyles(); RootBox root = new RootBox(styles); int ws = 1; // arbitrary with default renderer factory. AddSimpleTextPara(styles, ws, root); theSharpView.Root = root; root.SelectAtEnd().Install(); theSharpView.Focus(); }
private void InitDoubleString() { var styles = new AssembledStyles(); RootBox root = new RootBoxFdo(styles); int ws = 1; // arbitrary with default renderer factory. AddSimpleTextPara(styles, ws, root); AddSimpleTextPara(styles, ws, root); theSharpView.Root = root; root.SelectAtStart().Install(); theSharpView.Focus(); }
public void DragStartsOnMoveInSelection() { string contents = "This is the day."; 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 source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var extraBox = new BlockBox(styles, Color.Red, 50, 72000); // tall, narrow spacer at top var root = new RootBoxFdo(styles); root.AddBox(extraBox); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue/2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(96 + 13)); Assert.That(root.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); var ip1 = run.SelectAt(para, 5, false); var ip2 = run.SelectAt(para, 7, true); var range = new RangeSelection(ip1, ip2); range.Install(); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); var sbox = para.FirstBox as StringBox; MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; int indent = FakeRenderEngine.SimulatedWidth("This "); root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); root.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(GetStringDropData(site), Is.EqualTo("is")); Assert.That(site.LastDoDragDropArgs.AllowedEffects, Is.EqualTo(DragDropEffects.Copy), "editing not possible in this paragraph, we can only copy"); Assert.That(root.Selection, Is.EqualTo(range), "selection should not be changed by drag drop"); site.LastDoDragDropArgs = null; root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 3, 100, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(site.LastDoDragDropArgs, Is.Null, "click outside selection should not initiate drag"); // Tack on an extra check that a read-only view does not handle drop. var dataObj = new DataObject(DataFormats.StringFormat, "new "); var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.ControlKey, 10, 8, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, new Point(14, 8), m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None)); Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere)); }
public void StringRun() { string part1 = "abc def"; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun = new StringClientRun(part1, styles); Assert.AreEqual(1, clientRun.UniformRunCount); Assert.AreEqual(part1, clientRun.UniformRunText(0)); AssembledStyles style1 = clientRun.UniformRunStyles(0); Assert.AreEqual(wsEn, style1.Ws); Assert.AreEqual(0, clientRun.UniformRunStart(0)); Assert.AreEqual(part1.Length, clientRun.UniformRunLength(0)); }
public void SingleUniformRuns() { string part1 = "abc def"; var styles = new AssembledStyles().WithWs(wsEn); var clientRun = new StringClientRun(part1, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun); TextSource source = new TextSource(clientRuns); MapRun[] runs = source.Runs; Assert.AreEqual(1, runs.Length); VerifyRun(0, clientRun, 0, 0, part1, runs[0], "first run of simple source"); Assert.AreEqual(part1.Length, source.Length, "length of simple source"); }
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); }
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); }
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); }
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 PrepareDivFixupMap() { var styles = new AssembledStyles(); var div = new FixedSizeDiv(styles, 27, 37); var root = new FixedSizeRoot(styles, 49, 59); var block = new BlockBox(styles, Color.Red, 6000, 8000); div.AddBox(block); root.AddBox(div); div.Left = 5; div.Top = 7; block.Left = 10; block.Top = 20; var transform = new LayoutInfo(0, 0, 72, 72, 1000, m_gm.VwGraphics, new MockRendererFactory()); block.Layout(transform); //Assert.AreEqual(6, block.Width); // sanity check: we made it 4000 mp wide at 72 dpi, that's 4 points at one point per dot var map = block.PrepareFixupMap(); var invalidRect = map[block]; Assert.AreEqual(new Rectangle(5 + 10 - 2, 7 + 20 - 2, 6 + 4, 8 + 4), invalidRect); invalidRect = map[div]; Assert.AreEqual(new Rectangle(5 - 2, 7 - 2, 27 + 4, 37 + 4), invalidRect); invalidRect = map[root]; Assert.AreEqual(new Rectangle(- 2, - 2, 49 + 4, 59 + 4), invalidRect); }
public void TssRuns() { string part1 = "abc def"; ITsString tss = tsf.MakeString(part1, wsEn); AssembledStyles styles = new AssembledStyles(); TssClientRun clientRun = new TssClientRun(tss, styles); Assert.AreEqual(1, clientRun.UniformRunCount); Assert.AreEqual(part1, clientRun.UniformRunText(0)); AssembledStyles style1 = clientRun.UniformRunStyles(0); Assert.AreEqual(wsEn, style1.Ws); Assert.AreEqual(0, clientRun.UniformRunStart(0)); Assert.AreEqual(part1.Length, clientRun.UniformRunLength(0)); string part2 = " ghi"; ITsStrBldr bldr = tss.GetBldr(); bldr.Replace(part1.Length, part1.Length, part2, ttpFrn); TssClientRun clientRun2 = new TssClientRun(bldr.GetString(), styles); Assert.AreEqual(2, clientRun2.UniformRunCount); Assert.AreEqual(part1, clientRun2.UniformRunText(0)); Assert.AreEqual(part2, clientRun2.UniformRunText(1)); style1 = clientRun2.UniformRunStyles(0); Assert.AreEqual(wsEn, style1.Ws); AssembledStyles style2 = clientRun2.UniformRunStyles(1); Assert.AreEqual(wsFrn, style2.Ws); Assert.AreEqual(0, clientRun2.UniformRunStart(0)); Assert.AreEqual(part1.Length, clientRun2.UniformRunLength(0)); Assert.AreEqual(part1.Length, clientRun2.UniformRunStart(1)); Assert.AreEqual(part2.Length, clientRun2.UniformRunLength(1)); var source = new TextSource(new List<IClientRun>(new [] {clientRun2})); var runs = source.Runs; Assert.That(runs.Length, Is.EqualTo(2)); Assert.That(runs[0].LogLength, Is.EqualTo(part1.Length)); Assert.That(runs[1].LogLength, Is.EqualTo(part2.Length)); Assert.That(runs[1].LogStart, Is.EqualTo(part1.Length)); Assert.That(runs[1].Offset, Is.EqualTo(0)); // nothing fancy with ORCs, run starts at 0 in uniform run. }
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 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 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 DiffWS() { var tsf = TsStrFactoryClass.Create(); var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleTwo = tsf.MakeString("newoldcontents", 23); var bldr = mock1.SimpleTwo.GetBldr(); bldr.SetIntPropValues(3, 6, (int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, 24); bldr.SetIntPropValues(6, 14, (int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, 25); mock1.SimpleTwo = bldr.GetString(); var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.SimpleTwo)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; int x = FakeRenderEngine.SimulatedWidth("ne") + 2; var location = new Point(x, 8); EventArgs e = new EventArgs(); MouseEventArgs m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("new")); x = FakeRenderEngine.SimulatedWidth("new") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old")); x = FakeRenderEngine.SimulatedWidth("newold") + 2; location = new Point(x, 8); m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("contents")); x = FakeRenderEngine.SimulatedWidth("newold"); location = new Point(x, 8); // at the right edge of the d at the end of newold m = new MouseEventArgs(MouseButtons.Left, 1, location.X, location.Y, 0); root.OnMouseDown(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnMouseClick(m, Keys.None, site.m_vwGraphics, site.m_transform); root.OnDoubleClick(e); Assert.That(!root.Selection.IsInsertionPoint, "Should be ranged selection"); Assert.That((root.Selection as RangeSelection).SelectedText(), Is.EqualTo("old")); }
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); }
public void ParaSequenceTest() { var owner = new MockData1(55, 77); var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var layoutInfo = MakeLayoutInfo(int.MaxValue/2, m_gm.VwGraphics, 55); SetupFakeRootSite(root); var engine = layoutInfo.RendererFactory.GetRenderer(55, m_gm.VwGraphics) as FakeRenderEngine; MockSite site = new MockSite(); int topLazy = 0; // top of the part of the root box that is occupied by the lazy stuff, relative to the top of the root box itself. root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 96, 0, 10, 96, 96); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Builder.Show(LazyDisplay.Of(() => owner.ObjSeq1).Using((bldr, md) => bldr.AddString(() => md.SimpleThree, 55))); var heightOfOneItem = layoutInfo.MpToPixelsY(LazyBox<MockData1>.DefaultItemHeight * 1000); // This does two things: it makes sure the boxes produced by expanding a lazy box item won't be the SAME size, // so we'll get nontrivial changes in root box size; and it makes sure we don't have to expand MORE items than // expected based on the height estimate, which could throw off our predictions of what gets expanded. // Todo: we need a test where we DO have to expand more items after the initial estimate. engine.SegmentHeight = heightOfOneItem + 2; root.Layout(layoutInfo); VerifyParagraphs(root, new string[0]); var child1 = new MockData1(55, 77); var child1String = "Hello world, this is a wide string"; child1.SimpleThree = child1String; owner.InsertIntoObjSeq1(0, child1); Assert.That(root.FirstBox, Is.TypeOf(typeof(LazyBox<MockData1>))); var lazyBox = (LazyBox<MockData1>)root.FirstBox; Assert.That(lazyBox.Width, Is.EqualTo(int.MaxValue / 2)); // no margins, should equal avail width. Assert.That(lazyBox.Height, Is.EqualTo(heightOfOneItem)); var lazyTop = lazyBox.Top; var lazyBottom = lazyBox.Bottom; var oldRootHeight = root.Height; int invalidateWidth = lazyBox.Width + 2 * RootBox.InvalidateMargin; var expectedInvalidate1 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin, invalidateWidth, lazyBox.Height + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate1)); site.RectsInvalidatedInRoot.Clear(); var lazyHookup = ((IHookup) lazyBox).ParentHookup as LazyHookup<MockData1>; Assert.That(lazyHookup, Is.Not.Null); Assert.That(lazyHookup.Children[0], Is.EqualTo(lazyBox)); Assert.That(lazyHookup.Children, Has.Count.EqualTo(1)); root.LazyExpanded += root_LazyExpanded; using (var lc = new LayoutCallbacks(root)) { root.PrepareToPaint(layoutInfo, null, 0, 200); } VerifyParagraphs(root, new [] { child1String }); Assert.That(child1.SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "we don't need to invalidate expanding something that's never been painted"); VerifyExpandArgs(0, lazyTop + 2, lazyBottom + 2, root.Height - oldRootHeight); Assert.That(lazyHookup.Children, Has.Count.EqualTo(1)); Assert.That(lazyHookup.Children[0], Is.TypeOf(typeof(ItemHookup)), "the lazy box standing for item hookups should have been replaced"); // Now replace that one object with a list of several. I want to be able to expand two at the start, one at the end, // and one in the middle, and leave two lazy boxes behind. Then expand the rest and make them go away. So I need six. var values = new MockData1[10]; for (int i = 0; i < 10; i++) { values[i] = new MockData1(55, 77); values[i].SimpleThree = i.ToString(); } var newValues = values.Take(6).ToArray(); site.RectsInvalidatedInRoot.Clear(); int phase2RootHeight = root.Height; int phase2RootWidth = root.Width; owner.ReplaceObjSeq1(newValues); var expectedInvalidate2 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin, phase2RootWidth + 2 * RootBox.InvalidateMargin, phase2RootHeight + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate2), "should invalidate the old replaced paragraph."); lazyBox = (LazyBox<MockData1>)root.FirstBox; Assert.That(lazyBox.Width, Is.EqualTo(int.MaxValue / 2)); // no margins, should equal avail width. Assert.That(root.LastBox, Is.EqualTo(lazyBox), "old paragraph should have been replaced"); Assert.That(lazyHookup.Children[0], Is.EqualTo(lazyBox), "after second replace we just have the lazy box"); Assert.That(lazyHookup.Children, Has.Count.EqualTo(1), "should not have anything but lazy box after second replace"); Assert.That(lazyBox.Height, Is.EqualTo(6*heightOfOneItem)); // Make it expand the first two items. site.RectsInvalidatedInRoot.Clear(); m_expandArgs.Clear(); oldRootHeight = root.Height; using (var lc = new LayoutCallbacks(root)) { root.PrepareToPaint(layoutInfo, null, 0, heightOfOneItem * 2 - 2); } VerifyParagraphs(root, new[] { "0", "1", null }); // Should have two paras then lazy box Assert.That(newValues[0].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(newValues[1].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "we don't need to invalidate expanding something that's never been painted"); Assert.That(root.Height, Is.Not.EqualTo(oldRootHeight)); VerifyExpandArgs(0, 2, heightOfOneItem * 2 + 2, root.Height - oldRootHeight); // +2's from root layout offset Assert.That(lazyHookup.Children, Has.Count.EqualTo(3)); Assert.That(lazyHookup.Children[0], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the first expanded item should be inserted"); Assert.That(lazyHookup.Children[1], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 2nd expanded item should be inserted"); Assert.That(lazyHookup.Children[2], Is.TypeOf(typeof(LazyBox<MockData1>)), "the lazy box standing for item hookups should still be there"); lazyBox = root.FirstBox.Next.Next as LazyBox<MockData1>; Assert.That(lazyBox, Is.Not.Null); Assert.That(lazyBox.Height, Is.EqualTo(heightOfOneItem * 4)); int topOfLastItem = lazyBox.Bottom - heightOfOneItem + 2; // Make it expand the last item. site.RectsInvalidatedInRoot.Clear(); m_expandArgs.Clear(); oldRootHeight = root.Height; using (var lc = new LayoutCallbacks(root)) { root.PrepareToPaint(layoutInfo, null, topOfLastItem + 2, topOfLastItem + 10); } VerifyParagraphs(root, new[] { "0", "1", null, "5" }); // Should have two paras then lazy box then last para Assert.That(newValues[5].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "we don't need to invalidate expanding something that's never been painted"); Assert.That(root.Height, Is.Not.EqualTo(oldRootHeight)); VerifyExpandArgs(0, topOfLastItem, topOfLastItem + heightOfOneItem, root.Height - oldRootHeight); Assert.That(lazyHookup.Children, Has.Count.EqualTo(4)); Assert.That(lazyHookup.Children[0], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the first expanded item should be inserted"); Assert.That(lazyHookup.Children[1], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 2nd expanded item should be inserted"); Assert.That(lazyHookup.Children[2], Is.TypeOf(typeof(LazyBox<MockData1>)), "the lazy box standing for item hookups should still be there"); Assert.That(lazyHookup.Children[3], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the last expanded item should be inserted"); lazyBox = root.FirstBox.Next.Next as LazyBox<MockData1>; Assert.That(lazyBox, Is.Not.Null); Assert.That(lazyBox.Height, Is.EqualTo(heightOfOneItem * 3)); // Expand middle item in lazy box, leaving two lazy boxes. int topOfMiddleItem = lazyBox.Top + heightOfOneItem + 2; site.RectsInvalidatedInRoot.Clear(); m_expandArgs.Clear(); oldRootHeight = root.Height; using (var lc = new LayoutCallbacks(root)) { root.PrepareToPaint(layoutInfo, null, topOfMiddleItem + 2, topOfMiddleItem + 10); } VerifyParagraphs(root, new[] { "0", "1", null, "3", null, "5" }); // Should have two paras then lazy box then middle para then another lazy then last para Assert.That(newValues[3].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "we don't need to invalidate expanding something that's never been painted"); Assert.That(root.Height, Is.Not.EqualTo(oldRootHeight)); VerifyExpandArgs(0, topOfMiddleItem, topOfMiddleItem + heightOfOneItem, root.Height - oldRootHeight); Assert.That(lazyHookup.Children, Has.Count.EqualTo(6)); Assert.That(lazyHookup.Children[0], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the first expanded item should be inserted"); Assert.That(lazyHookup.Children[1], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 2nd expanded item should be inserted"); Assert.That(lazyHookup.Children[2], Is.TypeOf(typeof(LazyBox<MockData1>)), "the lazy box standing for item hookups should still be there"); Assert.That(lazyHookup.Children[3], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the last expanded item should be inserted"); Assert.That(lazyHookup.Children[4], Is.TypeOf(typeof(LazyBox<MockData1>)), "the lazy box standing for item hookups should still be there"); Assert.That(lazyHookup.Children[5], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the last expanded item should be inserted"); lazyBox = root.FirstBox.Next.Next as LazyBox<MockData1>; Assert.That(lazyBox, Is.Not.Null); Assert.That(lazyBox.Height, Is.EqualTo(heightOfOneItem)); var lazyBox2 = lazyBox.Next.Next as LazyBox<MockData1>; Assert.That(lazyBox2, Is.Not.Null); Assert.That(lazyBox2.Height, Is.EqualTo(heightOfOneItem)); // Expand lazy box when it is between two other items. (Also verify expanding two lazy boxes in one PrepareToPaint.) int topOfFirstLazy = lazyBox.Top + 2; int topOfLastLazy = lazyBox2.Top + 2; site.RectsInvalidatedInRoot.Clear(); m_expandArgs.Clear(); oldRootHeight = root.Height; using (var lc = new LayoutCallbacks(root)) { root.PrepareToPaint(layoutInfo, null, topOfFirstLazy + 2, topOfLastLazy + 2); } VerifyParagraphs(root, new[] { "0", "1", "2", "3", "4", "5" }); // Should have all the real paragraphs now. Assert.That(newValues[2].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(newValues[4].SimpleThreeHookupCount, Is.EqualTo(1), "expanding lazy box should set up a hookup for the string"); Assert.That(site.RectsInvalidatedInRoot, Is.Empty, "we don't need to invalidate expanding something that's never been painted"); Assert.That(root.Height, Is.Not.EqualTo(oldRootHeight)); var delta = engine.SegmentHeight - heightOfOneItem; VerifyExpandArgs(0, topOfFirstLazy, topOfFirstLazy + heightOfOneItem, delta); VerifyExpandArgs(1, topOfLastLazy + delta, topOfLastLazy + delta + heightOfOneItem, delta); Assert.That(lazyHookup.Children, Has.Count.EqualTo(6)); Assert.That(lazyHookup.Children[0], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the first expanded item should be inserted"); Assert.That(lazyHookup.Children[1], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 2nd expanded item should be inserted"); Assert.That(lazyHookup.Children[2], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 3rd expanded item should be inserted"); Assert.That(lazyHookup.Children[3], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 4th expanded item should be inserted"); Assert.That(lazyHookup.Children[4], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the 5th expanded item should be inserted"); Assert.That(lazyHookup.Children[5], Is.TypeOf(typeof(ItemHookup)), "a regular item hookup for the last expanded item should be inserted"); // Now try removing the first two items. site.RectsInvalidatedInRoot.Clear(); int heightOfFirst2Paras = root.FirstBox.Next.Bottom - root.FirstBox.Top; int phase3RootWidth = root.Width; int phase3RootHeight = root.Height; var phase3Values = newValues.Skip(2).ToArray(); owner.ReplaceObjSeq1(phase3Values); var expectedInvalidate3 = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin, phase3RootWidth + 2 * RootBox.InvalidateMargin, phase3RootHeight + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate3), "should invalidate the whole old root box; everything changes or moves."); VerifyParagraphs(root, new[] {"2", "3", "4", "5" }); // Should have last 4 paragraphs now (not made lazy). // Now try removing the last item. site.RectsInvalidatedInRoot.Clear(); int phase4RootWidth = root.Width; var phase4Values = phase3Values.Take(3).ToArray(); var topOfPara4 = root.FirstBox.Next.Next.Bottom + topLazy; owner.ReplaceObjSeq1(phase4Values); var expectedInvalidate4 = new Rectangle(-RootBox.InvalidateMargin, topOfPara4 - RootBox.InvalidateMargin, phase4RootWidth + 2 * RootBox.InvalidateMargin, root.FirstBox.Height + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate4), "should invalidate the old replaced paragraphs."); VerifyParagraphs(root, new[] { "2", "3", "4" }); // Should have last 3 paragraphs now (not made lazy). // Now try removing a middle item. site.RectsInvalidatedInRoot.Clear(); int phase5RootWidth = root.Width; var phase5Values = new [] {newValues[2], newValues[4]}; var topOfPara3 = root.FirstBox.Bottom + topLazy; var phase4RootHeight = root.Height; owner.ReplaceObjSeq1(phase5Values); var expectedInvalidate5 = new Rectangle(-RootBox.InvalidateMargin, topOfPara3 - RootBox.InvalidateMargin, phase5RootWidth + 2 * RootBox.InvalidateMargin, phase4RootHeight - topOfPara3 + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate5), "should invalidate the old replaced paragraphs."); VerifyParagraphs(root, new[] { "2", "4" }); // Should have remaining 2 paragraphs now (not made lazy). // Insert three items at start: 0, 1, 3, 2, 4. site.RectsInvalidatedInRoot.Clear(); int phase6RootWidth = root.Width; var phase6Values = new[] {newValues[0], newValues[1], newValues[3], newValues[2], newValues[4] }; owner.ReplaceObjSeq1(phase6Values); int lazyWidth = root.LastLayoutInfo.MaxWidth; // current standard width for lazy boxes. var expectedInvalidate6 = new Rectangle(-RootBox.InvalidateMargin, topLazy - RootBox.InvalidateMargin, lazyWidth + 2 * RootBox.InvalidateMargin, root.Height + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate6), "should invalidate everything...all moved or added."); VerifyParagraphs(root, new[] {null, "2", "4" }); // Should have added lazy box at start. VerifyLazyContents(root.FirstBox, new[] {newValues[0], newValues[1], newValues[3]}); // Insert at end: 0, 1, 3, 2, 4, 9. I think we've tested the invalidate rects enough. var phase7Values = new[] { values[0], values[1], values[3], values[2], values[4], values[9] }; owner.ReplaceObjSeq1(phase7Values); VerifyParagraphs(root, new[] { null, "2", "4", null }); // Should have added lazy box at end. VerifyLazyContents(root.LastBox, new[] { values[9] }); // Insert between two non-lazy items: 0, 1, 3, 2, 5, 6, 4, 9. var phase8Values = new[] { values[0], values[1], values[3], values[2], values[5], values[6], values[4], values[9] }; owner.ReplaceObjSeq1(phase8Values); VerifyParagraphs(root, new[] { null, "2", null, "4", null }); // Should have added lazy box in middle. VerifyLazyContents(root.FirstBox.Next.Next, new[] { values[5], values[6] }); // Try a more complex overwrite. We'll replace the last item in the first lazy box and the first one in the second var phase9Values = new[] { values[0], values[1], values[7], values[2], values[8], values[6], values[4], values[9] }; owner.ReplaceObjSeq1(phase9Values); VerifyParagraphs(root, new[] { null, "4", null }); // Should replace first 3 items with new lazy box. VerifyLazyContents(root.FirstBox, new[] { values[0], values[1], values[7], values[2], values[8], values[6] }); }
StringBox MakeStringBox(AssembledStyles styles, int depth, bool weak) { var seg = new MockDirectionSegment() {WeakDirection = weak, DirectionDepth = depth}; return new StringBox(styles, seg, 0); }
public void SetWeakDirections() { var line = new ParaLine(); var styles = new AssembledStyles(); // no boxes (pathological) line.SetWeakDirections(0); // no weak boxes line = new ParaLine(); line.Add(MakeStringBox(styles, 3, false)); line.SetWeakDirections(0); VerifyDepth(line, 0, 3); // one weak box alone: no change line = new ParaLine(); line.Add(MakeStringBox(styles, 3, true)); line.SetWeakDirections(1); VerifyDepth(line, 0, 1); // one at start, followed by a non-weak line = new ParaLine(); line.Add(MakeStringBox(styles, 2, true)); line.Add(MakeStringBox(styles, 1, false)); line.SetWeakDirections(0); VerifyDepth(line, 0, 0); // adjacent to paragraph boundary, topDepth wins line.SetWeakDirections(2); VerifyDepth(line, 0, 1); // adjacent box has lower depth. // two at start, followed by non-weak; also two at end and four in middle. line = new ParaLine(); line.Add(MakeStringBox(styles, 2, true)); line.Add(MakeStringBox(styles, 3, true)); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 4, true)); line.Add(MakeStringBox(styles, 4, true)); line.Add(MakeStringBox(styles, 4, true)); line.Add(MakeStringBox(styles, 4, true)); line.Add(MakeStringBox(styles, 3, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 5, true)); line.Add(MakeStringBox(styles, 5, true)); line.SetWeakDirections(6); // let the adjacent boxes rather than the paragraph depth win. VerifyDepth(line, 0, 1); // first two set to depth of following box VerifyDepth(line, 1, 1); VerifyDepth(line, 4, 2); // middle four set to depth of preceding box VerifyDepth(line, 5, 2); VerifyDepth(line, 6, 2); VerifyDepth(line, 7, 2); VerifyDepth(line, 10, 4); // last two set to depth of preceding VerifyDepth(line, 11, 4); line.SetWeakDirections(0); // let the adjacent boxes rather than the paragraph depth win. VerifyDepth(line, 0, 0); // topdepth from para boundary VerifyDepth(line, 1, 0); VerifyDepth(line, 4, 2); // middle four set to depth of preceding box VerifyDepth(line, 5, 2); VerifyDepth(line, 6, 2); VerifyDepth(line, 7, 2); VerifyDepth(line, 10, 0); // topdepth from para boundary VerifyDepth(line, 11, 0); line= new ParaLine(); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 3, true)); line.Add(new BlockBox(styles, Color.Red, 200, 300)); line.SetWeakDirections(1); // The block box is considered to have depth 1 and wins VerifyDepth(line, 1, 1); }
public void OrderedBoxes() { var styles = new AssembledStyles(); // Nothing is reversed when everything is at level 0. var line = new ParaLine(); line.Add(MakeStringBox(styles, 0, false)); line.Add(MakeStringBox(styles, 0, false)); line.Add(MakeStringBox(styles, 0, false)); var boxes = new List<Box>(line.OrderedBoxes(0)); VerifyBoxOrder(line, boxes, new[] { 0, 1, 2 }); // Also, three adjacent LTRs in an RTL paragraph are not reversed. boxes = new List<Box>(line.OrderedBoxes(1)); VerifyBoxOrder(line, boxes, new[] { 0, 1, 2 }); // Everything is reversed when everything is at level 1 (ordinary RTL text). line = new ParaLine(); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 1, false)); boxes = new List<Box>(line.OrderedBoxes(0)); VerifyBoxOrder(line, boxes, new[] { 2, 1, 0 }); // Also, three adjacent RTL boxes in an LTR paragraph are reversed. boxes = new List<Box>(line.OrderedBoxes(1)); VerifyBoxOrder(line, boxes, new[] { 2, 1, 0 }); // In an RTL paragraph with two adjacent upstream boxes, they preserve their order. line = new ParaLine(); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 1, false)); boxes = new List<Box>(line.OrderedBoxes(0)); VerifyBoxOrder(line, boxes, new[] { 3, 1, 2, 0 }); // In an RTL paragraph with two adjacent upstream boxes, where one is weak, it goes downstream. line = new ParaLine(); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 2, true)); line.Add(MakeStringBox(styles, 1, false)); boxes = new List<Box>(line.OrderedBoxes(0)); VerifyBoxOrder(line, boxes, new[] { 3, 2, 1, 0 }); // In an RTL paragraph with three adjacent upstream boxes, where the middle one is weak, it goes upstream. line = new ParaLine(); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 2, true)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 1, false)); boxes = new List<Box>(line.OrderedBoxes(0)); VerifyBoxOrder(line, boxes, new[] { 4, 1, 2, 3, 0 }); }
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 DragCopyRtf() { var stylesheet = new MockStylesheet(); var styleFirst = stylesheet.AddStyle("first", false); var styleSecond = stylesheet.AddStyle("second", false); var propsTrue = new MockStyleProp<bool>() {Value = true, ValueIsSet = true}; var charInfo = new MockCharStyleInfo(); styleFirst.DefaultCharacterStyleInfo = charInfo; charInfo.Bold = propsTrue; // Todo: make styleSecond have pretty much everything else. var charInfo2 = new MockCharStyleInfo(); styleSecond.DefaultCharacterStyleInfo = charInfo2; charInfo2.FontColor = MakeColorProp(Color.Red); charInfo2.BackColor = MakeColorProp(Color.Yellow); charInfo2.UnderlineColor = MakeColorProp(Color.Green); charInfo2.Italic = propsTrue; charInfo2.FontName = new MockStyleProp<string>() {Value = "Arial", ValueIsSet = true}; var styles = new AssembledStyles(stylesheet); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "This is"; var mock2 = new MockData1(23, 23); mock2.SimpleThree = " the day"; var mock3 = new MockData1(23, 23); mock3.SimpleThree = " that the"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); var wsf = new MockWsf(); engine.WritingSystemFactory = wsf; var wsEngine = wsf.MakeMockEngine(23, "en", engine); factory.SetRenderer(23, engine); root.Builder.Show( Paragraph.Containing( Display.Of(() => mock1.SimpleThree, 23).Style("first"), Display.Of(() => mock2.SimpleThree, 23).Style("second"), Display.Of(() => mock3.SimpleThree, 23).Style("first") )); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is the day that".Length).Install(); int indent = FakeRenderEngine.SimulatedWidth("This "); root.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans); root.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, indent + 5, 4, 0), Keys.None, m_gm.VwGraphics, ptrans); Assert.That(GetStringDropData(site), Is.EqualTo("is the day that")); // The order of the font and colors in the color table is arbitrary. This happens to be what the code does now. For some reason // Color.Green has green only 128. // The order of items in the definition of a style is arbitrary. // We're not doing anything yet for background color. \highlightN can specify background color for a character run, // but it can't be part of a style definition. Assert.That(GetRtfDropData(site), Is.EqualTo( RangeSelection.RtfPrefix + @"{\fonttbl{\f0 MockFont;}{\f1 Arial;}}" + @"{\colortbl ;\red0\green0\blue0;\red255\green255\blue255;\red255\green0\blue0;\red255\green255\blue0;\red0\green128\blue0;}" + @"{\stylesheet{\*\cs1\b\additive first;\*\cs2\i\f1\cf3\ulc5\additive second;}}" + RangeSelection.RtfDataPrefix + @"{\*\cs1\b is}{\*\cs2\i\f1\cf3\ulc5\highlight4 the day}{\*\cs1\b that\par}" + @"}")); // Todo: handle styles that depend on WS // Todo: handle more than two runs // Todo: handle runs where actual formatting differs from style-specified formatting // Todo: handle multiple paragraphs // Todo: handle paragraph styles }
public LayoutInfoRecorderBox(AssembledStyles styles, Color color, int mpWidth, int mpHeight) : base(styles, color, mpWidth, mpHeight) { }
public FgBlockBox(AssembledStyles styles, Color color, int mpWidth, int mpHeight) : base(styles, color, mpWidth, mpHeight) { }
public void ReverseUpstreamBoxes() { var line = new ParaLine(); var styles = new AssembledStyles(); // no boxes (pathological) line.ReverseUpstreamBoxes(0, new List<Box>(), 0); // one box line = new ParaLine(); line.Add(MakeStringBox(styles, 3, false)); var boxes = new List<Box>(line.Boxes); line.ReverseUpstreamBoxes(0, boxes, 0); VerifyBoxOrder(line, boxes, new [] {0}); // two boxes: should re-order only if depth is small enough. line = new ParaLine(); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 1, false)); boxes = new List<Box>(line.Boxes); line.ReverseUpstreamBoxes(3, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 0, 1 }); // not re-ordered, all depths too small line.ReverseUpstreamBoxes(2, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 0, 1 }); // not re-ordered, just one that could be line.ReverseUpstreamBoxes(1, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 1, 0 }); // re-ordered, all <= depth line.ReverseUpstreamBoxes(0, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 0, 1 }); // re-ordered again, all < depth // quite a mixture! line = new ParaLine(); MockDirectionSegment.NextIndex = 0; line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 3, false)); line.Add(MakeStringBox(styles, 1, false)); line.Add(MakeStringBox(styles, 2, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 3, false)); line.Add(MakeStringBox(styles, 4, false)); line.Add(MakeStringBox(styles, 5, false)); line.Add(MakeStringBox(styles, 5, false)); boxes = new List<Box>(line.Boxes); line.ReverseUpstreamBoxes(0, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 11,10,9,8,7,6,5,4,3,2,1,0 }); // reverse everything line.ReverseUpstreamBoxes(1, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 0,1,2,3,4,5,6,7,8,9,10,11 }); // back again // now the level 1 box at index 2 does not move line.ReverseUpstreamBoxes(2, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 1, 0, 2, 11, 10, 9, 8, 7, 6, 5, 4, 3 }); line.ReverseUpstreamBoxes(2, boxes, 0); // put them back! VerifyBoxOrder(line, boxes, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }); // back again line.ReverseUpstreamBoxes(4, boxes, 0); // only the groups with more 4 or more reverse VerifyBoxOrder(line, boxes, new[] { 0, 1, 2, 3, 7, 6, 5, 4, 8, 11, 10, 9 }); // back again boxes = new List<Box>(line.Boxes); line.ReverseUpstreamBoxes(1, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }); line.ReverseUpstreamBoxes(2, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 2, 0, 1 }); line.ReverseUpstreamBoxes(3, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 3, 11, 10, 9, 8, 7, 6, 5, 4, 2, 0, 1 }); line.ReverseUpstreamBoxes(4, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 3, 9, 10, 11, 8, 4, 5, 6, 7, 2, 0, 1 }); line.ReverseUpstreamBoxes(5, boxes, 0); VerifyBoxOrder(line, boxes, new[] { 3, 9, 11, 10, 8, 4, 5, 6, 7, 2, 0, 1 }); boxes = new List<Box>(line.OrderedBoxes(0)); // This should do all in one step the reversals indicated in the previous test // sequence. The results above indicate how the final sequence is arrived at. VerifyBoxOrder(line, boxes, new[] { 3, 9, 11, 10, 8, 4, 5, 6, 7, 2, 0, 1 }); line = new ParaLine(); line.Add(new BlockBox(styles, Color.Red, 200, 300)); line.Add(MakeStringBox(styles, 2, true)); line.Add(MakeStringBox(styles, 2, true)); line.Add(new BlockBox(styles, Color.Red, 200, 300)); boxes = new List<Box>(line.Boxes); line.ReverseUpstreamBoxes(2, boxes, 1); VerifyBoxOrder(line, boxes, new[] { 0, 2, 1, 3}); // reverse just the string boxes }
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 BasicDragMove() { var styles = new AssembledStyles(); var root = new RootBoxFdo(styles); var mock1 = new MockData1(23, 23); mock1.SimpleThree = "This is the day"; var engine = new FakeRenderEngine() { Ws = 23, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(23, engine); root.Builder.Show(Display.Of(() => mock1.SimpleThree, 23)); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This is ".Length).Install(); var dataObj = new DataObject(DataFormats.StringFormat, "is "); int x = FakeRenderEngine.SimulatedWidth("This is the ") + 2; var location = new Point(x, 8); // A drag to where we can drop, allowing both copy and move, no keys held var dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.OnDragEnter(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.Move)); Assert.That(root.DragState, Is.EqualTo(WindowDragState.DraggingHere)); var qcdArgs = new QueryContinueDragEventArgs((int) DragDropKeyStates.None, false, DragAction.Drop); root.OnQueryContinueDrag(qcdArgs); Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove)); root.OnDragLeave(); Assert.That(root.DragState, Is.EqualTo(WindowDragState.InternalMove), "DragLeave should not clear InternalMove"); root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(mock1.SimpleThree, Is.EqualTo("This the is day")); Assert.That(root.DragState, Is.EqualTo(WindowDragState.None)); // Now let's drag the 'is' out to another window. SelectionBuilder.In(root).Offset("This the ".Length).To.Offset("This the is ".Length).Install(); qcdArgs = new QueryContinueDragEventArgs((int)DragDropKeyStates.None, false, DragAction.Drop); root.OnQueryContinueDrag(qcdArgs); Assert.That(root.DragState, Is.EqualTo(WindowDragState.None), "We should only set InternalMove if this window is the destination"); Assert.That(mock1.SimpleThree, Is.EqualTo("This the day")); // Check that we can't drag inside our own selection. SelectionBuilder.In(root).Offset("This ".Length).To.Offset("This the".Length).Install(); x = FakeRenderEngine.SimulatedWidth("This t") + 2; location = new Point(x, 8); dragArgs = new DragEventArgs(dataObj, (int)DragDropKeyStates.None, 200, 300, DragDropEffects.Copy | DragDropEffects.Move, DragDropEffects.None); root.DragState = WindowDragState.InternalMove; root.OnDragDrop(dragArgs, location, m_gm.VwGraphics, ptrans); Assert.That(dragArgs.Effect, Is.EqualTo(DragDropEffects.None)); Assert.That(mock1.SimpleThree, Is.EqualTo("This the day")); }