Отрисовка текста с использованием шрифта Type1 | .NET
Contents
[
Hide
Show
]Отрисовка текста
Для отрисовки текста с помощью визуализатора контуров глифов реализуйте интерфейс Aspose.Font.Rendering.IGlyphOutlinePainter и используйте его для построения контуров отдельных глифов.
- Создайте класс
Type1GlyphOutlinePainter, принимающийSystem.Drawing.Drawing2D.GraphicsPath. Его методы преобразуют команды контура шрифта в линии и кривые Безье в этом пути.
1// Implement a painter that builds a graphics path from a glyph outline
2
3internal sealed class Type1GlyphOutlinePainter : IGlyphOutlinePainter
4{
5 private readonly GraphicsPath path;
6 private PointF currentPoint;
7
8 public Type1GlyphOutlinePainter(GraphicsPath path)
9 {
10 this.path = path;
11 }
12
13 public void MoveTo(MoveTo moveTo)
14 {
15 path.CloseFigure();
16 currentPoint = new PointF((float)moveTo.X, (float)moveTo.Y);
17 }
18
19 public void LineTo(LineTo lineTo)
20 {
21 PointF nextPoint = new PointF((float)lineTo.X, (float)lineTo.Y);
22 path.AddLine(currentPoint, nextPoint);
23 currentPoint = nextPoint;
24 }
25
26 public void CurveTo(CurveTo curveTo)
27 {
28 PointF nextPoint = new PointF((float)curveTo.X3, (float)curveTo.Y3);
29 path.AddBezier(
30 currentPoint,
31 new PointF((float)curveTo.X1, (float)curveTo.Y1),
32 new PointF((float)curveTo.X2, (float)curveTo.Y2),
33 nextPoint);
34 currentPoint = nextPoint;
35 }
36
37 public void ClosePath()
38 {
39 path.CloseFigure();
40 }
41}- Создайте метод
DrawText(), который рисует текст вSystem.Drawing.Bitmapи сохраняет его в файл PNG. Метод выполняет следующие операции:
- Преобразует каждый символ текста в идентификатор глифа.
- Создаёт растровое изображение размером 960 × 720 с разрешением 300 DPI, заполняет фон и включает высококачественное сглаживание.
- Для каждого глифа прибавляет к горизонтальной позиции ширину продвижения предыдущего глифа и значение кернинга пары.
- Создаёт
GraphicsPath,Type1GlyphOutlinePainterиGlyphOutlineRendererдля текущего глифа. - Использует
TransformationMatrixдля масштабирования и позиционирования глифа, после чего заполняет контур заданной кистью. - Явно сохраняет изображение в формате PNG. Растровое изображение, графический объект и контуры глифов освобождаются после использования.
Базовая линия в этом примере остаётся постоянной. Горизонтальная координата накапливается из ширины продвижения и кернинга предыдущего глифа. FontWidthToImageWidth() преобразует единицы шрифта в пиксели с учётом исходного разрешения, размера шрифта и DPI.
Реализация DrawText() показана ниже.
1// Render text into a bitmap with a custom glyph outline painter
2
3private static void DrawText(string text, IFont font, double fontSize,
4 Brush backgroundBrush, Brush textBrush, string outputFile)
5{
6 GlyphId[] glyphIds = text
7 .Select(character => font.Encoding.DecodeToGid(character))
8 .ToArray();
9 const double dpi = 300;
10 double resolutionCorrection = dpi / 72;
11
12 using var outputBitmap = new Bitmap(960, 720);
13 outputBitmap.SetResolution((float)dpi, (float)dpi);
14 using Graphics outputGraphics = Graphics.FromImage(outputBitmap);
15 outputGraphics.FillRectangle(backgroundBrush, 0, 0, outputBitmap.Width, outputBitmap.Height);
16 outputGraphics.SmoothingMode = SmoothingMode.HighQuality;
17
18 GlyphId? previousGlyphId = null;
19 double glyphXCoordinate = 0;
20 double glyphYCoordinate = fontSize * resolutionCorrection;
21
22 foreach (GlyphId glyphId in glyphIds)
23 {
24 Glyph glyph = font.GlyphAccessor.GetGlyphById(glyphId);
25 if (glyph == null)
26 continue;
27
28 if (previousGlyphId != null)
29 {
30 double kerning = font.Metrics.GetKerningValue(previousGlyphId, glyphId)
31 / (double)glyph.SourceResolution * fontSize * resolutionCorrection;
32 double advance = FontWidthToImageWidth(
33 font.Metrics.GetGlyphWidth(previousGlyphId),
34 glyph.SourceResolution,
35 fontSize,
36 dpi);
37 glyphXCoordinate += kerning + advance;
38 }
39
40 using var path = new GraphicsPath();
41 var outlinePainter = new Type1GlyphOutlinePainter(path);
42 IGlyphRenderer renderer = new GlyphOutlineRenderer(outlinePainter);
43 var glyphMatrix = new TransformationMatrix(new double[]
44 {
45 fontSize * resolutionCorrection,
46 0,
47 0,
48 -fontSize * resolutionCorrection,
49 glyphXCoordinate,
50 glyphYCoordinate
51 });
52
53 renderer.RenderGlyph(font, glyphId, glyphMatrix);
54 path.FillMode = FillMode.Winding;
55 outputGraphics.FillPath(textBrush, path);
56 previousGlyphId = glyphId;
57 }
58
59 outputBitmap.Save(outputFile, ImageFormat.Png);
60}- Добавьте служебный метод, который преобразует ширину в единицах шрифта в пиксели изображения.
1// Convert a width in font units to pixels
2
3private static double FontWidthToImageWidth(double width, int fontSourceResolution,
4 double fontSize, double dpi = 300)
5{
6 double resolutionCorrection = dpi / 72;
7 return width / fontSourceResolution * fontSize * resolutionCorrection;
8}Вызов функции отрисовки текста
Следующий пример загружает Type1/courier.pfb из DataDir, отображает один и тот же текст в двух цветовых схемах и записывает оба PNG-файла в OutputDir.
1// Load a Type1 font and render text in two color schemes
2
3string fileName = Path.Combine(DataDir, "Type1", "courier.pfb");
4FontDefinition fontDefinition = new FontDefinition(
5 FontType.Type1,
6 new FontFileDefinition("pfb", new FileSystemStreamSource(fileName)));
7
8Type1Font? font = Aspose.Font.Font.Open(fontDefinition) as Type1Font;
9if (font == null)
10 throw new InvalidOperationException("Unable to load the Type1 font.");
11
12string firstOutput = Path.Combine(OutputDir, "hello1_type1_out.png");
13string secondOutput = Path.Combine(OutputDir, "hello2_type1_out.png");
14DrawText("Hello world", font, 14, Brushes.White, Brushes.Black, firstOutput);
15DrawText("Hello world", font, 14, Brushes.Yellow, Brushes.Red, secondOutput);