Example #1
0
        private Run *GetRunAtCharacterIndex(int index, out int runIndex)
        {
            int        paragraphIndex;
            Paragraph *paragraph = GetParagraphAtCharacterIndex(index, out paragraphIndex);

            if (paragraph != null)
            {
                int remainingOffset = index - paragraph->CharIndex;

                Run *startRun = GetRunZero() + paragraph->RunIndex;
                Run *endRun   = startRun + paragraph->RunCount;
                for (Run *run = startRun; run != endRun; run++)
                {
                    remainingOffset -= run->CharCount;

                    if (remainingOffset < 0)
                    {
                        runIndex = (int)(run - startRun);
                        return(run);
                    }
                }
            }

            runIndex = -1;
            return(null);
        }
Example #2
0
        private Paragraph *GetParagraphAtCharacterIndex(int index, out int paragraphIndex)
        {
            Paragraph *paragraphZero  = GetParagraphZero();
            int        paragraphCount = ParagraphCount;

            int low  = 0;
            int high = paragraphCount;

            while (low < high)
            {
                int mid = (low + high) / 2;

                int candidateCharIndex = paragraphZero[mid].CharIndex;
                if (candidateCharIndex > index)
                {
                    high = mid;
                }
                else if (candidateCharIndex + paragraphZero[mid].CharCount < index)
                {
                    low = mid + 1;
                }
                else
                {
                    paragraphIndex = mid;
                    return(paragraphZero + mid);
                }
            }

            paragraphIndex = -1;
            return(null);
        }
Example #3
0
        private void InternalStartParagraph()
        {
            Debug.Assert(currentRun != null || currentParagraph == null,
                         "At least one run should be added to the current paragraph before a new one is started.");

            int paragraphIndex = paragraphBuffer.Count;

            paragraphBuffer.GrowBy(1);

            currentParagraph = GetParagraphZero() + paragraphIndex;
            currentParagraph->Initialize(charBuffer.Count, 0, runBuffer.Count, 0);

            currentRun = null;
        }
Example #4
0
        private void InternalClear()
        {
            currentParagraph = null;
            currentRun       = null;

            styleTable.Clear();
            objectTable.Clear();
            annotationTables.Clear();
            styleIndexStack.Clear();

            charBuffer.Clear();
            paragraphBuffer.Clear();
            runBuffer.Clear();

            InternalBeginStyle(Style.Default);
            InternalStartParagraph();
        }
Example #5
0
        public unsafe void AppendText_WhenRunIsExtremelyLong_SplitsRun(int length)
        {
            var document = new SplashDocument();
            var content  = new string(' ', length);

            document.AppendText(content);

            Assert.Multiple(() =>
            {
                // Check char content.
                Assert.AreEqual(content, document.ToString());

                // Check paragraph table.
                Assert.AreEqual(1, document.ParagraphCount);
                Paragraph *paragraphs = document.GetParagraphZero();

                int expectedRuns = (length + SplashDocument.MaxCharsPerRun - 1) / SplashDocument.MaxCharsPerRun;
                Assert.AreEqual(0, paragraphs[0].CharIndex);
                Assert.AreEqual(length, paragraphs[0].CharCount);
                Assert.AreEqual(0, paragraphs[0].RunIndex);
                Assert.AreEqual(expectedRuns, paragraphs[0].RunCount);

                // Check run table.
                Assert.AreEqual(expectedRuns, document.RunCount);
                Run *runs = document.GetRunZero();

                for (int i = 0; i < expectedRuns; i++)
                {
                    Assert.AreEqual(RunKind.Text, runs[i].RunKind);
                    Assert.AreEqual(Math.Min(length, SplashDocument.MaxCharsPerRun), runs[i].CharCount);
                    Assert.AreEqual(0, runs[i].StyleIndex);

                    length -= SplashDocument.MaxCharsPerRun;
                }
            });
        }
Example #6
0
        public unsafe void AppendStuff()
        {
            var style1 = new StyleBuilder()
            {
                Color = Color.Red
            }.ToStyle();
            var style2 = new StyleBuilder()
            {
                LeftMargin = 10, RightMargin = 10
            }.ToStyle();
            var style3 = new StyleBuilder()
            {
                Font = SystemFonts.SmallCaptionFont, Color = Color.Blue
            }.ToStyle();
            var embeddedObject = new EmbeddedImage(new Bitmap(16, 16));

            var document = new SplashDocument();
            var changedParagraphIndices = new List <int>();

            document.ParagraphChanged += (sender, e) => changedParagraphIndices.Add(e.ParagraphIndex);

            using (document.BeginStyle(style1))
                document.AppendText("Some text, lalala.\nMore text.");

            using (document.BeginStyle(style2))
            {
                document.AppendText("Tab\t.\n");

                document.AppendText("\0\r"); // these control characters will be discarded

                using (document.BeginStyle(style3))
                {
                    document.AppendLine();
                    document.AppendText(""); // to verify that no change event is raised for empty text
                }

                document.AppendText("(");
                document.AppendObject(embeddedObject);
                document.AppendText(")");
            }

            Assert.Multiple(() =>
            {
                // Check char content.
                Assert.AreEqual("Some text, lalala.\nMore text.Tab\t.\n\n( )", document.ToString());

                // Check style table.
                Assert.AreEqual(4, document.StyleCount);
                Assert.AreEqual(Style.Default, document.LookupStyle(0));
                Assert.AreEqual(style1, document.LookupStyle(1));
                Assert.AreEqual(style2, document.LookupStyle(2));
                Assert.AreEqual(style3, document.LookupStyle(3));

                // Check object table.
                Assert.AreEqual(1, document.ObjectCount);
                Assert.AreEqual(embeddedObject, document.LookupObject(0));

                // Check paragraph table.
                Assert.AreEqual(4, document.ParagraphCount);
                Paragraph *paragraphs = document.GetParagraphZero();

                Assert.AreEqual(0, paragraphs[0].CharIndex); // "Some text, lalala.\n"
                Assert.AreEqual(19, paragraphs[0].CharCount);
                Assert.AreEqual(0, paragraphs[0].RunIndex);
                Assert.AreEqual(1, paragraphs[0].RunCount);

                Assert.AreEqual(19, paragraphs[1].CharIndex); // "More text.Tab\t.\n"
                Assert.AreEqual(16, paragraphs[1].CharCount);
                Assert.AreEqual(1, paragraphs[1].RunIndex);
                Assert.AreEqual(4, paragraphs[1].RunCount);

                Assert.AreEqual(35, paragraphs[2].CharIndex); // "\n"
                Assert.AreEqual(1, paragraphs[2].CharCount);
                Assert.AreEqual(5, paragraphs[2].RunIndex);
                Assert.AreEqual(1, paragraphs[2].RunCount);

                Assert.AreEqual(36, paragraphs[3].CharIndex); // "( )"
                Assert.AreEqual(3, paragraphs[3].CharCount);
                Assert.AreEqual(6, paragraphs[3].RunIndex);
                Assert.AreEqual(3, paragraphs[3].RunCount);

                // Check run table.
                Assert.AreEqual(9, document.RunCount);
                Run *runs = document.GetRunZero();

                Assert.AreEqual(RunKind.Text, runs[0].RunKind); // "Some text, lalala.\n"
                Assert.AreEqual(19, runs[0].CharCount);
                Assert.AreEqual(1, runs[0].StyleIndex);

                Assert.AreEqual(RunKind.Text, runs[1].RunKind); // "More text."
                Assert.AreEqual(10, runs[1].CharCount);
                Assert.AreEqual(1, runs[1].StyleIndex);

                Assert.AreEqual(RunKind.Text, runs[2].RunKind); // "Tab"
                Assert.AreEqual(3, runs[2].CharCount);
                Assert.AreEqual(2, runs[2].StyleIndex);

                Assert.AreEqual(RunKind.Tab, runs[3].RunKind); // "\t"
                Assert.AreEqual(1, runs[3].CharCount);
                Assert.AreEqual(2, runs[3].StyleIndex);

                Assert.AreEqual(RunKind.Text, runs[4].RunKind); // ".\n"
                Assert.AreEqual(2, runs[4].CharCount);
                Assert.AreEqual(2, runs[4].StyleIndex);

                Assert.AreEqual(RunKind.Text, runs[5].RunKind); // "\n"
                Assert.AreEqual(1, runs[5].CharCount);
                Assert.AreEqual(3, runs[5].StyleIndex);

                Assert.AreEqual(RunKind.Text, runs[6].RunKind); // "("
                Assert.AreEqual(1, runs[6].CharCount);
                Assert.AreEqual(2, runs[6].StyleIndex);

                Assert.AreEqual(RunKind.Object, runs[7].RunKind); // "("
                Assert.AreEqual(1, runs[7].CharCount);
                Assert.AreEqual(2, runs[7].StyleIndex);
                Assert.AreEqual(0, runs[7].ObjectIndex);

                Assert.AreEqual(RunKind.Text, runs[8].RunKind); // ")"
                Assert.AreEqual(1, runs[8].CharCount);
                Assert.AreEqual(2, runs[8].StyleIndex);

                // Check that paragraph changed notifications were raised as needed.
                Assert.AreElementsEqual(new[] { 0, 1, 2, 2, 3, 3, 3 }, changedParagraphIndices);
            });
        }