Text Rendering using Type1 Font | .NET
Contents
[
Hide
Show
]Rendering Text
In order to render text, the Rendering subsystem requires the implementation of Aspose.Font.Rendering.IGlyphOutlinePainter interface to draw glyph. This can be achieved using the following steps.
- Implement the IGlyphOutlinePainter methods by creating a class GlyphOutlinePainter which requires object of type System.Drawing.Drawing2D.GraphicsPath for graphic drawing objectives. The implementation is as illustrated below.
1// For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-.NET
2class GlyphOutlinePainter : IGlyphOutlinePainter
3{
4 private System.Drawing.Drawing2D.GraphicsPath _path;
5 private System.Drawing.PointF _currentPoint;
6
7 public GlyphOutlinePainter(System.Drawing.Drawing2D.GraphicsPath path)
8 {
9 _path = path;
10 }
11
12 public void MoveTo(MoveTo moveTo)
13 {
14 _path.CloseFigure();
15 _currentPoint.X = (float)moveTo.X;
16 _currentPoint.Y = (float)moveTo.Y;
17 }
18
19 public void LineTo(LineTo lineTo)
20 {
21 float x = (float)lineTo.X;
22 float y = (float)lineTo.Y;
23 _path.AddLine(_currentPoint.X, _currentPoint.Y, x, y);
24 _currentPoint.X = x;
25 _currentPoint.Y = y;
26 }
27
28 public void CurveTo(CurveTo curveTo)
29 {
30 float x3 = (float)curveTo.X3;
31 float y3 = (float)curveTo.Y3;
32
33 _path.AddBezier(
34 _currentPoint.X,
35 _currentPoint.Y,
36 (float)curveTo.X1,
37 (float)curveTo.Y1,
38 (float)curveTo.X2,
39 (float)curveTo.Y2,
40 x3,
41 y3);
42
43 _currentPoint.X = x3;
44 _currentPoint.Y = y3;
45 }
46
47 public void ClosePath()
48 {
49 _path.CloseFigure();
50 }
51}
- Create method
DrawText()
which draws specified text into System.Drawing.Bitmap object and saves resultant bitmap on Disc. This will include the following steps:
- Iterate all symbols in text string.
- Get glyph identifier for every processed symbol - gid.
- Create object of type GlyphOutlinePainter which is required by rendering subsystem to draw current glyph.
- Create object of type Aspose.Font.Renderers.GlyphOutlineRenderer, and pass just created object of type GlyphOutlinePainter into constructor for GlyphOutlineRenderer. This object GlyphOutlineRenderer intended to render specified glyph.
- Render current processed glyph using method GlyphOutlineRenderer.RenderGlyph(). Aspose.Fonts.Matrix object is used to specify glyph coordinates. Glyph to render is specified by gid parameter.
Auxillary steps for this strategy
- Glyph coordinate for ‘Y’ axis is constant for this code snippet.
- Glyph coordinate for ‘X’ axis is calculated for every processed glyph.
- Both ‘X’ and ‘Y’ coordinates are passed into object Aspose.Fonts.Matrix which is used by GlyphOutlineRenderer to draw glyph.
- Distance between just processed and previous glyphs is calculated on every iteration step. This distance affects every glyph ‘X’ coordinate.
- Object of type GlyphOutlinePainter draws glyph with the help of GlyphOutlinePainter not into Bitmap directly, but into object GraphicsPath, which was passed into constructor for GlyphOutlinePainter, so we use object of type System.Drawing.Graphics to draw GraphicsPath into Bitmap.
- Method FontWidthToImageWith() which calculates glyph width for bitmap coordinate system.
Implementation of DrawText
method is as shown below.
1// For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-.NET
2static void DrawText(string text, IFont font, double fontSize,
3 Brush backgroundBrush, Brush textBrush, string outFile)
4{
5 //Get glyph identifiers for every symbol in text line
6 GlyphId[] gids = new GlyphId[text.Length];
7 for (int i = 0; i < text.Length; i++)
8 gids[i] = font.Encoding.DecodeToGid(text[i]);
9 // set common drawing settings
10 double dpi = 300;
11
12 double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
13 // prepare output bitmap
14 Bitmap outBitmap = new Bitmap(960, 720);
15 outBitmap.SetResolution((float)dpi, (float)dpi);
16 Graphics outGraphics = Graphics.FromImage(outBitmap);
17 outGraphics.FillRectangle(backgroundBrush, 0, 0, outBitmap.Width, outBitmap.Height);
18 outGraphics.SmoothingMode = SmoothingMode.HighQuality;
19 //declare coordinate variables and previous gid
20 GlyphId previousGid = null;
21 double glyphXCoordinate = 0;
22 double glyphYCoordinate = fontSize * resolutionCorrection;
23 //loop which paints every glyph in gids
24 foreach (GlyphId gid in gids)
25 {
26 // if the font contains the gid
27 if (gid != null)
28 {
29 Glyph glyph = font.GlyphAccessor.GetGlyphById(gid);
30 if (glyph == null)
31 continue;
32
33 // path that accepts drawing instructions
34 GraphicsPath path = new GraphicsPath();
35
36 // Create IGlyphOutlinePainter implementation
37 GlyphOutlinePainter outlinePainter = new GlyphOutlinePainter(path);
38
39 // Create the renderer
40 Aspose.Font.Renderers.IGlyphRenderer renderer = new
41 Aspose.Font.Renderers.GlyphOutlineRenderer(outlinePainter);
42
43 // get common glyph properties
44 double kerning = 0;
45
46 // get kerning value
47 if (previousGid != null)
48 {
49 kerning = (font.Metrics.GetKerningValue(previousGid, gid) /
50 glyph.SourceResolution) * fontSize * resolutionCorrection;
51 kerning += FontWidthToImageWith(font.Metrics.GetGlyphWidth(previousGid),
52 glyph.SourceResolution, fontSize);
53 }
54
55 // glyph positioning - increase glyph X coordinate according to kerning distance
56 glyphXCoordinate += kerning;
57
58 // Glyph placement matrix
59 TransformationMatrix glyphMatrix =
60 new TransformationMatrix(
61 new double[]
62 {
63 fontSize*resolutionCorrection,
64 0,
65 0,
66 // negative because of bitmap coordinate system begins from the top
67 - fontSize*resolutionCorrection,
68 glyphXCoordinate,
69 glyphYCoordinate
70 });
71
72 // render current glyph
73 renderer.RenderGlyph(font, gid, glyphMatrix);
74 // fill the path
75 path.FillMode = FillMode.Winding;
76 outGraphics.FillPath(textBrush, path);
77 }
78 //set current gid as previous to get correct kerning for next glyph
79 previousGid = gid;
80 }
81 //Save results
82 outBitmap.Save(outFile);
83}
- Create utility method to calculate font width to image width as shown in the code sample below
1// For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-.NET
2static double FontWidthToImageWith(double width, int fontSourceResulution, double fontSize, double dpi = 300)
3{
4 double resolutionCorrection = dpi / 72; // 72 is font's internal dpi
5 return (width / fontSourceResulution) * fontSize * resolutionCorrection;
6}
Calling the Rendering Text functionality
To use the above implementations, the following sample code can be executed from the Main method of a console based application.
1// For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-.NET
2string fileName = dataDir + "courier.pfb"; //Font file name with full path
3
4FontDefinition fd = new FontDefinition(FontType.Type1, new FontFileDefinition("pfb", new FileSystemStreamSource(fileName)));
5Type1Font font = Aspose.Font.Font.Open(fd) as Type1Font;
6
7
8DrawText("Hello world", font, 14, Brushes.White, Brushes.Black, dataDir + "hello1_type1_out.jpg");
9DrawText("Hello world", font, 14, Brushes.Yellow, Brushes.Red, dataDir + "hello2_type1_out.jpg");