Rendering di testo utilizzando il carattere Type1 | .NET

Rendering Testo

Per eseguire il rendering del testo con il renderer dei contorni dei glifi, implementare l’interfaccia Aspose.Font.Rendering.IGlyphOutlinePainter e usarla per creare i tracciati dei singoli glifi.

  1. Creare una classe Type1GlyphOutlinePainter che accetti un System.Drawing.Drawing2D.GraphicsPath. I suoi metodi trasformano i comandi del contorno del font in linee e curve di Bézier nel tracciato.
 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}
  1. Creare un metodo DrawText() che disegni il testo in un System.Drawing.Bitmap e lo salvi come file PNG. Il metodo esegue le operazioni seguenti:

In questo esempio la linea di base resta costante. La coordinata orizzontale accumula l’avanzamento e la crenatura del glifo precedente. FontWidthToImageWidth() converte le unità del font in pixel usando la risoluzione sorgente, la dimensione del font e i DPI.

L’implementazione di DrawText() è illustrata di seguito.

 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. Aggiungere il metodo di utilità che converte una larghezza espressa in unità del font in pixel dell’immagine.
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}

Chiamata della funzionalità di rendering del testo

L’esempio seguente carica Type1/courier.pfb da DataDir, esegue il rendering dello stesso testo con due combinazioni di colori e scrive entrambi i file PNG in 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);