Skip to content

Commit 70a8666

Browse files
authored
FOP-3277: Add font substitution support for PDFTranscoder
2 parents 3de713f + e0fca8b commit 70a8666

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

fop-core/src/main/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@
2828
import org.apache.fop.apps.io.ResourceResolverFactory;
2929
import org.apache.fop.configuration.Configuration;
3030
import org.apache.fop.configuration.ConfigurationException;
31+
import org.apache.fop.fonts.CustomFontCollection;
3132
import org.apache.fop.fonts.DefaultFontConfig;
3233
import org.apache.fop.fonts.DefaultFontConfigurator;
3334
import org.apache.fop.fonts.EmbedFontInfo;
3435
import org.apache.fop.fonts.FontCacheManagerFactory;
36+
import org.apache.fop.fonts.FontCollection;
3537
import org.apache.fop.fonts.FontDetectorFactory;
3638
import org.apache.fop.fonts.FontInfo;
3739
import org.apache.fop.fonts.FontManager;
40+
import org.apache.fop.fonts.FontManagerConfigurator;
3841
import org.apache.fop.fonts.FontSetup;
42+
import org.apache.fop.fonts.base14.Base14FontCollection;
3943
import org.apache.fop.pdf.PDFDocument;
4044
import org.apache.fop.render.pdf.PDFRendererConfig;
4145
import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
@@ -92,7 +96,11 @@ public static FontInfo createFontInfo(Configuration cfg, boolean useComplexScrip
9296
FontManager fontManager = new FontManager(resourceResolver, FontDetectorFactory.createDefault(),
9397
FontCacheManagerFactory.createDefault());
9498

95-
//TODO Make use of fontBaseURL, font substitution and referencing configuration
99+
FontManagerConfigurator fmConfigurator = new FontManagerConfigurator(cfg, thisUri,
100+
thisUri, null);
101+
fmConfigurator.configure(fontManager, strict);
102+
103+
//TODO Make use of fontBaseURL and referencing configuration
96104
//Requires a change to the expected configuration layout
97105

98106
DefaultFontConfig.DefaultFontConfigParser parser
@@ -102,7 +110,11 @@ public static FontInfo createFontInfo(Configuration cfg, boolean useComplexScrip
102110
= new DefaultFontConfigurator(fontManager, null, strict);
103111
List<EmbedFontInfo> fontInfoList = fontInfoConfigurator.configure(fontInfoConfig);
104112
fontManager.saveCache();
105-
FontSetup.setup(fontInfo, fontInfoList, resourceResolver, useComplexScriptFeatures);
113+
FontCollection[] fontCollections = new FontCollection[] {
114+
new Base14FontCollection(fontManager.isBase14KerningEnabled()),
115+
new CustomFontCollection(resourceResolver, fontInfoList, useComplexScriptFeatures)
116+
};
117+
fontManager.setup(fontInfo, fontCollections);
106118
} else {
107119
FontSetup.setup(fontInfo, useComplexScriptFeatures);
108120
}

fop-core/src/test/java/org/apache/fop/svg/BasicPDFTranscoderTestCase.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,28 @@
1919

2020
package org.apache.fop.svg;
2121

22-
import org.junit.Test;
22+
import java.io.ByteArrayInputStream;
23+
import java.io.ByteArrayOutputStream;
24+
import java.io.IOException;
25+
import java.util.HashMap;
26+
import java.util.Map;
2327

28+
import org.junit.Test;
2429
import static org.junit.Assert.assertEquals;
2530

31+
import org.apache.pdfbox.Loader;
32+
import org.apache.pdfbox.pdmodel.PDDocument;
33+
import org.apache.pdfbox.text.PDFTextStripper;
34+
import org.apache.pdfbox.text.TextPosition;
35+
2636
import org.apache.batik.transcoder.Transcoder;
37+
import org.apache.batik.transcoder.TranscoderException;
38+
import org.apache.batik.transcoder.TranscoderInput;
39+
import org.apache.batik.transcoder.TranscoderOutput;
2740

2841
import org.apache.fop.configuration.Configuration;
42+
import org.apache.fop.configuration.ConfigurationException;
43+
import org.apache.fop.configuration.DefaultConfigurationBuilder;
2944

3045
/**
3146
* Basic runtime test for the PDF transcoder. It is used to verify that
@@ -52,4 +67,63 @@ public void testFontAutoDetect() {
5267
autoDetectConf.getClass().getSimpleName());
5368
}
5469

70+
@Test
71+
public void testFontSubstitution() throws ConfigurationException, IOException, TranscoderException {
72+
73+
PDFTranscoder transcoder = (PDFTranscoder) createTranscoder();
74+
75+
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
76+
String cfgFragment =
77+
"<pdf-renderer>"
78+
+ "<fonts>"
79+
+ "<substitutions>"
80+
+ "<substitution>"
81+
+ "<from font-family=\"Helvetica\"/>"
82+
+ "<to font-family=\"Courier\"/>"
83+
+ "</substitution>"
84+
+ "</substitutions>"
85+
+ "</fonts>"
86+
+ "</pdf-renderer>";
87+
Configuration cfg = cfgBuilder.build(new ByteArrayInputStream(cfgFragment.getBytes()));
88+
transcoder.configure(cfg);
89+
90+
String svgFragment = "<svg xml:space=\"preserve\" x=\"-1.70458in\" y=\"0.198315in\" "
91+
+ "width=\"2.6622in\" height=\"1.89672in\""
92+
+ " viewBox=\"-4330 0 6762 4818\" xmlns=\"http://www.w3.org/2000/svg\">"
93+
+ " <text x=\"-3653\" y=\"841\" style=\"fill:#1F1A17;font-size:639;font-family:Helvetica\">H</text>"
94+
+ "</svg>";
95+
TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svgFragment.getBytes()));
96+
97+
ByteArrayOutputStream os = new ByteArrayOutputStream();
98+
TranscoderOutput output = new TranscoderOutput(os);
99+
100+
try {
101+
transcoder.transcode(input, output);
102+
} finally {
103+
os.close();
104+
}
105+
106+
try (PDDocument pdfDocument = Loader.loadPDF(os.toByteArray())) {
107+
FontExtractor fontExtractor = new FontExtractor();
108+
fontExtractor.getText(pdfDocument);
109+
assertEquals("Courier", fontExtractor.getFontUsage().get("H"));
110+
}
111+
}
112+
113+
static class FontExtractor extends PDFTextStripper {
114+
115+
private Map<String, String> fontUsage = new HashMap<>();
116+
117+
@Override
118+
protected void processTextPosition(TextPosition text) {
119+
String fontName = text.getFont().getName();
120+
fontUsage.put(text.toString(), fontName);
121+
super.processTextPosition(text);
122+
}
123+
124+
public Map<String, String> getFontUsage() {
125+
return fontUsage;
126+
}
127+
}
128+
55129
}

0 commit comments

Comments
 (0)