From 1c8b8ec4fc27afedc98f25c0992a34ef57ccb409 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Thu, 25 Feb 2021 13:40:11 +0000 Subject: [PATCH] FOP-3000: Absolute positioning wrong with AFP TTF git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1886917 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/render/afp/AFPPainter.java | 6 +-- .../org/apache/fop/render/afp/AFPParser.java | 7 ++- .../fop/render/afp/AFPTrueTypeTestCase.java | 44 +++++++++++++++++-- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java index a0ca446f4..35235668a 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java @@ -1025,7 +1025,7 @@ public class AFPPainter extends AbstractIFPainter { builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement); boolean fixedSpaceMode = false; - int ttPos = p.x; + double ttPos = p.x; for (int i = 0; i < l; i++) { char orgChar = text.charAt(i); @@ -1066,8 +1066,8 @@ public class AFPPainter extends AbstractIFPainter { if (afpFont.getFontType() == FontType.TRUETYPE) { flushText(builder, sb, charSet); - ttPos += Math.round(unitConv.mpt2units(glyphAdjust)); - builder.absoluteMoveInline(ttPos); + ttPos += unitConv.mpt2units(glyphAdjust); + builder.absoluteMoveInline((int) Math.round(ttPos)); } else if (glyphAdjust != 0) { flushText(builder, sb, charSet); int increment = Math.round(unitConv.mpt2units(glyphAdjust)); diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPParser.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPParser.java index 12c2f55cc..e3705271a 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPParser.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPParser.java @@ -31,6 +31,7 @@ import org.apache.fop.afp.ptoca.PtocaBuilder; public class AFPParser { private boolean readText; + protected boolean readWidths; public AFPParser(boolean readText) { this.readText = readText; } @@ -82,7 +83,11 @@ public class AFPParser { sb.append(" " + PTOCA_MAP.get(functionType)); - if ("TRN".equals(PTOCA_MAP.get(functionType))) { + if (readWidths && "AMI".equals(PTOCA_MAP.get(functionType))) { + byte[] data = new byte[len - 2]; + bis.read(data); + sb.append(" ").append(data[1] & 0xFF); + } else if ("TRN".equals(PTOCA_MAP.get(functionType))) { byte[] data = new byte[len - 2]; bis.read(data); sb.append(" " + new String(data, "UTF-16BE")); diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPTrueTypeTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPTrueTypeTestCase.java index f7980ac4e..0dfbd1a46 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPTrueTypeTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPTrueTypeTestCase.java @@ -238,8 +238,35 @@ public class AFPTrueTypeTestCase { sb.toString().contains("DATA PRESENTATION_TEXT AMB AMI SCFL TRN t TRN e TRN s TRN t")); } + @Test + public void testAFPPainterWidths() throws IFException, IOException { + AFPDocumentHandler afpDocumentHandler = mock(AFPDocumentHandler.class); + when(afpDocumentHandler.getPaintingState()).thenReturn(new AFPPaintingState()); + when(afpDocumentHandler.getResourceManager()).thenReturn(new AFPResourceManager(null)); + + DataStream ds = mock(DataStream.class); + when(afpDocumentHandler.getDataStream()).thenReturn(ds); + PageObject po = new PageObject(new Factory(), "PAGE0001", 0, 0, 0, 0, 0); + when(ds.getCurrentPage()).thenReturn(po); + + AFPPainter afpPainter = new MyAFPPainter(afpDocumentHandler); + afpPainter.setFont("any", "normal", 400, null, 12000, Color.BLACK); + afpPainter.drawText(0, 0, 0, 0, null, "abcdefghijklmno"); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + po.writeToStream(bos); + InputStream bis = new ByteArrayInputStream(bos.toByteArray()); + StringBuilder sb = new StringBuilder(); + AFPParser afpParser = new AFPParser(true); + afpParser.readWidths = true; + afpParser.read(bis, sb); + Assert.assertTrue(sb.toString(), sb.toString().contains("DATA PRESENTATION_TEXT AMB AMI 0 SCFL SVI TRN a AMI" + + " 9 TRN b AMI 29 TRN c AMI 59 TRN d AMI 99 TRN e AMI 149 TRN f AMI 209 TRN g AMI 24 TRN h AMI 105 TRN" + + " i AMI 196 TRN j AMI 42 TRN k AMI 153 TRN l AMI 19 TRN m AMI 151 TRN n AMI 38 TRN o AMI 190")); + } + class MyAFPPainter extends AFPPainter { - public MyAFPPainter(AFPDocumentHandler documentHandler) { + MyAFPPainter(AFPDocumentHandler documentHandler) { super(documentHandler); } @@ -251,8 +278,19 @@ public class AFPTrueTypeTestCase { protected FontInfo getFontInfo() { FontInfo f = new FontInfo(); f.addFontProperties("any", FontTriplet.DEFAULT_FONT_TRIPLET); - MultiByteFont font = new MultiByteFont(null, EmbeddingMode.AUTO); - font.setWidthArray(new int[100]); + MultiByteFont font = new MultiByteFont(null, EmbeddingMode.AUTO) { + public void setWidthArray(int[] wds) { + super.setWidthArray(wds); + for (int i = 'a'; i <= 'z'; i++) { + addPrivateUseMapping(i, i); + } + } + }; + int[] widths = new int[200]; + for (int i = 0; i < widths.length; i++) { + widths[i] = 1000 + (i * 256); + } + font.setWidthArray(widths); f.addMetrics("any", new AFPFontConfig.AFPTrueTypeFont("", true, new FopCharacterSet("", "UTF-16BE", "", font, null, null), null, null, null)); return f; -- 2.39.5