| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- using System;
- using System.Linq;
- using System.Text.RegularExpressions;
- using NUnit.Framework;
- using QuestPDF.Drawing;
- using QuestPDF.Examples.Engine;
- using QuestPDF.Fluent;
- using QuestPDF.Helpers;
- using QuestPDF.Infrastructure;
- using SkiaSharp;
- using SkiaSharp.HarfBuzz;
- namespace QuestPDF.Examples
- {
- public class TextShapingTests
- {
- [Test]
- public void ShapeText()
- {
- using var textPaint = new SKPaint
- {
- Color = SKColors.Black,
- Typeface = SKTypeface.CreateDefault(),
- IsAntialias = true,
- TextSize = 20
- };
-
- using var backgroundPaint = new SKPaint
- {
- Color = SKColors.LightGray
- };
-
- RenderingTest
- .Create()
- .PageSize(550, 250)
- .ProduceImages()
- .ShowResults()
- .Render(container =>
- {
- //var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec odio ipsum, aliquam a neque a, lacinia vehicula lectus.";
- //var arabic = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا الواجب والعمل سنتنازل غالباً ونرفض الشعور";
-
- var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
- var arabic = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا";
-
- var text = arabic;
- var metrics = textPaint.FontMetrics;
-
- container
- .Padding(25)
- .Canvas((canvas, space) =>
- {
- canvas.Translate(0, 20);
-
- var width = MeasureText(text, textPaint);
- var widthReal = textPaint.MeasureText(text);
- canvas.DrawRect(0, metrics.Descent, width, metrics.Ascent - metrics.Descent, backgroundPaint);
-
- canvas.DrawShapedText(text, 0, 0, textPaint);
-
- canvas.Translate(0, 40);
- canvas.DrawText(text, 0, 0, textPaint);
- });
- });
- }
-
- float MeasureText(string text, SKPaint paint)
- {
- var font = paint.ToFont();
- using var shaper = new SKShaper(paint.Typeface);
- var result = shaper.Shape(text + " ", paint);
- return Math.Max(result.Points.First().X, result.Points.Last().X);
- var glyphCount = result.Codepoints.Length;
- var glyphIds = new ushort[glyphCount];
- var glyphWidths = new float[glyphCount];
- var glyphBounds = new SKRect[glyphCount];
-
- font.GetGlyphs(result.Codepoints.Select(x => (int)x).ToArray(), glyphIds);
- font.GetGlyphWidths(glyphIds, glyphWidths, glyphBounds);
- return glyphWidths.Sum();
-
- return result.Points.Max(p => p.X);
- using var skTextBlobBuilder = new SKTextBlobBuilder();
- var positionedRunBuffer = skTextBlobBuilder.AllocatePositionedRun(font, result.Codepoints.Length);
- var glyphSpan = positionedRunBuffer.GetGlyphSpan();
- var positionSpan = positionedRunBuffer.GetPositionSpan();
-
- for (int index = 0; index < result.Codepoints.Length; ++index)
- {
- glyphSpan[index] = (ushort) result.Codepoints[index];
- positionSpan[index] = result.Points[index];
- }
- using var text1 = skTextBlobBuilder.Build();
- return text1.Bounds.Width;
- }
-
- [Test]
- public void ShapeSingle()
- {
- using var textPaint = new SKPaint
- {
- Color = SKColors.Black,
- Typeface = SKTypeface.CreateDefault(),
- IsAntialias = true,
- TextSize = 20
- };
- var text = string.Join(" ", Enumerable.Range(0, 10_000).Select(x => Placeholders.Sentence()));
-
- using var shaper = new SKShaper(textPaint.Typeface);
- var result = shaper.Shape(text + " ", textPaint);
- }
-
- [Test]
- public void ShapeMany()
- {
- using var textPaint = new SKPaint
- {
- Color = SKColors.Black,
- Typeface = SKTypeface.CreateDefault(),
- IsAntialias = true,
- TextSize = 20
- };
- var text = string.Join(" ", Enumerable.Range(0, 1_000).Select(x => Placeholders.Sentence()));
-
- foreach (var part in Regex.Split(text, "( )|(\\w+)"))
- {
- using var shaper = new SKShaper(textPaint.Typeface);
- var result = shaper.Shape(part + " ", textPaint);
- }
- }
-
- [Test]
- public void ShapeMany2()
- {
- using var textPaint = new SKPaint
- {
- Color = SKColors.Black,
- Typeface = SKTypeface.CreateDefault(),
- IsAntialias = true,
- TextSize = 20
- };
- using var shaper = new SKShaper(textPaint.Typeface);
-
- foreach (var i in Enumerable.Range(0, 10_000))
- {
- var text = Placeholders.Paragraph();
- textPaint.MeasureText(text);
- var result = shaper.Shape(text + " ", textPaint);
- }
- }
- }
- }
|