fixing warnings in pdfbox layout, adding fonts, adding barcodes, adding images

This commit is contained in:
Jörg Prante 2021-02-28 01:11:38 +01:00
parent 139d43e6b4
commit d434a9e4ee
71 changed files with 869 additions and 676 deletions

View file

@ -1,10 +1,93 @@
import org.xbib.graphics.barcode.AustraliaPost;
import org.xbib.graphics.barcode.AztecCode;
import org.xbib.graphics.barcode.AztecRune;
import org.xbib.graphics.barcode.ChannelCode;
import org.xbib.graphics.barcode.Codabar;
import org.xbib.graphics.barcode.CodablockF;
import org.xbib.graphics.barcode.Code11;
import org.xbib.graphics.barcode.Code128;
import org.xbib.graphics.barcode.Code16k;
import org.xbib.graphics.barcode.Code2Of5;
import org.xbib.graphics.barcode.Code32;
import org.xbib.graphics.barcode.Code3Of9;
import org.xbib.graphics.barcode.Code3Of9Extended;
import org.xbib.graphics.barcode.Code49;
import org.xbib.graphics.barcode.Code93;
import org.xbib.graphics.barcode.CodeOne;
import org.xbib.graphics.barcode.Composite;
import org.xbib.graphics.barcode.DataBar14;
import org.xbib.graphics.barcode.DataBarExpanded;
import org.xbib.graphics.barcode.DataBarLimited;
import org.xbib.graphics.barcode.DataMatrix;
import org.xbib.graphics.barcode.Ean;
import org.xbib.graphics.barcode.GridMatrix;
import org.xbib.graphics.barcode.JapanPost;
import org.xbib.graphics.barcode.KixCode;
import org.xbib.graphics.barcode.KoreaPost;
import org.xbib.graphics.barcode.Logmars;
import org.xbib.graphics.barcode.MaxiCode;
import org.xbib.graphics.barcode.MicroQrCode;
import org.xbib.graphics.barcode.MsiPlessey;
import org.xbib.graphics.barcode.Nve18;
import org.xbib.graphics.barcode.Pdf417;
import org.xbib.graphics.barcode.Pharmacode;
import org.xbib.graphics.barcode.Pharmacode2Track;
import org.xbib.graphics.barcode.Pharmazentralnummer;
import org.xbib.graphics.barcode.Postnet;
import org.xbib.graphics.barcode.QrCode;
import org.xbib.graphics.barcode.RoyalMail4State;
import org.xbib.graphics.barcode.SymbolProvider;
import org.xbib.graphics.barcode.Telepen;
import org.xbib.graphics.barcode.Upc;
import org.xbib.graphics.barcode.UspsOneCode;
import org.xbib.graphics.barcode.UspsPackage;
module org.xbib.graphics.barcode {
exports org.xbib.graphics.barcode;
exports org.xbib.graphics.barcode.util;
exports org.xbib.graphics.barcode.render;
requires transitive java.desktop;
provides SymbolProvider with Code3Of9.Provider;
provides SymbolProvider with
AustraliaPost.Provider,
AztecCode.Provider,
AztecRune.Provider,
ChannelCode.Provider,
Codabar.Provider,
CodablockF.Provider,
Code2Of5.Provider,
Code3Of9.Provider,
Code3Of9Extended.Provider,
Code11.Provider,
Code16k.Provider,
Code32.Provider,
Code49.Provider,
Code93.Provider,
Code128.Provider,
CodeOne.Provider,
Composite.Provider,
DataBar14.Provider,
DataBarExpanded.Provider,
DataBarLimited.Provider,
DataMatrix.Provider,
Ean.Provider,
GridMatrix.Provider,
JapanPost.Provider,
KixCode.Provider,
KoreaPost.Provider,
Logmars.Provider,
MaxiCode.Provider,
MicroQrCode.Provider,
MsiPlessey.Provider,
Nve18.Provider,
Pdf417.Provider,
Pharmacode.Provider,
Pharmacode2Track.Provider,
Pharmazentralnummer.Provider,
Postnet.Provider,
QrCode.Provider,
RoyalMail4State.Provider,
Telepen.Provider,
Upc.Provider,
UspsOneCode.Provider,
UspsPackage.Provider;
}

View file

@ -1,3 +1,4 @@
dependencies {
api "org.apache.pdfbox:pdfbox:${project.property('pdfbox.version')}"
api project(':graphics-pdfbox')
api project(':graphics-barcode')
}

View file

@ -1,10 +1,12 @@
module org.xbib.graphics.layout.pdfbox {
exports org.xbib.graphics.pdfbox.layout.elements;
exports org.xbib.graphics.pdfbox.layout.elements.render;
exports org.xbib.graphics.pdfbox.layout.font;
exports org.xbib.graphics.pdfbox.layout.shape;
exports org.xbib.graphics.pdfbox.layout.text;
exports org.xbib.graphics.pdfbox.layout.text.annotations;
exports org.xbib.graphics.pdfbox.layout.util;
requires transitive org.apache.pdfbox;
requires transitive org.xbib.graphics.barcode;
requires transitive org.xbib.graphics.pdfbox;
requires transitive java.desktop;
}

View file

@ -0,0 +1,116 @@
package org.xbib.graphics.pdfbox.layout.elements;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix;
import org.xbib.graphics.barcode.Symbol;
import org.xbib.graphics.barcode.render.BarcodeGraphicsRenderer;
import org.xbib.graphics.pdfbox.PdfBoxGraphics2D;
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.WidthRespecting;
import java.awt.Color;
import java.io.IOException;
public class BarcodeElement implements Element, Drawable, Dividable, WidthRespecting {
private final Symbol symbol;
private float width;
private float height;
private float maxWidth = -1;
private Position absolutePosition;
public BarcodeElement(Symbol symbol) {
this.symbol = symbol;
this.width = symbol.getWidth();
this.height = symbol.getHeight();
}
public void setScale(float scale) {
setWidth(width * scale);
setHeight(height * scale);
}
@Override
public float getWidth() throws IOException {
return width;
}
public void setWidth(float width) {
this.width = width;
}
@Override
public float getHeight() throws IOException {
return height;
}
public void setHeight(float height) {
this.height = height;
}
@Override
public Divided divide(float remainingHeight, float nextPageHeight)
throws IOException {
if (getHeight() <= nextPageHeight) {
return new Divided(new VerticalSpacer(remainingHeight), this);
}
return new Cutter(this).divide(remainingHeight, nextPageHeight);
}
@Override
public float getMaxWidth() {
return maxWidth;
}
@Override
public void setMaxWidth(float maxWidth) {
this.maxWidth = maxWidth;
}
@Override
public Position getAbsolutePosition() {
return absolutePosition;
}
/**
* Sets the absolute position to render at.
*
* @param absolutePosition the absolute position.
*/
public void setAbsolutePosition(Position absolutePosition) {
this.absolutePosition = absolutePosition;
}
@Override
public void draw(PDDocument pdDocument, PDPageContentStream contentStream,
Position upperLeft, DrawListener drawListener) throws IOException {
float x = upperLeft.getX();
float y = upperLeft.getY() - height;
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(pdDocument, width, height);
BarcodeGraphicsRenderer renderer = new BarcodeGraphicsRenderer(pdfBoxGraphics2D, null, 1.0d,
Color.WHITE, Color.BLACK, false, false);
renderer.render(symbol);
renderer.close();
PDFormXObject xFormObject = pdfBoxGraphics2D.getXFormObject();
Matrix matrix = new Matrix();
matrix.translate(x, y);
contentStream.saveGraphicsState();
contentStream.transform(matrix);
contentStream.drawForm(xFormObject);
contentStream.restoreGraphicsState();
if (drawListener != null) {
drawListener.drawn(this, upperLeft, getWidth(), getHeight());
}
}
@Override
public Drawable removeLeadingEmptyVerticalSpace() {
return this;
}
}

View file

@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The central class for creating a document.
@ -31,10 +30,13 @@ public class Document implements RenderListener {
public final static PageFormat DEFAULT_PAGE_FORMAT = new PageFormat();
private final List<Entry<Element, LayoutHint>> elements = new ArrayList<>();
private final List<Renderer> customRenderer = new CopyOnWriteArrayList<Renderer>();
private final List<RenderListener> renderListener = new CopyOnWriteArrayList<RenderListener>();
private final List<Renderer> customRenderer = new ArrayList<>();
private final List<RenderListener> renderListener = new ArrayList<>();
private PDDocument pdDocument;
private final PageFormat pageFormat;
/**
@ -60,36 +62,6 @@ public class Document implements RenderListener {
.build());
}
/**
* Creates a Document based on the given media box. By default, a
* {@link VerticalLayout} is used.
*
* @param mediaBox the media box to use.
* @deprecated use {@link #Document(PageFormat)} instead.
*/
@Deprecated
public Document(PDRectangle mediaBox) {
this(mediaBox, 0, 0, 0, 0);
}
/**
* Creates a Document based on the given media box and margins. By default,
* a {@link VerticalLayout} is used.
*
* @param mediaBox the media box to use.
* @param marginLeft the left margin
* @param marginRight the right margin
* @param marginTop the top margin
* @param marginBottom the bottom margin
* @deprecated use {@link #Document(PageFormat)} instead.
*/
@Deprecated
public Document(PDRectangle mediaBox, float marginLeft, float marginRight,
float marginTop, float marginBottom) {
this(new PageFormat(mediaBox, Orientation.Portrait, marginLeft,
marginRight, marginTop, marginBottom));
}
/**
* Creates a Document based on the given page format. By default, a
* {@link VerticalLayout} is used.

View file

@ -23,7 +23,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class Frame implements Element, Drawable, WidthRespecting, Dividable {
private final List<Drawable> innerList = new CopyOnWriteArrayList<Drawable>();
private final List<Drawable> innerList = new CopyOnWriteArrayList<>();
private float paddingLeft;
private float paddingRight;

View file

@ -2,18 +2,15 @@ package org.xbib.graphics.pdfbox.layout.elements;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.xbib.graphics.pdfbox.layout.text.DrawListener;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.WidthRespecting;
import org.xbib.graphics.pdfbox.layout.util.CompatibilityHelper;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class ImageElement implements Element, Drawable, Dividable,
WidthRespecting {
public class ImageElement implements Element, Drawable, Dividable, WidthRespecting {
/**
* Set this to {@link #setWidth(float)} resp. {@link #setHeight(float)}
@ -22,23 +19,24 @@ public class ImageElement implements Element, Drawable, Dividable,
public final static float SCALE_TO_RESPECT_WIDTH = -1f;
private final BufferedImage image;
private float width;
private float height;
private float maxWidth = -1;
private Position absolutePosition;
public ImageElement(final BufferedImage image) {
public ImageElement(BufferedImage image) {
this.image = image;
this.width = image.getWidth();
this.height = image.getHeight();
}
public ImageElement(final InputStream inputStream) throws IOException {
this(ImageIO.read(inputStream));
}
public ImageElement(final String filePath) throws IOException {
this(ImageIO.read(new File(filePath)));
public void setScale(float scale) {
setWidth(width * scale);
setHeight(height * scale);
}
@Override
@ -123,8 +121,10 @@ public class ImageElement implements Element, Drawable, Dividable,
@Override
public void draw(PDDocument pdDocument, PDPageContentStream contentStream,
Position upperLeft, DrawListener drawListener) throws IOException {
CompatibilityHelper.drawImage(image, pdDocument, contentStream,
upperLeft, getWidth(), getHeight());
float x = upperLeft.getX();
float y = upperLeft.getY() - height;
PDImageXObject imageXObject = LosslessFactory.createFromImage(pdDocument, image);
contentStream.drawImage(imageXObject, x, y, width, height);
if (drawListener != null) {
drawListener.drawn(this, upperLeft, getWidth(), getHeight());
}

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.pdfbox.layout.elements;
public enum Orientation {
Portrait, Landscape
PORTRAIT, LANDSCAPE
}

View file

@ -2,7 +2,6 @@ package org.xbib.graphics.pdfbox.layout.elements;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout;
import org.xbib.graphics.pdfbox.layout.text.Constants;
/**
* Defines the size and orientation of a page. The default is A4 portrait
@ -10,19 +9,48 @@ import org.xbib.graphics.pdfbox.layout.text.Constants;
*/
public class PageFormat implements Element {
private static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
private static final float MM_TO_UNITS = 1 / (10 * 2.54f)
* DEFAULT_USER_SPACE_UNIT_DPI;
public static final PDRectangle A0 = new PDRectangle(841 * MM_TO_UNITS,
1189 * MM_TO_UNITS);
public static final PDRectangle A1 = new PDRectangle(594 * MM_TO_UNITS,
841 * MM_TO_UNITS);
public static final PDRectangle A2 = new PDRectangle(420 * MM_TO_UNITS,
594 * MM_TO_UNITS);
public static final PDRectangle A3 = new PDRectangle(297 * MM_TO_UNITS,
420 * MM_TO_UNITS);
public static final PDRectangle A4 = new PDRectangle(210 * MM_TO_UNITS,
297 * MM_TO_UNITS);
public static final PDRectangle A5 = new PDRectangle(148 * MM_TO_UNITS,
210 * MM_TO_UNITS);
public static final PDRectangle A6 = new PDRectangle(105 * MM_TO_UNITS,
148 * MM_TO_UNITS);
public static final PDRectangle Letter = new PDRectangle(215.9f * MM_TO_UNITS,
279.4f * MM_TO_UNITS);
private final float marginLeft;
private final float marginRight;
private final float marginTop;
private final float marginBottom;
private final PDRectangle mediaBox;
private final Orientation orientation;
private final int rotation;
/**
* Creates a PageFormat with A4 portrait without margins.
*/
public PageFormat() {
this(Constants.A4);
this(A4);
}
/**
@ -31,7 +59,7 @@ public class PageFormat implements Element {
* @param mediaBox the size.
*/
public PageFormat(final PDRectangle mediaBox) {
this(mediaBox, Orientation.Portrait);
this(mediaBox, Orientation.PORTRAIT);
}
/**
@ -93,9 +121,9 @@ public class PageFormat implements Element {
return orientation;
}
if (getMediaBox().getWidth() > getMediaBox().getHeight()) {
return Orientation.Landscape;
return Orientation.LANDSCAPE;
}
return Orientation.Portrait;
return Orientation.PORTRAIT;
}
/**
@ -153,7 +181,7 @@ public class PageFormat implements Element {
private float marginRight;
private float marginTop;
private float marginBottom;
private PDRectangle mediaBox = Constants.A4;
private PDRectangle mediaBox = A4;
private Orientation orientation;
private int rotation;
@ -244,82 +272,82 @@ public class PageFormat implements Element {
}
/**
* Sets the media box to size {@link Constants#A0}.
* Sets the media box to size {@link #A0}.
*
* @return the builder.
*/
public PageFormatBuilder A0() {
this.mediaBox = Constants.A0;
this.mediaBox = A0;
return this;
}
/**
* Sets the media box to size {@link Constants#A1}.
* Sets the media box to size {@link #A1}.
*
* @return the builder.
*/
public PageFormatBuilder A1() {
this.mediaBox = Constants.A1;
this.mediaBox = A1;
return this;
}
/**
* Sets the media box to size {@link Constants#A2}.
* Sets the media box to size {@link #A2}.
*
* @return the builder.
*/
public PageFormatBuilder A2() {
this.mediaBox = Constants.A2;
this.mediaBox = A2;
return this;
}
/**
* Sets the media box to size {@link Constants#A3}.
* Sets the media box to size {@link #A3}.
*
* @return the builder.
*/
public PageFormatBuilder A3() {
this.mediaBox = Constants.A3;
this.mediaBox = A3;
return this;
}
/**
* Sets the media box to size {@link Constants#A4}.
* Sets the media box to size {@link #A4}.
*
* @return the builder.
*/
public PageFormatBuilder A4() {
this.mediaBox = Constants.A4;
this.mediaBox = A4;
return this;
}
/**
* Sets the media box to size {@link Constants#A5}.
* Sets the media box to size {@link #A5}.
*
* @return the builder.
*/
public PageFormatBuilder A5() {
this.mediaBox = Constants.A5;
this.mediaBox = A5;
return this;
}
/**
* Sets the media box to size {@link Constants#A6}.
* Sets the media box to size {@link #A6}.
*
* @return the builder.
*/
public PageFormatBuilder A6() {
this.mediaBox = Constants.A6;
this.mediaBox = A6;
return this;
}
/**
* Sets the media box to size {@link Constants#Letter}.
* Sets the media box to size {@link #Letter}.
*
* @return the builder.
*/
public PageFormatBuilder letter() {
this.mediaBox = Constants.Letter;
this.mediaBox = Letter;
return this;
}
@ -335,22 +363,22 @@ public class PageFormat implements Element {
}
/**
* Sets the orientation to {@link Orientation#Portrait}.
* Sets the orientation to {@link Orientation#PORTRAIT}.
*
* @return the builder.
*/
public PageFormatBuilder portrait() {
this.orientation = Orientation.Portrait;
this.orientation = Orientation.PORTRAIT;
return this;
}
/**
* Sets the orientation to {@link Orientation#Landscape}.
* Sets the orientation to {@link Orientation#LANDSCAPE}.
*
* @return the builder.
*/
public PageFormatBuilder landscape() {
this.orientation = Orientation.Landscape;
this.orientation = Orientation.LANDSCAPE;
return this;
}

View file

@ -0,0 +1,12 @@
package org.xbib.graphics.pdfbox.layout.elements;
public interface PageFormats {
PageFormat A4_PORTRAIT = new PageFormat();
PageFormat A4_LANDSCAPE = new PageFormat(PageFormat.A4, Orientation.LANDSCAPE);
PageFormat A5_PORTRAIT = new PageFormat(PageFormat.A5, Orientation.PORTRAIT);
PageFormat A5_LANDSCAPE = new PageFormat(PageFormat.A5, Orientation.LANDSCAPE);
}

View file

@ -16,11 +16,11 @@ import java.io.IOException;
* alignment}, and {@link WidthRespecting respects a given width} by applying
* word-wrap.
*/
public class Paragraph extends TextFlow implements Drawable, Element,
WidthRespecting, Dividable {
public class Paragraph extends TextFlow implements Drawable, Element, WidthRespecting, Dividable {
private Position absolutePosition;
private Alignment alignment = Alignment.Left;
private Alignment alignment = Alignment.LEFT;
@Override
public Position getAbsolutePosition() {

View file

@ -9,14 +9,14 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
public class ColumnLayoutHint extends VerticalLayoutHint {
public final static ColumnLayoutHint LEFT = new ColumnLayoutHint(
Alignment.Left);
Alignment.LEFT);
public final static ColumnLayoutHint CENTER = new ColumnLayoutHint(
Alignment.Center);
Alignment.CENTER);
public final static ColumnLayoutHint RIGHT = new ColumnLayoutHint(
Alignment.Right);
Alignment.RIGHT);
/**
* Creates a layout hint with {@link Alignment#Left left alignment}.
* Creates a layout hint with {@link Alignment#LEFT left alignment}.
*/
public ColumnLayoutHint() {
super();

View file

@ -28,16 +28,25 @@ import java.io.IOException;
public class RenderContext implements Renderer, Closeable, DrawContext, DrawListener {
private final Document document;
private final PDDocument pdDocument;
private PDPage page;
private int pageIndex = 0;
private PDPageContentStream contentStream;
private Position currentPosition;
private Position markedPosition;
private Position maxPositionOnPage;
private Layout layout = new VerticalLayout();
private PageFormat nextPageFormat;
private PageFormat pageFormat;
private final AnnotationDrawListener annotationDrawListener;
@ -49,8 +58,7 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
* @param pdDocument the underlying pdfbox document.
* @throws IOException by pdfbox.
*/
public RenderContext(Document document, PDDocument pdDocument)
throws IOException {
public RenderContext(Document document, PDDocument pdDocument) throws IOException {
this.document = document;
this.pdDocument = pdDocument;
this.pageFormat = document.getPageFormat();
@ -187,9 +195,9 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
*/
protected Orientation getPageOrientation() {
if (getPageWidth() > getPageHeight()) {
return Orientation.Landscape;
return Orientation.LANDSCAPE;
}
return Orientation.Portrait;
return Orientation.PORTRAIT;
}
/**
@ -328,21 +336,22 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
if (positionControl instanceof SetPosition) {
SetPosition setPosition = (SetPosition) positionControl;
Float x = setPosition.getX();
if (x == PositionControl.MARKED_POSITION) {
x = getMarkedPosition().getX();
}
if (x == null) {
x = getCurrentPosition().getX();
} else {
if (x.equals(PositionControl.MARKED_POSITION)) {
x = getMarkedPosition().getX();
}
}
Float y = setPosition.getY();
if (y == PositionControl.MARKED_POSITION) {
y = getMarkedPosition().getY();
}
if (y == null) {
y = getCurrentPosition().getY();
} else {
if (y.equals(PositionControl.MARKED_POSITION)) {
y = getMarkedPosition().getY();
}
Position newPosition = new Position(x, y);
currentPosition = newPosition;
}
currentPosition = new Position(x, y);
return true;
}
if (positionControl instanceof MovePosition) {
@ -379,12 +388,9 @@ public class RenderContext implements Renderer, Closeable, DrawContext, DrawList
page.setRotation(90);
}
}
if (isPageTilted()) {
CompatibilityHelper.transform(contentStream, 0, 1, -1, 0,
getPageHeight(), 0);
CompatibilityHelper.transform(contentStream, 0, 1, -1, 0, getPageHeight(), 0);
}
resetPositionToUpperLeft();
resetMaxPositionOnPage();
document.beforePage(this);

View file

@ -234,11 +234,11 @@ public class VerticalLayout implements Layout {
float horizontalExtraSpace = getTargetWidth(renderContext)
- drawable.getWidth();
switch (alignment) {
case Right:
case RIGHT:
offsetX = horizontalExtraSpace
- verticalLayoutHint.getMarginRight();
break;
case Center:
case CENTER:
offsetX = horizontalExtraSpace / 2f;
break;
default:

View file

@ -14,11 +14,13 @@ import org.xbib.graphics.pdfbox.layout.text.Alignment;
public class VerticalLayoutHint implements LayoutHint {
public final static VerticalLayoutHint LEFT = new VerticalLayoutHint(
Alignment.Left);
Alignment.LEFT);
public final static VerticalLayoutHint CENTER = new VerticalLayoutHint(
Alignment.Center);
Alignment.CENTER);
public final static VerticalLayoutHint RIGHT = new VerticalLayoutHint(
Alignment.Right);
Alignment.RIGHT);
private final Alignment alignment;
private final float marginLeft;
@ -28,10 +30,10 @@ public class VerticalLayoutHint implements LayoutHint {
private final boolean resetY;
/**
* Creates a layout hint with {@link Alignment#Left left alignment}.
* Creates a layout hint with {@link Alignment#LEFT left alignment}.
*/
public VerticalLayoutHint() {
this(Alignment.Left);
this(Alignment.LEFT);
}
/**
@ -124,7 +126,7 @@ public class VerticalLayoutHint implements LayoutHint {
* {@link VerticalLayoutHint} using a fluent API.
*/
public static class VerticalLayoutHintBuilder {
protected Alignment alignment = Alignment.Left;
protected Alignment alignment = Alignment.LEFT;
protected float marginLeft = 0;
protected float marginRight = 0;
protected float marginTop = 0;

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.pdfbox.layout.text;
package org.xbib.graphics.pdfbox.layout.font;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
@ -8,21 +8,24 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
* plain/italic/bold/bold-italic variants of the three standard font types
* {@link PDType1Font#TIMES_ROMAN Times},{@link PDType1Font#COURIER Courier} and
* {@link PDType1Font#HELVETICA Helveticy}.
*
* @author Ralf
*/
public enum BaseFont {
public enum BaseFont implements Font {
Times(PDType1Font.TIMES_ROMAN, PDType1Font.TIMES_BOLD,
TIMES(PDType1Font.TIMES_ROMAN, PDType1Font.TIMES_BOLD,
PDType1Font.TIMES_ITALIC, PDType1Font.TIMES_BOLD_ITALIC), //
Courier(PDType1Font.COURIER, PDType1Font.COURIER_BOLD,
COURIER(PDType1Font.COURIER, PDType1Font.COURIER_BOLD,
PDType1Font.COURIER_OBLIQUE, PDType1Font.COURIER_BOLD_OBLIQUE), //
Helvetica(PDType1Font.HELVETICA, PDType1Font.HELVETICA_BOLD,
HELVETICA(PDType1Font.HELVETICA, PDType1Font.HELVETICA_BOLD,
PDType1Font.HELVETICA_OBLIQUE, PDType1Font.HELVETICA_BOLD_OBLIQUE);
private final PDFont plainFont;
private final PDFont boldFont;
private final PDFont italicFont;
private final PDFont boldItalicFont;
BaseFont(PDFont plainFont, PDFont boldFont, PDFont italicFont,
@ -33,18 +36,22 @@ public enum BaseFont {
this.boldItalicFont = boldItalicFont;
}
@Override
public PDFont getPlainFont() {
return plainFont;
}
@Override
public PDFont getBoldFont() {
return boldFont;
}
@Override
public PDFont getItalicFont() {
return italicFont;
}
@Override
public PDFont getBoldItalicFont() {
return boldItalicFont;
}

View file

@ -0,0 +1,14 @@
package org.xbib.graphics.pdfbox.layout.font;
import org.apache.pdfbox.pdmodel.font.PDFont;
public interface Font {
PDFont getPlainFont();
PDFont getBoldFont();
PDFont getItalicFont();
PDFont getBoldItalicFont();
}

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.pdfbox.layout.text;
package org.xbib.graphics.pdfbox.layout.font;
import org.apache.pdfbox.pdmodel.font.PDFont;

View file

@ -0,0 +1,47 @@
package org.xbib.graphics.pdfbox.layout.font;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import java.io.IOException;
import java.util.Objects;
public class NotoSansFont implements Font {
private static PDType0Font regular;
private static PDType0Font bold;
private static PDType0Font italic;
private static PDType0Font bolditalic;
public NotoSansFont(PDDocument document) throws IOException {
if (regular == null) {
regular = PDType0Font.load(document, Objects.requireNonNull(getClass().getResourceAsStream("NotoSans-Regular.ttf")));
bold = PDType0Font.load(document, Objects.requireNonNull(getClass().getResourceAsStream("NotoSans-Bold.ttf")));
italic = PDType0Font.load(document, Objects.requireNonNull(getClass().getResourceAsStream("NotoSans-Italic.ttf")));
bolditalic = PDType0Font.load(document, Objects.requireNonNull(getClass().getResourceAsStream("NotoSans-BoldItalic.ttf")));
}
}
@Override
public PDFont getPlainFont() {
return regular;
}
@Override
public PDFont getBoldFont() {
return bold;
}
@Override
public PDFont getItalicFont() {
return italic;
}
@Override
public PDFont getBoldItalicFont() {
return bolditalic;
}
}

View file

@ -1,9 +1,12 @@
package org.xbib.graphics.pdfbox.layout.text;
/**
* Enumeration for (vertical) alignment.
* Enumeration for alignment.
*/
public enum Alignment {
Left, Center, Right, Justify
LEFT,
CENTER,
RIGHT,
JUSTIFY
}

View file

@ -1,28 +0,0 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
public class Constants {
private static final int DEFAULT_USER_SPACE_UNIT_DPI = 72;
private static final float MM_TO_UNITS = 1 / (10 * 2.54f)
* DEFAULT_USER_SPACE_UNIT_DPI;
public static final PDRectangle A0 = new PDRectangle(841 * MM_TO_UNITS,
1189 * MM_TO_UNITS);
public static final PDRectangle A1 = new PDRectangle(594 * MM_TO_UNITS,
841 * MM_TO_UNITS);
public static final PDRectangle A2 = new PDRectangle(420 * MM_TO_UNITS,
594 * MM_TO_UNITS);
public static final PDRectangle A3 = new PDRectangle(297 * MM_TO_UNITS,
420 * MM_TO_UNITS);
public static final PDRectangle A4 = new PDRectangle(210 * MM_TO_UNITS,
297 * MM_TO_UNITS);
public static final PDRectangle A5 = new PDRectangle(148 * MM_TO_UNITS,
210 * MM_TO_UNITS);
public static final PDRectangle A6 = new PDRectangle(105 * MM_TO_UNITS,
148 * MM_TO_UNITS);
public static final PDRectangle Letter = new PDRectangle(215.9f * MM_TO_UNITS,
279.4f * MM_TO_UNITS);
}

View file

@ -10,10 +10,11 @@ import java.util.regex.Pattern;
public class ControlCharacter implements CharSequence {
private final String description;
private final String charaterToEscape;
protected ControlCharacter(final String description,
final String charaterToEscape) {
protected ControlCharacter(String description,
String charaterToEscape) {
this.description = description;
this.charaterToEscape = charaterToEscape;
}

View file

@ -179,8 +179,7 @@ public class ControlCharacters {
}
private static class ColorControlCharacterFactory implements
ControlCharacterFactory {
private static class ColorControlCharacterFactory implements ControlCharacterFactory {
private final static Pattern PATTERN = Pattern
.compile("(?<!\\\\)(\\\\\\\\)*\\{color:#(\\p{XDigit}{6})\\}");
@ -279,5 +278,4 @@ public class ControlCharacters {
}
}
}

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color;
import java.io.IOException;

View file

@ -1,6 +1,5 @@
package org.xbib.graphics.pdfbox.layout.text;
/**
* Called if an object has been drawn.
*/

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color;
import java.io.IOException;
@ -14,9 +15,8 @@ public class Indent extends ControlFragment {
*/
public final static Indent UNINDENT = new Indent(0);
protected float indentWidth = 4;
protected SpaceUnit indentUnit = SpaceUnit.em;
protected Alignment alignment = Alignment.Left;
protected Alignment alignment = Alignment.LEFT;
protected StyledText styledText;
/**
@ -29,7 +29,7 @@ public class Indent extends ControlFragment {
public Indent(final float indentWidth, final SpaceUnit indentUnit)
throws IOException {
this("", indentWidth, indentUnit, DEFAULT_FONT_DESCRIPTOR,
Alignment.Left, Color.black);
Alignment.LEFT, Color.black);
}
/**
@ -48,7 +48,7 @@ public class Indent extends ControlFragment {
final SpaceUnit indentUnit, final float fontSize, final PDFont font)
throws IOException {
this(label, indentWidth, indentUnit, fontSize, font, Alignment.Left,
this(label, indentWidth, indentUnit, fontSize, font, Alignment.LEFT,
Color.black);
}
@ -120,10 +120,10 @@ public class Indent extends ControlFragment {
float marginRight = 0;
if (textWidth < indent) {
switch (alignment) {
case Left:
case LEFT:
marginRight = indent - textWidth;
break;
case Right:
case RIGHT:
marginLeft = indent - textWidth;
break;
default:

View file

@ -87,7 +87,7 @@ public class IndentCharacters {
public Indent createNewIndent(final float fontSize, final PDFont font,
final Color color) throws IOException {
return new Indent(nextLabel(), level * indentWidth, indentUnit,
fontSize, font, Alignment.Right, color);
fontSize, font, Alignment.RIGHT, color);
}
@Override

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
/**
* Control fragment that represents a new line in text. It has a (font and)
* height in order to specify the height of an empty line.

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
/**
* Acts as a replacement for whitespace that has been removed by word wrapping.
*/

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.io.IOException;
/**

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color;
import java.io.IOException;
@ -10,10 +11,15 @@ import java.io.IOException;
public class StyledText implements TextFragment {
private final String text;
private final FontDescriptor fontDescriptor;
private final Color color;
private final float leftMargin;
private final float rightMargin;
private final float baselineOffset;
/**

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.font.Font;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@ -13,7 +13,7 @@ import java.util.Map;
* A text flow is a text sequence that {@link WidthRespecting respects a given
* width} by word wrapping the text. The text may contain line breaks ('\n').<br>
* In order to ease creation of styled text, this class supports a kind of
* {@link #addMarkup(String, float, BaseFont) markup}. The following raw text
* {@link #addMarkup(String, float, Font) markup}. The following raw text
*
* <pre>
* Markup supports *bold*, _italic_, and *even _mixed* markup_.
@ -40,14 +40,19 @@ import java.util.Map;
public class TextFlow implements TextSequence, WidthRespecting {
public static final float DEFAULT_LINE_SPACING = 1.2f;
private static final String HEIGHT = "height";
private static final String WIDTH = "width";
private final Map<String, Object> cache = new HashMap<String, Object>();
private final Map<String, Object> cache = new HashMap<>();
private final List<TextFragment> text = new ArrayList<>();
private final List<TextFragment> text = new ArrayList<TextFragment>();
private float lineSpacing = DEFAULT_LINE_SPACING;
private float maxWidth = -1;
private boolean applyLineSpacingToFirstLine = true;
private void clearCache() {
@ -63,17 +68,8 @@ public class TextFlow implements TextSequence, WidthRespecting {
return (T) cache.get(key);
}
/**
* Adds some text associated with the font to draw. The text may contain
* line breaks ('\n').
*
* @param text the text to add.
* @param fontSize the size of the font.
* @param font the font to use to draw the text.
* @throws IOException by PDFBox
*/
public void addText(final String text, final float fontSize,
final PDFont font) throws IOException {
final Font font) throws IOException {
add(TextFlowUtil.createTextFlow(text, fontSize, font));
}
@ -87,28 +83,10 @@ public class TextFlow implements TextSequence, WidthRespecting {
* @throws IOException by PDFBox
*/
public void addMarkup(final String markup, final float fontSize,
final BaseFont baseFont) throws IOException {
final Font baseFont) throws IOException {
add(TextFlowUtil.createTextFlowFromMarkup(markup, fontSize, baseFont));
}
/**
* Adds some markup to the text flow.
*
* @param markup the markup to add.
* @param fontSize the font size to use.
* @param plainFont the plain font to use.
* @param boldFont the bold font to use.
* @param italicFont the italic font to use.
* @param boldItalicFont the bold-italic font to use.
* @throws IOException by PDFBox
*/
public void addMarkup(final String markup, final float fontSize,
final PDFont plainFont, final PDFont boldFont,
final PDFont italicFont, final PDFont boldItalicFont) throws IOException {
add(TextFlowUtil.createTextFlowFromMarkup(markup, fontSize, plainFont,
boldFont, italicFont, boldItalicFont));
}
/**
* Adds a text sequence to this flow.
*
@ -252,7 +230,7 @@ public class TextFlow implements TextSequence, WidthRespecting {
public void drawTextRightAligned(PDPageContentStream contentStream,
Position endOfFirstLine, DrawListener drawListener) throws IOException {
drawText(contentStream, endOfFirstLine.add(-getWidth(), 0),
Alignment.Right, drawListener);
Alignment.RIGHT, drawListener);
}
/**

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotatedStyledText;
import org.xbib.graphics.pdfbox.layout.text.annotations.Annotation;
import org.xbib.graphics.pdfbox.layout.text.annotations.AnnotationCharacters;
@ -16,40 +17,11 @@ import java.util.regex.Matcher;
public class TextFlowUtil {
/**
* Creates a text flow from the given text. The text may contain line
* breaks.
*
* @param text the text
* @param fontSize the font size to use.
* @param font the font to use.
* @return the created text flow.
* @throws IOException by pdfbox
*/
public static TextFlow createTextFlow(final String text,
final float fontSize, final PDFont font) throws IOException {
public static TextFlow createTextFlow(String text,
float fontSize,
Font baseFont) throws IOException {
final Iterable<CharSequence> parts = fromPlainText(text);
return createTextFlow(parts, fontSize, font, font, font, font);
}
/**
* Convenience alternative to
* {@link #createTextFlowFromMarkup(String, float, PDFont, PDFont, PDFont, PDFont)}
* which allows to specifies the fonts to use by using the {@link BaseFont}
* enum.
*
* @param markup the markup text.
* @param fontSize the font size to use.
* @param baseFont the base font describing the bundle of
* plain/blold/italic/bold-italic fonts.
* @return the created text flow.
* @throws IOException by pdfbox
*/
public static TextFlow createTextFlowFromMarkup(final String markup,
final float fontSize, final BaseFont baseFont) throws IOException {
return createTextFlowFromMarkup(markup, fontSize,
baseFont.getPlainFont(), baseFont.getBoldFont(),
baseFont.getItalicFont(), baseFont.getBoldItalicFont());
return createTextFlow(parts, fontSize, baseFont);
}
/**
@ -81,20 +53,15 @@ public class TextFlowUtil {
*
* @param markup the markup text.
* @param fontSize the font size to use.
* @param plainFont the plain font.
* @param boldFont the bold font.
* @param italicFont the italic font.
* @param boldItalicFont the bold-italic font.
* @param baseFont the font.
* @return the created text flow.
* @throws IOException by pdfbox
*/
public static TextFlow createTextFlowFromMarkup(final String markup,
final float fontSize, final PDFont plainFont,
final PDFont boldFont, final PDFont italicFont,
final PDFont boldItalicFont) throws IOException {
final float fontSize,
Font baseFont) throws IOException {
final Iterable<CharSequence> parts = fromMarkup(markup);
return createTextFlow(parts, fontSize, plainFont, boldFont, italicFont,
boldItalicFont);
return createTextFlow(parts, fontSize, baseFont);
}
/**
@ -102,17 +69,11 @@ public class TextFlowUtil {
*
* @param parts the parts to create the text flow from.
* @param fontSize the font size to use.
* @param plainFont the plain font.
* @param boldFont the bold font.
* @param italicFont the italic font.
* @param boldItalicFont the bold-italic font.
* @return the created text flow.
* @throws IOException by pdfbox
*/
protected static TextFlow createTextFlow(
final Iterable<CharSequence> parts, final float fontSize,
final PDFont plainFont, final PDFont boldFont,
final PDFont italicFont, final PDFont boldItalicFont)
protected static TextFlow createTextFlow(final Iterable<CharSequence> parts,
final float fontSize, Font baseFont)
throws IOException {
final TextFlow result = new TextFlow();
boolean bold = false;
@ -175,12 +136,11 @@ public class TextFlowUtil {
}
indentStack.push(currentIndent);
result.add(currentIndent.createNewIndent(fontSize,
plainFont, color));
baseFont.getPlainFont(), color));
}
}
} else {
PDFont font = getFont(bold, italic, plainFont, boldFont,
italicFont, boldItalicFont);
PDFont font = getFont(bold, italic, baseFont);
float baselineOffset = 0;
float currentFontSize = fontSize;
if (metricsControl != null) {
@ -193,7 +153,7 @@ public class TextFlowUtil {
result.add(styledText);
} else {
AnnotatedStyledText styledText = new AnnotatedStyledText(
fragment.toString(), currentFontSize, font, color, baselineOffset,
fragment.toString(), currentFontSize, baseFont, color, baselineOffset,
annotationMap.values());
result.add(styledText);
}
@ -210,12 +170,25 @@ public class TextFlowUtil {
font = boldFont;
} else if (!bold && italic) {
font = italicFont;
} else if (bold && italic) {
} else if (bold) {
font = boldItalicFont;
}
return font;
}
protected static PDFont getFont(boolean bold, boolean italic,
Font baseFont) {
PDFont font = baseFont.getPlainFont();
if (bold && !italic) {
font = baseFont.getBoldFont();
} else if (!bold && italic) {
font = baseFont.getItalicFont();
} else if (bold) {
font = baseFont.getBoldItalicFont();
}
return font;
}
/**
* Creates a char sequence where new-line is replaced by the corresponding
* {@link ControlCharacter}.

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color;
/**

View file

@ -1,7 +1,8 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.util.CompatibilityHelper;
import org.apache.pdfbox.util.Matrix;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
@ -30,9 +31,11 @@ public class TextLine implements TextSequence {
*/
private static final String WIDTH = "width";
private final List<StyledText> styledTextList = new ArrayList<StyledText>();
private final List<StyledText> styledTextList = new ArrayList<>();
private NewLine newLine;
private final Map<String, Object> cache = new HashMap<String, Object>();
private final Map<String, Object> cache = new HashMap<>();
private void clearCache() {
cache.clear();
@ -160,48 +163,44 @@ public class TextLine implements TextSequence {
Alignment alignment, float availableLineWidth,
DrawListener drawListener) throws IOException {
contentStream.saveGraphicsState();
contentStream.beginText();
float x = upperLeft.getX();
float y = upperLeft.getY() - getAscent(); // the baseline
float offset = TextSequenceUtil.getOffset(this, availableLineWidth, alignment);
x += offset;
CompatibilityHelper.setTextTranslation(contentStream, x, y);
float extraWordSpacing = 0;
if (alignment == Alignment.Justify && (getNewLine() instanceof WrappingNewLine)) {
extraWordSpacing = (availableLineWidth - getWidth()) / (styledTextList.size() - 1);
}
float y = upperLeft.getY() - getAscent();
FontDescriptor lastFontDesc = null;
float lastBaselineOffset = 0;
Color lastColor = null;
float gap = 0;
float extraWordSpacing = 0;
if (alignment == Alignment.JUSTIFY && (getNewLine() instanceof WrappingNewLine)) {
extraWordSpacing = (availableLineWidth - getWidth()) / (styledTextList.size() - 1);
}
float offset = TextSequenceUtil.getOffset(this, availableLineWidth, alignment);
x += offset;
for (StyledText styledText : styledTextList) {
Matrix matrix = Matrix.getTranslateInstance(x, y);
if (styledText.getLeftMargin() > 0) {
gap += styledText.getLeftMargin();
}
boolean moveBaseline = styledText.getBaselineOffset() != lastBaselineOffset;
if (moveBaseline || gap > 0) {
float baselineDelta = lastBaselineOffset - styledText.getBaselineOffset();
lastBaselineOffset = styledText.getBaselineOffset();
matrix = matrix.multiply(new Matrix(1, 0, 0, 1, gap, baselineDelta));
x += gap;
}
contentStream.beginText();
contentStream.setTextMatrix(matrix);
if (!styledText.getFontDescriptor().equals(lastFontDesc)) {
lastFontDesc = styledText.getFontDescriptor();
contentStream.setFont(lastFontDesc.getFont(),
lastFontDesc.getSize());
contentStream.setFont(lastFontDesc.getFont(), lastFontDesc.getSize());
}
if (!styledText.getColor().equals(lastColor)) {
lastColor = styledText.getColor();
contentStream.setNonStrokingColor(lastColor);
}
if (styledText.getLeftMargin() > 0) {
gap += styledText.getLeftMargin();
}
boolean moveBaseline = styledText.getBaselineOffset() != lastBaselineOffset;
if (moveBaseline || gap > 0) {
float baselineDelta = lastBaselineOffset - styledText.getBaselineOffset();
lastBaselineOffset = styledText.getBaselineOffset();
CompatibilityHelper.moveTextPosition(contentStream, gap, baselineDelta);
x += gap;
}
if (styledText.getText().length() > 0) {
CompatibilityHelper.showText(contentStream,
styledText.getText());
contentStream.showText(styledText.getText());
}
contentStream.endText();
if (drawListener != null) {
float currentUpperLeft = y + styledText.getAsent();
drawListener.drawn(styledText,
@ -210,13 +209,11 @@ public class TextLine implements TextSequence {
styledText.getHeight());
}
x += styledText.getWidthWithoutMargin();
gap = extraWordSpacing;
if (styledText.getRightMargin() > 0) {
gap += styledText.getRightMargin();
}
}
contentStream.endText();
contentStream.restoreGraphicsState();
}

View file

@ -3,6 +3,7 @@ package org.xbib.graphics.pdfbox.layout.text;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.xbib.graphics.pdfbox.layout.elements.Dividable.Divided;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.util.Pair;
import org.xbib.graphics.pdfbox.layout.util.WordBreakerFactory;
import java.io.IOException;
@ -473,9 +474,9 @@ public class TextSequenceUtil {
final float targetWidth, final Alignment alignment)
throws IOException {
switch (alignment) {
case Right:
case RIGHT:
return targetWidth - textLine.getWidth();
case Center:
case CENTER:
return (targetWidth - textLine.getWidth()) / 2f;
default:
return 0;

View file

@ -1,6 +1,8 @@
package org.xbib.graphics.pdfbox.layout.text;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
/**
* A NewLine introduced by wrapping. This interface is useful for detecting
* new-lines not contained in the original text.

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.pdfbox.layout.text.annotations;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.xbib.graphics.pdfbox.layout.text.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.font.Font;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.text.StyledText;
import java.awt.Color;
import java.util.ArrayList;
@ -15,7 +15,24 @@ import java.util.List;
*/
public class AnnotatedStyledText extends StyledText implements Annotated {
private final List<Annotation> annotations = new ArrayList<Annotation>();
private final List<Annotation> annotations = new ArrayList<>();
/**
* Creates a styled text.
*
* @param text the text to draw. Must not contain line feeds ('\n').
* @param size the size of the font.
* @param font the font to use..
* @param color the color to use.
* @param baselineOffset the offset of the baseline.
* @param annotations the annotations associated with the text.
*/
public AnnotatedStyledText(String text, float size, Font font,
Color color, final float baselineOffset,
Collection<? extends Annotation> annotations) {
this(text, new FontDescriptor(font.getPlainFont(), size), color, baselineOffset, 0, 0, annotations);
}
/**
* Creates a styled text.
@ -29,8 +46,10 @@ public class AnnotatedStyledText extends StyledText implements Annotated {
* @param annotations the annotations associated with the text.
*/
public AnnotatedStyledText(final String text,
final FontDescriptor fontDescriptor, final Color color,
final float leftMargin, final float rightMargin,
final FontDescriptor fontDescriptor,
final Color color,
final float leftMargin,
final float rightMargin,
final float baselineOffset,
Collection<? extends Annotation> annotations) {
super(text, fontDescriptor, color, baselineOffset, leftMargin,
@ -40,23 +59,6 @@ public class AnnotatedStyledText extends StyledText implements Annotated {
}
}
/**
* Creates a styled text.
*
* @param text the text to draw. Must not contain line feeds ('\n').
* @param size the size of the font.
* @param font the font to use..
* @param color the color to use.
* @param baselineOffset the offset of the baseline.
* @param annotations the annotations associated with the text.
*/
public AnnotatedStyledText(String text, float size, PDFont font,
Color color, final float baselineOffset,
Collection<? extends Annotation> annotations) {
this(text, new FontDescriptor(font, size), color, baselineOffset, 0, 0,
annotations);
}
@Override
public Iterator<Annotation> iterator() {
return annotations.iterator();

View file

@ -23,6 +23,7 @@ import java.io.IOException;
public class AnnotationDrawListener implements DrawListener, RenderListener {
private final DrawContext drawContext;
private final Iterable<AnnotationProcessor> annotationProcessors;
/**
@ -33,8 +34,7 @@ public class AnnotationDrawListener implements DrawListener, RenderListener {
*/
public AnnotationDrawListener(final DrawContext drawContext) {
this.drawContext = drawContext;
annotationProcessors = AnnotationProcessorFactory
.createAnnotationProcessors();
annotationProcessors = AnnotationProcessorFactory.createAnnotationProcessors();
}
@Override

View file

@ -2,7 +2,6 @@ package org.xbib.graphics.pdfbox.layout.text.annotations;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Factory used to create all available {@link AnnotationProcessor}s. You may
@ -11,7 +10,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class AnnotationProcessorFactory {
private final static List<Class<? extends AnnotationProcessor>> ANNOTATION_PROCESSORS = new CopyOnWriteArrayList<Class<? extends AnnotationProcessor>>();
private final static List<Class<? extends AnnotationProcessor>> ANNOTATION_PROCESSORS = new ArrayList<>();
static {
register(HyperlinkAnnotationProcessor.class);

View file

@ -61,11 +61,7 @@ public class HyperlinkAnnotationProcessor implements AnnotationProcessor {
Iterable<HyperlinkAnnotation> hyperlinkAnnotations = annotatedText
.getAnnotationsOfType(HyperlinkAnnotation.class);
for (HyperlinkAnnotation hyperlinkAnnotation : hyperlinkAnnotations) {
List<Hyperlink> links = linkMap.get(drawContext.getCurrentPage());
if (links == null) {
links = new ArrayList<Hyperlink>();
linkMap.put(drawContext.getCurrentPage(), links);
}
List<Hyperlink> links = linkMap.computeIfAbsent(drawContext.getCurrentPage(), k -> new ArrayList<>());
PDRectangle bounds = new PDRectangle();
bounds.setLowerLeftX(upperLeft.getX());
bounds.setLowerLeftY(upperLeft.getY() - height);

View file

@ -18,17 +18,15 @@ import java.util.List;
*/
public class UnderlineAnnotationProcessor implements AnnotationProcessor {
private final List<Line> linesOnPage = new ArrayList<Line>();
private final List<Line> linesOnPage = new ArrayList<>();
@Override
public void annotatedObjectDrawn(Annotated drawnObject,
DrawContext drawContext, Position upperLeft, float width,
float height) throws IOException {
float height) {
if (!(drawnObject instanceof StyledText)) {
return;
}
StyledText drawnText = (StyledText) drawnObject;
for (UnderlineAnnotation underlineAnnotation : drawnObject
.getAnnotationsOfType(UnderlineAnnotation.class)) {
@ -36,11 +34,9 @@ public class UnderlineAnnotationProcessor implements AnnotationProcessor {
float ascent = fontSize
* drawnText.getFontDescriptor().getFont()
.getFontDescriptor().getAscent() / 1000;
float baselineOffset = fontSize * underlineAnnotation.getBaselineOffsetScale();
float thickness = (0.01f + fontSize * 0.05f)
* underlineAnnotation.getLineWeight();
Position start = new Position(upperLeft.getX(), upperLeft.getY()
- ascent + baselineOffset);
Position end = new Position(start.getX() + width, start.getY());

View file

@ -14,8 +14,6 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.util.Matrix;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.annotations.Annotations.HyperlinkAnnotation.LinkStyle;
@ -23,23 +21,13 @@ import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
/**
* Provide compatible methods for API changes from pdfbox 1x to 2x.
*/
public class CompatibilityHelper {
private static final String BULLET = "\u2022";
private static final String DOUBLE_ANGLE = "\u00bb";
private static final String IMAGE_CACHE = "IMAGE_CACHE";
private static final Map<PDDocument, Map<String, Map<?, ?>>> documentCaches = new WeakHashMap<>();
private static PDBorderStyleDictionary noBorder;
/**
@ -88,51 +76,16 @@ public class CompatibilityHelper {
contentStream.showText(text);
}
public static void setTextTranslation(
final PDPageContentStream contentStream, final float x,
final float y) throws IOException {
contentStream.setTextMatrix(Matrix.getTranslateInstance(x, y));
}
public static void moveTextPosition(
final PDPageContentStream contentStream, final float x,
final float y) throws IOException {
contentStream.transform(new Matrix(1, 0, 0, 1, x, y));
}
public static PDPageContentStream createAppendablePDPageContentStream(
final PDDocument pdDocument, final PDPage page) throws IOException {
return new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true);
}
public static void drawImage(final BufferedImage image,
final PDDocument document, final PDPageContentStream contentStream,
Position upperLeft, final float width, final float height)
throws IOException {
PDImageXObject cachedImage = getCachedImage(document, image);
float x = upperLeft.getX();
float y = upperLeft.getY() - height;
contentStream.drawImage(cachedImage, x, y, width, height);
}
public static int getPageRotation(final PDPage page) {
return page.getRotation();
}
/**
* Renders the given page as an RGB image.
*
* @param document the document containing the page.
* @param pageIndex the index of the page to render.
* @param resolution the image resolution.
* @return the rendered image
* @throws IOException by pdfbox
*/
public static BufferedImage createImageFromPage(final PDDocument document, int pageIndex, final int resolution) throws IOException {
PDFRenderer pdfRenderer = new PDFRenderer(document);
return pdfRenderer.renderImageWithDPI(pageIndex, resolution, ImageType.RGB);
}
public static PDAnnotationLink createLink(PDPage page, PDRectangle rect, Color color,
LinkStyle linkStyle, final String uri) {
PDAnnotationLink pdLink = createLink(page, rect, color, linkStyle);
@ -146,7 +99,6 @@ public class CompatibilityHelper {
public static PDAnnotationLink createLink(PDPage page, PDRectangle rect, Color color,
LinkStyle linkStyle, final PDDestination destination) {
PDAnnotationLink pdLink = createLink(page, rect, color, linkStyle);
PDActionGoTo gotoAction = new PDActionGoTo();
gotoAction.setDestination(destination);
pdLink.setAction(gotoAction);
@ -159,37 +111,36 @@ public class CompatibilityHelper {
* @param annotation the annotation.
* @param color the color to set.
*/
public static void setAnnotationColor(final PDAnnotation annotation, Color color) {
public static void setAnnotationColor(PDAnnotation annotation, Color color) {
annotation.setColor(toPDColor(color));
}
private static PDColor toPDColor(final Color color) {
float[] components = {
color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f
};
return new PDColor(components, PDDeviceRGB.INSTANCE);
}
private static PDAnnotationLink createLink(PDPage page, PDRectangle rect, Color color,
LinkStyle linkStyle) {
PDAnnotationLink pdLink = new PDAnnotationLink();
pdLink.setBorderStyle(toBorderStyle(linkStyle));
if (linkStyle == LinkStyle.none) {
if (noBorder == null) {
noBorder = new PDBorderStyleDictionary();
noBorder.setWidth(0);
}
return pdLink;
}
PDBorderStyleDictionary borderStyle = new PDBorderStyleDictionary();
borderStyle.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
pdLink.setBorderStyle(borderStyle);
PDRectangle rotatedRect = transformToPageRotation(rect, page);
pdLink.setRectangle(rotatedRect);
setAnnotationColor(pdLink, color);
return pdLink;
}
private static PDBorderStyleDictionary toBorderStyle(
final LinkStyle linkStyle) {
if (linkStyle == LinkStyle.none) {
return getNoBorder();
}
PDBorderStyleDictionary borderStyle = new PDBorderStyleDictionary();
borderStyle.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
return borderStyle;
}
private static PDColor toPDColor(final Color color) {
float[] components = new float[]{
color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f};
return new PDColor(components, PDDeviceRGB.INSTANCE);
}
/**
* Return the quad points representation of the given rect.
*
@ -208,8 +159,7 @@ public class CompatibilityHelper {
* @param yOffset the offset in y-direction to add.
* @return the quad points.
*/
public static float[] toQuadPoints(final PDRectangle rect, float xOffset,
float yOffset) {
private static float[] toQuadPoints(final PDRectangle rect, float xOffset, float yOffset) {
float[] quads = new float[8];
quads[0] = rect.getLowerLeftX() + xOffset; // x1
quads[1] = rect.getUpperRightY() + yOffset; // y1
@ -229,8 +179,7 @@ public class CompatibilityHelper {
* @param page the page.
* @return the transformed quad points.
*/
public static float[] transformToPageRotation(
final float[] quadPoints, final PDPage page) {
public static float[] transformToPageRotation(final float[] quadPoints, final PDPage page) {
AffineTransform transform = transformToPageRotation(page);
if (transform == null) {
return quadPoints;
@ -247,8 +196,7 @@ public class CompatibilityHelper {
* @param page the page.
* @return the transformed rectangle.
*/
public static PDRectangle transformToPageRotation(
final PDRectangle rect, final PDPage page) {
private static PDRectangle transformToPageRotation(final PDRectangle rect, final PDPage page) {
AffineTransform transform = transformToPageRotation(page);
if (transform == null) {
return rect;
@ -278,49 +226,4 @@ public class CompatibilityHelper {
transform.translate(-offset, offset);
return transform;
}
private static PDBorderStyleDictionary getNoBorder() {
if (noBorder == null) {
noBorder = new PDBorderStyleDictionary();
noBorder.setWidth(0);
}
return noBorder;
}
private static synchronized Map<String, Map<?, ?>> getDocumentCache(
final PDDocument document) {
Map<String, Map<?, ?>> cache = documentCaches.get(document);
if (cache == null) {
cache = new HashMap<String, Map<?, ?>>();
documentCaches.put(document, cache);
}
return cache;
}
private static synchronized Map<BufferedImage, PDImageXObject> getImageCache(
final PDDocument document) {
Map<String, Map<?, ?>> documentCache = getDocumentCache(document);
@SuppressWarnings("unchecked")
Map<BufferedImage, PDImageXObject> imageCache = (Map<BufferedImage, PDImageXObject>) documentCache
.get(IMAGE_CACHE);
if (imageCache == null) {
imageCache = new HashMap<BufferedImage, PDImageXObject>();
documentCache.put(IMAGE_CACHE, imageCache);
}
return imageCache;
}
private static synchronized PDImageXObject getCachedImage(
final PDDocument document, final BufferedImage image)
throws IOException {
Map<BufferedImage, PDImageXObject> imageCache = getImageCache(document);
PDImageXObject pdxObjectImage = imageCache.get(image);
if (pdxObjectImage == null) {
pdxObjectImage = LosslessFactory.createFromImage(document, image);
imageCache.put(image, pdxObjectImage);
}
return pdxObjectImage;
}
}

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.layout.util;
import org.xbib.graphics.pdfbox.layout.text.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import java.io.IOException;
/**
@ -21,8 +21,8 @@ public interface WordBreaker {
* @return the broken word, or <code>null</code> if it cannot be broken.
* @throws IOException by pdfbox
*/
Pair<String> breakWord(final String word,
final FontDescriptor fontDescriptor, final float maxWidth,
final boolean breakHardIfNecessary) throws IOException;
Pair<String> breakWord(String word,
FontDescriptor fontDescriptor, float maxWidth,
boolean breakHardIfNecessary) throws IOException;
}

View file

@ -1,6 +1,6 @@
package org.xbib.graphics.pdfbox.layout.util;
import org.xbib.graphics.pdfbox.layout.text.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.font.FontDescriptor;
import org.xbib.graphics.pdfbox.layout.text.TextSequenceUtil;
import java.io.IOException;
import java.util.regex.Matcher;

View file

@ -1,16 +1,16 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.util.WordBreakerFactory;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Aligned {
public class AlignedTest {
@Test
public void test() throws Exception {
@ -18,27 +18,23 @@ public class Aligned {
WordBreakerFactory.LEGACY_WORD_BREAKER_CLASS_NAME);
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph = new Paragraph();
paragraph.addText("This is some left aligned text", 11,
PDType1Font.HELVETICA);
paragraph.setAlignment(Alignment.Left);
paragraph.addText("This is some left aligned text", 11, BaseFont.HELVETICA);
paragraph.setAlignment(Alignment.LEFT);
paragraph.setMaxWidth(40);
document.add(paragraph, VerticalLayoutHint.LEFT);
paragraph = new Paragraph();
paragraph.addText("This is some centered text", 11,
PDType1Font.HELVETICA);
paragraph.setAlignment(Alignment.Center);
paragraph.addText("This is some centered text", 11, BaseFont.HELVETICA);
paragraph.setAlignment(Alignment.CENTER);
paragraph.setMaxWidth(40);
document.add(paragraph, VerticalLayoutHint.CENTER);
paragraph = new Paragraph();
paragraph.addText("This is some right aligned text", 11,
PDType1Font.HELVETICA);
paragraph.setAlignment(Alignment.Right);
paragraph.addText("This is some right aligned text", 11, BaseFont.HELVETICA);
paragraph.setAlignment(Alignment.RIGHT);
paragraph.setMaxWidth(40);
document.add(paragraph, VerticalLayoutHint.RIGHT);
paragraph = new Paragraph();
paragraph.addText("Text is right aligned, and paragraph centered", 11,
PDType1Font.HELVETICA);
paragraph.setAlignment(Alignment.Right);
paragraph.addText("Text is right aligned, and paragraph centered", 11, BaseFont.HELVETICA);
paragraph.setAlignment(Alignment.RIGHT);
paragraph.setMaxWidth(40);
document.add(paragraph, VerticalLayoutHint.CENTER);
OutputStream outputStream = new FileOutputStream("build/aligned.pdf");

View file

@ -6,11 +6,11 @@ import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.VerticalSpacer;
import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Columns {
public class ColumnsTest {
@Test
public void test() throws Exception {
@ -35,7 +35,7 @@ public class Columns {
Document document = new Document(40, 50, 40, 60);
Paragraph title = new Paragraph();
title.addMarkup("*This Text is organized in Colums*", 20, BaseFont.Times);
title.addMarkup("*This Text is organized in Colums*", 20, BaseFont.TIMES);
document.add(title, VerticalLayoutHint.CENTER);
document.add(new VerticalSpacer(5));
@ -43,15 +43,15 @@ public class Columns {
document.add(new ColumnLayout(2, 10));
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.Times);
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph1);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
document.add(paragraph2);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.Courier);
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
document.add(paragraph3);
document.add(paragraph1);
@ -79,9 +79,7 @@ public class Columns {
document.add(paragraph3);
document.add(paragraph2);
document.add(paragraph2);
final OutputStream outputStream = new FileOutputStream("build/columns.pdf");
document.save(outputStream);
}
}

View file

@ -2,13 +2,12 @@ package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.PageFormat;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.DrawContext;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.annotations.Annotated;
@ -29,7 +28,7 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CustomAnnotation {
public class CustomAnnotationTest {
/**
* Represents a highlight annotation that might be added to a
@ -192,19 +191,19 @@ public class CustomAnnotation {
.margins(40, 60, 40, 60).portrait().build());
Paragraph paragraph = new Paragraph();
paragraph.addText("Hello there, here is ", 10, PDType1Font.HELVETICA);
paragraph.addText("Hello there, here is ", 10, BaseFont.HELVETICA);
// now add some annotated text using our custom highlight annotation
HighlightAnnotation annotation = new HighlightAnnotation(Color.green);
AnnotatedStyledText highlightedText = new AnnotatedStyledText(
"highlighted text", 10, PDType1Font.HELVETICA, Color.black, 0f,
"highlighted text", 10, BaseFont.HELVETICA, Color.black, 0f,
Collections.singleton(annotation));
paragraph.add(highlightedText);
paragraph
.addText(
". Do whatever you want here...strike, squiggle, whatsoever\n\n",
10, PDType1Font.HELVETICA);
10, BaseFont.HELVETICA);
paragraph.setMaxWidth(150);
document.add(paragraph);
@ -216,7 +215,7 @@ public class CustomAnnotation {
.addMarkup(
"Hello there, here is {hl:#ffff00}highlighted text{hl}. "
+ "Do whatever you want here...strike, squiggle, whatsoever\n\n",
10, BaseFont.Helvetica);
10, BaseFont.HELVETICA);
paragraph.setMaxWidth(150);
document.add(paragraph);

View file

@ -1,6 +1,5 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Element;
@ -14,7 +13,7 @@ import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.shape.Stroke;
import org.xbib.graphics.pdfbox.layout.shape.Stroke.CapStyle;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
@ -52,9 +51,9 @@ public class CustomRenderer {
document.addRenderListener(sectionRenderer);
Paragraph paragraph = new Paragraph();
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph.addMarkup(text1, 8, BaseFont.Courier);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
paragraph.addMarkup(text2, 12, BaseFont.HELVETICA);
paragraph.addMarkup(text1, 8, BaseFont.COURIER);
document.add(new Section(1));
document.add(paragraph);
@ -108,29 +107,13 @@ public class CustomRenderer {
public void afterPage(RenderContext renderContext) throws IOException {
String content = String.format("Section %s, Page %s",
sectionNumber, renderContext.getPageIndex() + 1);
TextFlow text = TextFlowUtil.createTextFlow(content, 11,
PDType1Font.TIMES_ROMAN);
float offset = renderContext.getPageFormat().getMarginLeft()
+ TextSequenceUtil.getOffset(text,
renderContext.getWidth(), Alignment.Right);
TextFlow text = TextFlowUtil.createTextFlow(content, 11, BaseFont.TIMES);
float offset = renderContext.getPageFormat().getMarginLeft() +
TextSequenceUtil.getOffset(text, renderContext.getWidth(), Alignment.RIGHT);
text.drawText(renderContext.getContentStream(), new Position(
offset, 30), Alignment.Right, null);
offset, 30), Alignment.RIGHT, null);
}
}
public static class Section extends Paragraph {
private final int number;
public Section(int number) throws IOException {
super();
this.number = number;
addMarkup(String.format("*Section %d", number), 16, BaseFont.Times);
}
public int getNumber() {
return number;
}
}
}

View file

@ -3,7 +3,7 @@ package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Frame;
import org.xbib.graphics.pdfbox.layout.elements.PageFormat;
import org.xbib.graphics.pdfbox.layout.elements.PageFormats;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.shape.Ellipse;
@ -11,13 +11,12 @@ import org.xbib.graphics.pdfbox.layout.shape.Rect;
import org.xbib.graphics.pdfbox.layout.shape.RoundRect;
import org.xbib.graphics.pdfbox.layout.shape.Stroke;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Constants;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.awt.Color;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Frames {
public class FramesTest {
@Test
public void test() throws Exception {
@ -39,10 +38,10 @@ public class Frames {
+ "eos et _accusam et *justo* duo dolores_ et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
Document document = new Document(new PageFormat(Constants.A5));
Document document = new Document(PageFormats.A5_PORTRAIT);
Paragraph paragraph = new Paragraph();
paragraph.addMarkup("Am I living in a box?", 11, BaseFont.Times);
paragraph.addMarkup("Am I living in a box?", 11, BaseFont.TIMES);
Frame frame = new Frame(paragraph);
frame.setShape(new Rect());
frame.setBorder(Color.black, new Stroke());
@ -51,7 +50,7 @@ public class Frames {
document.add(frame, VerticalLayoutHint.CENTER);
paragraph = new Paragraph();
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
frame = new Frame(paragraph, 200f, null);
frame.setShape(new Rect());
frame.setBackgroundColor(Color.black);
@ -60,8 +59,8 @@ public class Frames {
document.add(frame);
paragraph = new Paragraph();
paragraph.addMarkup("{color:#aa00aa}*Ain't no rectangle*", 22, BaseFont.Helvetica);
paragraph.setAlignment(Alignment.Center);
paragraph.addMarkup("{color:#aa00aa}*Ain't no rectangle*", 22, BaseFont.HELVETICA);
paragraph.setAlignment(Alignment.CENTER);
frame = new Frame(paragraph, 300f, 100f);
frame.setShape(new Ellipse());
frame.setBorder(Color.green, new Stroke(2));
@ -71,9 +70,9 @@ public class Frames {
document.add(frame);
paragraph = new Paragraph();
paragraph.addMarkup("Frames also paginate, see here:\n\n", 13, BaseFont.Times);
paragraph.addMarkup(text2, 11, BaseFont.Times);
paragraph.addMarkup(text2, 11, BaseFont.Times);
paragraph.addMarkup("Frames also paginate, see here:\n\n", 13, BaseFont.TIMES);
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
frame = new Frame(paragraph, null, null);
frame.setShape(new RoundRect(10));
frame.setBorder(Color.magenta, new Stroke(3));
@ -82,8 +81,8 @@ public class Frames {
frame.setMargin(50, 50, 20, 10);
paragraph = new Paragraph();
paragraph.addMarkup(text2, 11, BaseFont.Times);
paragraph.addMarkup(text2, 11, BaseFont.Times);
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
paragraph.addMarkup(text2, 11, BaseFont.TIMES);
frame.add(paragraph);
document.add(frame);

View file

@ -0,0 +1,38 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.barcode.Code3Of9;
import org.xbib.graphics.barcode.HumanReadableLocation;
import org.xbib.graphics.barcode.Symbol;
import org.xbib.graphics.pdfbox.layout.elements.BarcodeElement;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.PageFormats;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.font.NotoSansFont;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Indent;
import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class HelloBarcodeTest {
@Test
public void test() throws Exception {
Document document = new Document(PageFormats.A4_PORTRAIT);
Paragraph paragraph = new Paragraph();
paragraph.add(new Indent(50, SpaceUnit.pt));
paragraph.addMarkup("Hello Barcode\n", 12, BaseFont.HELVETICA);
document.add(paragraph);
Symbol symbol = new Code3Of9();
symbol.setContent("1234567890");
symbol.setBarHeight(150);
symbol.setHumanReadableLocation(HumanReadableLocation.BOTTOM);
BarcodeElement barcodeElement = new BarcodeElement(symbol);
document.add(barcodeElement, new VerticalLayoutHint(Alignment.LEFT, 10, 10, 10, 10, true));
final OutputStream outputStream = new FileOutputStream("build/hellobarcode.pdf");
document.save(outputStream);
}
}

View file

@ -0,0 +1,28 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.ImageElement;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
public class HelloCatTest {
@Test
public void test() throws Exception {
Document document = new Document();
Paragraph paragraph = new Paragraph();
paragraph.addText("Hello Cat", 12, BaseFont.HELVETICA);
document.add(paragraph);
ImageElement imageElement = new ImageElement(ImageIO.read(getClass().getResourceAsStream("cat.jpg")));
imageElement.setScale(0.1f);
document.add(imageElement, new VerticalLayoutHint(Alignment.LEFT, 10, 10, 10, 10, true));
final OutputStream outputStream = new FileOutputStream("build/hellocat.pdf");
document.save(outputStream);
}
}

View file

@ -1,9 +1,9 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
@ -14,10 +14,8 @@ public class HelloDoc {
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph = new Paragraph();
paragraph.addText("Hello Document", 20,
PDType1Font.HELVETICA);
paragraph.addText("Hello Document", 20, BaseFont.HELVETICA);
document.add(paragraph);
final OutputStream outputStream = new FileOutputStream("build/hellodoc.pdf");
document.save(outputStream);

View file

@ -0,0 +1,28 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.PageFormats;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.NotoSansFont;
import org.xbib.graphics.pdfbox.layout.text.Indent;
import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class HelloNotoFontTest {
@Test
public void test() throws Exception {
Document document = new Document(PageFormats.A4_PORTRAIT);
Paragraph paragraph = new Paragraph();
paragraph.add(new Indent(32, SpaceUnit.pt));
paragraph.addMarkup("Hello Noto Regular\n", 12, new NotoSansFont(document.getPDDocument()));
paragraph.addMarkup("*Hello Noto Bold*\n", 12, new NotoSansFont(document.getPDDocument()));
paragraph.addMarkup("_Hello Noto Italic_\n", 12, new NotoSansFont(document.getPDDocument()));
paragraph.addMarkup("*_Hello Noto Bold Italic_*\n", 12, new NotoSansFont(document.getPDDocument()));
document.add(paragraph);
final OutputStream outputStream = new FileOutputStream("build/hellonotofont.pdf");
document.save(outputStream);
}
}

View file

@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Indent;
import org.xbib.graphics.pdfbox.layout.text.SpaceUnit;
import org.xbib.graphics.pdfbox.layout.util.CompatibilityHelper;
@ -17,121 +17,115 @@ import org.xbib.graphics.pdfbox.layout.util.Enumerators.RomanEnumerator;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Indentation {
public class IndentationTest {
@Test
public void test() throws Exception {
String bulletOdd = CompatibilityHelper.getBulletCharacter(1) + " ";
String bulletEven = CompatibilityHelper.getBulletCharacter(2) + " ";
String text1 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
+ "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna "
+ "aliquyam erat\n";
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph = new Paragraph();
paragraph
.addMarkup(
"This is an example for the new indent feature. Let's do some empty space indentation:\n",
11, BaseFont.Times);
paragraph.addMarkup("This is an example for the new indent feature. Let's do some empty space indentation:\n",
11, BaseFont.TIMES);
paragraph.add(new Indent(50, SpaceUnit.pt));
paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.Times);
paragraph.addMarkup(
"The Indentation holds for the rest of the paragraph, or... \n",
11, BaseFont.Times);
paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.TIMES);
paragraph.addMarkup("The Indentation holds for the rest of the paragraph, or... \n",
11, BaseFont.TIMES);
paragraph.add(new Indent(70, SpaceUnit.pt));
paragraph.addMarkup("any new indent comes.\n", 11, BaseFont.Times);
paragraph.addMarkup("any new indent comes.\n", 11, BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
paragraph
.addMarkup(
"New paragraph, now indentation is gone. But we can indent with a label also:\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph.add(new Indent("This is some label", 100, SpaceUnit.pt, 11,
PDType1Font.TIMES_BOLD));
paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.Times);
paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.TIMES);
paragraph
.addMarkup(
"And again, the Indentation holds for the rest of the paragraph, or any new indent comes.\nLabels can be aligned:\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph.add(new Indent("Left", 100, SpaceUnit.pt, 11,
PDType1Font.TIMES_BOLD, Alignment.Left));
PDType1Font.TIMES_BOLD, Alignment.LEFT));
paragraph.addMarkup("Indent with label aligned to the left.\n", 11,
BaseFont.Times);
BaseFont.TIMES);
paragraph.add(new Indent("Center", 100, SpaceUnit.pt, 11,
PDType1Font.TIMES_BOLD, Alignment.Center));
PDType1Font.TIMES_BOLD, Alignment.CENTER));
paragraph.addMarkup("Indent with label aligned to the center.\n", 11,
BaseFont.Times);
BaseFont.TIMES);
paragraph.add(new Indent("Right", 100, SpaceUnit.pt, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Indent with label aligned to the right.\n", 11,
BaseFont.Times);
BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
paragraph.addMarkup(
"So, what can you do with that? How about lists:\n", 11,
BaseFont.Times);
BaseFont.TIMES);
paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("This is a list item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("This is a list item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("Another list item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Another list item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(bulletEven, 8, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("Sub list item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Sub list item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("And yet another one\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("And yet another one\n", 11, BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
paragraph.addMarkup("Also available with indents: Enumerators:\n", 11,
BaseFont.Times);
BaseFont.TIMES);
RomanEnumerator e1 = new RomanEnumerator();
LowerCaseAlphabeticEnumerator e2 = new LowerCaseAlphabeticEnumerator();
paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("First item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("First item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("Second item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Second item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(e2.next() + ") ", 8, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("A sub item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("A sub item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(e2.next() + ") ", 8, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("Another sub item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Another sub item\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11,
PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("Third item\n", 11, BaseFont.Times);
PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("Third item\n", 11, BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
paragraph.addMarkup("The following types are built in:\n", 11,
BaseFont.Times);
BaseFont.TIMES);
paragraph.add(new Indent(new ArabicEnumerator().next() + " ", 4,
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("ArabicEnumerator\n", 11, BaseFont.Times);
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("ArabicEnumerator\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(new RomanEnumerator().next() + " ", 4,
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("RomanEnumerator\n", 11, BaseFont.Times);
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("RomanEnumerator\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(new LowerCaseRomanEnumerator().next() + " ",
4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("LowerCaseRomanEnumerator\n", 11, BaseFont.Times);
4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("LowerCaseRomanEnumerator\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(new AlphabeticEnumerator().next() + " ", 4,
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right));
paragraph.addMarkup("AlphabeticEnumerator\n", 11, BaseFont.Times);
SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.RIGHT));
paragraph.addMarkup("AlphabeticEnumerator\n", 11, BaseFont.TIMES);
paragraph.add(new Indent(new LowerCaseAlphabeticEnumerator().next()
+ " ", 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD,
Alignment.Right));
Alignment.RIGHT));
paragraph.addMarkup("LowerCaseAlphabeticEnumerator\n", 11,
BaseFont.Times);
BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
text1 = "For your convenience, you can do all that much easier with markup, e.g. simple indentation\n"
String text1 = "For your convenience, you can do all that much easier with markup, e.g. simple indentation\n"
+ "--At vero eos et accusam\n\n"
+ "-!And end the indentation. Now a list:\n"
+ "-+This is a list item\n"
@ -148,7 +142,7 @@ public class Indentation {
+ "-#{I ->:5}Another list item\n"
+ " -#{a ~:30pt}A sub list item\n"
+ "-#{I ->:5}And yet another one\n\n";
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph);
final OutputStream outputStream = new FileOutputStream("build/indentation.pdf");

View file

@ -9,7 +9,7 @@ import org.xbib.graphics.pdfbox.layout.elements.VerticalSpacer;
import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
@ -36,16 +36,16 @@ public class Landscape {
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.Times);
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.Courier);
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
Paragraph titleA4 = new Paragraph();
titleA4.addMarkup("*Format A4 in Portrait*", 20, BaseFont.Times);
titleA4.addMarkup("*Format A4 in Portrait*", 20, BaseFont.TIMES);
Paragraph titleA5 = new Paragraph();
titleA5.addMarkup("*Format A5 in Landscape*", 20, BaseFont.Times);
titleA5.addMarkup("*Format A5 in Landscape*", 20, BaseFont.TIMES);
PageFormat a5_landscape = PageFormat.with().A5().landscape().margins(10, 50, 0, 30).build();
PageFormat a4_portrait = PageFormat.with().margins(40, 50, 40, 60).build();

View file

@ -1,6 +1,5 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.ImageElement;
@ -8,11 +7,13 @@ import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.VerticalSpacer;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Position;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
public class Letter {
@ -24,32 +25,31 @@ public class Letter {
ImageElement image;
if (new File("arrow.png").exists()) {
image = new ImageElement("arrow.png");
BufferedImage arrowImage = ImageIO.read(new File("arrow.png"));
image = new ImageElement(arrowImage);
} else {
image = new ImageElement(Letter.class.getResourceAsStream("arrow.png"));
BufferedImage arrowImage = ImageIO.read(getClass().getResourceAsStream("arrow.png"));
image = new ImageElement(arrowImage);
}
image.setWidth(image.getWidth() / 7);
image.setHeight(image.getHeight() / 7);
document.add(image, new VerticalLayoutHint(Alignment.Right, 0, 0,
0, 0, true));
document.add(image, new VerticalLayoutHint(Alignment.RIGHT, 0, 0, 0, 0, true));
document.add(new VerticalSpacer(100));
Paragraph paragraph = new Paragraph();
paragraph.addText("Blubberhausen, 01.04.2016", 11,
PDType1Font.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.Right, 0, 0,
paragraph.addText("Blubberhausen, 01.04.2016", 11, BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 0, 0,
0, 0, true));
paragraph = new Paragraph();
String address = "Ralf Stuckert\nAm Hollergraben 24\n67346 Blubberhausen";
paragraph.addText(address, 11, PDType1Font.HELVETICA);
paragraph.addText(address, 11, BaseFont.HELVETICA);
document.add(paragraph);
paragraph = new Paragraph();
paragraph.addMarkup("*Labore et dolore magna aliquyam erat*", 11,
BaseFont.Helvetica);
document.add(paragraph, new VerticalLayoutHint(Alignment.Left, 0, 0,
paragraph.addMarkup("*Labore et dolore magna aliquyam erat*", 11, BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 0,
40, 20));
String text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
@ -62,21 +62,21 @@ public class Letter {
+ "At vero eos et accusam* et justo duo dolores et ea rebum. Stet clita kasd "
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n";
paragraph = new Paragraph();
paragraph.addMarkup(text, 11, BaseFont.Helvetica);
paragraph.addMarkup(text, 11, BaseFont.HELVETICA);
document.add(paragraph);
document.add(paragraph);
paragraph = new Paragraph();
paragraph.addMarkup("Dolore magna aliquyam erat\nRalf Stuckert", 11,
BaseFont.Helvetica);
document.add(paragraph, new VerticalLayoutHint(Alignment.Left, 60, 0,
BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 60, 0,
40, 0));
paragraph = new Paragraph();
paragraph.addMarkup("*Sanctus est:* Lorem ipsum dolor consetetur "
+ "sadipscing sed diam nonumy eirmod tempor invidunt", 6,
BaseFont.Times);
BaseFont.TIMES);
paragraph.setAbsolutePosition(new Position(hMargin, vMargin));
document.add(paragraph);

View file

@ -4,11 +4,11 @@ import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class LineSpacing {
public class LineSpacingTest {
@Test
public void test() throws Exception {
@ -30,18 +30,15 @@ public class LineSpacing {
// use a bigger line spacing to visualize the effects of line spacing more drastically
left.setLineSpacing(1.5f);
left.setMaxWidth(document.getPageWidth() / 2);
left.addMarkup(text, 11, BaseFont.Times);
document.add(left);
left.addMarkup(text, 11, BaseFont.TIMES);
document.add(left);
document.add(left);
document.add(left);
document.add(ColumnLayout.NEWCOLUMN);
Paragraph right = new Paragraph();
right.setLineSpacing(1.5f);
right.setMaxWidth(document.getPageWidth() / 2);
right.addMarkup(text, 11, BaseFont.Times);
right.addMarkup(text, 11, BaseFont.TIMES);
document.add(right);
document.add(right);

View file

@ -3,7 +3,7 @@ package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
@ -33,25 +33,25 @@ public class Links {
Paragraph paragraph0 = new Paragraph();
paragraph0.addMarkup("This is a link to {link[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}.\n\n", 11, BaseFont.Times);
paragraph0.addMarkup("Now the same link with color instead of underline {color:#ff5000}{link:none[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}{color:#000000}.\n\n", 11, BaseFont.Times);
paragraph0.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, BaseFont.Times);
paragraph0.addMarkup("This is a link to {link[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}.\n\n", 11, BaseFont.TIMES);
paragraph0.addMarkup("Now the same link with color instead of underline {color:#ff5000}{link:none[https://github.com/ralfstuckert/pdfbox-layout]}PDFBox-Layout{link}{color:#000000}.\n\n", 11, BaseFont.TIMES);
paragraph0.addMarkup("And here comes a link to an internal anchor name {color:#ff5000}{link[#hello]}hello{link}{color:#000000}.\n\n", 11, BaseFont.TIMES);
document.add(paragraph0);
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.Times);
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph1);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
document.add(paragraph2);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.Courier);
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
document.add(paragraph3);
Paragraph paragraph4 = new Paragraph();
paragraph4.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 15, BaseFont.Courier);
paragraph4.addMarkup("\n\n{anchor:hello}Here{anchor} comes the internal anchor named *hello*\n\n", 15, BaseFont.COURIER);
document.add(paragraph1);
document.add(paragraph3);

View file

@ -1,13 +1,12 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.RenderContext;
import org.xbib.graphics.pdfbox.layout.elements.render.RenderListener;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
import org.xbib.graphics.pdfbox.layout.text.TextFlowUtil;
@ -52,20 +51,19 @@ public class Listener {
throws IOException {
String content = String.format("Page %s",
renderContext.getPageIndex() + 1);
TextFlow text = TextFlowUtil.createTextFlow(content, 11,
PDType1Font.TIMES_ROMAN);
TextFlow text = TextFlowUtil.createTextFlow(content, 11, BaseFont.HELVETICA);
float offset = renderContext.getPageFormat().getMarginLeft()
+ TextSequenceUtil.getOffset(text,
renderContext.getWidth(), Alignment.Right);
renderContext.getWidth(), Alignment.RIGHT);
text.drawText(renderContext.getContentStream(), new Position(
offset, 30), Alignment.Right, null);
offset, 30), Alignment.RIGHT, null);
}
});
Paragraph paragraph = new Paragraph();
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph.addMarkup(text1, 8, BaseFont.Courier);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
paragraph.addMarkup(text2, 12, BaseFont.HELVETICA);
paragraph.addMarkup(text1, 8, BaseFont.COURIER);
document.add(paragraph);
document.add(paragraph);

View file

@ -3,14 +3,13 @@ package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.PageFormat;
import org.xbib.graphics.pdfbox.layout.shape.RoundRect;
import org.xbib.graphics.pdfbox.layout.shape.Shape;
import org.xbib.graphics.pdfbox.layout.shape.Stroke;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.Constants;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import org.xbib.graphics.pdfbox.layout.text.DrawContext;
import org.xbib.graphics.pdfbox.layout.text.Position;
import org.xbib.graphics.pdfbox.layout.text.TextFlow;
@ -25,22 +24,19 @@ public class LowLevelText {
@Test
public void test() throws Exception {
final PDDocument test = new PDDocument();
final PDPage page = new PDPage(Constants.A4);
PDDocument pdDocument = new PDDocument();
PDPage page = new PDPage(PageFormat.A4);
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
test.addPage(page);
pdDocument.addPage(page);
final PDPageContentStream contentStream =
new PDPageContentStream(test, page, PDPageContentStream.AppendMode.APPEND, true);
new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true);
// AnnotationDrawListener is only needed if you use annoation based stuff, e.g. hyperlinks
AnnotationDrawListener annotationDrawListener = new AnnotationDrawListener(new DrawContext() {
@Override
public PDDocument getPdDocument() {
return test;
return pdDocument;
}
@Override
@ -59,17 +55,17 @@ public class LowLevelText {
TextFlow text = TextFlowUtil
.createTextFlowFromMarkup(
"Hello *bold _italic bold-end* italic-end_. Eirmod\ntempor invidunt ut \\*labore",
11, BaseFont.Times);
11, BaseFont.TIMES);
text.addText("Spongebob", 11, PDType1Font.COURIER);
text.addText(" is ", 20, PDType1Font.HELVETICA_BOLD_OBLIQUE);
text.addText("cool", 7, PDType1Font.HELVETICA);
text.addText("Spongebob", 11, BaseFont.COURIER);
text.addText(" is ", 20, BaseFont.HELVETICA);
text.addText("cool", 7, BaseFont.HELVETICA);
text.setMaxWidth(100);
float xOffset = TextSequenceUtil.getOffset(text, pageWidth,
Alignment.Right);
Alignment.RIGHT);
text.drawText(contentStream, new Position(xOffset, pageHeight - 50),
Alignment.Right, annotationDrawListener);
Alignment.RIGHT, annotationDrawListener);
String textBlock = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, "
+ "{link[https://github.com/ralfstuckert/pdfbox-layout/]}pdfbox layout{link} "
@ -83,11 +79,11 @@ public class LowLevelText {
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
text = new TextFlow();
text.addMarkup(textBlock, 8, BaseFont.Courier);
text.addMarkup(textBlock, 8, BaseFont.COURIER);
text.setMaxWidth(200);
xOffset = TextSequenceUtil.getOffset(text, pageWidth, Alignment.Center);
xOffset = TextSequenceUtil.getOffset(text, pageWidth, Alignment.CENTER);
text.drawText(contentStream, new Position(xOffset, pageHeight - 100),
Alignment.Justify, annotationDrawListener);
Alignment.JUSTIFY, annotationDrawListener);
// draw a round rect box with text
text.setMaxWidth(350);
@ -99,13 +95,13 @@ public class LowLevelText {
float boxHeight = text.getHeight() + 2 * paddingY;
Shape shape = new RoundRect(20);
shape.fill(test, contentStream, new Position(x, y), boxWidth,
shape.fill(pdDocument, contentStream, new Position(x, y), boxWidth,
boxHeight, Color.pink, null);
shape.draw(test, contentStream, new Position(x, y), boxWidth,
shape.draw(pdDocument, contentStream, new Position(x, y), boxWidth,
boxHeight, Color.blue, new Stroke(3), null);
// now the text
text.drawText(contentStream, new Position(x + paddingX, y - paddingY),
Alignment.Center, annotationDrawListener);
Alignment.CENTER, annotationDrawListener);
annotationDrawListener.afterPage(null);
contentStream.close();
@ -113,8 +109,7 @@ public class LowLevelText {
annotationDrawListener.afterRender();
final OutputStream outputStream = new FileOutputStream("build/lowleveltext.pdf");
test.save(outputStream);
test.close();
pdDocument.save(outputStream);
pdDocument.close();
}
}

View file

@ -1,11 +1,11 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
@ -37,18 +37,18 @@ public class Margin {
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph = new Paragraph();
paragraph.addText(text1, 11, PDType1Font.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.Left, 0, 100,
paragraph.addText(text1, 11, BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 100,
100, 100));
paragraph = new Paragraph();
paragraph.addText(text2, 11, PDType1Font.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.Right, 0, 50,
paragraph.addText(text2, 11, BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 0, 50,
0, 0));
paragraph = new Paragraph();
paragraph.addText(text3, 11, PDType1Font.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.Right, 150,
paragraph.addText(text3, 11, BaseFont.HELVETICA);
document.add(paragraph, new VerticalLayoutHint(Alignment.RIGHT, 150,
150, 20, 0));
final OutputStream outputStream = new FileOutputStream("build/margin.pdf");

View file

@ -5,11 +5,11 @@ import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.Alignment;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Markup {
public class MarkupTest {
@Test
public void test() throws Exception {
@ -25,32 +25,32 @@ public class Markup {
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph = new Paragraph();
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph);
paragraph = new Paragraph();
paragraph
.addMarkup(
"Markup supports *bold*, _italic_, and *even _mixed* markup_.\n\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph.addMarkup(
"Escape \\* with \\\\\\* and \\_ with \\\\\\_ in markup.\n\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph
.addMarkup(
"And now also {color:#ff0000}c{color:#00ff00}o{color:#0000ff}l{color:#00cccc}o{color:#cc00cc}r{color:#000000}",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph.addMarkup(" , {_}subscript{_} and {^}superscript{^}.\n\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
paragraph
.addMarkup(
"You can alternate the position and thickness of an __underline__, "
+ "so you may also use this to __{0.25:}strike through__ or blacken __{0.25:20}things__ out\n\n",
11, BaseFont.Times);
11, BaseFont.TIMES);
document.add(paragraph, new VerticalLayoutHint(Alignment.Left, 0, 0,
document.add(paragraph, new VerticalLayoutHint(Alignment.LEFT, 0, 0,
30, 0));
paragraph = new Paragraph();
@ -71,7 +71,7 @@ public class Markup {
+ "-#{I ->:5}Another list item\n"
+ " -#{a ~:30pt}A sub list item\n"
+ "-#{I ->:5}And yet another one\n\n";
paragraph.addMarkup(text1, 11, BaseFont.Times);
paragraph.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph);
final OutputStream outputStream = new FileOutputStream("build/markup.pdf");

View file

@ -3,11 +3,11 @@ package org.xbib.graphics.pdfbox.layout.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.pdfbox.layout.elements.Document;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class MultiplePages {
public class MultiplePagesTest {
@Test
public void test() throws Exception {
@ -32,15 +32,15 @@ public class MultiplePages {
Document document = new Document(40, 60, 40, 60);
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.Times);
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
document.add(paragraph1);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
document.add(paragraph2);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.Courier);
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
document.add(paragraph3);
document.add(paragraph1);

View file

@ -9,11 +9,11 @@ import org.xbib.graphics.pdfbox.layout.elements.VerticalSpacer;
import org.xbib.graphics.pdfbox.layout.elements.render.ColumnLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayout;
import org.xbib.graphics.pdfbox.layout.elements.render.VerticalLayoutHint;
import org.xbib.graphics.pdfbox.layout.text.BaseFont;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Rotation {
public class RotationTest {
@Test
public void test() throws Exception {
@ -36,16 +36,16 @@ public class Rotation {
+ "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n";
Paragraph paragraph1 = new Paragraph();
paragraph1.addMarkup(text1, 11, BaseFont.Times);
paragraph1.addMarkup(text1, 11, BaseFont.TIMES);
Paragraph paragraph2 = new Paragraph();
paragraph2.addMarkup(text2, 12, BaseFont.Helvetica);
paragraph2.addMarkup(text2, 12, BaseFont.HELVETICA);
Paragraph paragraph3 = new Paragraph();
paragraph3.addMarkup(text1, 8, BaseFont.Courier);
paragraph3.addMarkup(text1, 8, BaseFont.COURIER);
Paragraph titleA4 = new Paragraph();
titleA4.addMarkup("*Format A4 Landscape*", 20, BaseFont.Times);
titleA4.addMarkup("*Format A4 Landscape*", 20, BaseFont.TIMES);
Paragraph titleA5 = new Paragraph();
titleA5.addMarkup("*Format A4 Landscape rotated by -90 degrees*", 20, BaseFont.Times);
titleA5.addMarkup("*Format A4 Landscape rotated by -90 degrees*", 20, BaseFont.TIMES);
PageFormat a4_landscape = PageFormat.with().margins(40, 50, 40, 60).landscape().build();
PageFormat a4_landscape_rotated = PageFormat.with().margins(40, 50, 40, 60).landscape().rotation(-90).build();

View file

@ -0,0 +1,20 @@
package org.xbib.graphics.pdfbox.layout.test;
import org.xbib.graphics.pdfbox.layout.elements.Paragraph;
import org.xbib.graphics.pdfbox.layout.font.BaseFont;
import java.io.IOException;
public class Section extends Paragraph {
private final int number;
public Section(int number) throws IOException {
super();
this.number = number;
addMarkup(String.format("*Section %d", number), 16, BaseFont.TIMES);
}
public int getNumber() {
return number;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB