使用Type1字体|的文本渲染| Aspose.Font for .NET
Contents
[
Hide
Show
]渲染文字
要使用字形轮廓渲染器呈现文本,请实现 Aspose.Font.Rendering.IGlyphOutlinePainter 接口,并使用它为各个字形构建路径。
- 创建一个接受
System.Drawing.Drawing2D.GraphicsPath的Type1GlyphOutlinePainter类。该类的方法将字体轮廓命令转换为路径中的直线和贝塞尔曲线。
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 文件。该方法执行以下操作:
- 将文本中的每个字符解码为字形 ID。
- 创建一个 300 DPI、960 × 720 的位图,填充背景并启用高质量平滑处理。
- 对于每个字形,将前一个字形的前进宽度和字偶距值添加到其水平位置。
- 为当前字形创建
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}调用文本渲染功能
以下示例从 DataDir 加载 Type1/courier.pfb,使用两种配色渲染相同的文本,并将两个 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);