Textwiedergabe mit Type1-Schriftart | Java
Contents
[
Hide
Show
]Text rendern
Zum Rendern von Text erfordert das Rendering-Subsystem die Implementierung der Schnittstelle Aspose.Font.Rendering.IGlyphOutlinePainter zum Zeichnen von Glyphen. Dies kann mit den folgenden Schritten erreicht werden.
- Erstellen Sie die Methode „DrawText()“, die den angegebenen Text in das System.Drawing.Bitmap-Objekt zeichnet und die resultierende Bitmap auf der Disc speichert. Dies umfasst die folgenden Schritte:
- Iterieren Sie alle Symbole in der Textzeichenfolge.
- Glyphen-ID für jedes verarbeitete Symbol abrufen – GID.
- Erstellen Sie ein Objekt vom Typ GlyphOutlinePainter, das vom Rendering-Subsystem zum Zeichnen der aktuellen Glyphe benötigt wird.
- Erstellen Sie ein Objekt vom Typ Aspose.Font.Renderers.GlyphOutlineRenderer und übergeben Sie das gerade erstellte Objekt vom Typ GlyphOutlinePainter an den Konstruktor für GlyphOutlineRenderer. Dieses Objekt GlyphOutlineRenderer soll die angegebene Glyphe rendern.
- Rendern Sie das aktuell verarbeitete Glyph mit der Methode GlyphOutlineRenderer.RenderGlyph(). Das Aspose.Fonts.Matrix-Objekt wird zum Angeben von Glyphenkoordinaten verwendet. Die zu rendernde Glyphe wird durch den GID-Parameter angegeben.
Hilfsschritte für diese Strategie
- Die Glyphenkoordinate für die Y-Achse ist für dieses Codefragment konstant.
- Die Glyphenkoordinate für die X-Achse wird für jede verarbeitete Glyphe berechnet.
- Sowohl die X- als auch die Y-Koordinaten werden an das Objekt Aspose.Fonts.Matrix übergeben, das von GlyphOutlineRenderer zum Zeichnen von Glyphen verwendet wird.
- Der Abstand zwischen gerade verarbeiteten und vorherigen Glyphen wird bei jedem Iterationsschritt berechnet. Dieser Abstand wirkt sich auf jede Glyphen-X-Koordinate aus.
- Ein Objekt vom Typ GlyphOutlinePainter zeichnet Glyphen mithilfe von GlyphOutlinePainter nicht direkt in Bitmap, sondern in das Objekt GraphicsPath, das an den Konstruktor für GlyphOutlinePainter übergeben wurde. Daher verwenden wir ein Objekt vom Typ System.Drawing.Graphics, um GraphicsPath in Bitmap zu zeichnen.
- Methode FontWidthToImageWith(), die die Glyphenbreite für das Bitmap-Koordinatensystem berechnet.
Die Implementierung ist wie unten dargestellt.
1private static final class Type1GlyphOutlinePainter implements IGlyphOutlinePainter {
2 private final GeneralPath path;
3
4 private Type1GlyphOutlinePainter(GeneralPath path) {
5 this.path = path;
6 }
7
8 @Override
9 public void moveTo(MoveTo moveTo) {
10 path.moveTo(moveTo.getX(), moveTo.getY());
11 }
12
13 @Override
14 public void lineTo(LineTo lineTo) {
15 path.lineTo(lineTo.getX(), lineTo.getY());
16 }
17
18 @Override
19 public void curveTo(CurveTo curveTo) {
20 path.curveTo(curveTo.getX1(), curveTo.getY1(), curveTo.getX2(), curveTo.getY2(),
21 curveTo.getX3(), curveTo.getY3());
22 }
23
24 @Override
25 public void closePath() {
26 path.closePath();
27 }
28} 1private static void drawText(String text, IFont font, double fontSize,
2 Paint backgroundBrush, Paint textBrush, String outputFile) throws IOException {
3 GlyphId[] glyphIds = new GlyphId[text.length()];
4 for (int i = 0; i < text.length(); i++) {
5 glyphIds[i] = font.getEncoding().decodeToGid(text.charAt(i));
6 }
7 double dpi = 300;
8 double resolutionCorrection = dpi / 72;
9 BufferedImage outputBitmap = new BufferedImage(960, 720, BufferedImage.TYPE_INT_RGB);
10 Graphics2D graphics = outputBitmap.createGraphics();
11 try {
12 graphics.setPaint(backgroundBrush);
13 graphics.fillRect(0, 0, outputBitmap.getWidth(), outputBitmap.getHeight());
14 graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
15 GlyphId previousGlyphId = null;
16 double glyphXCoordinate = 0;
17 double glyphYCoordinate = fontSize * resolutionCorrection;
18 for (GlyphId glyphId : glyphIds) {
19 if (glyphId == null) {
20 continue;
21 }
22 Glyph glyph = font.getGlyphAccessor().getGlyphById(glyphId);
23 if (glyph == null) {
24 continue;
25 }
26 if (previousGlyphId != null) {
27 double kerning = font.getMetrics().getKerningValue(previousGlyphId, glyphId)
28 / glyph.getSourceResolution() * fontSize * resolutionCorrection;
29 double advance = fontWidthToImageWidth(font.getMetrics().getGlyphWidth(previousGlyphId),
30 glyph.getSourceResolution(), fontSize, dpi);
31 glyphXCoordinate += kerning + advance;
32 }
33 GeneralPath path = new GeneralPath();
34 IGlyphRenderer renderer = new GlyphOutlineRenderer(new Type1GlyphOutlinePainter(path));
35 TransformationMatrix matrix = new TransformationMatrix(new double[] {
36 fontSize * resolutionCorrection, 0, 0, -fontSize * resolutionCorrection,
37 glyphXCoordinate, glyphYCoordinate
38 });
39 renderer.renderGlyph(font, glyphId, matrix);
40 path.setWindingRule(GeneralPath.WIND_NON_ZERO);
41 graphics.setPaint(textBrush);
42 graphics.fill(path);
43 previousGlyphId = glyphId;
44 }
45 } finally {
46 graphics.dispose();
47 }
48 if (!ImageIO.write(outputBitmap, "png", new File(outputFile))) {
49 throw new IOException("No PNG writer is available.");
50 }
51}- Erstellen Sie eine Dienstprogrammmethode, um die Schriftbreite in die Bildbreite umzurechnen, wie im folgenden Codebeispiel gezeigt
1private static double fontWidthToImageWidth(double width, int fontSourceResolution,
2 double fontSize, double dpi) {
3 return width / fontSourceResolution * fontSize * (dpi / 72);
4}Aufrufen der Funktion „Text rendern“.
Um die oben genannten Implementierungen zu verwenden, kann der folgende Beispielcode über die Main-Methode einer konsolenbasierten Anwendung ausgeführt werden.
1String fileName = Paths.get(getDataDir(), "..", "Type1", "courier.pfb").normalize().toString();
2FontDefinition fd = new FontDefinition(FontType.Type1,
3 new FontFileDefinition("pfb", new FileSystemStreamSource(fileName)));
4Type1Font font = (Type1Font) Font.open(fd);
5
6String firstOutput = Paths.get(getOutputDir(), "hello1_type1_out.png").toString();
7String secondOutput = Paths.get(getOutputDir(), "hello2_type1_out.png").toString();
8drawText("Hello world", font, 14, Color.WHITE, Color.BLACK, firstOutput);
9drawText("Hello world", font, 14, Color.YELLOW, Color.RED, secondOutput);