Skip to content

Commit 5d0a98d

Browse files
committed
#683 #684 Test of avoiding double embedding fonts
1 parent 02eaf1a commit 5d0a98d

File tree

4 files changed

+96
-11
lines changed

4 files changed

+96
-11
lines changed

openhtmltopdf-examples/src/main/java/com/openhtmltopdf/visualtest/TestSupport.java

+25-10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import com.openhtmltopdf.visualtest.VisualTester.BuilderConfig;
4747

4848
public class TestSupport {
49+
public static final String FONT_FILES_PATH = "target/test/visual-tests/";
50+
4951
/**
5052
* Output the font file as a regular file so we don't have to use streams.
5153
* @throws IOException
@@ -54,15 +56,28 @@ public static void makeFontFile(String resource) throws IOException {
5456
File outputDirectory = new File("target/test/visual-tests/test-output/j2d/");
5557
outputDirectory.mkdirs();
5658

57-
File fontFile = new File("target/test/visual-tests/" + resource);
58-
59+
File fontFile = new File(FONT_FILES_PATH + resource);
60+
5961
if (!fontFile.exists()) {
6062
try (InputStream in = TestSupport.class.getResourceAsStream("/visualtest/html/fonts/" + resource)) {
6163
Files.copy(in, fontFile.toPath());
6264
}
6365
}
6466
}
65-
67+
68+
public static File fontFileKarlaBold() {
69+
return new File(FONT_FILES_PATH + "Karla-Bold.ttf");
70+
}
71+
72+
public static File fontFileNotoNaskhArabicRegular() {
73+
return new File(FONT_FILES_PATH + "NotoNaskhArabic-Regular.ttf");
74+
}
75+
76+
public static File fontFileSourceSansProRegular() {
77+
return new File(FONT_FILES_PATH + "SourceSansPro-Regular.ttf");
78+
}
79+
80+
6681
/**
6782
* Output the test fonts from classpath to files in target so we can use them
6883
* without streams.
@@ -153,25 +168,25 @@ public void setText(String newText) {
153168
this.matcher = SPACES.matcher(newText);
154169
}
155170
}
156-
171+
157172
public static final BuilderConfig WITH_FONT = (builder) -> {
158-
builder.useFont(new File("target/test/visual-tests/Karla-Bold.ttf"), "TestFont");
173+
builder.useFont(fontFileKarlaBold(), "TestFont");
159174
builder.useUnicodeLineBreaker(new SimpleTextBreaker());
160175
};
161-
176+
162177
public static final Java2DBuilderConfig J2D_WITH_FONT = (builder) -> {
163-
builder.useFont(new File("target/test/visual-tests/Karla-Bold.ttf"), "TestFont");
178+
builder.useFont(fontFileKarlaBold(), "TestFont");
164179
builder.useUnicodeLineBreaker(new SimpleTextBreaker());
165180
};
166-
181+
167182
public static final BuilderConfig WITH_EXTRA_FONT = (builder) -> {
168183
WITH_FONT.configure(builder);
169-
builder.useFont(new File("target/test/visual-tests/SourceSansPro-Regular.ttf"), "ExtraFont");
184+
builder.useFont(fontFileSourceSansProRegular(), "ExtraFont");
170185
};
171186

172187
public static final BuilderConfig WITH_ARABIC = (builder) -> {
173188
WITH_FONT.configure(builder);
174-
builder.useFont(new File("target/test/visual-tests/NotoNaskhArabic-Regular.ttf"), "arabic");
189+
builder.useFont(fontFileNotoNaskhArabicRegular(), "arabic");
175190
builder.useUnicodeBidiSplitter(new ICUBidiSplitter.ICUBidiSplitterFactory());
176191
builder.useUnicodeBidiReorderer(new ICUBidiReorderer());
177192
builder.useUnicodeLineBreaker(new ICUBreakers.ICULineBreaker(Locale.US)); // Overrides WITH_FONT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<html>
2+
<body style="font-family: 'MyFont'; font-size: 24px;">
3+
This first document should use the same font resource as the second document.
4+
</body>
5+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<html>
2+
<body style="font-family: 'MyFont'; font-size: 24px; margin-top: 100px;">
3+
This second document should use the same font resource as the first document.
4+
</body>
5+
</html>

openhtmltopdf-examples/src/test/java/com/openhtmltopdf/nonvisualregressiontests/NonVisualRegressionTest.java

+61-1
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@
2424
import org.apache.pdfbox.cos.COSDocument;
2525
import org.apache.pdfbox.cos.COSName;
2626
import org.apache.pdfbox.cos.COSObject;
27+
import org.apache.pdfbox.cos.COSObjectKey;
2728
import org.apache.pdfbox.io.IOUtils;
2829
import org.apache.pdfbox.pdmodel.PDDocument;
2930
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
3031
import org.apache.pdfbox.pdmodel.PDPageContentStream;
3132
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
3233
import org.apache.pdfbox.pdmodel.common.PDRectangle;
34+
import org.apache.pdfbox.pdmodel.font.PDFont;
35+
import org.apache.pdfbox.pdmodel.font.PDType0Font;
3336
import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
3437
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
3538
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationFileAttachment;
@@ -44,10 +47,12 @@
4447
import org.apache.pdfbox.text.PDFTextStripper;
4548
import org.hamcrest.CustomTypeSafeMatcher;
4649
import org.junit.Assert;
50+
import org.junit.BeforeClass;
4751
import org.junit.Test;
4852

4953
import com.openhtmltopdf.layout.Layer;
5054
import com.openhtmltopdf.outputdevice.helper.ExternalResourceControlPriority;
55+
import com.openhtmltopdf.pdfboxout.PDFontSupplier;
5156
import com.openhtmltopdf.pdfboxout.PagePosition;
5257
import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
5358
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
@@ -61,7 +66,12 @@
6166
public class NonVisualRegressionTest {
6267
private static final String RES_PATH = "/visualtest/html/";
6368
private static final String OUT_PATH = "target/test/visual-tests/test-output/";
64-
69+
70+
@BeforeClass
71+
public static void configureTests() throws IOException {
72+
TestSupport.makeFontFiles();
73+
}
74+
6575
private static void render(String fileName, String html, BuilderConfig config) throws IOException {
6676
ByteArrayOutputStream actual = new ByteArrayOutputStream();
6777

@@ -1169,6 +1179,56 @@ public void testIssue427GetBodyPagePositions() throws IOException {
11691179
assertEquals(111.48, lastContentLine, 0.5);
11701180
}
11711181

1182+
/**
1183+
* Tests that it is possible to use a PDDocument multiple times
1184+
* without re-embedding required fonts.
1185+
* PR#684, Issue#683
1186+
*/
1187+
@Test
1188+
public void testPr684FontReuse() throws IOException {
1189+
String html1 = loadHtml("pr-684-font-reuse-1");
1190+
String html2 = loadHtml("pr-684-font-reuse-2");
1191+
1192+
try (PDDocument doc = new PDDocument()) {
1193+
PDFont font = PDType0Font.load(doc, TestSupport.fontFileKarlaBold());
1194+
PDFontSupplier supplier = new PDFontSupplier(font);
1195+
1196+
try (PdfBoxRenderer renderer = new PdfRendererBuilder()
1197+
.usePDDocument(doc)
1198+
.withHtmlContent(html1, null)
1199+
.useFont(supplier, "MyFont")
1200+
.buildPdfRenderer()) {
1201+
renderer.createPDFWithoutClosing();
1202+
}
1203+
1204+
try (PdfBoxRenderer renderer = new PdfRendererBuilder()
1205+
.usePDDocument(doc)
1206+
.withHtmlContent(html2, null)
1207+
.useFont(supplier, "MyFont")
1208+
.buildPdfRenderer()) {
1209+
renderer.createPDFWithoutClosing();
1210+
}
1211+
1212+
ByteArrayOutputStream os = new ByteArrayOutputStream();
1213+
doc.save(os);
1214+
writePdfToFile("pr-684-font-reuse", os);
1215+
}
1216+
1217+
try (PDDocument doc = load("pr-684-font-reuse")) {
1218+
try (COSDocument cos = doc.getDocument()) {
1219+
COSName name1 = doc.getPage(0).getResources().getFontNames().iterator().next();
1220+
COSName name2 = doc.getPage(1).getResources().getFontNames().iterator().next();
1221+
1222+
COSObjectKey fnt1 = cos.getKey(doc.getPage(0).getResources().getFont(name1).getCOSObject());
1223+
COSObjectKey fnt2 = cos.getKey(doc.getPage(1).getResources().getFont(name2).getCOSObject());
1224+
1225+
assertEquals(fnt1, fnt2);
1226+
}
1227+
1228+
remove("pr-684-font-reuse", doc);
1229+
}
1230+
}
1231+
11721232
// TODO:
11731233
// + More form controls.
11741234
// + Custom meta info.

0 commit comments

Comments
 (0)