You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2022/10/27 07:23:08 UTC
svn commit: r1904869 - in /xmlgraphics/fop-pdf-images/trunk: lib/ src/java/org/apache/fop/render/pdf/pdfbox/ test/java/org/apache/fop/render/pdf/
Author: ssteiner
Date: Thu Oct 27 07:23:08 2022
New Revision: 1904869
URL: http://svn.apache.org/viewvc?rev=1904869&view=rev
Log:
FOP-3102: Move composite glyphs to the end
Modified:
xmlgraphics/fop-pdf-images/trunk/lib/fop.jar
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
Modified: xmlgraphics/fop-pdf-images/trunk/lib/fop.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/fop.jar?rev=1904869&r1=1904868&r2=1904869&view=diff
==============================================================================
Binary files - no diff available.
Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java?rev=1904869&r1=1904868&r2=1904869&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/FOPPDFMultiByteFont.java Thu Oct 27 07:23:08 2022
@@ -130,11 +130,7 @@ public class FOPPDFMultiByteFont extends
}
if (mergeFonts instanceof MergeTTFonts) {
mergeMaxp(ttf, ((MergeTTFonts)mergeFonts).maxp);
- int sizeNoCompGlyphs = oldToNewGIMap.size();
mergeFonts.readFont(ffr, null, null, oldToNewGIMap, true);
- if (oldToNewGIMap.size() > sizeNoCompGlyphs) {
- cidSet.mapChar(256 * 256, (char) 0);
- }
} else {
mergeFonts.readFont(ffr, getEmbedFontName(), null, null, true);
}
Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java?rev=1904869&r1=1904868&r2=1904869&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java Thu Oct 27 07:23:08 2022
@@ -16,10 +16,17 @@
*/
package org.apache.fop.render.pdf.pdfbox;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import org.apache.fop.fonts.truetype.FontFileReader;
@@ -30,19 +37,27 @@ import org.apache.fop.fonts.truetype.OFT
import org.apache.fop.fonts.truetype.TTFSubSetFile;
public class MergeTTFonts extends TTFSubSetFile implements MergeFonts {
- private Map<Integer, Glyph> added = new TreeMap<Integer, Glyph>();
+ private Map<Integer, Glyph> added = new TreeMap<>();
private int origIndexesLen;
private int size;
protected MaximumProfileTable maxp = new MaximumProfileTable();
private Integer nhmtxDiff = null;
private List<Cmap> cmap;
+ private Set<Integer> composedGlyphs = Collections.emptySet();
+ private Set<Integer> compositeGlyphs = Collections.emptySet();
static class Glyph {
final byte[] data;
final OFMtxEntry mtx;
- Glyph(byte[] d, OFMtxEntry m) {
- data = d;
- mtx = m;
+ final boolean composed;
+ final boolean composite;
+ final int origGlyphIndex;
+ Glyph(byte[] data, OFMtxEntry mtx, boolean composed, boolean composite, int origGlyphIndex) {
+ this.data = data;
+ this.mtx = mtx;
+ this.composed = composed;
+ this.composite = composite;
+ this.origGlyphIndex = origGlyphIndex;
}
}
@@ -77,7 +92,9 @@ public class MergeTTFonts extends TTFSub
(int)entry.getOffset() + glyphOffset,
glyphLength);
- Glyph g = new Glyph(glyphData, mtxTab[origGlyphIndex]);
+ Glyph g = new Glyph(glyphData, mtxTab[origGlyphIndex],
+ composedGlyphs.contains(origGlyphIndex),
+ compositeGlyphs.contains(origGlyphIndex), origGlyphIndex);
if (!cid && (origIndexesLen == 0 || (glyphLength > 0 && i > 0))) {
added.put(i, g);
} else if (cid) {
@@ -248,7 +265,9 @@ public class MergeTTFonts extends TTFSub
if (glyfTableInfo == null) {
throw new IOException("Glyf table could not be found");
}
- new MergeGlyfTable(in, mtxTab, glyfTableInfo, subsetGlyphs);
+ MergeGlyfTable mergeGlyfTable = new MergeGlyfTable(in, mtxTab, glyfTableInfo, subsetGlyphs);
+ composedGlyphs = mergeGlyfTable.getComposedGlyphs();
+ compositeGlyphs = mergeGlyfTable.getCompositeGlyphs();
}
static class MergeGlyfTable extends GlyfTable {
@@ -258,6 +277,34 @@ public class MergeTTFonts extends TTFSub
populateGlyphsWithComposites();
}
+ protected void populateGlyphsWithComposites() throws IOException {
+ for (int indexInOriginal : subset.keySet()) {
+ scanGlyphsRecursively(indexInOriginal);
+ }
+ addAllComposedGlyphsToSubset();
+ }
+
+ private void scanGlyphsRecursively(int indexInOriginal) throws IOException {
+ if (!subset.containsKey(indexInOriginal)) {
+ composedGlyphs.add(indexInOriginal);
+ }
+ if (isComposite(indexInOriginal)) {
+ compositeGlyphs.add(indexInOriginal);
+ Set<Integer> composedGlyphs = retrieveComposedGlyphs(indexInOriginal);
+ for (Integer composedGlyph : composedGlyphs) {
+ scanGlyphsRecursively(composedGlyph);
+ }
+ }
+ }
+
+ Set<Integer> getComposedGlyphs() {
+ return composedGlyphs;
+ }
+
+ Set<Integer> getCompositeGlyphs() {
+ return compositeGlyphs;
+ }
+
@Override
protected void addAllComposedGlyphsToSubset() {
int newIndex = -1;
@@ -272,11 +319,66 @@ public class MergeTTFonts extends TTFSub
}
}
+ private void reorderGlyphs() throws IOException {
+ Map<Integer, Integer> remap = new HashMap<>();
+ Map<Integer, Glyph> glyphMap = new TreeMap<>();
+ int i = 0;
+ for (Glyph glyph : added.values()) {
+ if (!glyph.composed) {
+ glyphMap.put(i, glyph);
+ remap.put(glyph.origGlyphIndex, i);
+ i++;
+ }
+ }
+ for (Glyph glyph : added.values()) {
+ if (glyph.composed) {
+ glyphMap.put(i, glyph);
+ remap.put(glyph.origGlyphIndex, i);
+ i++;
+ }
+ }
+ for (Glyph glyph : glyphMap.values()) {
+ if (glyph.composite && glyph.data.length > 0) {
+ remapComposite(glyph.data, remap);
+ }
+ }
+ added = glyphMap;
+ }
+
+ private void remapComposite(byte[] data, Map<Integer, Integer> remap) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
+ byte[] header = new byte[10];
+ read(dis, header);
+ dos.write(header);
+ int flags;
+ do {
+ flags = dis.readShort();
+ dos.writeShort(flags);
+ int glyphIndex = dis.readShort();
+ int indexInSubset = remap.get(glyphIndex);
+ dos.writeShort(indexInSubset);
+ int skip = GlyfTable.GlyfFlags.getOffsetToNextComposedGlyf(flags);
+ byte[] rest = new byte[skip];
+ read(dis, rest);
+ dos.write(rest);
+ } while(GlyfTable.GlyfFlags.hasMoreComposites(flags));
+ System.arraycopy(bos.toByteArray(), 0, data, 0, bos.size());
+ }
+
+ private void read(DataInputStream dis, byte[] data) throws IOException {
+ int size = dis.read(data);
+ assert size == data.length;
+ }
+
public byte[] getMergedFontSubset() throws IOException {
int sgsize = added.size();
if (sgsize == 1 && size == fontFile.getAllBytes().length) {
return fontFile.getAllBytes();
}
+ reorderGlyphs();
+
output = new byte[size * 2];
createDirectory(); // Create the TrueType header and directory
if (!cid) {
Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1904869&r1=1904868&r2=1904869&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Thu Oct 27 07:23:08 2022
@@ -28,6 +28,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -44,7 +45,9 @@ import static org.mockito.Mockito.when;
import org.apache.commons.io.IOUtils;
import org.apache.fontbox.cff.CFFParser;
+import org.apache.fontbox.ttf.GlyphData;
import org.apache.fontbox.ttf.TTFParser;
+import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.fontbox.type1.Type1Font;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
@@ -105,6 +108,8 @@ public class PDFBoxAdapterTestCase {
protected static final String TTSubset5 = "ttsubset5.pdf";
protected static final String TTSubset6 = "ttsubset6.pdf";
protected static final String TTSubset7 = "ttsubset7.pdf";
+ protected static final String TTSubset8 = "ttsubset8.pdf";
+ protected static final String TTSubset9 = "ttsubset9.pdf";
protected static final String CFFCID1 = "cffcid1.pdf";
protected static final String CFFCID2 = "cffcid2.pdf";
protected static final String Type1Subset1 = "t1subset.pdf";
@@ -612,7 +617,9 @@ public class PDFBoxAdapterTestCase {
@Test
public void testErrorMsgToPDF() throws IOException {
String msg = "";
- PDFRenderingContext context = new PDFRenderingContext(null, null, null, null);
+ PDFDocument pdfdoc = new PDFDocument("");
+ PDFContentGenerator contentGenerator = new PDFContentGenerator(pdfdoc, null, null);
+ PDFRenderingContext context = new PDFRenderingContext(null, contentGenerator, null, null);
ImagePDF imagePDF = new ImagePDF(new ImageInfo(ERROR, null), null);
try {
new PDFBoxImageHandler().handleImage(context, imagePDF, null);
@@ -734,4 +741,25 @@ public class PDFBoxAdapterTestCase {
String msg = writeText(fi, TTSubset7);
Assert.assertTrue(msg, msg.contains("( )Tj"));
}
+
+ @Test
+ public void testReorderGlyphs() throws IOException {
+ FontInfo fontInfo = new FontInfo();
+ writeText(fontInfo, TTSubset8);
+ writeText(fontInfo, TTSubset9);
+ List<Integer> compositeList = new ArrayList<>();
+ for (Typeface font : fontInfo.getUsedFonts().values()) {
+ InputStream inputStream = ((CustomFont) font).getInputStream();
+ TTFParser parser = new TTFParser(true);
+ TrueTypeFont trueTypeFont = parser.parse(inputStream);
+ int i = 0;
+ for (GlyphData glyphData : trueTypeFont.getGlyph().getGlyphs()) {
+ if (glyphData != null && glyphData.getDescription().isComposite()) {
+ compositeList.add(i);
+ }
+ i++;
+ }
+ }
+ Assert.assertEquals(compositeList, Arrays.asList(18, 19, 39, 42, 62, 63, 29));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org