Search in sources :

Example 1 with PDType3CharProc

use of org.apache.pdfbox.pdmodel.font.PDType3CharProc in project pdfbox by apache.

the class Type3FontValidator method checkCharProcsAndMetrics.

/**
 * CharProcs is a dictionary where the key is a character name and the value is a Stream which contains the glyph
 * representation of the key.
 *
 * This method checks that all characters codes defined in the Widths Array exist in the CharProcs dictionary. If
 * the CharProcs doesn't know the Character, it is mapped with the .notdef one.
 *
 * For each character, the Glyph width must be the same as the Width value declared in the Widths array.
 */
private void checkCharProcsAndMetrics() throws ValidationException {
    List<Float> widths = getWidths(font);
    if (widths == null || widths.isEmpty()) {
        this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, font.getName() + ": The Witdhs array is unreachable"));
        return;
    }
    COSDictionary charProcs = COSUtils.getAsDictionary(fontDictionary.getItem(COSName.CHAR_PROCS), cosDocument);
    if (charProcs == null) {
        this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, font.getName() + ": The CharProcs element isn't a dictionary"));
        return;
    }
    int fc = font.getCOSObject().getInt(COSName.FIRST_CHAR, -1);
    int lc = font.getCOSObject().getInt(COSName.LAST_CHAR, -1);
    /*
         * wArr length = (lc - fc) + 1 and it is an array of int. 
         * If FirstChar is greater than LastChar, the validation
         * will fail because of the array will have an expected size &lt;= 0.
         */
    int expectedLength = (lc - fc) + 1;
    if (widths.size() != expectedLength) {
        this.fontContainer.push(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, font.getName() + ": The length of Witdhs array is invalid. Expected : \"" + expectedLength + "\" Current : \"" + widths.size() + "\""));
        return;
    }
    // Check width consistency
    for (int i = 0; i < expectedLength; i++) {
        int code = fc + i;
        float width = widths.get(i);
        PDType3CharProc charProc = getCharProc(code);
        if (charProc != null) {
            try {
                float fontProgramWidth = getWidthFromCharProc(charProc);
                if (Math.abs(width - fontProgramWidth) < 0.001f) {
                    // Glyph is OK, we keep the CID.
                    // PDF/A-1b only states that the width "shall be consistent".
                    // For PDF/A-2,3 the description has been enhanced and is now requesting
                    // "consistent is defined to be a difference of no more than 1/1000 unit"
                    // We interpret this as clarification of the PDF/A-1b requirement.
                    this.fontContainer.markAsValid(code);
                } else {
                    GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, code, font.getName() + ": The character with CID " + code + " should have a width equals to " + width + ", but has " + fontProgramWidth);
                    this.fontContainer.markAsInvalid(code, glyphEx);
                }
            } catch (ContentStreamException e) {
                // TODO spaces/isartor-6-2-3-3-t02-fail-h.pdf --> si ajout de l'erreur dans le container le test
                // echoue... pourquoi si la font est utilisée ca devrait planter???
                this.context.addValidationError(new ValidationError(e.getErrorCode(), e.getMessage(), e));
                return;
            } catch (IOException e) {
                this.fontContainer.push(new ValidationError(ERROR_FONTS_TYPE3_DAMAGED, font.getName() + ": The CharProcs references an element which can't be read", e));
                return;
            }
        }
    }
}
Also used : PDType3CharProc(org.apache.pdfbox.pdmodel.font.PDType3CharProc) ContentStreamException(org.apache.pdfbox.preflight.content.ContentStreamException) COSDictionary(org.apache.pdfbox.cos.COSDictionary) GlyphException(org.apache.pdfbox.preflight.font.util.GlyphException) ValidationError(org.apache.pdfbox.preflight.ValidationResult.ValidationError) IOException(java.io.IOException)

Example 2 with PDType3CharProc

use of org.apache.pdfbox.pdmodel.font.PDType3CharProc in project pdfbox by apache.

the class Type3FontValidator method getCharProc.

private PDType3CharProc getCharProc(int code) throws ValidationException {
    PDType3CharProc charProc = font.getCharProc(code);
    if (charProc == null) {
        // There are no character description, we declare the Glyph as Invalid. If the character
        // is used in a Stream, the GlyphDetail will throw an exception.
        GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, code, font.getName() + ": The CharProcs \"" + font.getEncoding().getName(code) + "\" doesn't exist");
        this.fontContainer.markAsInvalid(code, glyphEx);
    }
    return charProc;
}
Also used : PDType3CharProc(org.apache.pdfbox.pdmodel.font.PDType3CharProc) GlyphException(org.apache.pdfbox.preflight.font.util.GlyphException)

Example 3 with PDType3CharProc

use of org.apache.pdfbox.pdmodel.font.PDType3CharProc in project pdfbox by apache.

the class Type3Font method calcBBox.

private void calcBBox(PDType3Font font) throws IOException {
    double minX = 0;
    double maxX = 0;
    double minY = 0;
    double maxY = 0;
    for (int index = 0; index <= 255; ++index) {
        PDType3CharProc charProc = font.getCharProc(index);
        if (charProc == null) {
            continue;
        }
        PDRectangle glyphBBox = charProc.getGlyphBBox();
        if (glyphBBox == null) {
            continue;
        }
        minX = Math.min(minX, glyphBBox.getLowerLeftX());
        maxX = Math.max(maxX, glyphBBox.getUpperRightX());
        minY = Math.min(minY, glyphBBox.getLowerLeftY());
        maxY = Math.max(maxY, glyphBBox.getUpperRightY());
    }
    fontBBox = new PDRectangle((float) minX, (float) minY, (float) (maxX - minX), (float) (maxY - minY));
}
Also used : PDType3CharProc(org.apache.pdfbox.pdmodel.font.PDType3CharProc) PDRectangle(org.apache.pdfbox.pdmodel.common.PDRectangle)

Example 4 with PDType3CharProc

use of org.apache.pdfbox.pdmodel.font.PDType3CharProc 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

PDType3CharProc (org.apache.pdfbox.pdmodel.font.PDType3CharProc)4 PDRectangle (org.apache.pdfbox.pdmodel.common.PDRectangle)2 GlyphException (org.apache.pdfbox.preflight.font.util.GlyphException)2 AffineTransform (java.awt.geom.AffineTransform)1 GeneralPath (java.awt.geom.GeneralPath)1 IOException (java.io.IOException)1 BoundingBox (org.apache.fontbox.util.BoundingBox)1 COSDictionary (org.apache.pdfbox.cos.COSDictionary)1 PDCIDFontType2 (org.apache.pdfbox.pdmodel.font.PDCIDFontType2)1 PDSimpleFont (org.apache.pdfbox.pdmodel.font.PDSimpleFont)1 PDTrueTypeFont (org.apache.pdfbox.pdmodel.font.PDTrueTypeFont)1 PDType0Font (org.apache.pdfbox.pdmodel.font.PDType0Font)1 PDType3Font (org.apache.pdfbox.pdmodel.font.PDType3Font)1 PDVectorFont (org.apache.pdfbox.pdmodel.font.PDVectorFont)1 ValidationError (org.apache.pdfbox.preflight.ValidationResult.ValidationError)1 ContentStreamException (org.apache.pdfbox.preflight.content.ContentStreamException)1