cleanup io-pdfbox
This commit is contained in:
parent
b5dc5f1b98
commit
5f4adca5c0
24 changed files with 312 additions and 360 deletions
|
@ -1,7 +1,12 @@
|
|||
module org.xbib.graphics.graphics2d.pdfbox {
|
||||
exports org.xbib.graphics.io.pdfbox;
|
||||
exports org.xbib.graphics.io.pdfbox.color;
|
||||
exports org.xbib.graphics.io.pdfbox.draw;
|
||||
exports org.xbib.graphics.io.pdfbox.font;
|
||||
exports org.xbib.graphics.io.pdfbox.image;
|
||||
exports org.xbib.graphics.io.pdfbox.paint;
|
||||
requires transitive org.apache.pdfbox;
|
||||
requires org.apache.fontbox;
|
||||
requires transitive java.desktop;
|
||||
requires java.logging;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
|
||||
import org.xbib.graphics.io.pdfbox.DrawControl.DrawControlEnv;
|
||||
import org.xbib.graphics.io.pdfbox.FontTextDrawer.FontTextDrawerEnv;
|
||||
import org.xbib.graphics.io.pdfbox.PaintApplier.PaintApplierEnv;
|
||||
import org.xbib.graphics.io.pdfbox.draw.DefaultDrawControl;
|
||||
import org.xbib.graphics.io.pdfbox.draw.DrawControl;
|
||||
import org.xbib.graphics.io.pdfbox.draw.DrawControl.DrawControlEnvironment;
|
||||
import org.xbib.graphics.io.pdfbox.color.ColorMapper;
|
||||
import org.xbib.graphics.io.pdfbox.color.DefaultColorMapper;
|
||||
import org.xbib.graphics.io.pdfbox.font.DefaultFontDrawer;
|
||||
import org.xbib.graphics.io.pdfbox.font.FontDrawer;
|
||||
import org.xbib.graphics.io.pdfbox.font.FontDrawer.FontDrawerEnvironment;
|
||||
import org.xbib.graphics.io.pdfbox.image.ImageEncoder;
|
||||
import org.xbib.graphics.io.pdfbox.image.LosslessImageEncoder;
|
||||
import org.xbib.graphics.io.pdfbox.paint.DefaultPaintApplier;
|
||||
import org.xbib.graphics.io.pdfbox.paint.PaintApplier;
|
||||
import org.xbib.graphics.io.pdfbox.paint.PaintApplier.PaintApplierEnvironment;
|
||||
import org.apache.pdfbox.cos.COSName;
|
||||
import org.apache.pdfbox.cos.COSStream;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
|
@ -74,23 +84,29 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
|
||||
private final PDPageContentStream contentStream;
|
||||
|
||||
private BufferedImage calcImage;
|
||||
private final BufferedImage calcImage;
|
||||
|
||||
private PDDocument document;
|
||||
private final PDDocument document;
|
||||
|
||||
private final AffineTransform baseTransform;
|
||||
|
||||
private AffineTransform transform = new AffineTransform();
|
||||
private final CopyInfo copyInfo;
|
||||
|
||||
private ImageEncoder imageEncoder = new LosslessImageEncoder();
|
||||
private final List<CopyInfo> copyList;
|
||||
|
||||
private ColorMapper colorMapper = new DefaultColorMapper();
|
||||
private final DefaultPaintApplierEnvironment paintEnv;
|
||||
|
||||
private PaintApplier paintApplier = new DefaultPaintApplier();
|
||||
private AffineTransform transform;
|
||||
|
||||
private FontTextDrawer fontTextDrawer = new DefaultFontTextDrawer();
|
||||
private ImageEncoder imageEncoder;
|
||||
|
||||
private DrawControl drawControl = DefaultDrawControl.INSTANCE;
|
||||
private ColorMapper colorMapper;
|
||||
|
||||
private PaintApplier paintApplier;
|
||||
|
||||
private FontDrawer fontDrawer;
|
||||
|
||||
private DrawControl drawControl;
|
||||
|
||||
private Paint paint;
|
||||
|
||||
|
@ -106,13 +122,9 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
|
||||
private Color backgroundColor;
|
||||
|
||||
private int saveCounter = 0;
|
||||
private int saveCounter;
|
||||
|
||||
private final CopyInfo copyInfo;
|
||||
|
||||
private final List<CopyInfo> copyList = new ArrayList<>();
|
||||
|
||||
private final PaintApplierEnvImpl paintEnv = new PaintApplierEnvImpl();
|
||||
private boolean disposed;
|
||||
|
||||
/**
|
||||
* Do we currently have an active path on the content stream, which has not been
|
||||
|
@ -121,11 +133,11 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
* clip and we have some clipping. If at the end we try to clip with an empty
|
||||
* path, then Acrobat Reader does not like that and draws nothing.
|
||||
*/
|
||||
private boolean hasPathOnStream = false;
|
||||
private boolean hasPathOnStream;
|
||||
|
||||
private Map<Key, Object> renderingHints = new HashMap<>();
|
||||
private Map<Key, Object> renderingHints;
|
||||
|
||||
private final DrawControlEnv drawControlEnv = new DrawControlEnv() {
|
||||
private final DrawControlEnvironment drawControlEnvironment = new DrawControlEnvironment() {
|
||||
@Override
|
||||
public Paint getPaint() {
|
||||
return paint;
|
||||
|
@ -137,7 +149,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
};
|
||||
|
||||
private final FontTextDrawerEnv fontDrawerEnv = new FontTextDrawerEnv() {
|
||||
private final FontDrawerEnvironment fontDrawerEnv = new FontDrawerEnvironment() {
|
||||
@Override
|
||||
public PDDocument getDocument() {
|
||||
return document;
|
||||
|
@ -246,24 +258,8 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
PDFormXObject xFormObject,
|
||||
PdfBoxGraphics2D parentGfx)
|
||||
throws IOException {
|
||||
this.document = document;
|
||||
this.xFormObject = xFormObject;
|
||||
this.contentStream = new PDPageContentStream(document, xFormObject,
|
||||
xFormObject.getStream().createOutputStream(COSName.FLATE_DECODE));
|
||||
contentStreamSaveState();
|
||||
if (parentGfx != null) {
|
||||
this.colorMapper = parentGfx.colorMapper;
|
||||
this.fontTextDrawer = parentGfx.fontTextDrawer;
|
||||
this.imageEncoder = parentGfx.imageEncoder;
|
||||
this.paintApplier = parentGfx.paintApplier;
|
||||
}
|
||||
baseTransform = new AffineTransform();
|
||||
baseTransform.translate(0, xFormObject.getBBox().getHeight());
|
||||
baseTransform.scale(1, -1);
|
||||
calcImage = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
calcGfx = calcImage.createGraphics();
|
||||
font = calcGfx.getFont();
|
||||
copyInfo = null;
|
||||
this(document, xFormObject, new PDPageContentStream(document, xFormObject,
|
||||
xFormObject.getStream().createOutputStream(COSName.FLATE_DECODE)), parentGfx);
|
||||
}
|
||||
|
||||
public PdfBoxGraphics2D(PDDocument document,
|
||||
|
@ -277,7 +273,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
contentStreamSaveState();
|
||||
if (parentGfx != null) {
|
||||
this.colorMapper = parentGfx.colorMapper;
|
||||
this.fontTextDrawer = parentGfx.fontTextDrawer;
|
||||
this.fontDrawer = parentGfx.fontDrawer;
|
||||
this.imageEncoder = parentGfx.imageEncoder;
|
||||
this.paintApplier = parentGfx.paintApplier;
|
||||
}
|
||||
|
@ -288,6 +284,15 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
calcGfx = calcImage.createGraphics();
|
||||
font = calcGfx.getFont();
|
||||
copyInfo = null;
|
||||
transform = new AffineTransform();
|
||||
imageEncoder = new LosslessImageEncoder();
|
||||
colorMapper = new DefaultColorMapper();
|
||||
paintApplier = new DefaultPaintApplier();
|
||||
fontDrawer = new DefaultFontDrawer();
|
||||
drawControl = DefaultDrawControl.INSTANCE;
|
||||
copyList = new ArrayList<>();
|
||||
paintEnv = new DefaultPaintApplierEnvironment();
|
||||
renderingHints = new HashMap<>();
|
||||
}
|
||||
|
||||
private PdfBoxGraphics2D(PdfBoxGraphics2D pdfBoxGraphics2D) throws IOException {
|
||||
|
@ -311,7 +316,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
this.clipShape = pdfBoxGraphics2D.clipShape;
|
||||
this.backgroundColor = pdfBoxGraphics2D.backgroundColor;
|
||||
this.colorMapper = pdfBoxGraphics2D.colorMapper;
|
||||
this.fontTextDrawer = pdfBoxGraphics2D.fontTextDrawer;
|
||||
this.fontDrawer = pdfBoxGraphics2D.fontDrawer;
|
||||
this.imageEncoder = pdfBoxGraphics2D.imageEncoder;
|
||||
this.paintApplier = pdfBoxGraphics2D.paintApplier;
|
||||
this.drawControl = pdfBoxGraphics2D.drawControl;
|
||||
|
@ -319,6 +324,11 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
this.renderingHints = new HashMap<>(pdfBoxGraphics2D.renderingHints);
|
||||
this.xorColor = pdfBoxGraphics2D.xorColor;
|
||||
this.saveCounter = 0;
|
||||
this.copyList = new ArrayList<>();
|
||||
this.disposed = false;
|
||||
this.paintEnv = pdfBoxGraphics2D.paintEnv;
|
||||
this.hasPathOnStream = pdfBoxGraphics2D.hasPathOnStream;
|
||||
this.renderingHints = pdfBoxGraphics2D.renderingHints;
|
||||
contentStreamSaveState();
|
||||
}
|
||||
|
||||
|
@ -346,10 +356,9 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
if (this.saveCounter != 0) {
|
||||
throw new IllegalStateException("SaveCounter should be 0, but is " + this.saveCounter);
|
||||
}
|
||||
document = null;
|
||||
calcGfx.dispose();
|
||||
calcImage.flush();
|
||||
calcImage = null;
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -360,7 +369,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
try {
|
||||
contentStreamSaveState();
|
||||
Shape shapeToDraw = drawControl.transformShapeBeforeDraw(s, drawControlEnv);
|
||||
Shape shapeToDraw = drawControl.transformShapeBeforeDraw(s, drawControlEnvironment);
|
||||
if (shapeToDraw != null) {
|
||||
walkShape(shapeToDraw);
|
||||
PDShading pdShading = applyPaint(shapeToDraw);
|
||||
|
@ -391,7 +400,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
contentStream.stroke();
|
||||
hasPathOnStream = false;
|
||||
}
|
||||
drawControl.afterShapeDraw(s, drawControlEnv);
|
||||
drawControl.afterShapeDraw(s, drawControlEnvironment);
|
||||
contentStreamRestoreState();
|
||||
} catch (IOException e) {
|
||||
throw new PdfBoxGraphics2dException(e);
|
||||
|
@ -538,7 +547,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
try {
|
||||
contentStreamSaveState();
|
||||
if (fontTextDrawer.canDrawText((AttributedCharacterIterator) iterator.clone(), fontDrawerEnv)) {
|
||||
if (fontDrawer.canDrawText((AttributedCharacterIterator) iterator.clone(), fontDrawerEnv)) {
|
||||
drawStringUsingText(iterator, x, y);
|
||||
} else {
|
||||
drawStringUsingShapes(iterator, x, y);
|
||||
|
@ -566,7 +575,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
try {
|
||||
contentStreamSaveState();
|
||||
Shape shapeToFill = drawControl.transformShapeBeforeFill(s, drawControlEnv);
|
||||
Shape shapeToFill = drawControl.transformShapeBeforeFill(s, drawControlEnvironment);
|
||||
if (shapeToFill != null) {
|
||||
boolean useEvenOdd = walkShape(shapeToFill);
|
||||
PDShading shading = applyPaint(shapeToFill);
|
||||
|
@ -584,7 +593,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
hasPathOnStream = false;
|
||||
}
|
||||
drawControl.afterShapeFill(s, drawControlEnv);
|
||||
drawControl.afterShapeFill(s, drawControlEnvironment);
|
||||
contentStreamRestoreState();
|
||||
} catch (IOException e) {
|
||||
throw new PdfBoxGraphics2dException(e);
|
||||
|
@ -717,7 +726,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
@Override
|
||||
public FontMetrics getFontMetrics(Font f) {
|
||||
try {
|
||||
return fontTextDrawer.getFontMetrics(f, fontDrawerEnv);
|
||||
return fontDrawer.getFontMetrics(f, fontDrawerEnv);
|
||||
} catch (IOException | FontFormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -934,32 +943,12 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
* @return the PDAppearanceStream which resulted in this graphics
|
||||
*/
|
||||
public PDFormXObject getXFormObject() {
|
||||
if (document != null) {
|
||||
throw new IllegalStateException("You can only get the XformObject after you disposed the Graphics2D!");
|
||||
}
|
||||
if (copyInfo != null) {
|
||||
throw new IllegalStateException("You can not get the Xform stream from the copy");
|
||||
if (!disposed) {
|
||||
throw new IllegalStateException("You can only get the XFormObject after you disposed the Graphics2D object");
|
||||
}
|
||||
return xFormObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes the users of {@link #create()} don't correctly {@link #dispose()}
|
||||
* the child graphics they create. And you may not always be able to fix this
|
||||
* uses, as it may be in some 3rdparty library. In this case this method can
|
||||
* help you. It will cleanup all dangling child graphics. The child graphics can
|
||||
* not be used after that. This method is a workaround for a buggy old code. You
|
||||
* should only use it if you have to.
|
||||
* Note: You can only call this method on the "main" graphics, not on a child
|
||||
* created with {@link #create()}
|
||||
*/
|
||||
public void disposeDanglingChildGraphics() {
|
||||
if (copyInfo != null)
|
||||
throw new IllegalStateException(
|
||||
"Don't call disposeDanglingChildGraphics() on a child!");
|
||||
disposeCopies(copyList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new color mapper.
|
||||
*
|
||||
|
@ -1011,10 +1000,10 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
* also must perform the text layout. If it can not map the text or font
|
||||
* correctly, the font drawing falls back to vectoring the text.
|
||||
*
|
||||
* @param fontTextDrawer The text drawer, which can draw text using fonts
|
||||
* @param fontDrawer The text drawer, which can draw text using fonts
|
||||
*/
|
||||
public void setFontTextDrawer(FontTextDrawer fontTextDrawer) {
|
||||
this.fontTextDrawer = fontTextDrawer;
|
||||
public void setFontTextDrawer(FontDrawer fontDrawer) {
|
||||
this.fontDrawer = fontDrawer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1022,7 +1011,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
* applyer to the content stream or by walkShape() - is on the content stream.
|
||||
* We can then safely clip() if there is a path on the content stream.
|
||||
*/
|
||||
void markPathIsOnStream() {
|
||||
public void markPathIsOnStream() {
|
||||
hasPathOnStream = true;
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1039,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
tf.concatenate(transform);
|
||||
tf.translate(x, y);
|
||||
contentStream.transform(new Matrix(tf));
|
||||
fontTextDrawer.drawText(iterator, fontDrawerEnv);
|
||||
fontDrawer.drawText(iterator, fontDrawerEnv);
|
||||
contentStreamRestoreState();
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1140,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
*
|
||||
* @param useEvenOdd true when we should use the evenOdd rule.
|
||||
*/
|
||||
void internalClip(boolean useEvenOdd) throws IOException {
|
||||
public void internalClip(boolean useEvenOdd) throws IOException {
|
||||
if (hasPathOnStream) {
|
||||
if (useEvenOdd) {
|
||||
contentStream.clipEvenOdd();
|
||||
|
@ -1226,7 +1215,7 @@ public class PdfBoxGraphics2D extends Graphics2D {
|
|||
}
|
||||
}
|
||||
|
||||
private class PaintApplierEnvImpl implements PaintApplierEnv {
|
||||
private class DefaultPaintApplierEnvironment implements PaintApplierEnvironment {
|
||||
|
||||
private Shape shapeToDraw;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.color;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.color;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
|
@ -1,9 +1,10 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.color;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceCMYK;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
|
||||
import org.xbib.graphics.io.pdfbox.paint.DefaultPaintApplier;
|
||||
|
||||
import java.awt.Color;
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.color;
|
||||
|
||||
import org.apache.pdfbox.cos.COSName;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
|
||||
import org.apache.pdfbox.pdmodel.graphics.color.PDICCBased;
|
||||
import org.xbib.graphics.io.pdfbox.color.DefaultColorMapper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.color.ICC_ColorSpace;
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.draw;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
|
@ -14,20 +14,20 @@ public class DefaultDrawControl implements DrawControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Shape transformShapeBeforeFill(Shape shape, DrawControlEnv env) {
|
||||
public Shape transformShapeBeforeFill(Shape shape, DrawControlEnvironment env) {
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape transformShapeBeforeDraw(Shape shape, DrawControlEnv env) {
|
||||
public Shape transformShapeBeforeDraw(Shape shape, DrawControlEnvironment env) {
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterShapeFill(Shape shape, DrawControlEnv env) {
|
||||
public void afterShapeFill(Shape shape, DrawControlEnvironment env) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterShapeDraw(Shape shape, DrawControlEnv env) {
|
||||
public void afterShapeDraw(Shape shape, DrawControlEnvironment env) {
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.draw;
|
||||
|
||||
import org.xbib.graphics.io.pdfbox.PdfBoxGraphics2D;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Shape;
|
||||
|
||||
|
@ -18,7 +19,7 @@ public interface DrawControl {
|
|||
* @param env Environment
|
||||
* @return the shape to be filled. If you return null, nothing will be filled
|
||||
*/
|
||||
Shape transformShapeBeforeFill(Shape shape, DrawControlEnv env);
|
||||
Shape transformShapeBeforeFill(Shape shape, DrawControlEnvironment env);
|
||||
|
||||
/**
|
||||
* You may optional change the shape that is going to be drawn. You can also do
|
||||
|
@ -28,36 +29,36 @@ public interface DrawControl {
|
|||
* @param env Environment
|
||||
* @return the shape to be filled. If you return null, nothing will be drawn
|
||||
*/
|
||||
Shape transformShapeBeforeDraw(Shape shape, DrawControlEnv env);
|
||||
Shape transformShapeBeforeDraw(Shape shape, DrawControlEnvironment env);
|
||||
|
||||
/**
|
||||
* Called after shape was filled. This method is always called, even if
|
||||
* {@link #transformShapeBeforeFill(Shape, DrawControlEnv)} returns
|
||||
* {@link #transformShapeBeforeFill(Shape, DrawControlEnvironment)} returns
|
||||
* null.
|
||||
*
|
||||
* @param shape the shape that was filled. This is the original shape, not the one
|
||||
* transformed by
|
||||
* {@link #transformShapeBeforeFill(Shape, DrawControlEnv)}.
|
||||
* {@link #transformShapeBeforeFill(Shape, DrawControlEnvironment)}.
|
||||
* @param env Environment
|
||||
*/
|
||||
void afterShapeFill(Shape shape, DrawControlEnv env);
|
||||
void afterShapeFill(Shape shape, DrawControlEnvironment env);
|
||||
|
||||
/**
|
||||
* Called after shape was drawn. This method is always called, even if
|
||||
* {@link #transformShapeBeforeDraw(Shape, DrawControlEnv)} returns
|
||||
* {@link #transformShapeBeforeDraw(Shape, DrawControlEnvironment)} returns
|
||||
* null.
|
||||
*
|
||||
* @param shape the shape that was drawn. This is the original shape, not the one
|
||||
* transformed by
|
||||
* {@link #transformShapeBeforeDraw(Shape, DrawControlEnv)}.
|
||||
* {@link #transformShapeBeforeDraw(Shape, DrawControlEnvironment)}.
|
||||
* @param env Environment
|
||||
*/
|
||||
void afterShapeDraw(Shape shape, DrawControlEnv env);
|
||||
void afterShapeDraw(Shape shape, DrawControlEnvironment env);
|
||||
|
||||
/**
|
||||
* The environment of the draw operation
|
||||
*/
|
||||
interface DrawControlEnv {
|
||||
interface DrawControlEnvironment {
|
||||
/**
|
||||
* @return the current paint set on the graphics.
|
||||
*/
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
|
||||
|
@ -7,17 +7,17 @@ import java.awt.FontFormatException;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Like {@link DefaultFontTextDrawer}, but tries to use default fonts
|
||||
* Like {@link DefaultFontDrawer}, but tries to use core fonts
|
||||
* whenever possible. Default fonts are not embedded. You can register
|
||||
* additional font files. If no font mapping is found, Helvetica is used.
|
||||
* This will fallback to vectorized text if any kind of RTL text is rendered
|
||||
* and/or any other not supported feature is used.
|
||||
*/
|
||||
public class DefaultFontTextDrawerFonts extends DefaultFontTextDrawer {
|
||||
public class CoreFontDrawer extends DefaultFontDrawer {
|
||||
|
||||
@Override
|
||||
protected PDFont mapFont(Font font, FontTextDrawerEnv env) throws IOException, FontFormatException {
|
||||
PDFont pdFont = mapDefaultFonts(font);
|
||||
protected PDFont mapFont(Font font, FontDrawerEnvironment env) throws IOException, FontFormatException {
|
||||
PDFont pdFont = mapToCoreFonts(font);
|
||||
if (pdFont != null) {
|
||||
return pdFont;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import org.apache.fontbox.ttf.TrueTypeCollection;
|
||||
import org.apache.pdfbox.io.IOUtils;
|
||||
|
@ -7,6 +7,7 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
|
|||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.xbib.graphics.io.pdfbox.PdfBoxGraphics2D;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
|
@ -33,9 +34,9 @@ import java.util.logging.Logger;
|
|||
* Just ensure that you call close after you closed the PDDocument to free any
|
||||
* temporary files.
|
||||
*/
|
||||
public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
||||
public class DefaultFontDrawer implements FontDrawer, Closeable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DefaultFontTextDrawer.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(DefaultFontDrawer.class.getName());
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
@ -141,54 +142,44 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
* the case if this class has been derived. The default implementation
|
||||
* just checks for this.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected boolean hasDynamicFontMapping() {
|
||||
return getClass() != DefaultFontTextDrawer.class;
|
||||
return getClass() != DefaultFontDrawer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDrawText(AttributedCharacterIterator iterator, FontTextDrawerEnv env)
|
||||
public boolean canDrawText(AttributedCharacterIterator iterator, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException {
|
||||
/*
|
||||
* When no font is registered we can not display the text using a font...
|
||||
*/
|
||||
if (fontMap.size() == 0 && fontFiles.size() == 0 && !hasDynamicFontMapping())
|
||||
if (fontMap.size() == 0 && fontFiles.size() == 0 && !hasDynamicFontMapping()) {
|
||||
return false;
|
||||
|
||||
}
|
||||
boolean run = true;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (run) {
|
||||
|
||||
Font attributeFont = (Font) iterator.getAttribute(TextAttribute.FONT);
|
||||
if (attributeFont == null)
|
||||
if (attributeFont == null) {
|
||||
attributeFont = env.getFont();
|
||||
if (mapFont(attributeFont, env) == null)
|
||||
}
|
||||
if (mapFont(attributeFont, env) == null) {
|
||||
return false;
|
||||
|
||||
/*
|
||||
* We can not do a Background on the text currently.
|
||||
*/
|
||||
if (iterator.getAttribute(TextAttribute.BACKGROUND) != null)
|
||||
}
|
||||
if (iterator.getAttribute(TextAttribute.BACKGROUND) != null) {
|
||||
return false;
|
||||
|
||||
boolean isStrikeThrough = TextAttribute.STRIKETHROUGH_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.STRIKETHROUGH));
|
||||
boolean isUnderline = TextAttribute.UNDERLINE_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.UNDERLINE));
|
||||
boolean isLigatures = TextAttribute.LIGATURES_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.LIGATURES));
|
||||
if (isStrikeThrough || isUnderline || isLigatures)
|
||||
}
|
||||
boolean isStrikeThrough =
|
||||
TextAttribute.STRIKETHROUGH_ON.equals(iterator.getAttribute(TextAttribute.STRIKETHROUGH));
|
||||
boolean isUnderline =
|
||||
TextAttribute.UNDERLINE_ON.equals(iterator.getAttribute(TextAttribute.UNDERLINE));
|
||||
boolean isLigatures =
|
||||
TextAttribute.LIGATURES_ON.equals(iterator.getAttribute(TextAttribute.LIGATURES));
|
||||
if (isStrikeThrough || isUnderline || isLigatures) {
|
||||
return false;
|
||||
|
||||
}
|
||||
run = iterateRun(iterator, sb);
|
||||
String s = sb.toString();
|
||||
int l = s.length();
|
||||
for (int i = 0; i < l; ) {
|
||||
int codePoint = s.codePointAt(i);
|
||||
switch (Character.getDirectionality(codePoint)) {
|
||||
/*
|
||||
* We can handle normal LTR.
|
||||
*/
|
||||
case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
|
||||
case Character.DIRECTIONALITY_EUROPEAN_NUMBER:
|
||||
case Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR:
|
||||
|
@ -207,20 +198,13 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
|
||||
case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
|
||||
case Character.DIRECTIONALITY_POP_DIRECTIONAL_FORMAT:
|
||||
/*
|
||||
* We can not handle this
|
||||
*/
|
||||
return false;
|
||||
default:
|
||||
/*
|
||||
* Default: We can not handle this
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!attributeFont.canDisplay(codePoint))
|
||||
if (!attributeFont.canDisplay(codePoint)) {
|
||||
return false;
|
||||
|
||||
}
|
||||
i += Character.charCount(codePoint);
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +212,7 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void drawText(AttributedCharacterIterator iterator, FontTextDrawerEnv env)
|
||||
public void drawText(AttributedCharacterIterator iterator, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException {
|
||||
PDPageContentStream contentStream = env.getContentStream();
|
||||
|
||||
|
@ -241,52 +225,37 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
boolean run = true;
|
||||
while (run) {
|
||||
|
||||
Font attributeFont = (Font) iterator.getAttribute(TextAttribute.FONT);
|
||||
if (attributeFont == null)
|
||||
if (attributeFont == null) {
|
||||
attributeFont = env.getFont();
|
||||
|
||||
}
|
||||
Number fontSize = ((Number) iterator.getAttribute(TextAttribute.SIZE));
|
||||
if (fontSize != null)
|
||||
if (fontSize != null) {
|
||||
attributeFont = attributeFont.deriveFont(fontSize.floatValue());
|
||||
}
|
||||
PDFont font = applyFont(attributeFont, env);
|
||||
|
||||
Paint paint = (Paint) iterator.getAttribute(TextAttribute.FOREGROUND);
|
||||
if (paint == null)
|
||||
if (paint == null) {
|
||||
paint = env.getPaint();
|
||||
|
||||
boolean isStrikeThrough = TextAttribute.STRIKETHROUGH_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.STRIKETHROUGH));
|
||||
boolean isUnderline = TextAttribute.UNDERLINE_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.UNDERLINE));
|
||||
boolean isLigatures = TextAttribute.LIGATURES_ON
|
||||
.equals(iterator.getAttribute(TextAttribute.LIGATURES));
|
||||
|
||||
}
|
||||
boolean isStrikeThrough =
|
||||
TextAttribute.STRIKETHROUGH_ON.equals(iterator.getAttribute(TextAttribute.STRIKETHROUGH));
|
||||
boolean isUnderline =
|
||||
TextAttribute.UNDERLINE_ON.equals(iterator.getAttribute(TextAttribute.UNDERLINE));
|
||||
boolean isLigatures =
|
||||
TextAttribute.LIGATURES_ON.equals(iterator.getAttribute(TextAttribute.LIGATURES));
|
||||
run = iterateRun(iterator, sb);
|
||||
String text = sb.toString();
|
||||
|
||||
/*
|
||||
* Apply the paint
|
||||
*/
|
||||
env.applyPaint(paint, null);
|
||||
|
||||
/*
|
||||
* If we force the text write we may encounter situations where the font can not
|
||||
* display the characters. PDFBox will throw an exception in this case. We will
|
||||
* just silently ignore the text and not display it instead.
|
||||
*/
|
||||
try {
|
||||
showTextOnStream(env, contentStream, attributeFont, font, isStrikeThrough,
|
||||
isUnderline, isLigatures, text);
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (font instanceof PDType1Font && !font.isEmbedded()) {
|
||||
/*
|
||||
* We tried to use a builtin default font, but it does not have the needed
|
||||
* characters. So we use a embedded font as fallback.
|
||||
*/
|
||||
try {
|
||||
if (fallbackFontUnknownEncodings == null)
|
||||
if (fallbackFontUnknownEncodings == null) {
|
||||
fallbackFontUnknownEncodings = findFallbackFont(env);
|
||||
}
|
||||
if (fallbackFontUnknownEncodings != null) {
|
||||
env.getContentStream().setFont(fallbackFontUnknownEncodings,
|
||||
attributeFont.getSize2D());
|
||||
|
@ -299,48 +268,35 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
e = e1;
|
||||
}
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
if (e != null) {
|
||||
logger.log(Level.WARNING, "PDFBoxGraphics: Can not map text " + text + " with font "
|
||||
+ attributeFont.getFontName() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
contentStream.endText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(final Font f, FontTextDrawerEnv env)
|
||||
public FontMetrics getFontMetrics(Font f, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException {
|
||||
final FontMetrics defaultMetrics = env.getCalculationGraphics().getFontMetrics(f);
|
||||
final FontMetrics fontMetrics = env.getCalculationGraphics().getFontMetrics(f);
|
||||
final PDFont pdFont = mapFont(f, env);
|
||||
/*
|
||||
* By default we delegate to the buffered image based calculation. This is wrong
|
||||
* as soon as we use the native PDF Box font, as those have sometimes different widths.
|
||||
*
|
||||
* But it is correct and fine as long as we use vector shapes.
|
||||
*/
|
||||
if (pdFont == null) {
|
||||
return defaultMetrics;
|
||||
return fontMetrics;
|
||||
}
|
||||
return new DefaultFontMetrics(f, defaultMetrics, pdFont);
|
||||
return new DefaultFontMetrics(f, fontMetrics, pdFont);
|
||||
}
|
||||
|
||||
private PDFont fallbackFontUnknownEncodings;
|
||||
|
||||
private PDFont findFallbackFont(FontTextDrawerEnv env) throws IOException {
|
||||
/*
|
||||
* We search for the right font in the folders... We try to use
|
||||
* LucidaSansRegular and if not found Arial, because this fonts often exists. We
|
||||
* use the Java default font as fallback.
|
||||
*
|
||||
* Normally this method is only used and called if a default font misses some
|
||||
* special characters, e.g. Hebrew or Arabic characters.
|
||||
*/
|
||||
private PDFont findFallbackFont(FontDrawerEnvironment env) {
|
||||
String javaHome = System.getProperty("java.home", ".");
|
||||
String javaFontDir = javaHome + "/lib/fonts";
|
||||
String windir = System.getenv("WINDIR");
|
||||
if (windir == null)
|
||||
if (windir == null) {
|
||||
windir = javaFontDir;
|
||||
}
|
||||
File[] paths = new File[]{new File(new File(windir), "fonts"),
|
||||
new File(System.getProperty("user.dir", ".")),
|
||||
// Mac Fonts
|
||||
|
@ -357,24 +313,26 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
if (arialFile.exists()) {
|
||||
// We try to use the first font we can find and use.
|
||||
PDType0Font pdType0Font = tryToLoadFont(env, arialFile);
|
||||
if (pdType0Font != null)
|
||||
if (pdType0Font != null) {
|
||||
return pdType0Font;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PDType0Font tryToLoadFont(FontTextDrawerEnv env, File foundFontFile) {
|
||||
private PDType0Font tryToLoadFont(FontDrawerEnvironment env, File foundFontFile) {
|
||||
try {
|
||||
return PDType0Font.load(env.getDocument(), foundFontFile);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, e.getMessage(), e);
|
||||
// The font may be have a embed restriction.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void showTextOnStream(FontTextDrawerEnv env,
|
||||
private void showTextOnStream(FontDrawerEnvironment env,
|
||||
PDPageContentStream contentStream,
|
||||
Font attributeFont,
|
||||
PDFont font,
|
||||
|
@ -385,11 +343,11 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
contentStream.showText(text);
|
||||
}
|
||||
|
||||
private PDFont applyFont(Font font, FontTextDrawerEnv env)
|
||||
private PDFont applyFont(Font font, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException {
|
||||
PDFont fontToUse = mapFont(font, env);
|
||||
if (fontToUse == null) {
|
||||
fontToUse = DefaultFontTextDrawerFonts.chooseMatchingHelvetica(font);
|
||||
fontToUse = CoreFontDrawer.chooseMatchingHelvetica(font);
|
||||
}
|
||||
env.getContentStream().setFont(fontToUse, font.getSize2D());
|
||||
return fontToUse;
|
||||
|
@ -404,13 +362,9 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
* @throws IOException when the font can not be loaded
|
||||
* @throws FontFormatException when the font file can not be loaded
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected PDFont mapFont(final Font font, final FontTextDrawerEnv env)
|
||||
protected PDFont mapFont(Font font, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException {
|
||||
/*
|
||||
* If we have any font registering's, we must perform them now
|
||||
*/
|
||||
for (final FontEntry fontEntry : fontFiles) {
|
||||
for (FontEntry fontEntry : fontFiles) {
|
||||
if (fontEntry.overrideName == null) {
|
||||
Font javaFont = Font.createFont(Font.TRUETYPE_FONT, fontEntry.file);
|
||||
fontEntry.overrideName = javaFont.getFontName();
|
||||
|
@ -447,13 +401,12 @@ public class DefaultFontTextDrawer implements FontTextDrawer, Closeable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Find a PDFont for the given font object, which does not need to be embedded.
|
||||
*
|
||||
* @param font font for which to find a suitable default font
|
||||
* @return null if no default font is found or a default font which does not
|
||||
* Find a PDFont for the given font object.
|
||||
* @param font font for which to find a suitable core font
|
||||
* @return null if no core font is found or a core font which does not
|
||||
* need to be embedded.
|
||||
*/
|
||||
protected static PDFont mapDefaultFonts(Font font) {
|
||||
protected static PDFont mapToCoreFonts(Font font) {
|
||||
if (fontNameEqualsAnyOf(font, Font.SANS_SERIF, Font.DIALOG, Font.DIALOG_INPUT, "Arial", "Helvetica")) {
|
||||
return chooseMatchingHelvetica(font);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import java.awt.Font;
|
||||
|
@ -151,9 +151,6 @@ public class DefaultFontMetrics extends FontMetrics {
|
|||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
/*
|
||||
* We let unknown chars be handled with
|
||||
*/
|
||||
return defaultMetrics.stringWidth(str);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.PDResources;
|
||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||
import org.xbib.graphics.io.pdfbox.PdfBoxGraphics2D;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
|
@ -16,9 +17,9 @@ import java.io.IOException;
|
|||
import java.text.AttributedCharacterIterator;
|
||||
|
||||
/**
|
||||
* Draw text using Fonts
|
||||
* Draw text using fonts.
|
||||
*/
|
||||
public interface FontTextDrawer {
|
||||
public interface FontDrawer {
|
||||
|
||||
/**
|
||||
* @param iterator Has the text and all its properties
|
||||
|
@ -28,7 +29,7 @@ public interface FontTextDrawer {
|
|||
* @throws IOException when a font can not be loaded or a paint can't be applied.
|
||||
* @throws FontFormatException when the font file can not be loaded
|
||||
*/
|
||||
boolean canDrawText(AttributedCharacterIterator iterator, FontTextDrawerEnv env)
|
||||
boolean canDrawText(AttributedCharacterIterator iterator, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException;
|
||||
|
||||
/**
|
||||
|
@ -37,16 +38,16 @@ public interface FontTextDrawer {
|
|||
* @throws IOException when a font can not be loaded or a paint can't be applied.
|
||||
* @throws FontFormatException when the font file can not be loaded
|
||||
*/
|
||||
void drawText(AttributedCharacterIterator iterator, FontTextDrawerEnv env)
|
||||
void drawText(AttributedCharacterIterator iterator, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException;
|
||||
|
||||
FontMetrics getFontMetrics(Font f, FontTextDrawerEnv env)
|
||||
FontMetrics getFontMetrics(Font f, FontDrawerEnvironment env)
|
||||
throws IOException, FontFormatException;
|
||||
|
||||
/**
|
||||
* Enviroment for font based drawing of text
|
||||
* Environment for font based drawing of text
|
||||
*/
|
||||
interface FontTextDrawerEnv {
|
||||
interface FontDrawerEnvironment {
|
||||
/**
|
||||
* @return the document we are writing to
|
||||
*/
|
|
@ -1,14 +1,14 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import java.text.AttributedCharacterIterator;
|
||||
|
||||
/**
|
||||
* Always draw using text, even if we know that we can not map the text correctly.
|
||||
*/
|
||||
public class DefaultFontTextDrawerForce extends DefaultFontTextDrawerFonts {
|
||||
public class ForcedFontDrawer extends CoreFontDrawer {
|
||||
|
||||
@Override
|
||||
public boolean canDrawText(AttributedCharacterIterator iterator, FontTextDrawerEnv env) {
|
||||
public boolean canDrawText(AttributedCharacterIterator iterator, FontDrawerEnvironment env) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.image;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.image;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
|
@ -42,11 +42,11 @@ public class LosslessImageEncoder implements ImageEncoder {
|
|||
int height = image.getHeight(null);
|
||||
bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
Graphics graphics = bi.getGraphics();
|
||||
if (!graphics.drawImage(image, 0, 0, null, null))
|
||||
throw new IllegalStateException("Not fully loaded images are not supported.");
|
||||
if (!graphics.drawImage(image, 0, 0, null, null)) {
|
||||
throw new IllegalStateException("Not fully loaded images are not supported");
|
||||
}
|
||||
graphics.dispose();
|
||||
}
|
||||
|
||||
try {
|
||||
if (doc == null || doc.get() != document) {
|
||||
imageMap = new HashMap<>();
|
||||
|
@ -76,7 +76,6 @@ public class LosslessImageEncoder implements ImageEncoder {
|
|||
}
|
||||
imageMap.put(new ImageSoftReference(image), new SoftReference<>(imageXObject));
|
||||
}
|
||||
|
||||
return imageXObject;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not encode Image", e);
|
||||
|
@ -93,6 +92,9 @@ public class LosslessImageEncoder implements ImageEncoder {
|
|||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof ImageSoftReference)) {
|
||||
return false;
|
||||
}
|
||||
return ((ImageSoftReference) obj).get() == get();
|
||||
}
|
||||
|
||||
|
@ -116,6 +118,9 @@ public class LosslessImageEncoder implements ImageEncoder {
|
|||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof ProfileSoftReference)) {
|
||||
return false;
|
||||
}
|
||||
return ((ProfileSoftReference) obj).get() == get();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.paint;
|
||||
|
||||
import org.apache.pdfbox.cos.COSArray;
|
||||
import org.apache.pdfbox.cos.COSBase;
|
||||
|
@ -26,6 +26,9 @@ import org.apache.pdfbox.pdmodel.graphics.shading.ShadingPaint;
|
|||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.xbib.graphics.io.pdfbox.image.ImageEncoder;
|
||||
import org.xbib.graphics.io.pdfbox.PdfBoxGraphics2D;
|
||||
import org.xbib.graphics.io.pdfbox.color.ColorMapper;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
|
@ -63,7 +66,7 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
|
||||
@Override
|
||||
public PDShading applyPaint(Paint paint, PDPageContentStream contentStream, AffineTransform tf,
|
||||
PaintApplierEnv env) throws IOException {
|
||||
PaintApplierEnvironment env) throws IOException {
|
||||
PaintApplierState state = new PaintApplierState();
|
||||
state.document = env.getDocument();
|
||||
state.resources = env.getResources();
|
||||
|
@ -72,8 +75,8 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
state.imageEncoder = env.getImageEncoder();
|
||||
state.composite = env.getComposite();
|
||||
state.pdExtendedGraphicsState = null;
|
||||
state.env = env;
|
||||
state.tf = tf;
|
||||
state.paintApplierEnvironment = env;
|
||||
state.affineTransform = tf;
|
||||
state.nestedTransform = null;
|
||||
PDShading shading = applyPaint(paint, state);
|
||||
if (state.pdExtendedGraphicsState != null) {
|
||||
|
@ -155,10 +158,10 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
AffineTransform patternTransform = new AffineTransform();
|
||||
if (paintPatternTransform != null) {
|
||||
paintPatternTransform = new AffineTransform(paintPatternTransform);
|
||||
paintPatternTransform.preConcatenate(state.tf);
|
||||
paintPatternTransform.preConcatenate(state.affineTransform);
|
||||
patternTransform.concatenate(paintPatternTransform);
|
||||
} else {
|
||||
patternTransform.concatenate(state.tf);
|
||||
patternTransform.concatenate(state.affineTransform);
|
||||
}
|
||||
patternTransform.scale(1f, -1f);
|
||||
pattern.setMatrix(patternTransform);
|
||||
|
@ -167,7 +170,7 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
appearance.setBBox(pattern.getBBox());
|
||||
Object graphicsNode = getPropertyValue(paint, "getGraphicsNode");
|
||||
PdfBoxGraphics2D pdfBoxGraphics2D =
|
||||
new PdfBoxGraphics2D(state.document, pattern.getBBox(), state.env.getGraphics2D());
|
||||
new PdfBoxGraphics2D(state.document, pattern.getBBox(), state.paintApplierEnvironment.getGraphics2D());
|
||||
try {
|
||||
Method paintMethod = graphicsNode.getClass().getMethod("paint", Graphics2D.class);
|
||||
paintMethod.invoke(graphicsNode, pdfBoxGraphics2D);
|
||||
|
@ -294,7 +297,7 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
Point2D startPoint = clonePoint(getPropertyValue(paint, "getStartPoint"));
|
||||
Point2D endPoint = clonePoint(getPropertyValue(paint, "getEndPoint"));
|
||||
AffineTransform gradientTransform = getPropertyValue(paint, "getTransform");
|
||||
state.tf.concatenate(gradientTransform);
|
||||
state.affineTransform.concatenate(gradientTransform);
|
||||
|
||||
// noinspection unused
|
||||
MultipleGradientPaint.CycleMethod cycleMethod = getCycleMethod(paint);
|
||||
|
@ -321,19 +324,13 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
// will display it another.
|
||||
float calculatedX = (float) Math.min(startPoint.getX(), endPoint.getX());
|
||||
float calculatedY = (float) Math.max(1.0f, Math.max(startPoint.getY(), endPoint.getY()));
|
||||
float calculatedWidth = Math
|
||||
.max(1.0f, Math.abs((float) (endPoint.getX() - startPoint.getX())));
|
||||
float negativeHeight =
|
||||
-1.0f * Math.max(1.0f, Math.abs((float) (endPoint.getY() - startPoint.getY())));
|
||||
|
||||
float calculatedWidth = Math.max(1.0f, Math.abs((float) (endPoint.getX() - startPoint.getX())));
|
||||
float negativeHeight = -1.0f * Math.max(1.0f, Math.abs((float) (endPoint.getY() - startPoint.getY())));
|
||||
state.contentStream.addRect(calculatedX, calculatedY, calculatedWidth, negativeHeight);
|
||||
|
||||
state.env.getGraphics2D().markPathIsOnStream();
|
||||
state.env.getGraphics2D().internalClip(false);
|
||||
|
||||
state.paintApplierEnvironment.getGraphics2D().markPathIsOnStream();
|
||||
state.paintApplierEnvironment.getGraphics2D().internalClip(false);
|
||||
// Warp the 1x1 box containing the gradient to fill a larger rectangular space
|
||||
state.contentStream.transform(new Matrix(state.tf));
|
||||
|
||||
state.contentStream.transform(new Matrix(state.affineTransform));
|
||||
return shading;
|
||||
}
|
||||
|
||||
|
@ -357,15 +354,15 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
Point2D startPoint = clonePoint(getPropertyValue(paint, "getStartPoint"));
|
||||
Point2D endPoint = clonePoint(getPropertyValue(paint, "getEndPoint"));
|
||||
AffineTransform gradientTransform = getPropertyValue(paint, "getTransform");
|
||||
state.tf.concatenate(gradientTransform);
|
||||
state.affineTransform.concatenate(gradientTransform);
|
||||
|
||||
// noinspection unused
|
||||
MultipleGradientPaint.CycleMethod cycleMethod = getCycleMethod(paint);
|
||||
// noinspection unused
|
||||
MultipleGradientPaint.ColorSpaceType colorSpaceType = getColorSpaceType(paint);
|
||||
|
||||
state.tf.transform(startPoint, startPoint);
|
||||
state.tf.transform(endPoint, endPoint);
|
||||
state.affineTransform.transform(startPoint, startPoint);
|
||||
state.affineTransform.transform(endPoint, endPoint);
|
||||
|
||||
setupShadingCoords(shading, startPoint, endPoint);
|
||||
|
||||
|
@ -483,12 +480,12 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
Point2D centerPoint = clonePoint(getPropertyValue(paint, "getCenterPoint"));
|
||||
Point2D focusPoint = clonePoint(getPropertyValue(paint, "getFocusPoint"));
|
||||
AffineTransform gradientTransform = getPropertyValue(paint, "getTransform");
|
||||
state.tf.concatenate(gradientTransform);
|
||||
state.tf.transform(centerPoint, centerPoint);
|
||||
state.tf.transform(focusPoint, focusPoint);
|
||||
state.affineTransform.concatenate(gradientTransform);
|
||||
state.affineTransform.transform(centerPoint, centerPoint);
|
||||
state.affineTransform.transform(focusPoint, focusPoint);
|
||||
|
||||
float radius = getPropertyValue(paint, "getRadius");
|
||||
radius = (float) Math.abs(radius * state.tf.getScaleX());
|
||||
radius = (float) Math.abs(radius * state.affineTransform.getScaleX());
|
||||
|
||||
COSArray coords = new COSArray();
|
||||
|
||||
|
@ -523,8 +520,8 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
Point2D startPoint = gradientPaint.getPoint1();
|
||||
Point2D endPoint = gradientPaint.getPoint2();
|
||||
|
||||
state.tf.transform(startPoint, startPoint);
|
||||
state.tf.transform(endPoint, endPoint);
|
||||
state.affineTransform.transform(startPoint, startPoint);
|
||||
state.affineTransform.transform(endPoint, endPoint);
|
||||
|
||||
setupShadingCoords(shading, startPoint, endPoint);
|
||||
|
||||
|
@ -670,7 +667,7 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
* @return the value read from the object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <T> T getPropertyValue(Object obj, String propertyGetter) {
|
||||
public static <T> T getPropertyValue(Object obj, String propertyGetter) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -696,8 +693,8 @@ public class DefaultPaintApplier implements PaintApplier {
|
|||
protected PDExtendedGraphicsState pdExtendedGraphicsState;
|
||||
protected Composite composite;
|
||||
private COSDictionary dictExtendedState;
|
||||
private PaintApplierEnv env;
|
||||
public AffineTransform tf;
|
||||
private PaintApplierEnvironment paintApplierEnvironment;
|
||||
private AffineTransform affineTransform;
|
||||
protected AffineTransform nestedTransform;
|
||||
|
||||
private void ensureExtendedState() {
|
|
@ -1,9 +1,12 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
package org.xbib.graphics.io.pdfbox.paint;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.PDResources;
|
||||
import org.apache.pdfbox.pdmodel.graphics.shading.PDShading;
|
||||
import org.xbib.graphics.io.pdfbox.image.ImageEncoder;
|
||||
import org.xbib.graphics.io.pdfbox.PdfBoxGraphics2D;
|
||||
import org.xbib.graphics.io.pdfbox.color.ColorMapper;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
|
@ -14,7 +17,7 @@ import java.awt.geom.AffineTransform;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Apply the given paint on the Content Stream.
|
||||
* Apply the given paint on the content stream.
|
||||
*/
|
||||
public interface PaintApplier {
|
||||
/**
|
||||
|
@ -30,13 +33,13 @@ public interface PaintApplier {
|
|||
* @throws IOException if its not possible to write the paint into the contentStream
|
||||
*/
|
||||
PDShading applyPaint(Paint paint, PDPageContentStream contentStream,
|
||||
AffineTransform currentTransform, PaintApplierEnv env) throws IOException;
|
||||
AffineTransform currentTransform, PaintApplierEnvironment env) throws IOException;
|
||||
|
||||
/**
|
||||
* The different mappers used by the paint applier. This interface is
|
||||
* implemented internally by {@link PdfBoxGraphics2D}
|
||||
*/
|
||||
interface PaintApplierEnv {
|
||||
interface PaintApplierEnvironment {
|
||||
/**
|
||||
* @return the color mapper
|
||||
*/
|
|
@ -29,7 +29,8 @@ public class DanglingCaseTest {
|
|||
child2.setColor(Color.GREEN);
|
||||
child2.drawOval(0, 0, 5, 5);
|
||||
child.create();
|
||||
pdfBoxGraphics2D.disposeDanglingChildGraphics();
|
||||
child.dispose();
|
||||
child2.dispose();
|
||||
pdfBoxGraphics2D.dispose();
|
||||
PDFormXObject appearanceStream = pdfBoxGraphics2D.getXFormObject();
|
||||
Matrix matrix = new Matrix();
|
||||
|
@ -54,15 +55,4 @@ public class DanglingCaseTest {
|
|||
pdfBoxGraphics2D.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDanglingDisposeException2() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
PDDocument document = new PDDocument();
|
||||
PDPage page = new PDPage(PDRectangle.A4);
|
||||
document.addPage(page);
|
||||
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(document, 400, 400);
|
||||
pdfBoxGraphics2D.create().disposeDanglingChildGraphics();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
package org.xbib.graphics.io.pdfbox;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class DefaultFontTextDrawerFontsTest {
|
||||
|
||||
@Test
|
||||
public void testFontStyleMatching() {
|
||||
Font anyFont = Font.decode("Dialog");
|
||||
Font anyFontBold = anyFont.deriveFont(Font.BOLD);
|
||||
Font anyFontItalic = anyFont.deriveFont(Font.ITALIC);
|
||||
Font anyFontBoldItalic = anyFont.deriveFont(Font.BOLD | Font.ITALIC);
|
||||
|
||||
assertEquals(PDType1Font.COURIER, DefaultFontTextDrawerFonts.chooseMatchingCourier(anyFont));
|
||||
assertEquals(PDType1Font.COURIER_BOLD,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingCourier(anyFontBold));
|
||||
assertEquals(PDType1Font.COURIER_OBLIQUE,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingCourier(anyFontItalic));
|
||||
assertEquals(PDType1Font.COURIER_BOLD_OBLIQUE,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingCourier(anyFontBoldItalic));
|
||||
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingHelvetica(anyFont));
|
||||
assertEquals(PDType1Font.HELVETICA_BOLD,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingHelvetica(anyFontBold));
|
||||
assertEquals(PDType1Font.HELVETICA_OBLIQUE,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingHelvetica(anyFontItalic));
|
||||
assertEquals(PDType1Font.HELVETICA_BOLD_OBLIQUE,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingHelvetica(anyFontBoldItalic));
|
||||
|
||||
assertEquals(PDType1Font.TIMES_ROMAN, DefaultFontTextDrawerFonts.chooseMatchingTimes(anyFont));
|
||||
assertEquals(PDType1Font.TIMES_BOLD,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingTimes(anyFontBold));
|
||||
assertEquals(PDType1Font.TIMES_ITALIC,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingTimes(anyFontItalic));
|
||||
assertEquals(PDType1Font.TIMES_BOLD_ITALIC,
|
||||
DefaultFontTextDrawerFonts.chooseMatchingTimes(anyFontBoldItalic));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultFontMapping() {
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode(Font.DIALOG)));
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode(Font.DIALOG_INPUT)));
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode("Arial")));
|
||||
assertEquals(PDType1Font.COURIER,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode(Font.MONOSPACED)));
|
||||
assertEquals(PDType1Font.TIMES_ROMAN,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode(Font.SERIF)));
|
||||
assertEquals(PDType1Font.ZAPF_DINGBATS,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode("Dingbats")));
|
||||
assertEquals(PDType1Font.SYMBOL,
|
||||
DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode("Symbol")));
|
||||
assertNull(DefaultFontTextDrawerFonts.mapDefaultFonts(Font.decode("Georgia")));
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,9 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
|
|||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.xbib.graphics.io.pdfbox.font.CoreFontDrawer;
|
||||
import org.xbib.graphics.io.pdfbox.font.DefaultFontDrawer;
|
||||
import org.xbib.graphics.io.pdfbox.font.ForcedFontDrawer;
|
||||
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.Graphics2D;
|
||||
|
@ -25,7 +28,7 @@ class PdfBoxGraphics2DTestBase {
|
|||
void exportGraphic(String dir, String name, GraphicsExporter exporter) {
|
||||
try {
|
||||
PDDocument document = new PDDocument();
|
||||
PDFont pdArial = PDType1Font.HELVETICA;
|
||||
PDFont helvetica = PDType1Font.HELVETICA;
|
||||
File parentDir = new File("build/test/" + dir);
|
||||
parentDir.mkdirs();
|
||||
BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_4BYTE_ABGR);
|
||||
|
@ -38,7 +41,6 @@ class PdfBoxGraphics2DTestBase {
|
|||
document.addPage(page);
|
||||
PDPageContentStream contentStream = new PDPageContentStream(document, page);
|
||||
PdfBoxGraphics2D pdfBoxGraphics2D = new PdfBoxGraphics2D(document, 400, 400);
|
||||
DefaultFontTextDrawer fontTextDrawer = null;
|
||||
contentStream.beginText();
|
||||
contentStream.setStrokingColor(0f, 0f, 0f);
|
||||
contentStream.setNonStrokingColor(0f, 0f, 0f);
|
||||
|
@ -46,20 +48,21 @@ class PdfBoxGraphics2DTestBase {
|
|||
contentStream.setTextMatrix(Matrix.getTranslateInstance(10, 800));
|
||||
contentStream.showText("Mode " + m);
|
||||
contentStream.endText();
|
||||
DefaultFontDrawer fontTextDrawer = null;
|
||||
switch (m) {
|
||||
case FontTextIfPossible:
|
||||
fontTextDrawer = new DefaultFontTextDrawer();
|
||||
registerFots(fontTextDrawer);
|
||||
fontTextDrawer = new DefaultFontDrawer();
|
||||
registerFonts(fontTextDrawer);
|
||||
break;
|
||||
case DefaultFontText: {
|
||||
fontTextDrawer = new DefaultFontTextDrawerFonts();
|
||||
registerFots(fontTextDrawer);
|
||||
fontTextDrawer = new CoreFontDrawer();
|
||||
registerFonts(fontTextDrawer);
|
||||
break;
|
||||
}
|
||||
case ForceFontText:
|
||||
fontTextDrawer = new DefaultFontTextDrawerForce();
|
||||
registerFots(fontTextDrawer);
|
||||
fontTextDrawer.registerFont("Arial", pdArial);
|
||||
fontTextDrawer = new ForcedFontDrawer();
|
||||
registerFonts(fontTextDrawer);
|
||||
fontTextDrawer.registerFont("Arial", helvetica);
|
||||
break;
|
||||
case DefaultVectorized:
|
||||
default:
|
||||
|
@ -88,7 +91,7 @@ class PdfBoxGraphics2DTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void registerFots(DefaultFontTextDrawer fontTextDrawer) {
|
||||
private void registerFonts(DefaultFontDrawer fontTextDrawer) {
|
||||
fontTextDrawer.registerFont(new File("src/test/resources/org/xbib/graphics/io/pdfbox/DejaVuSerifCondensed.ttf"));
|
||||
fontTextDrawer.registerFont(new File("src/test/resources/org/xbib/graphics/io/pdfbox/antonio/Antonio-Regular.ttf"));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.graphics.io.pdfbox;
|
|||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.graphics.io.pdfbox.color.CMYKColor;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
|
|
|
@ -17,6 +17,8 @@ import org.apache.pdfbox.rendering.PDFRenderer;
|
|||
import org.apache.pdfbox.rendering.PageDrawer;
|
||||
import org.apache.pdfbox.rendering.PageDrawerParameters;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.graphics.io.pdfbox.color.CMYKColor;
|
||||
import org.xbib.graphics.io.pdfbox.draw.DefaultDrawControl;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
|
@ -123,12 +125,12 @@ public class PdfRerenderTest {
|
|||
boolean insideOwnDraw = false;
|
||||
|
||||
@Override
|
||||
public void afterShapeFill(Shape shape, DrawControlEnv env) {
|
||||
public void afterShapeFill(Shape shape, DrawControlEnvironment env) {
|
||||
afterShapeDraw(shape, env);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterShapeDraw(Shape shape, DrawControlEnv env) {
|
||||
public void afterShapeDraw(Shape shape, DrawControlEnvironment env) {
|
||||
if (insideOwnDraw)
|
||||
return;
|
||||
insideOwnDraw = true;
|
||||
|
|
|
@ -17,8 +17,11 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xbib.graphics.io.pdfbox.color.DefaultColorMapper;
|
||||
import org.xbib.graphics.io.pdfbox.color.RGBtoCMYKColorMapper;
|
||||
import org.xbib.graphics.io.pdfbox.font.DefaultFontDrawer;
|
||||
import org.xbib.graphics.io.pdfbox.font.FontDrawer;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -96,7 +99,7 @@ public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
|
|||
"/org/apache/pdfbox/resources/icc/ISOcoated_v2_300_bas.icc"));
|
||||
DefaultColorMapper colorMapper = new RGBtoCMYKColorMapper(icc_profile, pdfDocument);
|
||||
pdfBoxGraphics2D.setColorMapper(colorMapper);
|
||||
FontTextDrawer fontTextDrawer;
|
||||
FontDrawer fontDrawer;
|
||||
contentStream.beginText();
|
||||
contentStream.setStrokingColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
contentStream.setNonStrokingColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
@ -104,8 +107,8 @@ public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
|
|||
contentStream.setTextMatrix(Matrix.getTranslateInstance(10, 800));
|
||||
contentStream.showText("Mode: CMYK colorspace");
|
||||
contentStream.endText();
|
||||
fontTextDrawer = new DefaultFontTextDrawer();
|
||||
pdfBoxGraphics2D.setFontTextDrawer(fontTextDrawer);
|
||||
fontDrawer = new DefaultFontDrawer();
|
||||
pdfBoxGraphics2D.setFontTextDrawer(fontDrawer);
|
||||
pdfBoxGraphics2D.scale(scale, scale);
|
||||
gvtRoot.paint(pdfBoxGraphics2D);
|
||||
pdfBoxGraphics2D.dispose();
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package org.xbib.graphics.io.pdfbox.font;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.Font;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class FontDrawerTest {
|
||||
|
||||
@Test
|
||||
public void testFontStyleMatching() {
|
||||
Font anyFont = Font.decode("Dialog");
|
||||
Font anyFontBold = anyFont.deriveFont(Font.BOLD);
|
||||
Font anyFontItalic = anyFont.deriveFont(Font.ITALIC);
|
||||
Font anyFontBoldItalic = anyFont.deriveFont(Font.BOLD | Font.ITALIC);
|
||||
|
||||
assertEquals(PDType1Font.COURIER, CoreFontDrawer.chooseMatchingCourier(anyFont));
|
||||
assertEquals(PDType1Font.COURIER_BOLD,
|
||||
CoreFontDrawer.chooseMatchingCourier(anyFontBold));
|
||||
assertEquals(PDType1Font.COURIER_OBLIQUE,
|
||||
CoreFontDrawer.chooseMatchingCourier(anyFontItalic));
|
||||
assertEquals(PDType1Font.COURIER_BOLD_OBLIQUE,
|
||||
CoreFontDrawer.chooseMatchingCourier(anyFontBoldItalic));
|
||||
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
CoreFontDrawer.chooseMatchingHelvetica(anyFont));
|
||||
assertEquals(PDType1Font.HELVETICA_BOLD,
|
||||
CoreFontDrawer.chooseMatchingHelvetica(anyFontBold));
|
||||
assertEquals(PDType1Font.HELVETICA_OBLIQUE,
|
||||
CoreFontDrawer.chooseMatchingHelvetica(anyFontItalic));
|
||||
assertEquals(PDType1Font.HELVETICA_BOLD_OBLIQUE,
|
||||
CoreFontDrawer.chooseMatchingHelvetica(anyFontBoldItalic));
|
||||
|
||||
assertEquals(PDType1Font.TIMES_ROMAN, CoreFontDrawer.chooseMatchingTimes(anyFont));
|
||||
assertEquals(PDType1Font.TIMES_BOLD,
|
||||
CoreFontDrawer.chooseMatchingTimes(anyFontBold));
|
||||
assertEquals(PDType1Font.TIMES_ITALIC,
|
||||
CoreFontDrawer.chooseMatchingTimes(anyFontItalic));
|
||||
assertEquals(PDType1Font.TIMES_BOLD_ITALIC,
|
||||
CoreFontDrawer.chooseMatchingTimes(anyFontBoldItalic));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultFontMapping() {
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG)));
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.DIALOG_INPUT)));
|
||||
assertEquals(PDType1Font.HELVETICA,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode("Arial")));
|
||||
assertEquals(PDType1Font.COURIER,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.MONOSPACED)));
|
||||
assertEquals(PDType1Font.TIMES_ROMAN,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode(Font.SERIF)));
|
||||
assertEquals(PDType1Font.ZAPF_DINGBATS,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode("Dingbats")));
|
||||
assertEquals(PDType1Font.SYMBOL,
|
||||
CoreFontDrawer.mapToCoreFonts(Font.decode("Symbol")));
|
||||
assertNull(CoreFontDrawer.mapToCoreFonts(Font.decode("Georgia")));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue