示例#1
0
        public void Should_HitTestTextRange_BiDi()
        {
            const string text = "זה כיףabcDEFזה כיף";

            using (Start())
            {
                var layout = new TextLayout(
                    text,
                    Typeface.Default,
                    12.0f,
                    Brushes.Black.ToImmutable());

                var textLine = layout.TextLines[0];

                var start = textLine.GetDistanceFromCharacterHit(new CharacterHit(5, 1));

                var end = textLine.GetDistanceFromCharacterHit(new CharacterHit(6, 1));

                var rects = layout.HitTestTextRange(0, 7).ToArray();

                Assert.Equal(1, rects.Length);

                var expected = rects[0];

                Assert.Equal(expected.Left, start);
                Assert.Equal(expected.Right, end);
            }
        }
示例#2
0
        public void Should_HitTestTextRange_RightToLeft()
        {
            using (Start())
            {
                const int start  = 0;
                const int length = 10;

                var layout = new TextLayout(
                    RightToLeftText,
                    Typeface.Default,
                    12,
                    Brushes.Black);

                var selectedText = new TextLayout(
                    RightToLeftText.Substring(start, length),
                    Typeface.Default,
                    12,
                    Brushes.Black);

                var rects = layout.HitTestTextRange(start, length).ToArray();

                Assert.Equal(1, rects.Length);

                var selectedRect = rects[0];

                Assert.Equal(selectedText.Bounds.Width, selectedRect.Width);
            }
        }
示例#3
0
        public void Should_HitTestTextRange()
        {
            using (Start())
            {
                var layout = new TextLayout(
                    SingleLineText,
                    Typeface.Default,
                    12.0f,
                    Brushes.Black.ToImmutable());

                var lineRects = layout.HitTestTextRange(0, SingleLineText.Length).ToList();

                Assert.Equal(layout.TextLines.Count, lineRects.Count);

                for (var i = 0; i < layout.TextLines.Count; i++)
                {
                    var textLine = layout.TextLines[i];
                    var rect     = lineRects[i];

                    Assert.Equal(textLine.WidthIncludingTrailingWhitespace, rect.Width);
                }

                var rects = layout.TextLines.SelectMany(x => x.TextRuns.Cast <ShapedTextCharacters>())
                            .SelectMany(x => x.ShapedBuffer.GlyphAdvances).ToArray();

                for (var i = 0; i < SingleLineText.Length; i++)
                {
                    for (var j = 1; i + j < SingleLineText.Length; j++)
                    {
                        var expected = rects.AsSpan(i, j).ToArray().Sum();
                        var actual   = layout.HitTestTextRange(i, j).Sum(x => x.Width);

                        Assert.Equal(expected, actual);
                    }
                }
            }
        }
示例#4
0
        public void Evaluate(int SpreadMax)
        {
            if (!FInLayout.IsConnected)
            {
                this.FLeft.SliceCount      = 0;
                this.FTop.SliceCount       = 0;
                this.FWidth.SliceCount     = 0;
                this.FHeight.SliceCount    = 0;
                this.FResultBin.SliceCount = 0;
                return;
            }

            if (this.FInLayout.IsChanged || this.FIndex.IsChanged ||
                this.FTrailing.IsChanged || this.FRange.IsChanged)
            {
                this.FLeft.SliceCount      = SpreadMax;
                this.FTop.SliceCount       = SpreadMax;
                this.FWidth.SliceCount     = SpreadMax;
                this.FHeight.SliceCount    = SpreadMax;
                this.FResultBin.SliceCount = SpreadMax;

                List <float> left   = new List <float>();
                List <float> width  = new List <float>();
                List <float> top    = new List <float>();
                List <float> height = new List <float>();

                for (int i = 0; i < SpreadMax; i++)
                {
                    TextLayout layout  = this.FInLayout[i];
                    var        results = layout.HitTestTextRange(this.FIndex[i], this.FRange[i], 0.0f, 0.0f);

                    this.FResultBin[i] = results.Length;

                    left.AddRange(from r in results select r.Left);
                    width.AddRange(from r in results select r.Width);
                    top.AddRange(from r in results select r.Top);
                    height.AddRange(from r in results select r.Height);
                }

                this.FHeight.AssignFrom(height);
                this.FLeft.AssignFrom(left);
                this.FTop.AssignFrom(top);
                this.FWidth.AssignFrom(width);
            }
        }
示例#5
0
        /// <summary>
        /// Obtains the current caret position (in untransformed space)</summary>
        /// <returns>Current caret position rectangle (in untransformed space)</returns>
        public RectangleF GetCaretRect()
        {
            if (TextLayout == null)
            {
                return(new RectangleF());
            }

            var   caretMetrics = TextLayout.HitTestTextPosition(m_caretPosition, m_caretPositionOffset > 0);
            float caretX       = caretMetrics.Point.X;
            float caretY       = caretMetrics.Point.Y;

            UpdateSelectionRange();
            // If a selection exists, draw the caret using the
            // line size rather than the font size.
            if (SelectionLength > 0)
            {
                var lineMetrics = TextLayout.HitTestTextRange(m_caretPosition, 0, 0, 0);
                caretY = lineMetrics[0].Top;
            }

            const int caretThickness = 1;

            return(new RectangleF(caretX - caretThickness / 2.0f, caretY, caretThickness, caretMetrics.Height));
        }
示例#6
0
        public float MeasureText(int start, int length)
        {
            var metrics = textLayout.HitTestTextRange(start, length, 0, 0);

            return(metrics[0].Width);
        }
示例#7
0
        public void Should_HitTestPoint_RightToLeft()
        {
            using (Start())
            {
                var text = "אאא AAA";

                var layout = new TextLayout(
                    text,
                    Typeface.Default,
                    12,
                    Brushes.Black,
                    flowDirection: FlowDirection.RightToLeft);

                var firstRun = layout.TextLines[0].TextRuns[0] as ShapedTextCharacters;

                var hit = layout.HitTestPoint(new Point());

                Assert.Equal(4, hit.TextPosition);

                var currentX = 0.0;

                for (var i = 0; i < firstRun.GlyphRun.GlyphClusters.Count; i++)
                {
                    var cluster = firstRun.GlyphRun.GlyphClusters[i];
                    var advance = firstRun.GlyphRun.GlyphAdvances[i];

                    hit = layout.HitTestPoint(new Point(currentX, 0));

                    Assert.Equal(cluster, hit.TextPosition);

                    var hitRange = layout.HitTestTextRange(hit.TextPosition, 1);

                    var distance = hitRange.First().Left;

                    Assert.Equal(currentX, distance);

                    currentX += advance;
                }

                var secondRun = layout.TextLines[0].TextRuns[1] as ShapedTextCharacters;

                hit = layout.HitTestPoint(new Point(firstRun.Size.Width, 0));

                Assert.Equal(7, hit.TextPosition);

                hit = layout.HitTestPoint(new Point(layout.TextLines[0].WidthIncludingTrailingWhitespace, 0));

                Assert.Equal(0, hit.TextPosition);

                currentX = firstRun.Size.Width + 0.5;

                for (var i = 0; i < secondRun.GlyphRun.GlyphClusters.Count; i++)
                {
                    var cluster = secondRun.GlyphRun.GlyphClusters[i];
                    var advance = secondRun.GlyphRun.GlyphAdvances[i];

                    hit = layout.HitTestPoint(new Point(currentX, 0));

                    Assert.Equal(cluster, hit.CharacterHit.FirstCharacterIndex);

                    var hitRange = layout.HitTestTextRange(hit.CharacterHit.FirstCharacterIndex, hit.CharacterHit.TrailingLength);

                    var distance = hitRange.First().Left + 0.5;

                    Assert.Equal(currentX, distance);

                    currentX += advance;
                }
            }
        }
示例#8
0
        static void Main(string[] args)
        {
            mainForm = new RenderForm("Advanced Text rendering demo");

            d2dFactory = new D2DFactory();
            dwFactory  = new DWriteFactory(SharpDX.DirectWrite.FactoryType.Shared);

            textRenderer = new CustomColorRenderer();

            CreateResources();

            var bgcolor = new Color4(0.1f, 0.1f, 0.1f, 1.0f);

            //This is the offset where we start our text layout
            Vector2 offset = new Vector2(202.0f, 250.0f);

            textFormat = new TextFormat(dwFactory, "Arial", FontWeight.Regular, FontStyle.Normal, 16.0f);
            textLayout = new TextLayout(dwFactory, introText, textFormat, 300.0f, 200.0f);

            //Apply various modifications to text
            textLayout.SetUnderline(true, new TextRange(0, 5));
            textLayout.SetDrawingEffect(greenBrush, new TextRange(10, 20));
            textLayout.SetFontSize(24.0f, new TextRange(6, 4));
            textLayout.SetFontFamilyName("Comic Sans MS", new TextRange(11, 7));

            //Measure full layout
            var textSize = textLayout.Metrics;

            fullTextBackground = new RectangleF(textSize.Left + offset.X, textSize.Top + offset.Y, textSize.Width, textSize.Height);

            //Measure text to apply background to
            var metrics = textLayout.HitTestTextRange(53, 4, 0.0f, 0.0f)[0];

            textRegionRect = new RectangleF(metrics.Left + offset.X, metrics.Top + offset.Y, metrics.Width, metrics.Height);

            //Assign render target and brush to our custom renderer
            textRenderer.AssignResources(renderTarget, defaultBrush);

            RenderLoop.Run(mainForm, () =>
            {
                renderTarget.BeginDraw();
                renderTarget.Clear(bgcolor);

                renderTarget.FillRectangle(fullTextBackground, backgroundBrush);

                renderTarget.FillRectangle(textRegionRect, redBrush);

                textLayout.Draw(textRenderer, offset.X, offset.Y);

                try
                {
                    renderTarget.EndDraw();
                }
                catch
                {
                    CreateResources();
                }
            });

            d2dFactory.Dispose();
            dwFactory.Dispose();
            renderTarget.Dispose();
        }