Files
quality_recticel/old code/tray/src/qz/printer/rendering/PdfFontPageDrawer.java
Quality System Admin c96039542d updated control access
2025-10-16 02:36:32 +03:00

199 lines
7.0 KiB
Java
Executable File

package qz.printer.rendering;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.*;
import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.rendering.PageDrawerParameters;
import org.apache.pdfbox.util.Matrix;
import org.apache.pdfbox.util.Vector;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* PageDrawer overrides derived from PDFBOX 1.8
* with the help of Alexander Scherbatiy
*/
public class PdfFontPageDrawer extends PageDrawer {
private static final Logger log = LogManager.getLogger(PdfFontPageDrawer.class);
private String fallbackFont = "helvetica"; //todo - definable parameter?
private final Map<PDFont,Font> fonts = new HashMap<>();
public PdfFontPageDrawer(PageDrawerParameters parameters, boolean ignoresTransparency) throws IOException {
super(parameters);
if (ignoresTransparency) {
// Note: These must match ParamPdfRenderer's OpaquePageDrawer
addOperator(new OpaqueDrawObject());
addOperator(new OpaqueGraphicStateParameters());
}
}
@Override
protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, Vector displacement) throws IOException {
// fall-back to draw Glyph when awt font has not been found
AffineTransform at = textRenderingMatrix.createAffineTransform();
at.concatenate(font.getFontMatrix().createAffineTransform());
Graphics2D graphics = getGraphics();
setClip();
AffineTransform prevTx = graphics.getTransform();
stretchNonEmbeddedFont(at, font, code, displacement);
// Probably relates to DEFAULT_FONT_MATRIX transform from PDFont
at.scale(100, -100);
graphics.transform(at);
graphics.setComposite(getGraphicsState().getNonStrokingJavaComposite());
graphics.setPaint(getNonStrokingPaint());
Font prevFont = graphics.getFont();
Font awtFont = getAwtFont(font);
graphics.setFont(awtFont);
graphics.drawString(font.toUnicode(code), 0, 0);
graphics.setFont(prevFont);
graphics.setTransform(prevTx);
}
private void stretchNonEmbeddedFont(AffineTransform at, PDFont font, int code, Vector displacement) throws IOException {
// Stretch non-embedded glyph if it does not match the height/width contained in the PDF.
// Vertical fonts have zero X displacement, so the following code scales to 0 if we don't skip it.
if (!font.isEmbedded() && !font.isVertical() && !font.isStandard14() && font.hasExplicitWidth(code)) {
float fontWidth = font.getWidthFromFont(code);
if (fontWidth > 0 && Math.abs(fontWidth - displacement.getX() * 1000) > 0.0001) {
float pdfWidth = displacement.getX() * 1000;
at.scale(pdfWidth / fontWidth, 1);
}
}
}
private Font cacheFont(PDFont font, Font awtFont) {
fonts.put(font, awtFont);
return awtFont;
}
private Font getAwtFont(PDFont font) throws IOException {
Font awtFont = fonts.get(font);
if (awtFont != null) {
return awtFont;
}
if (font instanceof PDType0Font) {
return cacheFont(font, getPDType0AwtFont((PDType0Font)font));
}
if (font instanceof PDType1Font) {
return cacheFont(font, getPDType1AwtFont((PDType1Font)font));
}
String msg = String.format("Not yet implemented: %s", font.getClass().getName());
throw new UnsupportedOperationException(msg);
}
public Font getPDType0AwtFont(PDType0Font font) throws IOException {
Font awtFont = null;
PDCIDFont descendantFont = font.getDescendantFont();
if (descendantFont != null) {
if (descendantFont instanceof PDCIDFontType2) {
awtFont = getPDCIDAwtFontType2((PDCIDFontType2)descendantFont);
}
if (awtFont != null) {
/*
* Fix Oracle JVM Crashes.
* Tested with Oracle JRE 6.0_45-b06 and 7.0_21-b11
*/
awtFont.canDisplay(1);
}
}
if (awtFont == null) {
awtFont = FontManager.getAwtFont(fallbackFont);
log.debug("Using font {} instead of {}", awtFont.getName(), descendantFont.getFontDescriptor().getFontName());
}
return awtFont.deriveFont(10f);
}
private Font getPDType1AwtFont(PDType1Font font) throws IOException {
Font awtFont = null;
String baseFont = font.getBaseFont();
PDFontDescriptor fd = font.getFontDescriptor();
if (fd != null) {
if (fd.getFontFile() != null) {
try {
// create a type1 font with the embedded data
awtFont = Font.createFont(Font.TYPE1_FONT, fd.getFontFile().createInputStream());
}
catch(java.awt.FontFormatException e) {
log.debug("Can't read the embedded type1 font {}", fd.getFontName());
}
}
if (awtFont == null) {
// check if the font is part of our environment
if (fd.getFontName() != null) {
awtFont = FontManager.getAwtFont(fd.getFontName());
}
if (awtFont == null) {
log.debug("Can't find the specified font {}", fd.getFontName());
}
}
} else {
// check if the font is part of our environment
awtFont = FontManager.getAwtFont(baseFont);
if (awtFont == null) {
log.debug("Can't find the specified basefont {}", baseFont);
}
}
if (awtFont == null) {
// we can't find anything, so we have to use the standard font
awtFont = FontManager.getAwtFont(fallbackFont);
log.debug("Using font {} instead", awtFont.getName());
}
return awtFont.deriveFont(20f);
}
public Font getPDCIDAwtFontType2(PDCIDFontType2 font) throws IOException {
Font awtFont = null;
PDFontDescriptor fd = font.getFontDescriptor();
PDStream ff2Stream = fd.getFontFile2();
if (ff2Stream != null) {
try {
// create a font with the embedded data
awtFont = Font.createFont(Font.TRUETYPE_FONT, ff2Stream.createInputStream());
}
catch(java.awt.FontFormatException f) {
log.debug("Can't read the embedded font {}", fd.getFontName());
}
if (awtFont == null) {
if (fd.getFontName() != null) {
awtFont = FontManager.getAwtFont(fd.getFontName());
}
if (awtFont != null) {
log.debug("Using font {} instead", awtFont.getName());
}
}
}
return awtFont;
}
}