/// <summary> /// This function adds a string to the group box, in the specified writing system /// </summary> public ViewBuilder AddString(Expression <Func <string> > fetchString, int ws) { var fetcher = fetchString.Compile(); var run = new StringClientRun(fetcher(), NestedBoxStyles.WithWs(ws)); return(AddStringClientRun(run, fetchString, fetcher)); }
public void InsertCharInEmptyLine() { string contents = ""; var engine = new FakeRenderEngine() { Ws = 34, SegmentHeight = 13 }; var factory = new FakeRendererFactory(); factory.SetRenderer(34, engine); var styles = new AssembledStyles().WithWs(34); var clientRuns = new List <IClientRun>(); var run = new StringClientRun(contents, styles); clientRuns.Add(run); var data1 = new MockData1(34, 35); data1.SimpleThree = contents; var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => data1.SimpleThree, hook => data1.SimpleThreeChanged += hook.StringPropChanged, hook => data1.SimpleThreeChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => data1.SimpleThree = newVal; run.Hookup = hookup; var root = new RootBox(styles); var block = new BlockBox(styles, Color.Red, 20000, 10000); root.AddBox(block); root.AddBox(para); var layoutArgs = MakeLayoutInfo(Int32.MaxValue / 2, m_gm.VwGraphics, factory); root.Layout(layoutArgs); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(para.Width, Is.EqualTo(FakeRenderEngine.SimulatedWidth(contents))); Assert.That(root.Width, Is.EqualTo(block.Width)); int simulatedWidth = FakeRenderEngine.SimulatedWidth("x"); Assert.That(root.Width, Is.GreaterThan(para.Width + simulatedWidth)); PaintTransform ptrans = new PaintTransform(2, 4, 96, 100, 0, 10, 120, 128); MockSite site = new MockSite(); site.m_transform = ptrans; site.m_vwGraphics = m_gm.VwGraphics; root.Site = site; var oldRootWidth = root.Width; var ip = root.SelectAtEnd(); ip.InsertText("x"); Assert.That(root.Height, Is.EqualTo(13 + block.Height)); Assert.That(root.Width, Is.EqualTo(oldRootWidth)); Assert.That(para.Width, Is.EqualTo(simulatedWidth)); var expectedInvalidate = new Rectangle(-RootBox.InvalidateMargin, -RootBox.InvalidateMargin + block.Height, simulatedWidth + RootBox.InvalidateMargin * 2, 13 + 2 * RootBox.InvalidateMargin); Assert.That(site.RectsInvalidatedInRoot, Has.Member(expectedInvalidate)); }
public void 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"); }
/// <summary> /// The common logic of the two versions of AddString. /// </summary> private ViewBuilder AddStringClientRun(StringClientRun run, Expression <Func <string> > fetchString, Func <string> fetcher) { ParaBox para = InsertParaOrRun(run); // Try to hook an event for notification of changes to the property. var mexp = (fetchString.Body as MemberExpression); var argExp = Expression.Lambda <Func <object> >(mexp.Expression); Type type = mexp.Member.DeclaringType; string name = mexp.Member.Name; EventInfo einfo = type.GetEvent(name + "Changed"); if (einfo != null) { var target = argExp.Compile().Invoke(); var stringHookup = new StringHookup(target, fetcher, hookup => einfo.AddEventHandler(target, new EventHandler <EventArgs>(hookup.StringPropChanged)), hookup => einfo.RemoveEventHandler(target, new EventHandler <EventArgs>(hookup.StringPropChanged)), para); AddHookupToRun(run, stringHookup); var propInfo = type.GetProperty(name); if (propInfo.CanWrite) { stringHookup.Writer = newVal => propInfo.SetValue(target, newVal, null); } } return(this); }
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); }
// Add to the root a text paragraph which reflects the SimpleText property. private void AddSimpleTextPara(AssembledStyles styles, int ws, RootBox root) { var items = new List <ClientRun>(); var run = new StringClientRun("This is the day that the Lord has made. We will rejoice and be glad in it", styles.WithWs(ws)); items.Add(run); TextSource source = new TextSource(items); ParaBox para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => this.SimpleText, hook => SimpleTextChanged += hook.StringPropChanged, hook => SimpleTextChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => SimpleText = newVal; run.Hookup = hookup; root.AddBox(para); }
/// <summary> /// This function adds a (literal) string to the group box, in the specified writing system /// (and returns the builder, in case we want to do more). /// </summary> public ViewBuilder AddString(string content, int ws) { var actualWs = ws; if (ws == 0) { var factory = Root.RendererFactory; if (factory != null) { actualWs = factory.UserWs; } } var run = new StringClientRun(content, NestedBoxStyles.WithWs(actualWs)); ParaBox para = InsertParaOrRun(run); return(this); }
private ParaBox MakePara(MockSequenceHookup hookup, AssembledStyles styles, MockData1 itemNew, string contents, RootBox root) { var newItemHookup = new ItemHookup(itemNew, null); hookup.InsertChildHookup(newItemHookup, 1); // Give that hookup a stringhookup child, connected to a paragraph and root box. var clientRuns = new List <IClientRun>(); itemNew.SimpleThree = contents; var run = new StringClientRun(contents, styles); clientRuns.Add(run); var source = new TextSource(clientRuns, null); var para = new ParaBox(styles, source); run.Hookup = new LiteralStringParaHookup(itemNew, para); newItemHookup.InsertChildHookup(run.Hookup, 0); root.AddBox(para); return(para); }
public void 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 StringChangedTests() { string part0 = "abc"; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun0 = new StringClientRun(part0, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); TextSource source = new TextSource(clientRuns); List <IRenderRun> renderRuns = source.RenderRuns; VerifyRenderRun(renderRuns[0], 0, 3, "initial state has all in one run"); var clientRun1 = new StringClientRun("abcd", styles); var output1 = source.ClientRunChanged(0, clientRun1); Assert.AreEqual(1, output1.NewSource.RenderRuns.Count, "replacing single run with simple string should produce single render run."); VerifyRenderRun(output1.NewSource.RenderRuns[0], 0, 4, "replacing client run should make a new source with modified single run"); Assert.AreEqual(3, output1.StartChange); Assert.AreEqual(0, output1.DeleteCount); Assert.AreEqual(1, output1.InsertCount); // try changing the middle of three runs, from a simple one to a complex one. clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); string part2 = "def"; var clientRun2 = new StringClientRun(part2, styles); clientRuns.Add(clientRun2); string part3 = " mnop"; var clientRun3 = new StringClientRun(part3, styles); clientRuns.Add(clientRun3); source = new TextSource(clientRuns, MockInterpretOrc); string part4 = "q\xfffc"; var clientRun4 = new StringClientRun(part4, styles); var output2 = source.ClientRunChanged(1, clientRun4); Assert.AreEqual(3, output2.NewSource.RenderRuns.Count, "three render runs because ORC interprets as french string."); VerifyRenderRun(output2.NewSource.RenderRuns[0], 0, part0.Length + 1, "first run up to ORC"); VerifyRenderRun(output2.NewSource.RenderRuns[1], part0.Length + 1, orcText.Length, "second run is French from ORC"); VerifyRenderRun(output2.NewSource.RenderRuns[2], part0.Length + 1 + orcText.Length, part3.Length, "third run is stuff after ORC"); VerifyFetch(output2.NewSource, 0, output2.NewSource.Length, part0 + "q" + orcText + part3); Assert.AreEqual(part0.Length, output2.StartChange); Assert.AreEqual(part2.Length, output2.DeleteCount); Assert.AreEqual(1 + orcText.Length, output2.InsertCount); // Now do a variation where some of the new run survives at each end. // To catch a tricky special case, we want to replace some regular text with an ORC // that expands to the same thing. var bldr = tsf.MakeString("de" + orcText, wsEn).GetBldr(); bldr.SetIntPropValues(2, 2 + orcText.Length, (int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, wsFrn); var clientRunFakeOrc = new TssClientRun(bldr.GetString(), styles); clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); clientRuns.Add(clientRunFakeOrc); clientRuns.Add(clientRun3); source = new TextSource(clientRuns, MockInterpretOrc); string partDeqOrc = "deq\xfffc"; var clientRun5 = new StringClientRun(partDeqOrc, styles); var output3 = source.ClientRunChanged(1, clientRun5); Assert.AreEqual(3, output3.NewSource.RenderRuns.Count, "three render runs because ORC interprets as french string."); VerifyRenderRun(output3.NewSource.RenderRuns[0], 0, part0.Length + 3, "first run up to ORC"); VerifyRenderRun(output3.NewSource.RenderRuns[1], part0.Length + 3, orcText.Length, "second run is French from ORC"); VerifyRenderRun(output3.NewSource.RenderRuns[2], part0.Length + 3 + orcText.Length, part3.Length, "third run is stuff after ORC"); VerifyFetch(output3.NewSource, 0, output3.NewSource.Length, part0 + "deq" + orcText + part3); // This should be interpreted as inserting the "q" after the "de" and before the orc text. Assert.AreEqual(part0.Length + 2, output3.StartChange); Assert.AreEqual(0, output3.DeleteCount); Assert.AreEqual(1, output3.InsertCount); // special case where nothing changes. clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); clientRuns.Add(clientRun2); source = new TextSource(clientRuns, MockInterpretOrc); var output4 = source.ClientRunChanged(1, clientRun2); Assert.AreEqual(1, output4.NewSource.RenderRuns.Count, "two client runs collapse to one render"); VerifyRenderRun(output4.NewSource.RenderRuns[0], 0, part0.Length + part2.Length, "run has expected length"); VerifyFetch(output4.NewSource, 0, output4.NewSource.Length, part0 + part2); Assert.AreEqual(part0.Length, output4.StartChange); Assert.AreEqual(0, output4.DeleteCount); Assert.AreEqual(0, output4.InsertCount); }
public void RenderRuns() { string part0 = "abc def"; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun0 = new StringClientRun(part0, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); string part0a = " frn"; StringClientRun clientRun0a = new StringClientRun(part0a, styles.WithWs(wsFrn)); clientRuns.Add(clientRun0a); // Run 1 string part1 = " ghijk"; // english string part2 = " lmno"; // french ITsString tss = tsf.MakeString(part1, wsEn); ITsStrBldr bldr = tss.GetBldr(); bldr.Replace(bldr.Length, bldr.Length, part2, ttpFrn); TssClientRun clientRun1 = new TssClientRun(bldr.GetString(), styles); clientRuns.Add(clientRun1); // Run 2a string part2a = " french insert"; string part2b = " insert"; // english ITsString tssInsert = tsf.MakeString(part2b, wsEn); bldr = tssInsert.GetBldr(); bldr.Replace(0, 0, part2a, ttpFrn); TssClientRun clientRun2b = new TssClientRun(bldr.GetString(), styles); clientRuns.Add(clientRun2b); // IRuntem 2 string part3 = " pq"; string part4 = "\xfffc"; StringClientRun clientRun2 = new StringClientRun(part3 + part4, styles); clientRuns.Add(clientRun2); // Run 3 string part5 = "more french"; string part6 = "\xfffc"; StringClientRun clientRun3 = new StringClientRun(part5 + part6, styles.WithWs(wsFrn)); clientRuns.Add(clientRun3); // Run 4 string part7 = "English"; StringClientRun clientRun4 = new StringClientRun(part7, styles.WithWs(wsFrn)); clientRuns.Add(clientRun4); BlockBox box = new BlockBox(styles.WithWs(wsFrn), Color.Red, 72000, 36000); TextSource source = new TextSource(clientRuns, (run, offset) => (run == clientRun2 ? new StringClientRun(orcText, run.UniformRunStyles(0).WithWs(wsFrn)) : (IClientRun)box)); List <IRenderRun> renderRuns = source.RenderRuns; VerifyRenderRun(renderRuns[0], 0, part0.Length, "first - en"); int len = part0.Length; VerifyRenderRun(renderRuns[1], len, part0a.Length, "0a - frn"); len += part0a.Length; VerifyRenderRun(renderRuns[2], len, part1.Length, "part1 - en"); len += part1.Length; VerifyRenderRun(renderRuns[3], len, part2.Length + part2a.Length, "part2 & 2a (french)"); len += part2.Length + part2a.Length; VerifyRenderRun(renderRuns[4], len, part2b.Length + part3.Length, "2b and 2 (Eng)"); len += part2b.Length + part3.Length; VerifyRenderRun(renderRuns[5], len, orcText.Length + part5.Length, "orc + other french"); len += orcText.Length + part5.Length; VerifyRenderRun(renderRuns[6], len, 1, "single box"); len += 1; VerifyRenderRun(renderRuns[7], len, part7.Length, "run with same props as preceding box"); Assert.AreEqual(8, renderRuns.Count); }
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); }
public void MultiUniformRuns() { // Run 0 string part0 = "abc def"; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun0 = new StringClientRun(part0, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); // Run 1 string part1 = " ghijk"; string part2 = " lmno"; ITsString tss = tsf.MakeString(part2, wsEn); ITsStrBldr bldr = tss.GetBldr(); bldr.Replace(0, 0, part1, ttpFrn); TssClientRun clientRun1 = new TssClientRun(bldr.GetString(), styles); clientRuns.Add(clientRun1); // Run 2 string part3 = " pq"; string part4 = "\xfffc"; string part5 = "r"; StringClientRun clientRun2 = new StringClientRun(part3 + part4 + part5, styles); clientRuns.Add(clientRun2); TextSource source = new TextSource(clientRuns, MockInterpretOrc); MapRun[] runs = source.Runs; Assert.AreEqual(6, runs.Length); VerifyRun(0, clientRun0, 0, 0, part0, runs[0], "first run of complex source (abcdef)"); int len = part0.Length; VerifyRun(len, clientRun1, len, 0, part1, runs[1], "2nd run of complex source( ghijk)"); len += part1.Length; VerifyRun(len, clientRun1, len, 0, 1, part2, runs[2], "3rd run of complex source( lmno)"); len += part2.Length; VerifyRun(len, clientRun2, len, 0, part3, runs[3], "4th run of complex source (pq)"); len += part3.Length; int orcPos = len; VerifyRun(len, clientRun2, len, part3.Length, orcText, runs[4], "5th run of complex source (orc->xyz)"); int render = len + orcText.Length; len += 1; VerifyRun(len, clientRun2, render, part3.Length + part4.Length, part5, runs[5], "6th run of complex source(r)"); len += part5.Length; render += part5.Length; Assert.AreEqual(render, source.Length, "Length of complex source"); // LogToRen Assert.AreEqual(0, source.LogToRen(0)); Assert.AreEqual(1, source.LogToRen(1)); Assert.AreEqual(part1.Length - 1, source.LogToRen(part1.Length - 1)); Assert.AreEqual(part1.Length, source.LogToRen(part1.Length)); Assert.AreEqual(part1.Length + 1, source.LogToRen(part1.Length + 1)); Assert.AreEqual(orcPos - 1, source.LogToRen(orcPos - 1)); Assert.AreEqual(orcPos, source.LogToRen(orcPos)); int delta = orcText.Length - 1; Assert.AreEqual(orcPos + 1 + delta, source.LogToRen(orcPos + 1)); Assert.AreEqual(len + delta, source.LogToRen(len)); Assert.AreEqual(len - 1 + delta, source.LogToRen(len - 1)); //RenToLog Assert.AreEqual(0, source.RenToLog(0)); Assert.AreEqual(1, source.RenToLog(1)); Assert.AreEqual(part1.Length - 1, source.RenToLog(part1.Length - 1)); Assert.AreEqual(part1.Length, source.RenToLog(part1.Length)); Assert.AreEqual(part1.Length + 1, source.RenToLog(part1.Length + 1)); Assert.AreEqual(orcPos - 1, source.RenToLog(orcPos - 1)); Assert.AreEqual(orcPos, source.RenToLog(orcPos)); Assert.AreEqual(orcPos, source.RenToLog(orcPos + orcText.Length - 1)); Assert.AreEqual(orcPos + 1, source.RenToLog(orcPos + orcText.Length)); Assert.AreEqual(len, source.RenToLog(len + delta)); Assert.AreEqual(len - 1, source.RenToLog(len + delta - 1)); // Fetch VerifyFetch(source, 0, 0, ""); VerifyFetch(source, 0, 1, "a"); VerifyFetch(source, 0, part0.Length, part0); VerifyFetch(source, orcPos, orcPos + orcText.Length, orcText); VerifyFetch(source, part0.Length, part0.Length + part1.Length, part1); VerifyFetch(source, part0.Length + part1.Length - 2, part0.Length + part1.Length + 2, part1.Substring(part1.Length - 2) + part2.Substring(0, 2)); VerifyFetch(source, part0.Length, part0.Length + part1.Length + part2.Length + 1, part1 + part2 + part3.Substring(0, 1)); VerifyFetch(source, orcPos + orcText.Length - 1, orcPos + orcText.Length + 1, orcText.Substring(orcText.Length - 1) + part5); // GetCharProps. (This test is too restrictive. In several cases, a larger range could be returned. OTOH it is weak // in only verifying the writing system to check the properties returned.) VerifyCharProps(source, 0, wsEn, 0, part0.Length, "props at 0 in complex string"); VerifyCharProps(source, 2, wsEn, 0, part0.Length, "props in middle of first run in complex string"); VerifyCharProps(source, part0.Length - 1, wsEn, 0, part0.Length, "props of last char of first run in complex string"); VerifyCharProps(source, part0.Length, wsFrn, part0.Length, part0.Length + part1.Length, "props at start of second run in complex string"); VerifyCharProps(source, orcPos - 1, wsEn, orcPos - part3.Length, orcPos, "props of last char before ORC"); VerifyCharProps(source, orcPos, wsFrn, orcPos, orcPos + orcText.Length, "props of first char of ORC expansion"); VerifyCharProps(source, orcPos + 1, wsFrn, orcPos, orcPos + orcText.Length, "props of mid char of ORC expansion"); VerifyCharProps(source, orcPos + orcText.Length - 1, wsFrn, orcPos, orcPos + orcText.Length, "props of last char of ORC expansion"); VerifyCharProps(source, orcPos + orcText.Length, wsEn, orcPos + orcText.Length, orcPos + orcText.Length + part5.Length, "props of first char after ORC expansion"); }
public void ValidSelections() { AssembledStyles styles = new AssembledStyles(); var clientRuns = new List <IClientRun>(); var run0 = new StringClientRun("First run", styles); var run1 = new StringClientRun("Middle run", styles); BlockBox box0 = new BlockBox(styles, Color.Red, 72000, 36000); var run2 = new StringClientRun("Last run", styles); clientRuns.Add(run0); clientRuns.Add(run1); clientRuns.Add(box0); clientRuns.Add(run2); TextSource source = new TextSource(clientRuns, null); ParaBox para0 = new ParaBox(styles, source); run0.Hookup = new LiteralStringParaHookup(para0, para0); run1.Hookup = new LiteralStringParaHookup(para0, para0); run2.Hookup = new LiteralStringParaHookup(para0, para0); DivBox div = new DivBox(styles); RootBox root = new RootBox(styles); para0.Container = div; MockGraphics graphics = new MockGraphics(); LayoutInfo layoutArgs = ParaBuilderTests.MakeLayoutInfo(100, graphics); root.Layout(layoutArgs); root.AddBox(div); var sel = para0.SelectAtStart(); root.Selection = sel; Assert.That(!root.Selection.IsValid); div.AddBox(para0); root.RemoveBoxes(div, div); div.Container = root; Assert.That(!root.Selection.IsValid); root.AddBox(div); Assert.That(root.Selection.IsValid); (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 4; Assert.That(!root.Selection.IsValid); (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 2; Assert.That(!root.Selection.IsValid); (root.Selection as InsertionPoint).Hookup.ClientRunIndex = 0; (root.Selection as InsertionPoint).StringPosition = 10; Assert.That(!root.Selection.IsValid); (root.Selection as InsertionPoint).StringPosition = 0; run0.Hookup = null; Assert.That(!root.Selection.IsValid); run0.Hookup = new LiteralStringParaHookup(para0, para0); sel = para0.SelectAtStart(); root.Selection = sel; Assert.That(root.Selection.IsValid); }
public void EmptyRuns() { // Run 0 string part0 = ""; AssembledStyles styles = new AssembledStyles().WithWs(wsEn); StringClientRun clientRun0 = new StringClientRun(part0, styles); var clientRuns = new List <IClientRun>(); clientRuns.Add(clientRun0); // We want an empty run if it's the only thing in the paragraph. TextSource source = new TextSource(clientRuns, MockInterpretOrc); MapRun[] runs = source.Runs; Assert.AreEqual(1, runs.Length); VerifyRun(0, clientRun0, 0, 0, "", runs[0], "first run of empty source"); Assert.AreEqual(0, source.Length, "length of empty source"); VerifyCharProps(source, 0, wsEn, 0, 0, "props at 0 in empty string"); // We don't want an empty run adjacent to a non-empty one. string part1 = "abc"; StringClientRun clientRun1 = new StringClientRun(part1, styles); clientRuns.Add(clientRun1); source = new TextSource(clientRuns, MockInterpretOrc); runs = source.Runs; Assert.AreEqual(1, runs.Length); VerifyRun(0, clientRun1, 0, 0, part1, runs[0], "first run of (empty, abc) source"); Assert.AreEqual(part1.Length, source.Length, "length of (empty, abc) source"); // (empty, box) keeps empty BlockBox box = new BlockBox(styles, Color.Red, 72000, 36000); clientRuns[1] = box; source = new TextSource(clientRuns, MockInterpretOrc); runs = source.Runs; Assert.AreEqual(2, runs.Length); VerifyRun(0, clientRun0, 0, 0, "", runs[0], "first run of (empty, box) source"); VerifyRun(0, box, 0, 0, "\xfffc", runs[1], "2nd run of (empty, box) source"); Assert.AreEqual(1, source.Length, "length of (empty, box) source"); // Two adjacent empty strings produce a single run for the first client run. clientRuns.RemoveAt(1); StringClientRun clientRun1e = new StringClientRun(part0, styles); clientRuns.Add(clientRun1e); source = new TextSource(clientRuns, MockInterpretOrc); runs = source.Runs; Assert.AreEqual(1, runs.Length); VerifyRun(0, clientRun0, 0, 0, "", runs[0], "first run of (empty, empty) source"); Assert.AreEqual(0, source.Length, "length of (empty, empty) source"); // (something,empty) keeps the something. clientRuns[0] = clientRun1; source = new TextSource(clientRuns, MockInterpretOrc); runs = source.Runs; Assert.AreEqual(1, runs.Length); VerifyRun(0, clientRun1, 0, 0, part1, runs[0], "first run of (abc, empty) source"); Assert.AreEqual(part1.Length, source.Length, "length of (abc, empty) source"); // (box, empty) keeps empty clientRuns[0] = box; source = new TextSource(clientRuns, MockInterpretOrc); runs = source.Runs; Assert.AreEqual(2, runs.Length); VerifyRun(0, box, 0, 0, "\xfffc", runs[0], "first run of (box, empty) source"); VerifyRun(1, clientRun1e, 1, 0, "", runs[1], "2nd run of (box, empty) source"); Assert.AreEqual(1, source.Length, "length of (box, empty) source"); }
// Add to the root a text paragraph which reflects the SimpleText property. private void AddSimpleTextPara(AssembledStyles styles, int ws, RootBox root) { var items = new List<ClientRun>(); var run = new StringClientRun("This is the day that the Lord has made. We will rejoice and be glad in it", styles.WithWs(ws)); items.Add(run); TextSource source = new TextSource(items); ParaBox para = new ParaBox(styles, source); var hookup = new StringHookup(this, () => this.SimpleText, hook => SimpleTextChanged += hook.StringPropChanged, hook => SimpleTextChanged -= hook.StringPropChanged, para); hookup.Writer = newVal => SimpleText = newVal; run.Hookup = hookup; root.AddBox(para); }