Search in sources :

Example 6 with BoundingBox

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;
}
Also used : BoundingBox(org.apache.fontbox.util.BoundingBox) ArrayList(java.util.ArrayList) IOException(java.io.IOException)

Example 7 with BoundingBox

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);
    }
}
Also used : BoundingBox(org.apache.fontbox.util.BoundingBox)

Example 8 with BoundingBox

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;
}
Also used : Matrix(org.apache.pdfbox.util.Matrix) BoundingBox(org.apache.fontbox.util.BoundingBox) PDFormXObject(org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject) PDResources(org.apache.pdfbox.pdmodel.PDResources) AffineTransform(java.awt.geom.AffineTransform) PDRectangle(org.apache.pdfbox.pdmodel.common.PDRectangle) PDStream(org.apache.pdfbox.pdmodel.common.PDStream)

Example 9 with BoundingBox

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());
}
Also used : PDType3CharProc(org.apache.pdfbox.pdmodel.font.PDType3CharProc) GeneralPath(java.awt.geom.GeneralPath) PDType3Font(org.apache.pdfbox.pdmodel.font.PDType3Font) PDType0Font(org.apache.pdfbox.pdmodel.font.PDType0Font) BoundingBox(org.apache.fontbox.util.BoundingBox) PDTrueTypeFont(org.apache.pdfbox.pdmodel.font.PDTrueTypeFont) AffineTransform(java.awt.geom.AffineTransform) PDRectangle(org.apache.pdfbox.pdmodel.common.PDRectangle) PDCIDFontType2(org.apache.pdfbox.pdmodel.font.PDCIDFontType2) PDVectorFont(org.apache.pdfbox.pdmodel.font.PDVectorFont) PDSimpleFont(org.apache.pdfbox.pdmodel.font.PDSimpleFont)

Aggregations

BoundingBox (org.apache.fontbox.util.BoundingBox)9 IOException (java.io.IOException)4 AffineTransform (java.awt.geom.AffineTransform)3 PDRectangle (org.apache.pdfbox.pdmodel.common.PDRectangle)3 PDType3Font (org.apache.pdfbox.pdmodel.font.PDType3Font)3 PDCIDFontType2 (org.apache.pdfbox.pdmodel.font.PDCIDFontType2)2 PDSimpleFont (org.apache.pdfbox.pdmodel.font.PDSimpleFont)2 PDTrueTypeFont (org.apache.pdfbox.pdmodel.font.PDTrueTypeFont)2 PDType0Font (org.apache.pdfbox.pdmodel.font.PDType0Font)2 Matrix (org.apache.pdfbox.util.Matrix)2 Shape (java.awt.Shape)1 GeneralPath (java.awt.geom.GeneralPath)1 Rectangle2D (java.awt.geom.Rectangle2D)1 ArrayList (java.util.ArrayList)1 StringTokenizer (java.util.StringTokenizer)1 TrueTypeFont (org.apache.fontbox.ttf.TrueTypeFont)1 SetMatrix (org.apache.pdfbox.contentstream.operator.state.SetMatrix)1 COSBase (org.apache.pdfbox.cos.COSBase)1 COSDictionary (org.apache.pdfbox.cos.COSDictionary)1 COSName (org.apache.pdfbox.cos.COSName)1