Rendu de texte à l'aide de la police TrueType | Java
Contents
[
Hide
Show
]Rendu du texte
Afin de restituer le texte, le sous-système de rendu nécessite l’implémentation de l’interface Aspose.Font.Rendering.IGlyphOutlinePainter pour dessiner le glyphe. Ceci peut être réalisé en suivant les étapes suivantes.
- Créez la méthode
DrawText()qui dessine le texte spécifié dans l’objet System.Drawing.Bitmap et enregistre le bitmap résultant sur le disque. Cela comprendra les étapes suivantes :
- Itérer tous les symboles dans la chaîne de texte.
- Obtenez l’identifiant de glyphe pour chaque symbole traité - gid.
- Créez un objet de type GlyphOutlinePainter qui est requis par le sous-système de rendu pour dessiner le glyphe actuel.
- Créez un objet de type Aspose.Font.Renderers.GlyphOutlineRenderer et transmettez l’objet de type GlyphOutlinePainter que vous venez de créer dans le constructeur de GlyphOutlineRenderer. Cet objet GlyphOutlineRenderer était destiné à restituer le glyphe spécifié.
- Rendre le glyphe traité actuel à l’aide de la méthode GlyphOutlineRenderer.RenderGlyph(). L’objet Aspose.Fonts.Matrix est utilisé pour spécifier les coordonnées du glyphe. Le glyphe à restituer est spécifié par le paramètre gid.
Étapes auxiliaires pour cette stratégie
- La coordonnée du glyphe pour l’axe ‘Y’ est constante pour cet extrait de code.
- Les coordonnées du glyphe pour l’axe ‘X’ sont calculées pour chaque glyphe traité.
- Les coordonnées ‘X’ et ‘Y’ sont transmises à l’objet Aspose.Fonts.Matrix qui est utilisé par GlyphOutlineRenderer pour dessiner un glyphe.
- La distance entre les glyphes qui viennent d’être traités et les glyphes précédents est calculée à chaque étape d’itération. Cette distance affecte chaque coordonnée ‘X’ de glyphe.
- L’objet de type GlyphOutlinePainter dessine le glyphe à l’aide de GlyphOutlinePainter non pas directement dans Bitmap, mais dans l’objet GraphicsPath, qui a été passé au constructeur pour GlyphOutlinePainter, nous utilisons donc un objet de type System.Drawing.Graphics pour dessiner GraphicsPath dans Bitmap.
- Méthode FontWidthToImageWith() qui calcule la largeur du glyphe pour le système de coordonnées bitmap.
L’implémentation de la méthode DrawText est comme indiqué ci-dessous.
1private static final class GlyphOutlinePainter implements IGlyphOutlinePainter {
2 private final GeneralPath path;
3
4 private GlyphOutlinePainter(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 GlyphOutlinePainter(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}- créer une méthode utilitaire pour calculer la largeur de la police par rapport à la largeur de l’image, comme indiqué dans l’exemple de code ci-dessous
1private static double fontWidthToImageWidth(double width, int fontSourceResolution,
2 double fontSize, double dpi) {
3 return width / fontSourceResolution * fontSize * (dpi / 72);
4}Appel de la fonctionnalité Rendu du texte
Pour utiliser les implémentations ci-dessus, l’exemple de code suivant peut être exécuté à partir de la méthode Main d’une application basée sur console.
1String firstFontPath = Paths.get(getDataDir(), "..", "TTF", "montserrat-bold.ttf")
2 .normalize().toString();
3String secondFontPath = Paths.get(getDataDir(), "..", "TTF", "LatoWeb-Regular.ttf")
4 .normalize().toString();
5TtfFont firstFont = (TtfFont) Font.open(new FontDefinition(FontType.TTF,
6 new FontFileDefinition("ttf", new FileSystemStreamSource(firstFontPath))));
7TtfFont secondFont = (TtfFont) Font.open(new FontDefinition(FontType.TTF,
8 new FontFileDefinition("ttf", new FileSystemStreamSource(secondFontPath))));
9
10String firstOutput = Paths.get(getOutputDir(), "hello1_montserrat_out.png").toString();
11String secondOutput = Paths.get(getOutputDir(), "hello2_lato_out.png").toString();
12drawText("Hello world", firstFont, 14, Color.WHITE, Color.BLACK, firstOutput);
13drawText("Hello world", secondFont, 14, Color.YELLOW, Color.RED, secondOutput);