Search in sources :

Example 1 with PDTrueTypeFont

use of com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont in project PdfBox-Android by TomRoush.

the class PageDrawer method createGlyph2D.

/**
 * Provide a Glyph2D for the given font.
 *
 * @param font the font
 * @return the implementation of the Glyph2D interface for the given font
 * @throws IOException if something went wrong
 */
private Glyph2D createGlyph2D(PDFont font) throws IOException {
    Glyph2D glyph2D = fontGlyph2D.get(font);
    // Is there already a Glyph2D for the given font?
    if (glyph2D != null) {
        return glyph2D;
    }
    if (font instanceof PDTrueTypeFont) {
        PDTrueTypeFont ttfFont = (PDTrueTypeFont) font;
        // TTF is never null
        glyph2D = new TTFGlyph2D(ttfFont);
    } else if (font instanceof PDType1Font) {
        PDType1Font pdType1Font = (PDType1Font) font;
        // T1 is never null
        glyph2D = new Type1Glyph2D(pdType1Font);
    } else if (font instanceof PDType1CFont) {
        PDType1CFont type1CFont = (PDType1CFont) font;
        glyph2D = new Type1Glyph2D(type1CFont);
    } else if (font instanceof PDType0Font) {
        PDType0Font type0Font = (PDType0Font) font;
        if (type0Font.getDescendantFont() instanceof PDCIDFontType2) {
            // TTF is never null
            glyph2D = new TTFGlyph2D(type0Font);
        } else if (type0Font.getDescendantFont() instanceof PDCIDFontType0) {
            // a Type0 CIDFont contains CFF font
            PDCIDFontType0 cidType0Font = (PDCIDFontType0) type0Font.getDescendantFont();
            // todo: could be null (need incorporate fallback)
            glyph2D = new CIDType0Glyph2D(cidType0Font);
        }
    } else {
        throw new IllegalStateException("Bad font type: " + font.getClass().getSimpleName());
    }
    // cache the Glyph2D instance
    if (glyph2D != null) {
        fontGlyph2D.put(font, glyph2D);
    }
    if (glyph2D == null) {
        // todo: make sure this never happens
        throw new UnsupportedOperationException("No font for " + font.getName());
    }
    return glyph2D;
}
Also used : PDType1Font(com.tom_roush.pdfbox.pdmodel.font.PDType1Font) PDType1CFont(com.tom_roush.pdfbox.pdmodel.font.PDType1CFont) PDType0Font(com.tom_roush.pdfbox.pdmodel.font.PDType0Font) PDTrueTypeFont(com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont) PDCIDFontType0(com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType0) PDCIDFontType2(com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType2)

Example 2 with PDTrueTypeFont

use of com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont in project PdfBox-Android by TomRoush.

the class LegacyPDFStreamEngine method showGlyph.

/**
 * This method was originally written by Ben Litchfield for PDFStreamEngine.
 */
@Override
protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode, Vector displacement) throws IOException {
    // 
    // legacy calculations which were previously in PDFStreamEngine
    // 
    // DO NOT USE THIS CODE UNLESS YOU ARE WORKING WITH PDFTextStripper.
    // THIS CODE IS DELIBERATELY INCORRECT
    // 
    PDGraphicsState state = getGraphicsState();
    Matrix ctm = state.getCurrentTransformationMatrix();
    float fontSize = state.getTextState().getFontSize();
    float horizontalScaling = state.getTextState().getHorizontalScaling() / 100f;
    Matrix textMatrix = getTextMatrix();
    BoundingBox bbox = font.getBoundingBox();
    if (bbox.getLowerLeftY() < Short.MIN_VALUE) {
        // PDFBOX-2158 and PDFBOX-3130
        // files by Salmat eSolutions / ClibPDF Library
        bbox.setLowerLeftY(-(bbox.getLowerLeftY() + 65536));
    }
    // 1/2 the bbox is used as the height todo: why?
    float glyphHeight = bbox.getHeight() / 2;
    // sometimes the bbox has very high values, but CapHeight is OK
    PDFontDescriptor fontDescriptor = font.getFontDescriptor();
    if (fontDescriptor != null) {
        float capHeight = fontDescriptor.getCapHeight();
        if (Float.compare(capHeight, 0) != 0 && (capHeight < glyphHeight || Float.compare(glyphHeight, 0) == 0)) {
            glyphHeight = capHeight;
        }
        // PDFBOX-3464, PDFBOX-4480, PDFBOX-4553:
        // sometimes even CapHeight has very high value, but Ascent and Descent are ok
        float ascent = fontDescriptor.getAscent();
        float descent = fontDescriptor.getDescent();
        if (capHeight > ascent && ascent > 0 && descent < 0 && ((ascent - descent) / 2 < glyphHeight || Float.compare(glyphHeight, 0) == 0)) {
            glyphHeight = (ascent - descent) / 2;
        }
    }
    // transformPoint from glyph space -> text space
    float height;
    if (font instanceof PDType3Font) {
        height = font.getFontMatrix().transformPoint(0, glyphHeight).y;
    } else {
        height = glyphHeight / 1000;
    }
    float displacementX = displacement.getX();
    // calculate our own
    if (font.isVertical()) {
        displacementX = font.getWidth(code) / 1000;
        // there may be an additional scaling factor for true type fonts
        TrueTypeFont ttf = null;
        if (font instanceof PDTrueTypeFont) {
            ttf = ((PDTrueTypeFont) font).getTrueTypeFont();
        } else if (font instanceof PDType0Font) {
            PDCIDFont cidFont = ((PDType0Font) font).getDescendantFont();
            if (cidFont instanceof PDCIDFontType2) {
                ttf = ((PDCIDFontType2) cidFont).getTrueTypeFont();
            }
        }
        if (ttf != null && ttf.getUnitsPerEm() != 1000) {
            displacementX *= 1000f / ttf.getUnitsPerEm();
        }
    }
    // 
    // legacy calculations which were previously in PDFStreamEngine
    // 
    // DO NOT USE THIS CODE UNLESS YOU ARE WORKING WITH PDFTextStripper.
    // THIS CODE IS DELIBERATELY INCORRECT
    // 
    // (modified) combined displacement, this is calculated *without* taking the character
    // spacing and word spacing into account, due to legacy code in TextStripper
    float tx = displacementX * fontSize * horizontalScaling;
    float ty = displacement.getY() * fontSize;
    // (modified) combined displacement matrix
    Matrix td = Matrix.getTranslateInstance(tx, ty);
    // (modified) text rendering matrix
    // text space -> device space
    Matrix nextTextRenderingMatrix = td.multiply(textMatrix).multiply(ctm);
    float nextX = nextTextRenderingMatrix.getTranslateX();
    float nextY = nextTextRenderingMatrix.getTranslateY();
    // (modified) width and height calculations
    float dxDisplay = nextX - textRenderingMatrix.getTranslateX();
    float dyDisplay = height * textRenderingMatrix.getScalingFactorY();
    // 
    // start of the original method
    // 
    // Note on variable names. There are three different units being used in this code.
    // Character sizes are given in glyph units, text locations are initially given in text
    // units, and we want to save the data in display units. The variable names should end with
    // Text or Disp to represent if the values are in text or disp units (no glyph units are
    // saved).
    float glyphSpaceToTextSpaceFactor = 1 / 1000f;
    if (font instanceof PDType3Font) {
        glyphSpaceToTextSpaceFactor = font.getFontMatrix().getScaleX();
    }
    float spaceWidthText = 0;
    try {
        // to avoid crash as described in PDFBOX-614, see what the space displacement should be
        spaceWidthText = font.getSpaceWidth() * glyphSpaceToTextSpaceFactor;
    } catch (Throwable exception) {
        Log.w("PdfBox-Android", exception.getMessage(), exception);
    }
    if (spaceWidthText == 0) {
        spaceWidthText = font.getAverageFontWidth() * glyphSpaceToTextSpaceFactor;
        // the average space width appears to be higher than necessary so make it smaller
        spaceWidthText *= .80f;
    }
    if (spaceWidthText == 0) {
        // if could not find font, use a generic value
        spaceWidthText = 1.0f;
    }
    // the space width has to be transformed into display units
    float spaceWidthDisplay = spaceWidthText * textRenderingMatrix.getScalingFactorX();
    // use our additional glyph list for Unicode mapping
    unicode = font.toUnicode(code, glyphList);
    // this, which is why we leave it until this point in PDFTextStreamEngine.
    if (unicode == null) {
        if (font instanceof PDSimpleFont) {
            char c = (char) code;
            unicode = new String(new char[] { c });
        } else {
            // skips them. See the "allah2.pdf" TestTextStripper file.
            return;
        }
    }
    // adjust for cropbox if needed
    Matrix translatedTextRenderingMatrix;
    if (translateMatrix == null) {
        translatedTextRenderingMatrix = textRenderingMatrix;
    } else {
        translatedTextRenderingMatrix = Matrix.concatenate(translateMatrix, textRenderingMatrix);
        nextX -= pageSize.getLowerLeftX();
        nextY -= pageSize.getLowerLeftY();
    }
    processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(), pageSize.getHeight(), translatedTextRenderingMatrix, nextX, nextY, Math.abs(dyDisplay), dxDisplay, Math.abs(spaceWidthDisplay), unicode, new int[] { code }, font, fontSize, (int) (fontSize * textMatrix.getScalingFactorX())));
}
Also used : PDTrueTypeFont(com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont) TrueTypeFont(com.tom_roush.fontbox.ttf.TrueTypeFont) PDType0Font(com.tom_roush.pdfbox.pdmodel.font.PDType0Font) PDFontDescriptor(com.tom_roush.pdfbox.pdmodel.font.PDFontDescriptor) PDSimpleFont(com.tom_roush.pdfbox.pdmodel.font.PDSimpleFont) Matrix(com.tom_roush.pdfbox.util.Matrix) SetMatrix(com.tom_roush.pdfbox.contentstream.operator.state.SetMatrix) PDType3Font(com.tom_roush.pdfbox.pdmodel.font.PDType3Font) BoundingBox(com.tom_roush.fontbox.util.BoundingBox) PDTrueTypeFont(com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont) PDCIDFontType2(com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType2) PDCIDFont(com.tom_roush.pdfbox.pdmodel.font.PDCIDFont) PDGraphicsState(com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState)

Aggregations

PDCIDFontType2 (com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType2)2 PDTrueTypeFont (com.tom_roush.pdfbox.pdmodel.font.PDTrueTypeFont)2 PDType0Font (com.tom_roush.pdfbox.pdmodel.font.PDType0Font)2 TrueTypeFont (com.tom_roush.fontbox.ttf.TrueTypeFont)1 BoundingBox (com.tom_roush.fontbox.util.BoundingBox)1 SetMatrix (com.tom_roush.pdfbox.contentstream.operator.state.SetMatrix)1 PDCIDFont (com.tom_roush.pdfbox.pdmodel.font.PDCIDFont)1 PDCIDFontType0 (com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType0)1 PDFontDescriptor (com.tom_roush.pdfbox.pdmodel.font.PDFontDescriptor)1 PDSimpleFont (com.tom_roush.pdfbox.pdmodel.font.PDSimpleFont)1 PDType1CFont (com.tom_roush.pdfbox.pdmodel.font.PDType1CFont)1 PDType1Font (com.tom_roush.pdfbox.pdmodel.font.PDType1Font)1 PDType3Font (com.tom_roush.pdfbox.pdmodel.font.PDType3Font)1 PDGraphicsState (com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState)1 Matrix (com.tom_roush.pdfbox.util.Matrix)1