Skip to content

Commit

Permalink
#79 - Support and test for running content (ie. fixed, running, page …
Browse files Browse the repository at this point in the history
…margins).

Also fixed language code in document catalog.
  • Loading branch information
danfickle committed Jan 23, 2019
1 parent d43af23 commit 2dd7a3f
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public enum StructureType {
LAYER,
RUNNING,
BACKGROUND,
TEXT,
FLOAT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.openhtmltopdf.css.style.CssContext;
import com.openhtmltopdf.css.style.derived.LengthValue;
import com.openhtmltopdf.css.style.derived.RectPropertySet;
import com.openhtmltopdf.extend.StructureType;
import com.openhtmltopdf.layout.BoxBuilder;
import com.openhtmltopdf.layout.Layer;
import com.openhtmltopdf.layout.LayoutContext;
Expand Down Expand Up @@ -425,7 +426,9 @@ public void paintMarginAreas(RenderingContext c, int additionalClearance, short
if (c.getOutputDevice().isFastRenderer()) {
table.getLayer().propagateCurrentTransformationMatrix(c);
SimplePainter painter = new SimplePainter(p.x, p.y);
Object token = c.getOutputDevice().startStructure(StructureType.RUNNING, table);
painter.paintLayer(c, table.getLayer());
c.getOutputDevice().endStructure(token);
} else {
table.getLayer().paint(c);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ public void paint(RenderingContext c, DisplayListPageContainer pageOperations) {
if (op instanceof PaintRootElementBackground) {

PaintRootElementBackground dlo = (PaintRootElementBackground) op;

Object token = c.getOutputDevice().startStructure(StructureType.BACKGROUND, dlo.getRoot());
dlo.getRoot().paintRootElementBackground(c);
c.getOutputDevice().endStructure(token);

} else if (op instanceof PaintLayerBackgroundAndBorder) {

Expand Down Expand Up @@ -273,7 +276,9 @@ public void paint(RenderingContext c, DisplayListPageContainer pageOperations) {
} else if (op instanceof PaintFixedLayer) {

PaintFixedLayer dlo = (PaintFixedLayer) op;
Object token = c.getOutputDevice().startStructure(StructureType.RUNNING, dlo.getLayer().getMaster());
paintFixed(c, dlo.getLayer());
c.getOutputDevice().endStructure(token);

} else if (op instanceof PaintPushClipRect) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ public static void main(String... args) throws Exception {
run("text-over-two-pages");
run("image");
run("image-over-two-pages");
run("running");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<html lang="EN-US">
<head>
<title>Simple PDF/UA Testcase</title>
<meta name="description" content="A simple example"/>
<style>
@page {
size: 200px 200px;
margin: 20px 10px 20px 10px;

@top-center {
font-family: 'TestFont';
content: "Running Content";
}

@bottom-center {
font-family: 'TestFont';
content: element(ftr);
}
}
body {
margin: 0;
width: 180px;
}
</style>
</head>
<body style="font-family: 'TestFont'; font-size: 14px;">
<div style="position: fixed;left: 0; top: 0;">
<div><span style="background-color: red;">Hello</span> World!</div>
</div>

<div style="position: running(ftr);">
<div>Goodbye World!</div>
</div>

<p>Paragraph one. Some text that goes over multiple lines. OK, this is getting to the required length.</p>
<p>Paragraph two. Some text that goes over multiple lines. OK, this is getting to the required length.</p>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class PdfBoxAccessibilityHelper {
private float _pageHeight;
private AffineTransform _transform;

private int _runningLevel;

public PdfBoxAccessibilityHelper(PdfBoxFastOutputDevice od, Box root, Document doc) {
this._od = od;
this._rootBox = root;
Expand Down Expand Up @@ -372,60 +374,101 @@ private COSDictionary createBackgroundArtifact(StructureType type, Box box) {
return dict;
}

public Object startStructure(StructureType type, Box box) {
private COSDictionary createPaginationArtifact(StructureType type, Box box) {
COSDictionary dict = new COSDictionary();
dict.setItem(COSName.TYPE, COSName.getPDFName("Pagination"));
return dict;
}

private static class Token {
}

private static final Token TRUE_TOKEN = new Token();
private static final Token FALSE_TOKEN = new Token();
private static final Token INSIDE_RUNNING = new Token();
private static final Token STARTING_RUNNING = new Token();
private static final Token NESTED_RUNNING = new Token();

public Token startStructure(StructureType type, Box box) {
// Check for items that appear on every page (fixed, running, page margins).
if (type == StructureType.RUNNING) {
// Only mark artifact for first level of running element (we might have
// nested fixed elements).
if (_runningLevel == 0) {
_runningLevel++;
COSDictionary run = createPaginationArtifact(type, box);
_cs.beginMarkedContent(COSName.ARTIFACT, run);
return STARTING_RUNNING;
}

_runningLevel++;
return NESTED_RUNNING;
} else if (_runningLevel > 0) {
// We are in a running artifact.
return INSIDE_RUNNING;
}

switch (type) {
case LAYER:
case FLOAT:
case BLOCK: {
createStructureItem(type, box);
return Boolean.FALSE;
return FALSE_TOKEN;
}
case INLINE: {
if (box.hasNonTextContent(_ctx) ||
box.getChildCount() > 0 ||
// Only create a structual element holder for this element if it has non text child nodes.
if (box.getChildCount() > 0 ||
(box instanceof InlineLayoutBox && !((InlineLayoutBox) box).isAllTextItems(_ctx))) {
createStructureItem(type, box);
}
return Boolean.FALSE;
return FALSE_TOKEN;
}
case BACKGROUND: {
if (box.hasNonTextContent(_ctx)) {
COSDictionary current = createBackgroundArtifact(type, box);
_cs.beginMarkedContent(COSName.ARTIFACT, current);
return Boolean.TRUE;
return TRUE_TOKEN;
}
return Boolean.FALSE;
return FALSE_TOKEN;
}
case TEXT: {
StructureItem current = createMarkedContentStructureItem(type, box);
_cs.beginMarkedContent(COSName.getPDFName(StandardStructureTypes.SPAN), current.dict);
return Boolean.TRUE;
return TRUE_TOKEN;
}
case REPLACED: {
createStructureItem(type, box);
StructureItem current = createFigureContentStructureItem(type, box);
if (current != null) {
_cs.beginMarkedContent(COSName.getPDFName(StandardStructureTypes.Figure), current.dict);
return Boolean.TRUE;
return TRUE_TOKEN;
} else {
// For images that continue over more than one page, just mark the portion on the second
// and subsequent pages as an artifact. The spec (PDF 1.7) is not clear on what to do in this
// situation.
COSDictionary bg = createBackgroundArtifact(type, box);
_cs.beginMarkedContent(COSName.ARTIFACT, bg);
return Boolean.TRUE;
return TRUE_TOKEN;
}
}
default: {
return Boolean.FALSE;
return FALSE_TOKEN;
}
}
}

public void endStructure(Object token) {
Boolean marked = (Boolean) token;
Token value = (Token) token;

if (marked.booleanValue()) {
if (value == TRUE_TOKEN) {
_cs.endMarkedContent();
} else if (value == FALSE_TOKEN ||
value == INSIDE_RUNNING) {
// do nothing...
} else if (value == NESTED_RUNNING) {
_runningLevel--;
} else if (value == STARTING_RUNNING) {
_runningLevel--;
_cs.endMarkedContent();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ private void addPdfUaXMPSchema(PDDocument doc) {
{
PDDocumentCatalog catalog = doc.getDocumentCatalog();
String lang = _doc.getDocumentElement().getAttribute("lang");
catalog.setLanguage(lang != null ? lang : "English");
catalog.setLanguage(lang != null ? lang : "EN-US");
catalog.setViewerPreferences(new PDViewerPreferences(new COSDictionary()));
catalog.getViewerPreferences().setDisplayDocTitle(true);

Expand Down

0 comments on commit 2dd7a3f

Please sign in to comment.