use of org.apache.fontbox.util.BoundingBox in project pdfbox by apache.
the class AFMParser method parseFontMetric.
/**
* This will parse a font metrics item.
*
* @return The parse font metrics item.
*
* @throws IOException If there is an error reading the AFM file.
*/
private FontMetrics parseFontMetric(boolean reducedDataset) throws IOException {
FontMetrics fontMetrics = new FontMetrics();
String startFontMetrics = readString();
if (!START_FONT_METRICS.equals(startFontMetrics)) {
throw new IOException("Error: The AFM file should start with " + START_FONT_METRICS + " and not '" + startFontMetrics + "'");
}
fontMetrics.setAFMVersion(readFloat());
String nextCommand;
boolean charMetricsRead = false;
while (!END_FONT_METRICS.equals(nextCommand = readString())) {
switch(nextCommand) {
case FONT_NAME:
fontMetrics.setFontName(readLine());
break;
case FULL_NAME:
fontMetrics.setFullName(readLine());
break;
case FAMILY_NAME:
fontMetrics.setFamilyName(readLine());
break;
case WEIGHT:
fontMetrics.setWeight(readLine());
break;
case FONT_BBOX:
BoundingBox bBox = new BoundingBox();
bBox.setLowerLeftX(readFloat());
bBox.setLowerLeftY(readFloat());
bBox.setUpperRightX(readFloat());
bBox.setUpperRightY(readFloat());
fontMetrics.setFontBBox(bBox);
break;
case VERSION:
fontMetrics.setFontVersion(readLine());
break;
case NOTICE:
fontMetrics.setNotice(readLine());
break;
case ENCODING_SCHEME:
fontMetrics.setEncodingScheme(readLine());
break;
case MAPPING_SCHEME:
fontMetrics.setMappingScheme(readInt());
break;
case ESC_CHAR:
fontMetrics.setEscChar(readInt());
break;
case CHARACTER_SET:
fontMetrics.setCharacterSet(readLine());
break;
case CHARACTERS:
fontMetrics.setCharacters(readInt());
break;
case IS_BASE_FONT:
fontMetrics.setIsBaseFont(readBoolean());
break;
case V_VECTOR:
float[] vector = new float[2];
vector[0] = readFloat();
vector[1] = readFloat();
fontMetrics.setVVector(vector);
break;
case IS_FIXED_V:
fontMetrics.setIsFixedV(readBoolean());
break;
case CAP_HEIGHT:
fontMetrics.setCapHeight(readFloat());
break;
case X_HEIGHT:
fontMetrics.setXHeight(readFloat());
break;
case ASCENDER:
fontMetrics.setAscender(readFloat());
break;
case DESCENDER:
fontMetrics.setDescender(readFloat());
break;
case STD_HW:
fontMetrics.setStandardHorizontalWidth(readFloat());
break;
case STD_VW:
fontMetrics.setStandardVerticalWidth(readFloat());
break;
case COMMENT:
fontMetrics.addComment(readLine());
break;
case UNDERLINE_POSITION:
fontMetrics.setUnderlinePosition(readFloat());
break;
case UNDERLINE_THICKNESS:
fontMetrics.setUnderlineThickness(readFloat());
break;
case ITALIC_ANGLE:
fontMetrics.setItalicAngle(readFloat());
break;
case CHAR_WIDTH:
float[] widths = new float[2];
widths[0] = readFloat();
widths[1] = readFloat();
fontMetrics.setCharWidth(widths);
break;
case IS_FIXED_PITCH:
fontMetrics.setFixedPitch(readBoolean());
break;
case START_CHAR_METRICS:
int countMetrics = readInt();
List<CharMetric> charMetrics = new ArrayList<>(countMetrics);
for (int i = 0; i < countMetrics; i++) {
CharMetric charMetric = parseCharMetric();
charMetrics.add(charMetric);
}
String endCharMetrics = readString();
if (!endCharMetrics.equals(END_CHAR_METRICS)) {
throw new IOException("Error: Expected '" + END_CHAR_METRICS + "' actual '" + endCharMetrics + "'");
}
charMetricsRead = true;
fontMetrics.setCharMetrics(charMetrics);
break;
case START_COMPOSITES:
if (!reducedDataset) {
int countComposites = readInt();
for (int i = 0; i < countComposites; i++) {
Composite part = parseComposite();
fontMetrics.addComposite(part);
}
String endComposites = readString();
if (!endComposites.equals(END_COMPOSITES)) {
throw new IOException("Error: Expected '" + END_COMPOSITES + "' actual '" + endComposites + "'");
}
}
break;
case START_KERN_DATA:
if (!reducedDataset) {
parseKernData(fontMetrics);
}
break;
default:
if (reducedDataset && charMetricsRead) {
break;
}
throw new IOException("Unknown AFM key '" + nextCommand + "'");
}
}
return fontMetrics;
}
use of org.apache.fontbox.util.BoundingBox in project pdfbox by apache.
the class GlyphData method initData.
/**
* This will read the required data from the stream.
*
* @param glyphTable The glyph table this glyph belongs to.
* @param data The stream to read the data from.
* @param leftSideBearing The left side bearing for this glyph.
* @throws IOException If there is an error reading the data.
*/
public void initData(GlyphTable glyphTable, TTFDataStream data, int leftSideBearing) throws IOException {
numberOfContours = data.readSignedShort();
xMin = data.readSignedShort();
yMin = data.readSignedShort();
xMax = data.readSignedShort();
yMax = data.readSignedShort();
boundingBox = new BoundingBox(xMin, yMin, xMax, yMax);
if (numberOfContours >= 0) {
// create a simple glyph
short x0 = (short) (leftSideBearing - xMin);
glyphDescription = new GlyfSimpleDescript(numberOfContours, data, x0);
} else {
// create a composite glyph
glyphDescription = new GlyfCompositeDescript(data, glyphTable);
}
}
use of org.apache.fontbox.util.BoundingBox in project pdfbox by apache.
the class LayerUtility method importPageAsForm.
/**
* Imports a page from some PDF file as a Form XObject so it can be placed on another page
* in the target document.
* <p>
* You may want to call {@link #wrapInSaveRestore(PDPage) wrapInSaveRestore(PDPage)} before invoking the Form XObject to
* make sure that the graphics state is reset.
*
* @param sourceDoc the source PDF document that contains the page to be copied
* @param page the page in the source PDF document to be copied
* @return a Form XObject containing the original page's content
* @throws IOException if an I/O error occurs
*/
public PDFormXObject importPageAsForm(PDDocument sourceDoc, PDPage page) throws IOException {
importOcProperties(sourceDoc);
PDStream newStream = new PDStream(targetDoc, page.getContents(), COSName.FLATE_DECODE);
PDFormXObject form = new PDFormXObject(newStream);
// Copy resources
PDResources pageRes = page.getResources();
PDResources formRes = new PDResources();
cloner.cloneMerge(pageRes, formRes);
form.setResources(formRes);
// Transfer some values from page to form
transferDict(page.getCOSObject(), form.getCOSObject(), PAGE_TO_FORM_FILTER, true);
Matrix matrix = form.getMatrix();
AffineTransform at = matrix.createAffineTransform();
PDRectangle mediaBox = page.getMediaBox();
PDRectangle cropBox = page.getCropBox();
PDRectangle viewBox = (cropBox != null ? cropBox : mediaBox);
// Handle the /Rotation entry on the page dict
int rotation = page.getRotation();
// Transform to FOP's user space
// at.scale(1 / viewBox.getWidth(), 1 / viewBox.getHeight());
at.translate(mediaBox.getLowerLeftX() - viewBox.getLowerLeftX(), mediaBox.getLowerLeftY() - viewBox.getLowerLeftY());
switch(rotation) {
case 90:
at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
at.translate(0, viewBox.getWidth());
at.rotate(-Math.PI / 2.0);
break;
case 180:
at.translate(viewBox.getWidth(), viewBox.getHeight());
at.rotate(-Math.PI);
break;
case 270:
at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
at.translate(viewBox.getHeight(), 0);
at.rotate(-Math.PI * 1.5);
break;
default:
}
// Compensate for Crop Boxes not starting at 0,0
at.translate(-viewBox.getLowerLeftX(), -viewBox.getLowerLeftY());
if (!at.isIdentity()) {
form.setMatrix(at);
}
BoundingBox bbox = new BoundingBox();
bbox.setLowerLeftX(viewBox.getLowerLeftX());
bbox.setLowerLeftY(viewBox.getLowerLeftY());
bbox.setUpperRightX(viewBox.getUpperRightX());
bbox.setUpperRightY(viewBox.getUpperRightY());
form.setBBox(new PDRectangle(bbox));
return form;
}
use of org.apache.fontbox.util.BoundingBox in project pdfbox by apache.
the class DrawPrintTextLocations method calculateGlyphBounds.
// this calculates the real (except for type 3 fonts) individual glyph bounds
private Shape calculateGlyphBounds(Matrix textRenderingMatrix, PDFont font, int code) throws IOException {
GeneralPath path = null;
AffineTransform at = textRenderingMatrix.createAffineTransform();
at.concatenate(font.getFontMatrix().createAffineTransform());
if (font instanceof PDType3Font) {
// It is difficult to calculate the real individual glyph bounds for type 3 fonts
// because these are not vector fonts, the content stream could contain almost anything
// that is found in page content streams.
PDType3Font t3Font = (PDType3Font) font;
PDType3CharProc charProc = t3Font.getCharProc(code);
if (charProc != null) {
BoundingBox fontBBox = t3Font.getBoundingBox();
PDRectangle glyphBBox = charProc.getGlyphBBox();
if (glyphBBox != null) {
// PDFBOX-3850: glyph bbox could be larger than the font bbox
glyphBBox.setLowerLeftX(Math.max(fontBBox.getLowerLeftX(), glyphBBox.getLowerLeftX()));
glyphBBox.setLowerLeftY(Math.max(fontBBox.getLowerLeftY(), glyphBBox.getLowerLeftY()));
glyphBBox.setUpperRightX(Math.min(fontBBox.getUpperRightX(), glyphBBox.getUpperRightX()));
glyphBBox.setUpperRightY(Math.min(fontBBox.getUpperRightY(), glyphBBox.getUpperRightY()));
path = glyphBBox.toGeneralPath();
}
}
} else if (font instanceof PDVectorFont) {
PDVectorFont vectorFont = (PDVectorFont) font;
path = vectorFont.getPath(code);
if (font instanceof PDTrueTypeFont) {
PDTrueTypeFont ttFont = (PDTrueTypeFont) font;
int unitsPerEm = ttFont.getTrueTypeFont().getHeader().getUnitsPerEm();
at.scale(1000d / unitsPerEm, 1000d / unitsPerEm);
}
if (font instanceof PDType0Font) {
PDType0Font t0font = (PDType0Font) font;
if (t0font.getDescendantFont() instanceof PDCIDFontType2) {
int unitsPerEm = ((PDCIDFontType2) t0font.getDescendantFont()).getTrueTypeFont().getHeader().getUnitsPerEm();
at.scale(1000d / unitsPerEm, 1000d / unitsPerEm);
}
}
} else if (font instanceof PDSimpleFont) {
PDSimpleFont simpleFont = (PDSimpleFont) font;
// these two lines do not always work, e.g. for the TT fonts in file 032431.pdf
// which is why PDVectorFont is tried first.
String name = simpleFont.getEncoding().getName(code);
path = simpleFont.getPath(name);
} else {
// shouldn't happen, please open issue in JIRA
System.out.println("Unknown font class: " + font.getClass());
}
if (path == null) {
return null;
}
return at.createTransformedShape(path.getBounds2D());
}
Aggregations