]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3042: SVG text containing certain glyphs isn't rendered by Dave Roxburgh
authorSimon Steiner <ssteiner@apache.org>
Tue, 11 Jul 2023 12:02:18 +0000 (13:02 +0100)
committerSimon Steiner <ssteiner@apache.org>
Tue, 11 Jul 2023 12:02:18 +0000 (13:02 +0100)
fop-core/src/main/java/org/apache/fop/svg/PDFTextPainter.java
fop-core/src/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java

index e46642892d26890d1c764a987d8b5ff0e58448dc..301af20703900593a13fe49266a4a187f621575c 100644 (file)
@@ -118,32 +118,30 @@ class PDFTextPainter extends NativeTextPainter {
             String fk = gvtFont.getFontKey();
             Font f = gvtFont.getFont();
             Point2D initialPos = gv.getGlyphPosition(0);
-            if (f.isMultiByte()) {
-                int         fs              = f.getFontSize();
-                float       fsPoints        = fs / 1000f;
-                double      xc              = 0f;
-                double      yc              = 0f;
-                double      xoLast          = 0f;
-                double      yoLast          = 0f;
-                textUtil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, initialPos.getX(), initialPos.getY()));
-                textUtil.updateTf(fk, fsPoints, true, false);
-                int[][] dp = gv.getGlyphPositionAdjustments();
-                for (int i = 0, n = gv.getNumGlyphs(); i < n; i++) {
-                    int     gc              = gv.getGlyphCode(i);
-                    int[]   pa              = ((i > dp.length) || (dp[i] == null)) ? paZero : dp[i];
-                    double  xo              = xc + pa[0];
-                    double  yo              = yc + pa[1];
-                    double  xa              = f.getWidth(gc);
-                    double  ya              = 0;
-                    double  xd              = (xo - xoLast) / 1000f;
-                    double  yd              = (yo - yoLast) / 1000f;
-                    textUtil.writeTd(xd, yd);
-                    textUtil.writeTj((char) gc, true, false);
-                    xc += xa + pa[2];
-                    yc += ya + pa[3];
-                    xoLast = xo;
-                    yoLast = yo;
-                }
+            int         fs              = f.getFontSize();
+            float       fsPoints        = fs / 1000f;
+            double      xc              = 0f;
+            double      yc              = 0f;
+            double      xoLast          = 0f;
+            double      yoLast          = 0f;
+            textUtil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, initialPos.getX(), initialPos.getY()));
+            textUtil.updateTf(fk, fsPoints, f.isMultiByte(), false);
+            int[][] dp = gv.getGlyphPositionAdjustments();
+            for (int i = 0, n = gv.getNumGlyphs(); i < n; i++) {
+                int     gc              = gv.getGlyphCode(i);
+                int[]   pa              = ((i > dp.length) || (dp[i] == null)) ? paZero : dp[i];
+                double  xo              = xc + pa[0];
+                double  yo              = yc + pa[1];
+                double  xa              = f.getWidth(gc);
+                double  ya              = 0;
+                double  xd              = (xo - xoLast) / 1000f;
+                double  yd              = (yo - yoLast) / 1000f;
+                textUtil.writeTd(xd, yd);
+                textUtil.writeTj((char) gc, f.isMultiByte(), false);
+                xc += xa + pa[2];
+                yc += ya + pa[3];
+                xoLast = xo;
+                yoLast = yo;
             }
         }
     }
index 3e64cb58f8353528d9c272fe99caa3e002b85a43..317e969d2f5281d8b44e7d4b96f3741c4f72b61e 100644 (file)
 package org.apache.fop.svg;
 
 import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
 import java.io.StringWriter;
 
+import org.junit.Assert;
 import org.junit.Test;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import org.apache.batik.bridge.TextPainter;
+import org.apache.batik.gvt.text.TextPaintInfo;
 
 import org.apache.xmlgraphics.java2d.GraphicContext;
 
+import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.base14.Base14FontCollection;
 import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.svg.font.FOPGVTFont;
+import org.apache.fop.svg.font.FOPGVTGlyphVector;
 
 public class PDFTextPainterTestCase extends NativeTextPainterTest {
 
@@ -145,4 +158,48 @@ public class PDFTextPainterTestCase extends NativeTextPainterTest {
                 .addOperatorMatch("TJ", "[(IJ)] TJ\n"));
     }
 
+    /**
+     * Tests that glyph vectors in single-byte fonts with glyph position adjustments are properly written.
+     * @throws Exception
+     */
+    @Test
+    public void testSingleByteAdjustments() throws Exception {
+        FontInfo fontInfo = new FontInfo();
+        new Base14FontCollection(true).setup(0, fontInfo);
+
+        PDFTextPainter painter = new PDFTextPainter(fontInfo);
+        PDFGraphics2D g2d = mock(PDFGraphics2D.class);
+        g2d.currentStream = new StringWriter();
+        painter.preparePainting(g2d);
+        painter.setInitialTransform(new AffineTransform());
+        TextPaintInfo tpi = new TextPaintInfo();
+        tpi.visible = true;
+        painter.tpi = tpi;
+        painter.beginTextObject();
+
+        FOPGVTGlyphVector mockGV = mock(FOPGVTGlyphVector.class);
+        FontTriplet triplet = new FontTriplet("Times", "normal", 400);
+        Font font = fontInfo.getFontInstance(triplet, 12);
+
+        FOPGVTFont mockGvtFont = mock(FOPGVTFont.class);
+        org.apache.fop.fonts.FontMetrics fontMetrics = font.getFontMetrics();
+        when(mockGvtFont.getFont()).thenReturn(new Font("Times", triplet, fontMetrics, 12));
+        when(mockGvtFont.getFontKey()).thenReturn("Times");
+
+        when(mockGV.getFont()).thenReturn(mockGvtFont);
+        when(mockGV.getGlyphPositionAdjustments()).thenReturn(new int[][] {{2, 3, 4, 5}, {6, 7, 8, 9}});
+        when(mockGV.getGlyphPosition(0)).thenReturn(new Point(0, 0));
+        when(mockGV.getNumGlyphs()).thenReturn(1);
+        when(mockGV.getGlyphCode(0)).thenReturn(1);
+
+        GeneralPath gp = new GeneralPath();
+
+        painter.writeGlyphs(mockGV, gp);
+        Assert.assertEquals("BT\n"
+                        + "3 Tr\n"
+                        + "1 0 0 -1 0 0 Tm /Times 0.012 Tf\n"
+                        + "0.002 0.003 Td\n"
+                        + "(\\1) Tj\n",
+                g2d.currentStream.toString());
+    }
 }