com.openhtmltopdf.java2d.api.Java2DRendererBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openhtmltopdf-java2d Show documentation
Show all versions of openhtmltopdf-java2d Show documentation
Openhtmltopdf is a CSS 2.1 renderer written in Java. This artifact supports image output with the Java2D API.
package com.openhtmltopdf.java2d.api;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.openhtmltopdf.layout.Layer;
import org.w3c.dom.Document;
import com.openhtmltopdf.bidi.BidiReorderer;
import com.openhtmltopdf.bidi.BidiSplitterFactory;
import com.openhtmltopdf.extend.*;
import com.openhtmltopdf.java2d.Java2DRenderer;
import com.openhtmltopdf.outputdevice.helper.BaseDocument;
import com.openhtmltopdf.outputdevice.helper.PageDimensions;
import com.openhtmltopdf.outputdevice.helper.UnicodeImplementation;
import com.openhtmltopdf.render.RenderingContext;
import com.openhtmltopdf.swing.EmptyReplacedElement;
/**
* Build a Java2D renderer for a given HTML. The renderer allows to get a
* BufferedImage of the HTML and to render it in components (using Graphics2D).
*/
public class Java2DRendererBuilder {
private HttpStreamFactory _httpStreamFactory;
private FSCache _cache;
private FSUriResolver _resolver;
private String _html;
private String _baseUri;
private Document _document;
private SVGDrawer _svgImpl;
private String _replacementText;
private FSTextBreaker _lineBreaker;
private FSTextBreaker _charBreaker;
private FSTextTransformer _unicodeToUpperTransformer;
private FSTextTransformer _unicodeToLowerTransformer;
private FSTextTransformer _unicodeToTitleTransformer;
private BidiSplitterFactory _splitter;
private BidiReorderer _reorderer;
private boolean _textDirection = false;
private Float _pageWidth;
private Float _pageHeight;
private boolean _isPageSizeInches;
private FSPageProcessor _pageProcessor;
private String _uri;
private File _file;
private boolean _testMode = false;
private Graphics2D _layoutGraphics;
private int _initialPageNumber;
private short _pagingMode = Layer.PAGED_MODE_PRINT;
private FSObjectDrawerFactory _objectDrawerFactory;
public enum TextDirection { RTL, LTR; }
public enum PageSizeUnits { MM, INCHES }
public enum FontStyle { NORMAL, ITALIC, OBLIQUE }
private static class AddedFont {
private final FSSupplier supplier;
private final Integer weight;
private final String family;
private final FontStyle style;
private AddedFont(FSSupplier supplier, Integer weight, String family, FontStyle style) {
this.supplier = supplier;
this.weight = weight;
this.family = family;
this.style = style;
}
}
private List _fonts = new ArrayList();
/**
* Provides an HttpStreamFactory implementation if the user desires to use
* an external HTTP/HTTPS implementation. Uses URL::openStream by default.
*
* @param factory
* @return
*/
public Java2DRendererBuilder useHttpStreamImplementation(HttpStreamFactory factory) {
this._httpStreamFactory = factory;
return this;
}
/**
* Provides a uri resolver to resolve relative uris or private uri schemes.
*
* @param resolver
* @return
*/
public Java2DRendererBuilder useUriResolver(FSUriResolver resolver) {
this._resolver = resolver;
return this;
}
/**
* Provides an external cache which can choose to cache items between runs,
* such as fonts or logo images.
*
* @param cache
* @return
*/
public Java2DRendererBuilder useCache(FSCache cache) {
this._cache = cache;
return this;
}
/**
* Provides a string containing XHTML/XML to convert to image.
*
* @param html
* @param baseUri
* @return
*/
public Java2DRendererBuilder withHtmlContent(String html, String baseUri) {
this._html = html;
this._baseUri = baseUri;
return this;
}
/**
* Provides a w3c DOM Document acquired from an external source.
*
* @param doc
* @param baseUri
* @return
*/
public Java2DRendererBuilder withW3cDocument(org.w3c.dom.Document doc, String baseUri) {
this._document = doc;
this._baseUri = baseUri;
return this;
}
/**
* Provides a URI to convert to image. The URI MUST point to a strict XHTML/XML document.
* @param uri
* @return
*/
public Java2DRendererBuilder withUri(String uri) {
this._uri = uri;
return this;
}
/**
* Uses the specified SVG drawer implementation.
*
* @param svgImpl
* @return
*/
public Java2DRendererBuilder useSVGDrawer(SVGDrawer svgImpl) {
this._svgImpl = svgImpl;
return this;
}
/**
* Compulsory method. The layout graphics are used to measure text and should be from an image or device with
* the same characteristics as the output graphicsw provided by the page processor.
* @param g2d
* @return
*/
public Java2DRendererBuilder useLayoutGraphics(Graphics2D g2d) {
this._layoutGraphics = g2d;
return this;
}
/**
* The default text direction of the document. LTR by default.
* @param textDirection
* @return
*/
public Java2DRendererBuilder defaultTextDirection(TextDirection textDirection) {
this._textDirection = textDirection == TextDirection.RTL;
return this;
}
/**
* Whether to use test mode which will output box boundaries on the result. Turned off by default.
* @param mode
* @return
*/
public Java2DRendererBuilder testMode(boolean mode) {
this._testMode = mode;
return this;
}
/**
* Provides a text splitter to split text into directional runs. Does nothing by default.
* @param splitter
* @return
*/
public Java2DRendererBuilder useUnicodeBidiSplitter(BidiSplitterFactory splitter) {
this._splitter = splitter;
return this;
}
/**
* Provides a reorderer to properly reverse RTL text. No-op by default.
* @param reorderer
* @return
*/
public Java2DRendererBuilder useUnicodeBidiReorderer(BidiReorderer reorderer) {
this._reorderer = reorderer;
return this;
}
/**
* Provides a file to convert to PDF. The file MUST contain XHTML/XML in UTF-8 encoding.
* @param file
* @return
*/
public Java2DRendererBuilder withFile(File file) {
this._file = file;
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.
* Also, make sure it can be rendered by at least one of your specified fonts!
* The default is the # character.
* @param replacement
* @return
*/
public Java2DRendererBuilder useReplacementText(String replacement) {
this._replacementText = replacement;
return this;
}
/**
* Specify the line breaker. By default a Java default BreakIterator line instance is used
* with US locale. Additionally, this is wrapped with UrlAwareLineBreakIterator to also
* break before the forward slash (/) character so that long URIs can be broken on to multiple lines.
*
* You may want to use a BreakIterator with a different locale (wrapped by UrlAwareLineBreakIterator or not)
* or a more advanced BreakIterator from icu4j (see the rtl-support module for an example).
* @param breaker
* @return
*/
public Java2DRendererBuilder useUnicodeLineBreaker(FSTextBreaker breaker) {
this._lineBreaker = breaker;
return this;
}
/**
* Specify the character breaker. By default a break iterator character instance is used with
* US locale. Currently this is used when word-wrap: break-word
is in
* effect.
* @param breaker
* @return
*/
public Java2DRendererBuilder useUnicodeCharacterBreaker(FSTextBreaker breaker) {
this._charBreaker = breaker;
return this;
}
/**
* Specify a transformer to use to upper case strings.
* By default String::toUpperCase(Locale.US)
is used.
* @param tr
* @return
*/
public Java2DRendererBuilder useUnicodeToUpperTransformer(FSTextTransformer tr) {
this._unicodeToUpperTransformer = tr;
return this;
}
/**
* Specify a transformer to use to lower case strings.
* By default String::toLowerCase(Locale.US)
is used.
* @param tr
* @return
*/
public Java2DRendererBuilder useUnicodeToLowerTransformer(FSTextTransformer tr) {
this._unicodeToLowerTransformer = tr;
return this;
}
/**
* Specify a transformer to title case strings.
* By default a best effort implementation (non locale aware) is used.
* @param tr
* @return
*/
public Java2DRendererBuilder useUnicodeToTitleTransformer(FSTextTransformer tr) {
this._unicodeToTitleTransformer = tr;
return this;
}
/**
* Add a font programmatically. The font will only be downloaded if needed.
*
* The InputStream returned by the supplier will be closed by the caller.
* FSSupplier is a lambda compatible interface.
*
* Fonts can also be added using a font-face at-rule in the CSS.
* @param supplier
* @param fontFamily
* @param fontWeight
* @param fontStyle
* @return
*/
public Java2DRendererBuilder useFont(FSSupplier supplier, String fontFamily, Integer fontWeight, FontStyle fontStyle) {
this._fonts.add(new AddedFont(supplier, fontWeight, fontFamily, fontStyle));
return this;
}
/**
* Simpler overload for {@link #useFont(FSSupplier, String, Integer, FontStyle)}
* @param supplier
* @param fontFamily
* @return
*/
public Java2DRendererBuilder useFont(FSSupplier supplier, String fontFamily) {
return this.useFont(supplier, fontFamily, 400, FontStyle.NORMAL);
}
/**
* Specifies the default page size to use if none is specified in CSS.
* @param pageWidth
* @param pageHeight
* @param units either mm or inches.
* @see {@link #PAGE_SIZE_LETTER_WIDTH}, {@link #PAGE_SIZE_LETTER_HEIGHT} and {@link #PAGE_SIZE_LETTER_UNITS}
* @return
*/
public Java2DRendererBuilder useDefaultPageSize(float pageWidth, float pageHeight, PageSizeUnits units) {
this._pageWidth = pageWidth;
this._pageHeight = pageHeight;
this._isPageSizeInches = (units == PageSizeUnits.INCHES);
return this;
}
/**
* Used to set an initial page number for use with page counters, etc.
* @param pageNumberInitial
* @return
*/
public Java2DRendererBuilder useInitialPageNumber(int pageNumberInitial) {
this._initialPageNumber = pageNumberInitial;
return this;
}
/**
* Render everything to a single page. I.e. only one big page is genereated,
* no pagebreak will be done. The page is only as height as needed.
*/
public Java2DRendererBuilder toSinglePage(FSPageProcessor pageProcessor){
this._pagingMode = Layer.PAGED_MODE_SCREEN;
this._pageProcessor = pageProcessor;
return this;
}
/**
* Output the document in paged format. The user can use the DefaultPageProcessor or use its source
* as a reference to code their own page processor for advanced usage.
* @param pageProcessor
* @return
*/
public Java2DRendererBuilder toPageProcessor(FSPageProcessor pageProcessor) {
this._pagingMode = Layer.PAGED_MODE_PRINT;
this._pageProcessor = pageProcessor;
return this;
}
/**
* useLayoutGraphics
and toPageProcessor
MUST have been called.
* Also a document MUST have been set with one of the with* methods.
* This will build the renderer and output each page of the document to the specified page
* processor.
* @throws Exception
*/
public void runPaged() throws Exception {
Java2DRenderer renderer = this.buildJava2DRenderer();
renderer.layout();
if( _pagingMode == Layer.PAGED_MODE_PRINT)
renderer.writePages();
else
renderer.writeSinglePage();
}
/**
* useLayoutGraphics
and toPageProcessor
MUST have been called.
* Also a document MUST have been set with one of the with* methods.
* This will build the renderer and output the first page of the document to the specified page
* processor.
* @throws Exception
*/
public void runFirstPage() throws Exception {
Java2DRenderer renderer = this.buildJava2DRenderer();
renderer.layout();
if( _pagingMode == Layer.PAGED_MODE_PRINT)
renderer.writePage(0);
else
renderer.writeSinglePage();
}
public Java2DRenderer buildJava2DRenderer() {
UnicodeImplementation unicode = new UnicodeImplementation(_reorderer, _splitter, _lineBreaker,
_unicodeToLowerTransformer, _unicodeToUpperTransformer, _unicodeToTitleTransformer, _textDirection, _charBreaker);
PageDimensions pageSize = new PageDimensions(_pageWidth, _pageHeight, _isPageSizeInches);
BaseDocument doc = new BaseDocument(_baseUri, _html, _document, _file, _uri);
/*
* If no layout graphics is provied, just use a sane default
*/
if(_layoutGraphics == null ) {
BufferedImage bf = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
_layoutGraphics = bf.createGraphics();
}
return new Java2DRenderer(doc, unicode, _httpStreamFactory, _resolver, _cache, _svgImpl, pageSize, _replacementText, _testMode, _pageProcessor, _layoutGraphics, _initialPageNumber, _pagingMode, _objectDrawerFactory);
}
/**
* Set a factory for <object> drawers
* @param objectDrawerFactory Object Drawer Factory
* @return this for method chaining
*/
public Java2DRendererBuilder useObjectDrawerFactory(FSObjectDrawerFactory objectDrawerFactory) {
this._objectDrawerFactory = objectDrawerFactory;
return this;
}
public static abstract class Graphics2DPaintingReplacedElement extends EmptyReplacedElement {
protected Graphics2DPaintingReplacedElement(int width, int height) {
super(width, height);
}
public abstract void paint(OutputDevice outputDevice, RenderingContext ctx, double x, double y, double width,
double height);
public static double DOTS_PER_INCH = 72.0;
}
}