Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#683 #684 Test of avoiding double embedding fonts #695

Draft
wants to merge 1 commit into
base: open-dev-v1
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import com.openhtmltopdf.visualtest.VisualTester.BuilderConfig;

public class TestSupport {
public static final String FONT_FILES_PATH = "target/test/visual-tests/";

/**
* Output the font file as a regular file so we don't have to use streams.
* @throws IOException
Expand All @@ -54,15 +56,28 @@ public static void makeFontFile(String resource) throws IOException {
File outputDirectory = new File("target/test/visual-tests/test-output/j2d/");
outputDirectory.mkdirs();

File fontFile = new File("target/test/visual-tests/" + resource);
File fontFile = new File(FONT_FILES_PATH + resource);

if (!fontFile.exists()) {
try (InputStream in = TestSupport.class.getResourceAsStream("/visualtest/html/fonts/" + resource)) {
Files.copy(in, fontFile.toPath());
}
}
}


public static File fontFileKarlaBold() {
return new File(FONT_FILES_PATH + "Karla-Bold.ttf");
}

public static File fontFileNotoNaskhArabicRegular() {
return new File(FONT_FILES_PATH + "NotoNaskhArabic-Regular.ttf");
}

public static File fontFileSourceSansProRegular() {
return new File(FONT_FILES_PATH + "SourceSansPro-Regular.ttf");
}


/**
* Output the test fonts from classpath to files in target so we can use them
* without streams.
Expand Down Expand Up @@ -153,25 +168,25 @@ public void setText(String newText) {
this.matcher = SPACES.matcher(newText);
}
}

public static final BuilderConfig WITH_FONT = (builder) -> {
builder.useFont(new File("target/test/visual-tests/Karla-Bold.ttf"), "TestFont");
builder.useFont(fontFileKarlaBold(), "TestFont");
builder.useUnicodeLineBreaker(new SimpleTextBreaker());
};

public static final Java2DBuilderConfig J2D_WITH_FONT = (builder) -> {
builder.useFont(new File("target/test/visual-tests/Karla-Bold.ttf"), "TestFont");
builder.useFont(fontFileKarlaBold(), "TestFont");
builder.useUnicodeLineBreaker(new SimpleTextBreaker());
};

public static final BuilderConfig WITH_EXTRA_FONT = (builder) -> {
WITH_FONT.configure(builder);
builder.useFont(new File("target/test/visual-tests/SourceSansPro-Regular.ttf"), "ExtraFont");
builder.useFont(fontFileSourceSansProRegular(), "ExtraFont");
};

public static final BuilderConfig WITH_ARABIC = (builder) -> {
WITH_FONT.configure(builder);
builder.useFont(new File("target/test/visual-tests/NotoNaskhArabic-Regular.ttf"), "arabic");
builder.useFont(fontFileNotoNaskhArabicRegular(), "arabic");
builder.useUnicodeBidiSplitter(new ICUBidiSplitter.ICUBidiSplitterFactory());
builder.useUnicodeBidiReorderer(new ICUBidiReorderer());
builder.useUnicodeLineBreaker(new ICUBreakers.ICULineBreaker(Locale.US)); // Overrides WITH_FONT
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body style="font-family: 'MyFont'; font-size: 24px;">
This first document should use the same font resource as the second document.
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body style="font-family: 'MyFont'; font-size: 24px; margin-top: 100px;">
This second document should use the same font resource as the first document.
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.cos.COSObjectKey;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationFileAttachment;
Expand All @@ -44,10 +47,12 @@
import org.apache.pdfbox.text.PDFTextStripper;
import org.hamcrest.CustomTypeSafeMatcher;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.openhtmltopdf.layout.Layer;
import com.openhtmltopdf.outputdevice.helper.ExternalResourceControlPriority;
import com.openhtmltopdf.pdfboxout.PDFontSupplier;
import com.openhtmltopdf.pdfboxout.PagePosition;
import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
Expand All @@ -61,7 +66,12 @@
public class NonVisualRegressionTest {
private static final String RES_PATH = "/visualtest/html/";
private static final String OUT_PATH = "target/test/visual-tests/test-output/";


@BeforeClass
public static void configureTests() throws IOException {
TestSupport.makeFontFiles();
}

private static void render(String fileName, String html, BuilderConfig config) throws IOException {
ByteArrayOutputStream actual = new ByteArrayOutputStream();

Expand Down Expand Up @@ -1169,6 +1179,56 @@ public void testIssue427GetBodyPagePositions() throws IOException {
assertEquals(111.48, lastContentLine, 0.5);
}

/**
* Tests that it is possible to use a PDDocument multiple times
* without re-embedding required fonts.
* PR#684, Issue#683
*/
@Test
public void testPr684FontReuse() throws IOException {
String html1 = loadHtml("pr-684-font-reuse-1");
String html2 = loadHtml("pr-684-font-reuse-2");

try (PDDocument doc = new PDDocument()) {
PDFont font = PDType0Font.load(doc, TestSupport.fontFileKarlaBold());
PDFontSupplier supplier = new PDFontSupplier(font);

try (PdfBoxRenderer renderer = new PdfRendererBuilder()
.usePDDocument(doc)
.withHtmlContent(html1, null)
.useFont(supplier, "MyFont")
.buildPdfRenderer()) {
renderer.createPDFWithoutClosing();
}

try (PdfBoxRenderer renderer = new PdfRendererBuilder()
.usePDDocument(doc)
.withHtmlContent(html2, null)
.useFont(supplier, "MyFont")
.buildPdfRenderer()) {
renderer.createPDFWithoutClosing();
}

ByteArrayOutputStream os = new ByteArrayOutputStream();
doc.save(os);
writePdfToFile("pr-684-font-reuse", os);
}

try (PDDocument doc = load("pr-684-font-reuse")) {
try (COSDocument cos = doc.getDocument()) {
COSName name1 = doc.getPage(0).getResources().getFontNames().iterator().next();
COSName name2 = doc.getPage(1).getResources().getFontNames().iterator().next();

COSObjectKey fnt1 = cos.getKey(doc.getPage(0).getResources().getFont(name1).getCOSObject());
COSObjectKey fnt2 = cos.getKey(doc.getPage(1).getResources().getFont(name2).getCOSObject());

assertEquals(fnt1, fnt2);
}

remove("pr-684-font-reuse", doc);
}
}

// TODO:
// + More form controls.
// + Custom meta info.
Expand Down