diff --git a/openhtmltopdf-core/pom.xml b/openhtmltopdf-core/pom.xml index 1ab8dbb02..5ee2cb168 100644 --- a/openhtmltopdf-core/pom.xml +++ b/openhtmltopdf-core/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-core @@ -21,8 +21,9 @@ - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/CSSName.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/CSSName.java index 2a93a7fcd..eac211804 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/CSSName.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/CSSName.java @@ -1673,6 +1673,18 @@ public final class CSSName implements Comparable { NOT_INHERITED, new SizePropertyBuilder() ); + + /** + * Unique CSSName instance for CSS2 property. + */ + public final static CSSName BOX_SIZING = + addProperty( + "box-sizing", + PRIMITIVE, + "content-box", + NOT_INHERITED, + new PrimitivePropertyBuilders.BoxSizing() + ); /** * Unique CSSName instance for CSS3 property. diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java index 5e3fa486f..eb20639ae 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/IdentValue.java @@ -242,6 +242,12 @@ public class IdentValue implements FSDerivedValue { public static final IdentValue SKEW_X = addValue("skewX"); public static final IdentValue SKEW_Y = addValue("skewY"); + /* + * Box-sizing + */ + public static final IdentValue BORDER_BOX = addValue("border-box"); + public static final IdentValue CONTENT_BOX = addValue("content-box"); + /** * Description of the Field diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java index 0cfb2ea9d..d27976c1d 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/PrimitivePropertyBuilders.java @@ -1562,6 +1562,17 @@ protected BitSet getAllowed() { } } + public static class BoxSizing extends SingleIdent { + // border-box | content-box + private static final BitSet ALLOWED = setFor( + new IdentValue[] { + IdentValue.BORDER_BOX, IdentValue.CONTENT_BOX}); + + protected BitSet getAllowed() { + return ALLOWED; + } + } + public static class Widows extends PlainInteger { protected boolean isNegativeValuesAllowed() { diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java index 51ba7dc39..e145d3bdb 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/CalculatedStyle.java @@ -120,7 +120,7 @@ protected boolean removeEldestEntry(Map.Entry eldest) { * this for class instantiation externally. */ protected CalculatedStyle() { - _derivedValuesById = new FSDerivedValue[CSSName.countCSSPrimitiveNames()]; + _derivedValuesById = new FSDerivedValue[CSSName.countCSSNames()]; } @@ -1140,6 +1140,10 @@ public boolean isMaxHeightNone() { return isIdent(CSSName.MAX_HEIGHT, IdentValue.NONE); } + public boolean isBorderBox() { + return isIdent(CSSName.BOX_SIZING, IdentValue.BORDER_BOX); + } + public int getMinWidth(CssContext c, int cbWidth) { return (int) getFloatPropertyProportionalTo(CSSName.MIN_WIDTH, cbWidth, c); } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/CounterFunction.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/CounterFunction.java index 8413a6467..a9e76117a 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/CounterFunction.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/layout/CounterFunction.java @@ -66,6 +66,8 @@ public static String createCounterText(IdentValue listStyle, int listCounter) { text = toRoman(listCounter).toUpperCase(); } else if (listStyle == IdentValue.DECIMAL_LEADING_ZERO) { text = (listCounter >= 10 ? "" : "0") + listCounter; + } else if (listStyle == IdentValue.DISC) { + text = "\u2022"; } else { // listStyle == IdentValue.DECIMAL or anything else text = Integer.toString(listCounter); } diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java index 49367cd30..fc1a50cdf 100755 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/render/BlockBox.java @@ -687,6 +687,7 @@ public void calcDimensions(LayoutContext c) { protected void calcDimensions(LayoutContext c, int cssWidth) { if (! isDimensionsCalculated()) { CalculatedStyle style = getStyle(); + boolean borderBox = style.isBorderBox(); RectPropertySet padding = getPadding(c); BorderPropertySet border = getBorder(c); @@ -707,16 +708,21 @@ protected void calcDimensions(LayoutContext c, int cssWidth) { if (c.isPrint() && getStyle().isDynamicAutoWidth()) { setContentWidth(calcEffPageRelativeWidth(c)); } else { - setContentWidth((getContainingBlockWidth() - getLeftMBP() - getRightMBP())); + int proporcionalContainingBlockWidth = cssWidth != -1 ? cssWidth : getContainingBlockWidth(); + + if (borderBox) { + setContentWidth((proporcionalContainingBlockWidth - (int)border.width() - (int)padding.width())); + } else { + setContentWidth((proporcionalContainingBlockWidth) - getLeftMBP() - getRightMBP()); + } + } setHeight(0); if (! isAnonymous() || (isFromCaptionedTable() && isFloated())) { int pinnedContentWidth = -1; - if (cssWidth != -1) { - setContentWidth(cssWidth); - } else if (getStyle().isAbsolute() || getStyle().isFixed()) { + if (getStyle().isAbsolute() || getStyle().isFixed()) { pinnedContentWidth = calcPinnedContentWidth(c); if (pinnedContentWidth != -1) { setContentWidth(pinnedContentWidth); @@ -725,7 +731,13 @@ protected void calcDimensions(LayoutContext c, int cssWidth) { int cssHeight = getCSSHeight(c); if (cssHeight != -1) { - setHeight(cssHeight); + if (borderBox) { + setHeight(cssHeight - (int)padding.height() - (int)border.height()); + } else { + setHeight(cssHeight); + } + + } //check if replaced diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/swing/NaiveUserAgent.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/swing/NaiveUserAgent.java index 97fad150b..3dd4eb09e 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/swing/NaiveUserAgent.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/swing/NaiveUserAgent.java @@ -179,22 +179,25 @@ protected InputStream openStream(String uri) { java.io.InputStream is = null; try { - URL urlObj = new URL(uri); - - if (urlObj.getProtocol().equalsIgnoreCase("http") || - urlObj.getProtocol().equalsIgnoreCase("https")) { - return _streamFactory.getUrl(uri).getStream(); - } - else { - try { - is = new URL(uri).openStream(); - } catch (java.net.MalformedURLException e) { - XRLog.exception("bad URL given: " + uri, e); - } catch (java.io.FileNotFoundException e) { - XRLog.exception("item at URI " + uri + " not found"); - } catch (java.io.IOException e) { - XRLog.exception("IO problem for " + uri, e); - } + if (uri.startsWith("classpath:")) { + is = NaiveUserAgent.class.getResourceAsStream(uri.substring("classpath:".length())); + } else { + URL urlObj = new URL(uri); + + if (urlObj.getProtocol().equalsIgnoreCase("http") || + urlObj.getProtocol().equalsIgnoreCase("https")) { + return _streamFactory.getUrl(uri).getStream(); + } else { + try { + is = new URL(uri).openStream(); + } catch (java.net.MalformedURLException e) { + XRLog.exception("bad URL given: " + uri, e); + } catch (java.io.FileNotFoundException e) { + XRLog.exception("item at URI " + uri + " not found"); + } catch (java.io.IOException e) { + XRLog.exception("IO problem for " + uri, e); + } + } } } catch (MalformedURLException e2) { XRLog.exception("bad URL given: " + uri, e2); @@ -210,22 +213,25 @@ protected Reader openReader(String uri) { InputStream is = null; try { - URL urlObj = new URL(uri); - - if (urlObj.getProtocol().equalsIgnoreCase("http") || - urlObj.getProtocol().equalsIgnoreCase("https")) { - return _streamFactory.getUrl(uri).getReader(); - } - else { - try { - is = new URL(uri).openStream(); - } catch (java.net.MalformedURLException e) { - XRLog.exception("bad URL given: " + uri, e); - } catch (java.io.FileNotFoundException e) { - XRLog.exception("item at URI " + uri + " not found"); - } catch (java.io.IOException e) { - XRLog.exception("IO problem for " + uri, e); - } + if (uri.startsWith("classpath:")) { + is = NaiveUserAgent.class.getResourceAsStream(uri.substring("classpath:".length())); + } else { + URL urlObj = new URL(uri); + + if (urlObj.getProtocol().equalsIgnoreCase("http") || + urlObj.getProtocol().equalsIgnoreCase("https")) { + return _streamFactory.getUrl(uri).getReader(); + } else { + try { + is = new URL(uri).openStream(); + } catch (java.net.MalformedURLException e) { + XRLog.exception("bad URL given: " + uri, e); + } catch (java.io.FileNotFoundException e) { + XRLog.exception("item at URI " + uri + " not found"); + } catch (java.io.IOException e) { + XRLog.exception("IO problem for " + uri, e); + } + } } } catch (MalformedURLException e2) { XRLog.exception("bad URL given: " + uri, e2); diff --git a/openhtmltopdf-examples/pom.xml b/openhtmltopdf-examples/pom.xml index 74002fb67..dbb893497 100644 --- a/openhtmltopdf-examples/pom.xml +++ b/openhtmltopdf-examples/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-examples diff --git a/openhtmltopdf-java2d/pom.xml b/openhtmltopdf-java2d/pom.xml index dd96731f7..9d8d6a795 100644 --- a/openhtmltopdf-java2d/pom.xml +++ b/openhtmltopdf-java2d/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-java2d @@ -23,10 +23,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/openhtmltopdf-jsoup-dom-converter/pom.xml b/openhtmltopdf-jsoup-dom-converter/pom.xml index 77e867646..dcfc6bd7e 100644 --- a/openhtmltopdf-jsoup-dom-converter/pom.xml +++ b/openhtmltopdf-jsoup-dom-converter/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-jsoup-dom-converter @@ -24,10 +24,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/openhtmltopdf-log4j/pom.xml b/openhtmltopdf-log4j/pom.xml index 2a3049f28..797b96934 100644 --- a/openhtmltopdf-log4j/pom.xml +++ b/openhtmltopdf-log4j/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-log4j @@ -24,10 +24,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/openhtmltopdf-pdfbox/pom.xml b/openhtmltopdf-pdfbox/pom.xml index b7632f1bc..8451d9009 100644 --- a/openhtmltopdf-pdfbox/pom.xml +++ b/openhtmltopdf-pdfbox/pom.xml @@ -18,7 +18,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-pdfbox @@ -35,10 +35,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + @@ -50,8 +51,14 @@ org.apache.pdfbox pdfbox - 2.0.7 + + 2.0.5-inqool + + org.apache.pdfbox + xmpbox + 2.0.5-inqool + com.openhtmltopdf openhtmltopdf-core diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java index ba009e43e..f481e9baa 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java @@ -33,6 +33,7 @@ import com.openhtmltopdf.extend.OutputDevice; import com.openhtmltopdf.extend.OutputDeviceGraphicsDrawer; import com.openhtmltopdf.layout.SharedContext; +import com.openhtmltopdf.outputdevice.helper.FontResolverHelper; import com.openhtmltopdf.pdfboxout.PdfBoxFontResolver.FontDescription; import com.openhtmltopdf.pdfboxout.PdfBoxForm.CheckboxStyle; import com.openhtmltopdf.render.*; @@ -51,6 +52,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory; import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; +import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitHeightDestination; @@ -520,8 +522,6 @@ public void drawString(String s, float x, float y, JustificationInfo info) { } public void drawStringFast(String s, float x, float y, JustificationInfo info, FontDescription desc, float fontSize) { - // TODO: Emulate bold and italic. - if (s.length() == 0) return; @@ -540,21 +540,66 @@ public void drawStringFast(String s, float x, float y, JustificationInfo info, F fontSize = fontSize / _dotsPerPoint; + boolean resetMode = false; + FontSpecification fontSpec = getFontSpecification(); + if (fontSpec != null) { + int need = FontResolverHelper.convertWeightToInt(fontSpec.fontWeight); + int have = desc.getWeight(); + if (need > have) { + _cp.setRenderingMode(RenderingMode.FILL_STROKE); + float lineWidth = fontSize * 0.04f; // 4% of font size + _cp.setLineWidth(lineWidth); + resetMode = true; + ensureStrokeColor(); + } + if ((fontSpec.fontStyle == IdentValue.ITALIC) && (desc.getStyle() != IdentValue.ITALIC)) { + b = 0f; + c = 0.21256f; + } + } + _cp.beginText(); _cp.setFont(desc.getFont(), fontSize); + + _cp.setTextMatrix((float) mx[0], b, c, (float) mx[3], (float) mx[4], (float) mx[5]); if (info != null ) { - // The JustificationInfo numbers need to be normalized using the current document DPI - _cp.setTextSpacing(info.getNonSpaceAdjust() / _dotsPerPoint); - _cp.setSpaceSpacing(info.getSpaceAdjust() / _dotsPerPoint); + // Justification must be done through TJ rendering because Tw param is not working for UNICODE fonts + Object[] array = makeJustificationArray(s, info); + _cp.drawStringWithPositioning(array); } else { _cp.setTextSpacing(0.0f); _cp.setSpaceSpacing(0.0f); + _cp.drawString(s); } - - _cp.drawString(s); + _cp.endText(); + + if (resetMode) { + _cp.setRenderingMode(RenderingMode.FILL); + _cp.setLineWidth(1); + } + } + + private Object[] makeJustificationArray(String s, JustificationInfo info) { + List data = new ArrayList(); + + int len = s.length(); + for (int i = 0; i < len; i++) { + char c = s.charAt(i); + data.add(Character.toString(c)); + if (i != len - 1) { + float offset; + if (c == ' ' || c == '\u00a0' || c == '\u3000') { + offset = info.getSpaceAdjust(); + } else { + offset = info.getNonSpaceAdjust(); + } + data.add((-offset / _dotsPerPoint) * 1000 / (_font.getSize2D() / _dotsPerPoint)); + } + } + return data.toArray(); } public static class FontRun { diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java index ec38340dc..9fbe12d55 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java @@ -43,14 +43,20 @@ import com.openhtmltopdf.util.Configuration; import com.openhtmltopdf.util.ThreadCtx; import com.openhtmltopdf.util.XRLog; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.*; import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode; +import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo; import org.apache.pdfbox.pdmodel.encryption.PDEncryption; +import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; +import org.apache.xmpbox.XMPMetadata; +import org.apache.xmpbox.schema.AdobePDFSchema; +import org.apache.xmpbox.schema.PDFAIdentificationSchema; +import org.apache.xmpbox.schema.XMPBasicSchema; +import org.apache.xmpbox.schema.XMPSchema; +import org.apache.xmpbox.type.BadFieldValueException; +import org.apache.xmpbox.xml.XmpSerializer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -87,7 +93,11 @@ public class PdfBoxRenderer { // Usually 1.7 private float _pdfVersion; - + + private String _pdfAConformance; + + private byte[] _colorProfile; + private boolean _testMode; private PDFCreationListener _listener; @@ -169,11 +179,12 @@ public PdfBoxRenderer(float dotsPerPoint, int dotsPerPixel, boolean useSubsets, PdfBoxRenderer(BaseDocument doc, UnicodeImplementation unicode, HttpStreamFactory httpStreamFactory, OutputStream os, FSUriResolver resolver, FSCache cache, SVGDrawer svgImpl, - PageDimensions pageSize, float pdfVersion, String replacementText, boolean testMode, FSObjectDrawerFactory objectDrawerFactory) { + PageDimensions pageSize, float pdfVersion, String pdfAConformance, byte[] colorProfile, String replacementText, boolean testMode, FSObjectDrawerFactory objectDrawerFactory) { _pdfDoc = new PDDocument(); + _pdfAConformance = pdfAConformance; + _colorProfile = colorProfile; _pdfDoc.setVersion(pdfVersion); - _svgImpl = svgImpl; _dotsPerPoint = DEFAULT_DOTS_PER_POINT; _testMode = testMode; @@ -585,7 +596,11 @@ private void writePDF(List pages, RenderingContext c, Rectangle2D first c.setPageCount(pageCount); firePreWrite(pageCount); // opportunity to adjust meta data setDidValues(doc); // set PDF header fields from meta data - + + if (_pdfAConformance != null) { + addPdfASchema(doc, _pdfAConformance); + } + for (int i = 0; i < pageCount; i++) { PageBox currentPage = pages.get(i); @@ -607,10 +622,59 @@ private void writePDF(List pages, RenderingContext c, Rectangle2D first _outputDevice.finish(c, _root); } + private void addPdfASchema(PDDocument document, String conformance) { + PDDocumentInformation information = document.getDocumentInformation(); + XMPMetadata metadata = XMPMetadata.createXMPMetadata(); + + try { + PDFAIdentificationSchema pdfaid = metadata.createAndAddPFAIdentificationSchema(); + pdfaid.setConformance(conformance); + pdfaid.setPart(1); + + AdobePDFSchema pdfSchema = metadata.createAndAddAdobePDFSchema(); + pdfSchema.setProducer(information.getProducer()); + + XMPBasicSchema xmpBasicSchema = metadata.createAndAddXMPBasicSchema(); + xmpBasicSchema.setCreateDate(information.getCreationDate()); + + PDMetadata metadataStream = new PDMetadata(document); + PDMarkInfo markInfo = new PDMarkInfo(); + markInfo.setMarked(true); + + // add to catalog + PDDocumentCatalog catalog = document.getDocumentCatalog(); + catalog.setMetadata( metadataStream ); + catalog.setMarkInfo(markInfo); + + XmpSerializer serializer = new XmpSerializer(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + serializer.serialize(metadata, baos, true); + metadataStream.importXMPMetadata( baos.toByteArray() ); + + + if (_colorProfile != null) { + ByteArrayInputStream colorProfile = new ByteArrayInputStream(_colorProfile); + PDOutputIntent oi = new PDOutputIntent(document, colorProfile); + oi.setInfo("sRGB IEC61966-2.1"); + oi.setOutputCondition("sRGB IEC61966-2.1"); + oi.setOutputConditionIdentifier("sRGB IEC61966-2.1"); + oi.setRegistryName("http://www.color.org"); + catalog.addOutputIntent(oi); + } + + } catch (BadFieldValueException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (TransformerException e) { + throw new RuntimeException(e); + } + } + // Sets the document information dictionary values from html metadata private void setDidValues(PDDocument doc) { PDDocumentInformation info = new PDDocumentInformation(); - + info.setCreationDate(Calendar.getInstance()); info.setProducer("openhtmltopdf.com"); diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java index 36838ecaa..9150a6ff7 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java @@ -20,6 +20,7 @@ package com.openhtmltopdf.pdfboxout; import com.openhtmltopdf.css.constants.CSSName; +import com.openhtmltopdf.css.style.CssContext; import com.openhtmltopdf.extend.*; import com.openhtmltopdf.layout.LayoutContext; import com.openhtmltopdf.render.BlockBox; @@ -58,7 +59,7 @@ public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, boolean hasMaxProperty = hasMaxWidth || hasMaxHeight; if (cssWidth == -1 && cssHeight == -1) { if (hasMaxProperty) { - long maxWidth = box.getStyle().asLength(c, CSSName.MAX_WIDTH).value(); + long maxWidth = getCSSMaxWidth(c, box); long maxHeight = box.getStyle().asLength(c, CSSName.MAX_HEIGHT).value(); int intrinsicHeight = fsImage.getHeight(); int intrinsicWidth = fsImage.getWidth(); @@ -139,6 +140,10 @@ public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, return null; } + private int getCSSMaxWidth(CssContext c, BlockBox box) { + return box.getStyle().getMaxWidth(c, box.getContainingBlock().getContentWidth()); + } + public void setFormSubmissionListener(FormSubmissionListener listener) { // nothing to do, form submission is handled by pdf readers } diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java index c02d0f346..b696e74f9 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxTextRenderer.java @@ -65,7 +65,7 @@ public FSFontMetrics getFSFontMetrics(FontContext context, FSFont font, String s try { float largestAscent = Float.MIN_VALUE; float largestDescent = Float.MIN_VALUE; - float largestStrikethroughOffset = Float.MIN_VALUE; + float largestStrikethroughOffset = -Float.MAX_VALUE; float largestStrikethroughThickness = Float.MIN_VALUE; float largestUnderlinePosition = Float.MIN_VALUE; float largestUnderlineThickness = Float.MIN_VALUE; diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfContentStreamAdapter.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfContentStreamAdapter.java index 8225aa390..939837a64 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfContentStreamAdapter.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfContentStreamAdapter.java @@ -6,6 +6,7 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; +import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode; import org.apache.pdfbox.util.Matrix; import java.awt.geom.AffineTransform; @@ -265,6 +266,14 @@ public void setTextMatrix(float a, float b, float c, float d, float e, } } + public void setRenderingMode(RenderingMode rm) { + try { + cs.setRenderingMode(rm); + } catch (IOException e) { + logAndThrow("setRenderingMode", e); + } + } + public void drawString(String s) { try { cs.showText(s); @@ -273,6 +282,14 @@ public void drawString(String s) { } } + public void drawStringWithPositioning(Object[] array) { + try { + cs.showTextWithPositioning(array); + } catch (IOException e) { + logAndThrow("drawString", e); + } + } + public void drawImage(PDImageXObject xobject, float x, float y, float w, float h) { try { diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfRendererBuilder.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfRendererBuilder.java index 3443689cc..b49871281 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfRendererBuilder.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfRendererBuilder.java @@ -53,7 +53,9 @@ public static enum FontStyle { NORMAL, ITALIC, OBLIQUE } private FSTextTransformer _unicodeToLowerTransformer; private FSTextTransformer _unicodeToTitleTransformer; private FSObjectDrawerFactory _objectDrawerFactory; - + private String _pdfAConformance; + private byte[] _colorProfile; + private static class AddedFont { private final FSSupplier supplier; private final File fontFile; @@ -103,7 +105,8 @@ public PdfBoxRenderer buildPdfRenderer() { BaseDocument doc = new BaseDocument(_baseUri, _html, _document, _file, _uri); - PdfBoxRenderer renderer = new PdfBoxRenderer(doc, unicode, _httpStreamFactory, _os, _resolver, _cache, _svgImpl, pageSize, _pdfVersion, _replacementText, _testMode, _objectDrawerFactory); + PdfBoxRenderer renderer = new PdfBoxRenderer(doc, unicode, _httpStreamFactory, _os, _resolver, _cache, _svgImpl, pageSize, _pdfVersion, _pdfAConformance, + _colorProfile, _replacementText, _testMode, _objectDrawerFactory); /* * Register all Fonts @@ -298,7 +301,28 @@ public PdfRendererBuilder usePdfVersion(float version) { this._pdfVersion = version; return this; } - + + /** + * Set the PDF/A conformance, typically we use A + * Possible values are 'A', 'B' or 'U' for PDF/A-1, PDF/A-2 and PDF/A-3 respectively + * @param pdfAConformance + * @return + */ + public PdfRendererBuilder usePdfAConformance(String pdfAConformance) { + this._pdfAConformance = pdfAConformance; + return this; + } + + /** + * Sets the color profile, needed for PDF/A conformance + * @param colorProfile + * @return + */ + public PdfRendererBuilder useColorProfile(byte[] colorProfile) { + this._colorProfile = colorProfile; + return this; + } + /** * The replacement text to use if a character is cannot be renderered by any of the specified fonts. * This is not broken across lines so should be one or zero characters for best results. diff --git a/openhtmltopdf-rtl-support/pom.xml b/openhtmltopdf-rtl-support/pom.xml index 1e651448f..87ea8d0a7 100644 --- a/openhtmltopdf-rtl-support/pom.xml +++ b/openhtmltopdf-rtl-support/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-rtl-support @@ -24,10 +24,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/openhtmltopdf-slf4j/pom.xml b/openhtmltopdf-slf4j/pom.xml index c07ead699..a9dbe0b16 100644 --- a/openhtmltopdf-slf4j/pom.xml +++ b/openhtmltopdf-slf4j/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-slf4j @@ -24,10 +24,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/openhtmltopdf-svg-support/pom.xml b/openhtmltopdf-svg-support/pom.xml index 5389fdf7f..3d097ab94 100644 --- a/openhtmltopdf-svg-support/pom.xml +++ b/openhtmltopdf-svg-support/pom.xml @@ -6,7 +6,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool openhtmltopdf-svg-support @@ -24,10 +24,11 @@ - - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent - + + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/ + diff --git a/pom.xml b/pom.xml index 42428362c..7b61c911e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.openhtmltopdf openhtmltopdf-parent - 0.0.1-RC12-SNAPSHOT + 0.0.1-RC12-inqool pom @@ -42,8 +42,9 @@ - bintray - https://api.bintray.com/maven/danfickle/maven/com.openhtmltopdf:openhtmltopdf-parent + nexus.inqool.cz + nexus.inqool.cz + http://nexus.inqool.cz/repository/maven-releases/