Text Rendering using Type1 Font | .NET
Contents
[
Hide
Show
]Rendering Text
To render text with the glyph outline renderer, implement the Aspose.Font.Rendering.IGlyphOutlinePainter interface and use it to build paths for individual glyphs.
- Create a
Type1GlyphOutlinePainterclass that accepts aSystem.Drawing.Drawing2D.GraphicsPath. Its methods translate the font outline commands into lines and Bézier curves in that path.
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}- Create a
DrawText()method that draws text into aSystem.Drawing.Bitmapand saves it as a PNG file. The method performs the following operations:
- Decode every character in the text into a glyph ID.
- Create a 960 × 720 bitmap at 300 DPI, fill its background, and enable high-quality smoothing.
- For each glyph, add the previous glyph’s advance width and the pair kerning value to its horizontal position.
- Create a
GraphicsPath, aType1GlyphOutlinePainter, and aGlyphOutlineRendererfor the current glyph. - Use a
TransformationMatrixto scale and position the glyph, then fill the resulting path with the requested text brush. - Save the bitmap explicitly as PNG. The bitmap, graphics object, and glyph paths are disposed after use.
The glyph baseline remains constant in this example. The horizontal coordinate is accumulated from the previous glyph’s advance and kerning. FontWidthToImageWidth() converts font units to bitmap pixels using the source resolution, font size, and DPI.
The implementation of DrawText() is shown below.
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}- Add the utility method that converts a width in font units to image pixels.
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}Calling the Rendering Text functionality
The following example loads Type1/courier.pfb from DataDir, renders the same text with two color schemes, and writes both PNG files to 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);