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