Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java (original) +++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java Mon Mar 19 08:49:57 2018 @@ -22,6 +22,7 @@ package org.apache.fop.fonts.truetype; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; import java.util.Map; import org.junit.Test; @@ -30,6 +31,7 @@ import static org.junit.Assert.assertEqu import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.fonts.CMapSegment; import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion; /** @@ -45,6 +47,11 @@ public class TTFFileTestCase { protected final TTFFile droidmonoTTFFile; /** The FontFileReader for ttfFile (DroidSansMono) */ protected final FontFileReader droidmonoReader; + /** The truetype font file (AndroidEmoji) fonr non-BMP codepoints */ + protected final TTFFile androidEmojiTTFFile; + /** The FontFileReader for ttfFile (AndroidEmoji) */ + protected final FontFileReader androidEmojiReader; + /** @@ -52,20 +59,27 @@ public class TTFFileTestCase { * @throws IOException exception */ public TTFFileTestCase() throws IOException { - dejavuTTFFile = new TTFFile(); InputStream dejaStream = new FileInputStream("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); + dejavuTTFFile = new TTFFile(); dejavuReader = new FontFileReader(dejaStream); String dejavuHeader = OFFontLoader.readHeader(dejavuReader); dejavuTTFFile.readFont(dejavuReader, dejavuHeader); dejaStream.close(); InputStream droidStream = new FileInputStream("test/resources/fonts/ttf/DroidSansMono.ttf"); - droidmonoTTFFile = new TTFFile(); droidmonoReader = new FontFileReader(droidStream); String droidmonoHeader = OFFontLoader.readHeader(droidmonoReader); droidmonoTTFFile.readFont(droidmonoReader, droidmonoHeader); droidStream.close(); + + InputStream emojiStream = new FileInputStream("test/resources/fonts/ttf/AndroidEmoji.ttf"); + androidEmojiTTFFile = new TTFFile(); + androidEmojiReader = new FontFileReader(emojiStream); + String androidEmojiHeader = OFFontLoader.readHeader(androidEmojiReader); + androidEmojiTTFFile.readFont(androidEmojiReader, androidEmojiHeader); + emojiStream.close(); + } /** @@ -110,12 +124,11 @@ public class TTFFileTestCase { */ @Test public void testGetAnsiKerning() { - Map<Integer, Map<Integer, Integer>> ansiKerning = dejavuTTFFile.getKerning(); + Map<Integer, Map<Integer, Integer>> ansiKerning = dejavuTTFFile.getAnsiKerning(); if (ansiKerning.isEmpty()) { fail(); } - Integer k1 = ansiKerning.get((int) 'A').get( - (int) 'T'); + Integer k1 = ansiKerning.get((int) 'A').get((int) 'T'); assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-112), k1.intValue()); Integer k2 = ansiKerning.get((int) 'Y').get((int) 'u'); assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-178), k2.intValue()); @@ -125,6 +138,12 @@ public class TTFFileTestCase { if (!ansiKerning.isEmpty()) { fail("DroidSansMono shouldn't have any kerning data."); } + + // AndroidEmoji doens't have kerning + ansiKerning = androidEmojiTTFFile.getAnsiKerning(); + if (!ansiKerning.isEmpty()) { + fail("AndroidEmoji shouldn't have any kerning data."); + } } /** @@ -145,6 +164,10 @@ public class TTFFileTestCase { // height of "H" = 1462 assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1462), droidmonoTTFFile.getCapHeight()); + // AndroidEmoji doesn't have a PCLT table either + // height of "H" = 1462 + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(1462), + androidEmojiTTFFile.getCapHeight()); } /** @@ -154,6 +177,8 @@ public class TTFFileTestCase { public void testGetCharSetName() { assertTrue("WinAnsiEncoding".equals(dejavuTTFFile.getCharSetName())); assertTrue("WinAnsiEncoding".equals(droidmonoTTFFile.getCharSetName())); + //Even though this pass I'm not sure whether is what we want + assertTrue("WinAnsiEncoding".equals(androidEmojiTTFFile.getCharSetName())); } /** @@ -175,12 +200,24 @@ public class TTFFileTestCase { for (int i = 0; i < 255; i++) { assertEquals(charWidth, droidmonoTTFFile.getCharWidth(i)); } + + // All the glyphs should be the same width in EmojiAndroid (mono-spaced) + charWidth = androidEmojiTTFFile.convertTTFUnit2PDFUnit(2600); + for (int i = 0; i < 255; i++) { + assertEquals(charWidth, androidEmojiTTFFile.getCharWidth(i)); + } } /** * TODO: add implementation to this test */ + @Test public void testGetCMaps() { + List<CMapSegment> cmaps = androidEmojiTTFFile.getCMaps(); + + for (CMapSegment seg : cmaps) { + System.out.println(seg.getUnicodeStart() + "-" + seg.getUnicodeEnd() + " -> " + seg.getGlyphStartIndex()); + } } /** @@ -196,6 +233,10 @@ public class TTFFileTestCase { for (String name : droidmonoTTFFile.getFamilyNames()) { assertEquals("Droid Sans Mono", name); } + assertEquals(1, androidEmojiTTFFile.getFamilyNames().size()); + for (String name : androidEmojiTTFFile.getFamilyNames()) { + assertEquals("Android Emoji", name); + } } /** @@ -206,6 +247,7 @@ public class TTFFileTestCase { // Not really sure how to test this intelligently assertEquals(0, dejavuTTFFile.getFirstChar()); assertEquals(0, droidmonoTTFFile.getFirstChar()); + assertEquals(0, androidEmojiTTFFile.getFirstChar()); } /** @@ -234,6 +276,17 @@ public class TTFFileTestCase { assertEquals(32, flags & 32); assertEquals(2, flags & 2); assertEquals(1, flags & 1); + /* + * Android Emoji flags are: + * italic angle = 0 + * fixed pitch = 0 + * has serifs = true (default value; this font doesn't have a PCLT table) + */ + flags = androidEmojiTTFFile.getFlags(); + assertEquals(0, flags & 64); + assertEquals(32, flags & 32); + assertEquals(0, flags & 2); + assertEquals(1, flags & 1); } /** @@ -259,6 +312,16 @@ public class TTFFileTestCase { assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(-555), bBox[1]); assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1315), bBox[2]); assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(2163), bBox[3]); + + /* + * The head table has the following values (DroidSansMono): + * xMin = -50, yMin = -733, xMax = 2550, yMax = 2181 + */ + bBox = androidEmojiTTFFile.getFontBBox(); + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(-50), bBox[0]); + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(-733), bBox[1]); + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(2550), bBox[2]); + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(2181), bBox[3]); } /** @@ -268,6 +331,7 @@ public class TTFFileTestCase { public void testGetFullName() { assertEquals("DejaVu LGC Serif", dejavuTTFFile.getFullName()); assertEquals("Droid Sans Mono", droidmonoTTFFile.getFullName()); + assertEquals("Android Emoji", androidEmojiTTFFile.getFullName()); } /** @@ -277,6 +341,7 @@ public class TTFFileTestCase { public void testGetGlyphName() { assertEquals("H", dejavuTTFFile.getGlyphName(43)); assertEquals("H", droidmonoTTFFile.getGlyphName(43)); + assertEquals("smileface", androidEmojiTTFFile.getGlyphName(64)); } /** @@ -286,6 +351,7 @@ public class TTFFileTestCase { public void testGetItalicAngle() { assertEquals("0", dejavuTTFFile.getItalicAngle()); assertEquals("0", droidmonoTTFFile.getItalicAngle()); + assertEquals("0", androidEmojiTTFFile.getItalicAngle()); } /** @@ -307,6 +373,12 @@ public class TTFFileTestCase { if (!kerning.isEmpty()) { fail("DroidSansMono shouldn't have any kerning data"); } + + // AndroidEmoji doens't have kerning + kerning = androidEmojiTTFFile.getKerning(); + if (!kerning.isEmpty()) { + fail("AndroidEmoji shouldn't have any kerning data."); + } } /** @@ -316,6 +388,7 @@ public class TTFFileTestCase { public void testLastChar() { assertEquals(0xff, dejavuTTFFile.getLastChar()); assertEquals(0xff, droidmonoTTFFile.getLastChar()); + assertEquals(0xae, androidEmojiTTFFile.getLastChar()); // Last ASCII mapped char is REGISTERED SIGN } /** @@ -331,6 +404,11 @@ public class TTFFileTestCase { // Curiously the same value assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1556), droidmonoTTFFile.getLowerCaseAscent()); + //TODO: Nedd to be fixed? + // 0 because the font miss letter glyph that are used in this method to guess the ascender: + // OpenFont.guessVerticalMetricsFromGlyphBBox + assertEquals(androidEmojiTTFFile.convertTTFUnit2PDFUnit(0), + androidEmojiTTFFile.getLowerCaseAscent()); } /** @@ -340,6 +418,7 @@ public class TTFFileTestCase { public void testGetPostScriptName() { assertEquals(PostScriptVersion.V2, dejavuTTFFile.getPostScriptVersion()); assertEquals(PostScriptVersion.V2, droidmonoTTFFile.getPostScriptVersion()); + assertEquals(PostScriptVersion.V2, androidEmojiTTFFile.getPostScriptVersion()); } /** @@ -350,6 +429,7 @@ public class TTFFileTestCase { // Undefined assertEquals("0", dejavuTTFFile.getStemV()); assertEquals("0", droidmonoTTFFile.getStemV()); + assertEquals("0", androidEmojiTTFFile.getStemV()); } /** @@ -359,6 +439,7 @@ public class TTFFileTestCase { public void testGetSubFamilyName() { assertEquals("Book", dejavuTTFFile.getSubFamilyName()); assertEquals("Regular", droidmonoTTFFile.getSubFamilyName()); + assertEquals("Regular", androidEmojiTTFFile.getSubFamilyName()); } /** @@ -376,6 +457,7 @@ public class TTFFileTestCase { // Retrieved from OS/2 table assertEquals(400, dejavuTTFFile.getWeightClass()); assertEquals(400, droidmonoTTFFile.getWeightClass()); + assertEquals(400, androidEmojiTTFFile.getWeightClass()); } /** @@ -388,14 +470,38 @@ public class TTFFileTestCase { assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1479), widths[36]); // using the width of '|' index = 95 assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(690), widths[95]); - widths = droidmonoTTFFile.getWidths(); + // DroidSansMono should have all widths the same size (mono-spaced) - int width = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229); - for (int i = 0; i < 255; i++) { - assertEquals(width, widths[i]); + widths = droidmonoTTFFile.getWidths(); + int charWidth = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229); + for (OpenFont.UnicodeMapping unicodeMapping : droidmonoTTFFile.unicodeMappings) { + assertEquals(charWidth, widths[unicodeMapping.getGlyphIndex()]); + } + + // All the glyphs should be the same width in EmojiAndroid (mono-spaced) + charWidth = androidEmojiTTFFile.convertTTFUnit2PDFUnit(2600); + widths = androidEmojiTTFFile.getWidths(); + for (OpenFont.UnicodeMapping unicodeMapping : androidEmojiTTFFile.unicodeMappings) { + assertEquals(charWidth, widths[unicodeMapping.getGlyphIndex()]); } } + @Test + public void textUnicodeCoverage() { + int nonBMPcount = 0; + for (OpenFont.UnicodeMapping unicodeMapping : droidmonoTTFFile.unicodeMappings) { + nonBMPcount += unicodeMapping.getUnicodeIndex() > 0xFFFF ? 1 : 0; + } + assertEquals("The font DroidSansMono is supposed to have only BMP codepoints", 0, nonBMPcount); + + nonBMPcount = 0; + for (OpenFont.UnicodeMapping unicodeMapping : androidEmojiTTFFile.unicodeMappings) { + nonBMPcount += unicodeMapping.getUnicodeIndex() > 0xFFFF ? 1 : 0; + } + + assertTrue("The font AndroidEmoji is supposed to have non-BMP codepoints", 0 != nonBMPcount); + } + /** * Test getXHeight() - There are several paths to test: * 1) The PCLT table (if available) @@ -418,6 +524,7 @@ public class TTFFileTestCase { // Neither DejaVu nor DroidSansMono are a compact format font assertEquals(false, dejavuTTFFile.isCFF()); assertEquals(false, droidmonoTTFFile.isCFF()); + assertEquals(false, androidEmojiTTFFile.isCFF()); } /** @@ -428,6 +535,7 @@ public class TTFFileTestCase { // Dejavu and DroidSansMono are both embeddable assertEquals(true, dejavuTTFFile.isEmbeddable()); assertEquals(true, droidmonoTTFFile.isEmbeddable()); + assertEquals(true, androidEmojiTTFFile.isEmbeddable()); } /** Underline position and thickness. */ @@ -437,6 +545,8 @@ public class TTFFileTestCase { assertEquals(43, dejavuTTFFile.getUnderlineThickness()); assertEquals(-75, droidmonoTTFFile.getUnderlinePosition()); assertEquals(49, droidmonoTTFFile.getUnderlineThickness()); + assertEquals(-75, androidEmojiTTFFile.getUnderlinePosition()); + assertEquals(49, androidEmojiTTFFile.getUnderlineThickness()); } /** Strikeout position and thickness. */ @@ -446,6 +556,8 @@ public class TTFFileTestCase { assertEquals(49, dejavuTTFFile.getStrikeoutThickness()); assertEquals(243, droidmonoTTFFile.getStrikeoutPosition()); assertEquals(49, droidmonoTTFFile.getStrikeoutThickness()); + assertEquals(122, androidEmojiTTFFile.getStrikeoutPosition()); + assertEquals(24, androidEmojiTTFFile.getStrikeoutThickness()); } /**
Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java (original) +++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java Mon Mar 19 08:49:57 2018 @@ -19,19 +19,23 @@ package org.apache.fop.render.pdf; + + import java.io.File; import java.io.IOException; -import java.util.StringTokenizer; -import org.junit.Ignore; import org.junit.Test; import org.xml.sax.SAXException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; + import org.apache.fop.apps.FOUserAgent; + /** Test that characters are correctly encoded in a generated PDF file */ public class PDFEncodingTestCase extends BasePDFTest { private File foBaseDir = new File("test/xml/pdf-encoding"); @@ -67,24 +71,21 @@ public class PDFEncodingTestCase extends */ final String[] testPatterns = { TEST_MARKER + "1", "Standard", - TEST_MARKER + "2", "XX_\\351_XX", - TEST_MARKER + "3", "XX_\\342\\352\\356\\364\\373_XX" + TEST_MARKER + "2", "XX_é_XX", + TEST_MARKER + "3", "XX_âêîôû_XX" }; runTest("test-standard-font.fo", testPatterns); } /** - * TODO test disabled for now, fails due (probably) do different PDF - * encoding when custom font is used. - * TODO This should be tested using PDFBox. If PDFBox can extract the text correctly, - * everything is fine. The tests here are too unstable. + * Test encoding with a Custom Font using BMP characters. + * + * NB: The Gladiator font do not contain '_' Glyph * * @throws Exception * checkstyle wants a comment here, even a silly one */ - @Ignore("This should be tested using PDFBox. If PDFBox can extract the text correctly," - + "everything is fine. The tests here are too unstable.") @Test public void testPDFEncodingWithCustomFont() throws Exception { @@ -94,14 +95,31 @@ public class PDFEncodingTestCase extends * The following array is used to look for these patterns */ final String[] testPatterns = { - TEST_MARKER + "1", "(Gladiator)", - TEST_MARKER + "2", "XX_\\351_XX", - TEST_MARKER + "3", "XX_\\342\\352\\356\\364\\373_XX" + TEST_MARKER + "1", "Gladiator", + TEST_MARKER + "2", "XX_é_XX", + TEST_MARKER + "3", "XX_âêîôû_XX" }; runTest("test-custom-font.fo", testPatterns); } + /** + * Test encoding with a Custom Font using non-BMP characters + * + * @throws Exception + * checkstyle wants a comment here, even a silly one + */ + @Test + public void testPDFEncodingWithNonBMPFont() throws Exception { + + final String[] testPatterns = { + TEST_MARKER + "1", "AndroidEmoji", + TEST_MARKER + "2", "\uD800\uDF00", + }; + + runTest("test-custom-non-bmp-font.fo", testPatterns); + } + /** Test encoding using specified input file and test patterns array */ private void runTest(String inputFile, String[] testPatterns) throws Exception { @@ -119,26 +137,26 @@ public class PDFEncodingTestCase extends private void checkEncoding(byte[] pdf, String[] testPattern) throws IOException { + String s = extractTextFromPDF(pdf); + int markersFound = 0; - final String input = new String(pdf); - int pos = 0; - if ((pos = input.indexOf(TEST_MARKER)) >= 0) { - final StringTokenizer tk = new StringTokenizer( - input.substring(pos), "\n"); - - while (tk.hasMoreTokens()) { - final String line = tk.nextToken(); - if (line.indexOf(TEST_MARKER) >= 0) { - markersFound++; - for (int i = 0; i < testPattern.length; i += 2) { - if (line.indexOf(testPattern[i]) >= 0) { - final String ref = testPattern[i + 1]; - final boolean patternFound = line.indexOf(ref) >= 0; - assertTrue("line containing '" + testPattern[i] - + "' must contain '" + ref, patternFound); - } - } + for (String line : s.split("\n")) { + if (!line.contains(TEST_MARKER)) { + continue; + } + + markersFound++; + + for (int i = 0; i < testPattern.length; i++) { + String marker = testPattern[i]; + String pattern = testPattern[++i]; + + if (!line.contains(marker)) { + continue; } + + String msg = String.format("line containing '%s' must contain '%s'", marker, pattern); + assertTrue(msg, line.contains(pattern)); } } @@ -146,4 +164,10 @@ public class PDFEncodingTestCase extends assertEquals(nMarkers + " " + TEST_MARKER + " markers must be found", nMarkers, markersFound); } + + private static String extractTextFromPDF(byte[] pdfContent) throws IOException { + PDFTextStripper pdfStripper = new PDFTextStripper(); + PDDocument pdDoc = PDDocument.load(pdfContent); + return pdfStripper.getText(pdDoc); + } } Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java (original) +++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java Mon Mar 19 08:49:57 2018 @@ -28,9 +28,14 @@ import java.io.File; import javax.xml.transform.stream.StreamResult; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.endsWith; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -50,8 +55,6 @@ import org.apache.fop.render.intermediat import org.apache.fop.render.intermediate.IFException; import org.apache.fop.traits.BorderProps; -import junit.framework.Assert; - public class PDFPainterTestCase { private FOUserAgent foUserAgent; @@ -122,7 +125,7 @@ public class PDFPainterTestCase { pdfDocumentHandler.getContext().setPageNumber(3); MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null); pdfPainter.drawImage("test/resources/images/cmyk.jpg", new Rectangle()); - Assert.assertEquals(pdfPainter.renderingContext.getHints().get("page-number"), 3); + assertEquals(pdfPainter.renderingContext.getHints().get("page-number"), 3); } class MyPDFPainter extends PDFPainter { @@ -139,10 +142,52 @@ public class PDFPainterTestCase { @Test public void testSimulateStyle() throws IFException { + final StringBuilder sb = new StringBuilder(); + pdfDocumentHandler = makePDFDocumentHandler(sb); + + FontInfo fi = new FontInfo(); + fi.addFontProperties("f1", new FontTriplet("a", "italic", 700)); + MultiByteFont font = new MultiByteFont(null, null); + font.setSimulateStyle(true); + fi.addMetrics("f1", font); + pdfDocumentHandler.setFontInfo(fi); + MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null); + pdfPainter.setFont("a", "italic", 700, null, 12, null); + pdfPainter.drawText(0, 0, 0, 0, null, "test"); + + assertEquals(sb.toString(), "BT\n/f1 0.012 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n"); + verify(pdfContentGenerator).add("q\n"); + verify(pdfContentGenerator).add("2 Tr 0.31543 w\n"); + verify(pdfContentGenerator).add("Q\n"); + } + + @Test + public void testDrawTextWithMultiByteFont() throws IFException { + StringBuilder output = new StringBuilder(); + PDFDocumentHandler pdfDocumentHandler = makePDFDocumentHandler(output); + //0x48 0x65 0x6C 0x6C 0x6F 0x20 0x4D 0x6F 0x63 0x6B 0x21 0x1F4A9 + String text = "Hello Mock!\uD83D\uDCA9"; + String expectedHex = "00480065006C006C006F0020004D006F0063006B002101F4A9"; + + MultiByteFont font = spy(new MultiByteFont(null, null)); + when(font.mapCodePoint(anyInt())).thenAnswer(new FontMapCodepointAnswer()); + + FontInfo fi = new FontInfo(); + fi.addFontProperties("f1", new FontTriplet("a", "normal", 400)); + fi.addMetrics("f1", font); + pdfDocumentHandler.setFontInfo(fi); + + MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null); + pdfPainter.setFont("a", "normal", 400, null, 12, null); + pdfPainter.drawText(0, 0, 0, 0, null, text); + + assertEquals("BT\n/f1 0.012 Tf\n1 0 0 -1 0 0 Tm [<" + expectedHex + ">] TJ\n", output.toString()); + } + + private PDFDocumentHandler makePDFDocumentHandler(final StringBuilder sb) throws IFException { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); foUserAgent = fopFactory.newFOUserAgent(); mockPDFContentGenerator(); - final StringBuilder sb = new StringBuilder(); PDFTextUtil pdfTextUtil = new PDFTextUtil() { protected void write(String code) { sb.append(code); @@ -163,19 +208,14 @@ public class PDFPainterTestCase { pdfDocumentHandler.setResult(new StreamResult(new ByteArrayOutputStream())); pdfDocumentHandler.startDocument(); pdfDocumentHandler.startPage(0, "", "", new Dimension()); - FontInfo fi = new FontInfo(); - fi.addFontProperties("f1", new FontTriplet("a", "italic", 700)); - MultiByteFont font = new MultiByteFont(null, null); - font.setSimulateStyle(true); - fi.addMetrics("f1", font); - pdfDocumentHandler.setFontInfo(fi); - MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null); - pdfPainter.setFont("a", "italic", 700, null, 12, null); - pdfPainter.drawText(0, 0, 0, 0, null, "test"); + return pdfDocumentHandler; + } - Assert.assertEquals(sb.toString(), "BT\n/f1 0.012 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n"); - verify(pdfContentGenerator).add("q\n"); - verify(pdfContentGenerator).add("2 Tr 0.31543 w\n"); - verify(pdfContentGenerator).add("Q\n"); + private static class FontMapCodepointAnswer implements Answer<Integer> { + + @Override + public Integer answer(InvocationOnMock invocation) throws Throwable { + return (Integer) invocation.getArguments()[0]; + } } } Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java (original) +++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java Mon Mar 19 08:49:57 2018 @@ -58,6 +58,7 @@ import org.apache.fop.render.intermediat import org.apache.fop.render.intermediate.IFException; import org.apache.fop.render.intermediate.IFState; import org.apache.fop.traits.BorderProps; +import org.apache.fop.util.CharUtilities; public class PSPainterTestCase { @@ -126,7 +127,7 @@ public class PSPainterTestCase { } @Test - public void testDrawText() { + public void testDrawText() throws IOException { int fontSize = 12000; String fontName = "MockFont"; PSGenerator psGenerator = mock(PSGenerator.class); @@ -160,12 +161,19 @@ public class PSPainterTestCase { double yAsDouble = (y - dp[0][1]) / 1000.0; when(psGenerator.formatDouble(xAsDouble)).thenReturn("100.100"); when(psGenerator.formatDouble(yAsDouble)).thenReturn("99.900"); - String text = "Hello Mock!"; + + //0x48 0x65 0x6C 0x6C 0x6F 0x20 0x4D 0x6F 0x63 0x6B 0x21 0x1F4A9 + String text = "Hello Mock!\uD83D\uDCA9"; + + for (int cp : CharUtilities.codepointsIter(text)) { + when(font.mapCodePoint(cp)).thenReturn(cp); + } + try { psPainter.drawText(x, y, letterSpacing, wordSpacing, dp, text); verify(psGenerator).writeln("1 0 0 -1 100.100 99.900 Tm"); - verify(psGenerator).writeln("[<0000> [-100 100] <00000000> [200 -200] <0000> [-300 300] " - + "<0000000000000000000000000000>] TJ"); + verify(psGenerator).writeln("[<0048> [-100 100] <0065006C> [200 -200] <006C> [-300 300] " + + "<006F0020004D006F0063006B002101F4A9>] TJ"); } catch (Exception e) { fail("something broke..."); } Modified: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/util/HexEncoderTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/util/HexEncoderTestCase.java?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/util/HexEncoderTestCase.java (original) +++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/util/HexEncoderTestCase.java Mon Mar 19 08:49:57 2018 @@ -40,8 +40,21 @@ public class HexEncoderTestCase { } } + + /** + * Tests that codepoints are properly encoded into hex strings. + */ + @Test + public void testEncodeCodepoints() { + char[] digits = new char[] {'0', '1', '0', '0', '0', '0'}; + for (int c = 0x10000; c <= 0x1FFFF; c++) { + assertEquals(new String(digits), HexEncoder.encode(c)); + increment(digits); + } + } + private static void increment(char[] digits) { - int d = 4; + int d = digits.length; do { d--; digits[d] = successor(digits[d]); Modified: xmlgraphics/fop/trunk/fop/build.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop/build.xml?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop/build.xml (original) +++ xmlgraphics/fop/trunk/fop/build.xml Mon Mar 19 08:49:57 2018 @@ -638,7 +638,7 @@ list of possible build targets. <include name="org/apache/fop/util/*OutputStream.class"/> <include name="org/apache/fop/util/SubInputStream.class"/> <include name="org/apache/fop/util/Finalizable.class"/> - <include name="org/apache/fop/util/CharUtilities.class"/> + <include name="org/apache/fop/util/CharUtilities*.class"/> <include name="org/apache/fop/util/DecimalFormatCache*.class"/> <include name="org/apache/fop/util/ImageObject.class"/> <include name="org/apache/fop/util/HexEncoder.class"/> Modified: xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/pdf-encoding-test.xconf URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/pdf-encoding-test.xconf?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/pdf-encoding-test.xconf (original) +++ xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/pdf-encoding-test.xconf Mon Mar 19 08:49:57 2018 @@ -29,19 +29,22 @@ <renderers> <renderer mime="application/pdf"> <!-- disable PDF text compression --> - <filterList> + <filterList> <value>null</value> </filterList> <filterList type="image"> <value>flate</value> <value>ascii-85</value> </filterList> - + <!-- use a custom font to show encoding problems --> <fonts> - <font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> + <font metrics-url="../../resources/fonts/ttf/glb12.ttf.xml" embed-url="../../resources/fonts/ttf/glb12.ttf"> <font-triplet name="Gladiator" style="normal" weight="normal"/> </font> + <font embed-url="../../resources/fonts/ttf/Aegean600.ttf" > + <font-triplet name="Aegean600" style="normal" weight="normal"/> + </font> </fonts> </renderer> </renderers> Modified: xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/test-custom-font.fo URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/test-custom-font.fo?rev=1827168&r1=1827167&r2=1827168&view=diff ============================================================================== --- xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/test-custom-font.fo (original) +++ xmlgraphics/fop/trunk/fop/test/xml/pdf-encoding/test-custom-font.fo Mon Mar 19 08:49:57 2018 @@ -21,7 +21,7 @@ Minimal FO document used to test PDF encoding --> -<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator"> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator" font-size="10px"> <fo:layout-master-set> <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> <fo:region-body/> --------------------------------------------------------------------- To unsubscribe, e-mail: fop-commits-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-h...@xmlgraphics.apache.org