public void PaintParaBox() { AssembledStyles styles = new AssembledStyles(); var clientRuns = new List<IClientRun>(); BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns.Add(box0); BlockBox box1 = new BlockBox(styles, Color.Blue, 36000, 18000); clientRuns.Add(box1); BlockBox box2 = new BlockBox(styles, Color.Red, 24000, 18000); clientRuns.Add(box2); BlockBox box3 = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns.Add(box3); BlockBox box4 = new BlockBox(styles, Color.Red, 36000, 36000); clientRuns.Add(box4); TextSource source = new TextSource(clientRuns, null); ParaBox para = new ParaBox(styles, source); RootBox root = new RootBox(styles); root.AddBox(para); MockGraphics graphics = new MockGraphics(); LayoutInfo layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics); root.Layout(layoutArgs); PaintTransform ptrans = new PaintTransform(2, 2, 96, 96, 0, 0, 96, 96); root.Paint(graphics, ptrans); Assert.AreEqual(5, graphics.RectanglesDrawn.Count); VerifyRect(2, 2, 96, 48, graphics, 0, Color.Red); VerifyRect(2, 48+2, 48, 24, graphics, 1, Color.Blue); VerifyRect(2+48, 48 + 2, 32, 24, graphics, 2, Color.Red); VerifyRect(2, 24 + 48 + 2, 96, 48, graphics, 3, Color.Red); VerifyRect(2, 48 + 24 + 48 + 2, 48, 48, graphics, 4, Color.Red); }
private bool m_nextUpstreamSegWsOnly; // toggle for whether to try whitespace-only or no-ws for next upstream seg. public ParaBuilder(ParaBox para, LayoutInfo layoutInfo) { m_para = para; m_layoutInfo = layoutInfo; m_renderRuns = para.Source.RenderRuns; m_gapTop = m_para.GapTop(layoutInfo); m_gapLeft = m_para.GapLeading(layoutInfo); // Todo RTL. m_gapRight = m_para.GapTrailing(layoutInfo); m_surroundWidth = m_para.SurroundWidth(layoutInfo); m_surroundHeight = m_para.SurroundHeight(layoutInfo); }
/// <summary> /// Return an insertion point at specified position in THIS RUN within the paragraph. /// </summary> public InsertionPoint SelectAt(ParaBox para, int ichRun, bool associatePrevious) { LiteralStringParaHookup hookup = Hookup; if (hookup == null) { hookup = new LiteralStringParaHookup(null, para); hookup.ClientRunIndex = para.Source.ClientRuns.IndexOf(this); } return new InsertionPoint(hookup, ichRun, associatePrevious); }
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)); }
private void VerifyRangeSegmentDrawing(ParaBox para, StringBox stringBox, MockSegment seg, RangeSelection range, int top, int ydTop, int bottom) { Assert.AreEqual(stringBox.IchMin, seg.LastDrawRangeCall.IchBase); Assert.AreEqual(m_gm.VwGraphics, seg.LastDrawRangeCall.Graphics); Assert.AreEqual(range.Start.StringPosition, seg.LastDrawRangeCall.IchMin); Assert.AreEqual(range.End.StringPosition, seg.LastDrawRangeCall.IchLim); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcSrc, -2, top, 96, 100); ParaTests.VerifySimpleRect(seg.LastDrawRangeCall.RcDst, 0, -10, 120, 128); Assert.AreEqual(ydTop, seg.LastDrawRangeCall.YdTop); Assert.AreEqual(bottom, seg.LastDrawRangeCall.YdBottom); Assert.AreEqual(seg.LastDrawRangeCall.On, true, "Should currently always pass true to segment drawRange On argument"); // The old Views code appears to always pass true for this argument, so we should too, until I figure out what it's // really supposed to be, if anything. Assert.AreEqual(true, seg.LastDrawRangeCall.IsLastLineOfSelection); }
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); }
/// <summary> /// Given a function that fetches strings, a run which represents the initial value of that string /// already inserted into a particular paragraph box, and that we have identified the fetcher as /// a property with the specified name of the specified target object, but we have not been able to find /// a ''Name'Changed' event on the target object, this stub provides a possible place for a subclass to /// use an alternative strategy for hooking something up to notify the view of changes to the property. /// </summary> protected override void MakeHookupForString(Func<ITsString> fetcher, TssClientRun run, string name, object target, ParaBox para) { var cmObj = target as ICmObject; if (cmObj != null) { // Set up for PropChanged notification. RootFdo.DataAccess = cmObj.Cache.DomainDataByFlid; // ensures hooked up to receive PropChanged. Tuple<int, int> key = GetPropChangedKey(name, cmObj); var stringHookup = new TssHookup(target, fetcher, hookup => RootFdo.AddHookupToPropChanged(key, hookup), hookup => RootFdo.RemoveHookupFromPropChanged(key, hookup), para); stringHookup.Tag = key.Item2; AddHookupToRun(run, stringHookup); // Enhance JohnT: consider doing this by reflection. stringHookup.Writer = newVal => RootFdo.DataAccess.SetString(cmObj.Hvo, key.Item2, newVal); } }
/// <summary> /// Some common logic for several tests. Returns the old paragraph height (before the change). /// </summary> private int TestChangeNotAffectingLineBreaks(out ParaBox para, Action<string[]> wordsModifier, Func<ParaBox, Rectangle, Rectangle> invalidRectModifier, Action<List<MockSegment>> potentialSegsModifier) { RootBox root = MakeTestParaSimpleString(m_gm.VwGraphics, MockBreakOption.ThreeFullLines, out para); int result = para.Height; Rectangle expectedInvalidate = para.InvalidateRect; var modWords = new string[s_simpleStringWords.Length]; Array.Copy(s_simpleStringWords, modWords, modWords.Length); wordsModifier(modWords); // make whatever change we intend to the text. var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics); var engine = root.LastLayoutInfo.RendererFactory.GetRenderer(s_simpleStringWs, m_gm.VwGraphics) as MockRenderEngine; var modContents = AssembleStrings(modWords); SetupMockEngineForThreeLines(modContents, engine, modWords); // The one we want to modify is the fourth to be added; this is the same engine, so it already has // the three potential segments from the original layout. potentialSegsModifier(engine.m_potentialSegsInOrder); MockSite site = new MockSite(); root.Site = site; PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; var hookup = new StringHookup(null, null, hook => DoNothing(), hook => DoNothing(), para); ((StringClientRun) para.Source.ClientRuns[0]).Hookup = hookup; para.StringChanged(0, modContents); Assert.AreEqual(modContents, para.Source.RenderText); Assert.That(((StringClientRun) para.Source.ClientRuns[0]).Hookup, Is.EqualTo(hookup)); int ichEndFirstLine = SumStringLengths(modWords, 0, 3); // We inserted at the start, so only the first line should have been invalidated; but char offsets for other lines should have changed. VerifySegment(para, 0, s_widthFirstMockSeg, ichEndFirstLine, 0); int ichEndSecondLine = SumStringLengths(modWords, 0, 6); VerifySegment(para, 1, s_widthSecondMockSeg, ichEndSecondLine - ichEndFirstLine, ichEndFirstLine); VerifySegment(para, 2, s_widthThirdMockSeg, modContents.Length - ichEndSecondLine, ichEndSecondLine); expectedInvalidate = invalidRectModifier(para, expectedInvalidate); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate)); return result; }
void VerifySegment(ParaBox para, int index, int expectedWidth, int expectedLength, int expectedStart) { Box target = para.FirstBox; for (int i = 0; i < index; i++) target = target.Next; Assert.IsTrue(target is StringBox); var sbox = target as StringBox; Assert.AreEqual(para, sbox.Container); var seg = sbox.Segment; Assert.AreEqual(expectedStart, sbox.IchMin); Assert.AreEqual(expectedWidth, seg.get_Width(sbox.IchMin, m_gm.VwGraphics)); Assert.AreEqual(expectedLength, seg.get_Lim(sbox.IchMin)); }
void VerifyParaLine(ParaBox para, int lineIndex, Box first, Box last, int top, string label) { ParaLine line = para.Lines[lineIndex]; Assert.AreEqual(first, line.FirstBox, label + " - first box"); Assert.AreEqual(last, line.LastBox, label + " - last box"); Assert.AreEqual(top, line.Top, label + " - top"); }
public void EmptyString() { int ws = 1; AssembledStyles styles = new AssembledStyles().WithWs((ws)); var clientRuns = new List<IClientRun>(); StringClientRun clientRun = new StringClientRun("", styles); clientRuns.Add(clientRun); TextSource source = new TextSource(clientRuns, null); ParaBox para = new ParaBox(styles, source); RootBox root = new RootBox(styles); root.AddBox(para); LayoutInfo layoutArgs = MakeLayoutInfo(); var engine = layoutArgs.GetRenderer(1) as MockRenderEngine; engine.AddMockSeg(0, 0, 0, 0, ws, LgEndSegmentType.kestNoMore); root.Layout(layoutArgs); Assert.AreEqual(1, para.Lines.Count); Assert.IsTrue(root.Height > 0); }
private void VerifySegmentDrawing(ParaBox para, StringBox third, MockSegment seg3, int top) { VerifySegmentDrawing(para, third, seg3.LastDrawIpCall, top); }
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)); }
/// <summary> /// This setup method for para builder is also useful for testing stuff related to the paragraph itself. /// For example, we take advantage of it for testing backspace at start of client run. /// </summary> internal static RootBox MakeTestParaThreeStrings(IVwGraphics vg, MockBreakOption breakOption, out ParaBox para) { var styles = new AssembledStyles().WithWs(s_simpleStringWs); var styles2 = new AssembledStyles().WithWs(s_secondGroupWs); string contents1 = AssembleStrings(s_firstGroupWords); string contents2 = AssembleStrings(s_secondGroupWords); string contents3 = AssembleStrings(s_thirdGroupWords); var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents1, styles)); clientRuns.Add(new StringClientRun(contents2, styles2)); clientRuns.Add(new StringClientRun(contents3, styles)); var source = new TextSource(clientRuns, null); para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, vg); int totalLength = contents1.Length + contents2.Length + contents3.Length; // Arrange the following line breaks. // First the builder will ask to break the whole string, it puts the first three words on a line and indicates it is full. SetupMockEngineForThreeStringsPara(s_firstGroupWords, s_secondGroupWords, s_thirdGroupWords, layoutArgs); root.Layout(layoutArgs); return root; }
private void VerifyRangeSegmentQuery(ParaBox para, StringBox stringBox, FakeSegment seg, int ichMin, int ichLim, int top, int ydTop, int bottom) { var args = seg.LastPositionOfRangeArgs; VerifyRangeDrawingArgs(args, stringBox, ichMin, ichLim, top, ydTop, bottom); }
/// <summary> /// Return an insertion point at the start of the specified paragraph (of which this is the first run) /// </summary> public InsertionPoint SelectAtStart(ParaBox para) { // Review JohnT: do we want associatePrevious true or false if the paragraph is empty? return(SelectAt(para, 0, false)); }
// Add to the root a text paragraph which reflects the SimpleText property. private void AddSimpleTextPara(AssembledStyles styles, int ws, RootBox root) { var items = new List<IClientRun>(); var run = new StringClientRun("This is the day that the Lord has made. We will rejoice and be glad in it", styles.WithWs(ws)); items.Add(run); var source = new TextSource(items); var para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => this.SimpleText, hook => SimpleTextChanged += hook.StringPropChanged, hook => SimpleTextChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => SimpleText = newVal; run.Hookup = hookup; root.AddBox(para); }
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; }
private void VerifyRange(Selection sel, ParaBox paraAnchor, string textBeforeAnchor, ParaBox paraEnd, string textBeforeEnd, string label) { Assert.That(sel, Is.TypeOf(typeof(RangeSelection)), label + " should produce range"); var range = (RangeSelection) sel; VerifyIp(range.Anchor, paraAnchor, textBeforeAnchor, range.EndBeforeAnchor, label + " (anchor)"); VerifyIp(range.DragEnd, paraEnd, textBeforeEnd, !range.EndBeforeAnchor, label + " (end)"); }
private void VerifyIp(Selection sel, ParaBox para, string textBefore, bool assocPrev, string label) { Assert.That(sel, Is.TypeOf(typeof(InsertionPoint)), label + " should produce IP"); var ip = (InsertionPoint) sel; Assert.That(ip.Para, Is.EqualTo(para), label + " should be in expected para"); Assert.That(ip.LogicalParaPosition, Is.EqualTo(textBefore.Length), label + " should be at expected position"); Assert.That(ip.AssociatePrevious, Is.EqualTo(assocPrev), label + " should associate correctly"); }
/// <summary> /// The setup method for para builder is also useful for testing stuff related to the paragraph itself. /// </summary> /// <param name="vg"></param> /// <param name="para"></param> /// <returns></returns> internal static RootBox MakeTestParaSimpleString(IVwGraphics vg, MockBreakOption breakOption, out ParaBox para) { var styles = new AssembledStyles().WithWs(s_simpleStringWs); string contents = AssembleStrings(s_simpleStringWords); var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents, styles)); var source = new TextSource(clientRuns, null); para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, vg); var engine = layoutArgs.GetRenderer(1) as MockRenderEngine; switch (breakOption) { case MockBreakOption.ThreeOkayBreaks: // This option generates three lines as long as the width is sufficient because // Asked to break the whole string we answer a segment that has the first three words. engine.AddMockSeg(0, contents.Length, SumStringLengths(s_simpleStringWords, 0, 3), s_widthFirstMockSeg, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we answer a segment with the next three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 3), contents.Length, SumStringLengths(s_simpleStringWords, 3, 6), s_widthSecondMockSeg, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we answer a segment with the last three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 6), contents.Length, SumStringLengths(s_simpleStringWords, 6, 9), s_widthThirdMockSeg, s_simpleStringWs, LgEndSegmentType.kestNoMore); break; case MockBreakOption.FourSegsThreeLines: // Asked to break the whole string we answer a segment that has the first two words but allows more. engine.AddMockSeg(0, contents.Length, SumStringLengths(s_simpleStringWords, 0, 2), 50, s_simpleStringWs, LgEndSegmentType.kestOkayBreak); // Asked to break the rest of the line we give one more word and say it fills the line. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 2), contents.Length, SumStringLengths(s_simpleStringWords, 0, 3), 20, s_simpleStringWs, LgEndSegmentType.kestMoreLines); // Asked to break the rest of the line we answer a segment with the next three and say it fills the line. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 3), contents.Length, SumStringLengths(s_simpleStringWords, 3, 6), s_widthSecondMockSeg, s_simpleStringWs, LgEndSegmentType.kestMoreLines); // Asked to break the rest of the line we answer a segment with the last three. engine.AddMockSeg(SumStringLengths(s_simpleStringWords, 0, 6), contents.Length, SumStringLengths(s_simpleStringWords, 6, 9), s_widthThirdMockSeg, s_simpleStringWs, LgEndSegmentType.kestNoMore); // Asked to do anything else engine.OtherSegPolicy = UnexpectedSegments.MakeOneCharSeg; break; case MockBreakOption.ThreeFullLines: // Asked to break the whole string we answer a segment that has the first three words. SetupMockEngineForThreeLines(contents, engine, s_simpleStringWords); break; } root.Layout(layoutArgs); return root; }
public void ContentChangeWrapping() { var styles = new AssembledStyles().WithWs(s_simpleStringWs); string contents1 = "This is a simple string. It has two sentences."; var clientRuns = new List<IClientRun>(); clientRuns.Add(new StringClientRun(contents1, styles)); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var root = new RootBox(styles); root.AddBox(para); var layoutArgs = MakeLayoutInfo(30, m_gm.VwGraphics); }
private void InitSeveralBoxes() { var styles = new AssembledStyles(); RootBox root = new RootBoxFdo(styles); var items = new List<IClientRun>(); items.Add(new BlockBox(styles, Color.Red, 72000, 36000)); items.Add(new BlockBox(styles, Color.Blue, 36000, 18000)); items.Add(new BlockBox(styles, Color.Orange, 18000, 36000)); items.Add(new BlockBox(styles, Color.Green, 72000, 18000)); items.Add(new ImageBox(styles.WithBackColor(Color.Pink).WithBorderColor(Color.Blue) .WithBorders(new Thickness(2.0)).WithPads(new Thickness(4.0)), new Icon(SystemIcons.Shield, 40, 40).ToBitmap())); items.Add(new BlockBox(styles, Color.Yellow, 72000, 36000)); var source = new TextSource(items); var para = new ParaBox(styles, source); root.AddBox(para); theSharpView.Root = root; }
private void VerifyRangeSegmentDrawing(ParaBox para, StringBox stringBox, FakeSegment seg, int ichMin, int ichLim, int top, int ydTop, int bottom) { var args = seg.LastDrawRangeCall; VerifyRangeDrawingArgs(args, stringBox, ichMin, ichLim, top, ydTop, bottom); }
public void FiveBlockPara() { AssembledStyles styles = new AssembledStyles(); var clientRuns = new List<IClientRun>(); BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns.Add(box0); BlockBox box1 = new BlockBox(styles, Color.Blue, 36000, 18000); clientRuns.Add(box1); BlockBox box2 = new BlockBox(styles, Color.Red, 24000, 18000); clientRuns.Add(box2); BlockBox box3 = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns.Add(box3); BlockBox box4 = new BlockBox(styles, Color.Red, 36000, 36000); clientRuns.Add(box4); TextSource source = new TextSource(clientRuns, null); ParaBox para = new ParaBox(styles, source); RootBox root = new RootBox(styles); root.AddBox(para); LayoutInfo layoutArgs = MakeLayoutInfo(); root.Layout(layoutArgs); VerifyBox(box0, 96, 48, box1, para, "box0"); VerifyBox(box1, 48, 24, box2, para, "box1"); VerifyBox(box2, 32, 24, box3, para, "box2"); VerifyBox(box3, 96, 48, box4, para, "box3"); VerifyBox(box4, 48, 48, null, para, "box4"); VerifyGroup(para, 96 + 48 + 32 + 96 + 48, 48, null, root, box0, box4, "para"); VerifyGroup(root, 96 + 48 + 32 + 96 + 48, 48, null, null, para, para, "root"); VerifyParaLine(para, 0, box0, box4, 0, "para unlimited one line"); // Check multi-line layout (one line has room for two boxes). LayoutInfo layoutArgs2 = MakeLayoutInfo(100, m_gm.VwGraphics); root.Layout(layoutArgs2); Assert.AreEqual(4, para.Lines.Count, "para1 at 100 has four lines"); VerifyBox(box0, 96, 48, box1, para, "box0/100"); VerifyBox(box1, 48, 24, box2, para, "box1/100"); VerifyBox(box2, 32, 24, box3, para, "box2/100"); VerifyBox(box3, 96, 48, box4, para, "box3/100"); VerifyBox(box4, 48, 48, null, para, "box4/100"); VerifyParaLine(para, 0, box0, box0, 0, "para/100 first"); VerifyParaLine(para, 1, box1, box2, 48, "para/100 second"); VerifyParaLine(para, 2, box3, box3, 48 + 24, "para/100 third"); VerifyParaLine(para, 3, box4, box4, 48 + 24 + 48, "para/100 fourth"); // At 100 pixels wide, box0 goes on the first line, boxes 1 and 2 on the third, box 3 and box4 take the fourth and fifth. // Multiple lines means the paragraph occupies its full width. int height100 = 48 + 24 + 48 + 48; VerifyGroup(para, 100, height100, null, root, box0, box4, "para/100"); VerifyGroup(root, 100, height100, null, null, para, para, "root/100"); // Check layout when some boxes won't fit on a whole line. LayoutInfo layoutArgs3 = MakeLayoutInfo(50, m_gm.VwGraphics); root.Layout(layoutArgs3); Assert.AreEqual(5, para.Lines.Count, "para1 at 50 has five lines"); VerifyBox(box0, 96, 48, box1, para, "box0/50"); VerifyParaLine(para, 0, box0, box0, 0, "para/50 first"); VerifyParaLine(para, 1, box1, box1, 48, "para/50 second"); VerifyParaLine(para, 2, box2, box2, 48 + 24, "para/50 third"); VerifyParaLine(para, 3, box3, box3, 48 + 24 + 24, "para/50 fourth"); VerifyParaLine(para, 4, box4, box4, 48 + 24 + 24 +48, "para/50 fifth"); // At 100 pixels wide, box0 goes on the first line, boxes 1 and 2 on the third, box 3 and box4 take the fourth and fifth. // Multiple lines means the paragraph occupies its full width. int height50 = 48 + 24 + 24 + 48 + 48; VerifyGroup(para, 96, height50, null, root, box0, box4, "para/50"); VerifyGroup(root, 96, height50, null, null, para, para, "root/50"); }
internal InsertionPoint SelectAt(ParaBox para, int ich, bool asscociatePrevious) { throw new NotImplementedException(); }
public void BidiLayout() { string content1 = "This is the "; string contentRtl = "day "; string content3 = "that "; // Two writing systems int wsLtr = 5; int wsRtl = 6; // Two corresponding renderers var factory = new FakeRendererFactory(); var engineLtr = new FakeRenderEngine() { Ws = wsLtr, SegmentHeight = 13 }; factory.SetRenderer(wsLtr, engineLtr); var engineRtl = new FakeRenderEngine() {Ws = wsRtl, SegmentHeight = 13 }; engineRtl.RightToLeft = true; factory.SetRenderer(wsRtl, engineRtl); // Two corresponding styles (and a vanilla one) var styles = new AssembledStyles(); var stylesLtr = new AssembledStyles().WithWs(wsLtr); var stylesRtl = new AssembledStyles().WithWs(wsRtl); var clientRuns = new List<IClientRun>(); var run1 = new StringClientRun(content1, stylesLtr); clientRuns.Add(run1); var runRtl = new StringClientRun(contentRtl, stylesRtl); clientRuns.Add(runRtl); var run3 = new StringClientRun(content3, stylesLtr); clientRuns.Add(run3); var root = new RootBoxFdo(styles); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); root.AddBox(para); var stylesParaRtl = styles.WithRightToLeft(true); var sourceRtl = new TextSource(clientRuns, null); var paraRtl = new ParaBox(stylesParaRtl, sourceRtl); root.AddBox(paraRtl); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); // "day " being upstream should make two distinct boxes. // We should get something like // "This is the yad that ", where the space between "yad" and "that" is the one that // follows the 'y' in "day". var box1 = para.FirstBox as StringBox; var box2 = box1.Next as StringBox; var box3 = box2.Next as StringBox; var box4 = box3.Next as StringBox; Assert.That(box4, Is.Not.Null); Assert.That(box1.Segment.get_Lim(box1.IchMin) == content1.Length); Assert.That(box2.Segment.get_Lim(box2.IchMin) == contentRtl.Length - 1); Assert.That(box3.Segment.get_Lim(box3.IchMin) == 1); Assert.That(box4.Segment.get_Lim(box4.IchMin) == content3.Length); Assert.That(box1.Left, Is.LessThan(box2.Left)); Assert.That(box2.Left, Is.LessThan(box3.Left)); Assert.That(box3.Left, Is.LessThan(box4.Left)); // In the second paragraph, the two LRT runs are upstream. We should get boxes // "This is the", " ", "day ", "that" and " " (but the final space will have zero width at end of line) // The effect should be something like // that yad This is the", where the space between "yad" and "This" is the one following "the", // and the one between "that" and "yad" is the one following "day", and the space following "that" // is invisible at the end of the line to the left of 'that'. var boxR1 = paraRtl.FirstBox as StringBox; var boxR2 = boxR1.Next as StringBox; var boxR3 = boxR2.Next as StringBox; var boxR4 = boxR3.Next as StringBox; var boxR5 = boxR4.Next as StringBox; Assert.That(boxR5, Is.Not.Null); Assert.That(boxR1.Segment.get_Lim(boxR1.IchMin) == content1.Length - 1); Assert.That(boxR2.Segment.get_Lim(boxR2.IchMin) == 1); Assert.That(boxR3.Segment.get_Lim(boxR3.IchMin) == contentRtl.Length); Assert.That(boxR4.Segment.get_Lim(boxR4.IchMin) == content3.Length - 1); Assert.That(boxR5.Segment.get_Lim(boxR5.IchMin) == 1); }
private MockData1 HookDataToClientRun(ParaBox para, string contents1, int runIndex) { var data1 = new MockData1(ParaBuilderTests.s_simpleStringWs, ParaBuilderTests.s_simpleStringWs); data1.SimpleThree = contents1; var hookup = new StringHookup(data1, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged, hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => data1.SimpleThree = newVal; hookup.ClientRunIndex = runIndex; (para.Source.ClientRuns[runIndex] as StringClientRun).Hookup = hookup; return data1; }
/// <summary> /// This overload fulfils the interface contract for some kinds of Box to function as ClientRun. /// In general a box can select at start without needing to know its containing paragraph (if any) or index within it. /// </summary> public InsertionPoint SelectAtStart(ParaBox para) { return SelectAtStart(); }
public void InsertGrowsPara() { 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 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 extraBox = new BlockBox(styles, Color.Red, 50, 72000); var root = new RootBoxFdo(styles); root.SizeChanged += root_SizeChanged; root.AddBox(para); root.AddBox(extraBox); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.IsTrue(m_sizeChangedCalled); Assert.That(root.Height, Is.EqualTo(13 + 96)); Assert.That(root.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); int widthThisIsThe = FakeRenderEngine.SimulatedWidth("This is the"); layoutArgs = MakeLayoutInfo(widthThisIsThe + 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(26 + 96), "two line para is twice the height"); Assert.That(root.Width, Is.EqualTo(widthThisIsThe + 2), "two-line para occupies full available width"); Assert.That(extraBox.Top, Is.EqualTo(26)); 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; m_sizeChangedCalled = false; var ip = para.SelectAtEnd(); ip.InsertText(" We will be"); Assert.That(para.Height, Is.EqualTo(39), "inserted text makes para a line higher"); Assert.That(root.Height, Is.EqualTo(39 + 96), "root grows when para does"); Assert.That(root.Width, Is.EqualTo(widthThisIsThe + 2), "three-line para occupies full available width"); Assert.That(extraBox.Top, Is.EqualTo(39)); Assert.IsTrue(m_sizeChangedCalled); }
/// <summary> /// This overload fulfils the interface contract for some kinds of Box to function as ClientRun. /// In general a box can select at end without needing to know its containing paragraph (if any) or index within it. /// </summary> public InsertionPoint SelectAtEnd(ParaBox para) { return SelectAtEnd(); }
private void VerifySegmentDrawing(ParaBox para, StringBox third, MockSegment.DrawInsertionPointArgs drawInsertionPointArgs, int top) { Assert.AreEqual(third.IchMin, drawInsertionPointArgs.IchBase); Assert.AreEqual(m_gm.VwGraphics, drawInsertionPointArgs.Graphics); Assert.AreEqual(true, drawInsertionPointArgs.AssocPrev, "assoc prev should match IP"); ParaTests.VerifySimpleRect(drawInsertionPointArgs.RcSrc, -2, top, 96, 100); ParaTests.VerifySimpleRect(drawInsertionPointArgs.RcDst, 0, 10, 120, 128); Assert.AreEqual(drawInsertionPointArgs.Ich, para.Source.Length); Assert.AreEqual(drawInsertionPointArgs.On, true, "Should currently always pass true to segment drawIP routine"); Assert.AreEqual(drawInsertionPointArgs.DrawMode, LgIPDrawMode.kdmNormal, "all drawing modes normal till we test BIDI with Graphite"); }