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); } }
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); } }
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); } } } }
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); } }
/// <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)); }
public float MeasureText(int start, int length) { var metrics = textLayout.HitTestTextRange(start, length, 0, 0); return(metrics[0].Width); }
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; } } }
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(); }