Search in sources :

Example 6 with TrueTypeFont

use of com.tom_roush.fontbox.ttf.TrueTypeFont 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)

Example 7 with TrueTypeFont

use of com.tom_roush.fontbox.ttf.TrueTypeFont in project PdfBox-Android by TomRoush.

the class TestCMap method testPDFBox3997.

/**
 * PDFBOX-3997: test unicode that is above the basic multilingual plane, here: helicopter
 * symbol, or D83D DE81 in the Noto Emoji font.
 *
 * @throws IOException
 */
@Test
public // TODO: PdfBox-Android - provide test file
void testPDFBox3997() throws IOException {
    String fontPath = "target/pdfs/NotoEmoji-Regular.ttf";
    assumeTrue(new File(fontPath).exists());
    TrueTypeFont ttf = new TTFParser().parse(fontPath);
    CmapLookup cmap = ttf.getUnicodeCmapLookup(false);
    Assert.assertEquals(886, cmap.getGlyphId(0x1F681));
    ttf.close();
}
Also used : TrueTypeFont(com.tom_roush.fontbox.ttf.TrueTypeFont) CmapLookup(com.tom_roush.fontbox.ttf.CmapLookup) File(java.io.File) TTFParser(com.tom_roush.fontbox.ttf.TTFParser) Test(org.junit.Test)

Example 8 with TrueTypeFont

use of com.tom_roush.fontbox.ttf.TrueTypeFont in project PdfBox-Android by TomRoush.

the class PDDocument method close.

/**
 * This will close the underlying COSDocument object.
 *
 * @throws IOException If there is an error releasing resources.
 */
@Override
public void close() throws IOException {
    if (!document.isClosed()) {
        // Make sure that:
        // - first Exception is kept
        // - all IO resources are closed
        // - there's a way to see which errors occurred
        IOException firstException = null;
        // close resources and COSWriter
        if (signingSupport != null) {
            firstException = IOUtils.closeAndLogException(signingSupport, "SigningSupport", firstException);
        }
        // close all intermediate I/O streams
        firstException = IOUtils.closeAndLogException(document, "COSDocument", firstException);
        // close the source PDF stream, if we read from one
        if (pdfSource != null) {
            firstException = IOUtils.closeAndLogException(pdfSource, "RandomAccessRead pdfSource", firstException);
        }
        // close fonts
        for (TrueTypeFont ttf : fontsToClose) {
            firstException = IOUtils.closeAndLogException(ttf, "TrueTypeFont", firstException);
        }
        // rethrow first exception to keep method contract
        if (firstException != null) {
            throw firstException;
        }
    }
}
Also used : TrueTypeFont(com.tom_roush.fontbox.ttf.TrueTypeFont) IOException(java.io.IOException)

Example 9 with TrueTypeFont

use of com.tom_roush.fontbox.ttf.TrueTypeFont in project PdfBox-Android by TomRoush.

the class FileSystemFontProvider method addTrueTypeCollection.

/**
 * Adds a TTC or OTC to the file cache. To reduce memory, the parsed font is not cached.
 */
private void addTrueTypeCollection(final File ttcFile) throws IOException {
    TrueTypeCollection ttc = null;
    try {
        ttc = new TrueTypeCollection(ttcFile);
        ttc.processAllFonts(new TrueTypeFontProcessor() {

            @Override
            public void process(TrueTypeFont ttf) throws IOException {
                addTrueTypeFontImpl(ttf, ttcFile);
            }
        });
    } catch (// TTF parser is buggy
    NullPointerException e) {
        Log.e("PdfBox-Android", "Could not load font file: " + ttcFile, e);
    } catch (IOException e) {
        Log.e("PdfBox-Android", "Could not load font file: " + ttcFile, e);
    } finally {
        if (ttc != null) {
            ttc.close();
        }
    }
}
Also used : TrueTypeFont(com.tom_roush.fontbox.ttf.TrueTypeFont) TrueTypeCollection(com.tom_roush.fontbox.ttf.TrueTypeCollection) IOException(java.io.IOException) TrueTypeFontProcessor(com.tom_roush.fontbox.ttf.TrueTypeCollection.TrueTypeFontProcessor)

Example 10 with TrueTypeFont

use of com.tom_roush.fontbox.ttf.TrueTypeFont in project PdfBox-Android by TomRoush.

the class FontMapperImpl method getTrueTypeFont.

/**
 * Finds a TrueType font with the given PostScript name, or a suitable substitute, or null.
 *
 * @param fontDescriptor FontDescriptor
 */
@Override
public FontMapping<TrueTypeFont> getTrueTypeFont(String baseFont, PDFontDescriptor fontDescriptor) {
    TrueTypeFont ttf = (TrueTypeFont) findFont(FontFormat.TTF, baseFont);
    if (ttf != null) {
        return new FontMapping<TrueTypeFont>(ttf, false);
    } else {
        // fallback - todo: i.e. fuzzy match
        String fontName = getFallbackFontName(fontDescriptor);
        ttf = (TrueTypeFont) findFont(FontFormat.TTF, fontName);
        if (ttf == null) {
            // we have to return something here as TTFs aren't strictly required on the system
            ttf = lastResortFont;
        }
        return new FontMapping<TrueTypeFont>(ttf, true);
    }
}
Also used : TrueTypeFont(com.tom_roush.fontbox.ttf.TrueTypeFont)

Aggregations

TrueTypeFont (com.tom_roush.fontbox.ttf.TrueTypeFont)11 TTFParser (com.tom_roush.fontbox.ttf.TTFParser)4 OpenTypeFont (com.tom_roush.fontbox.ttf.OpenTypeFont)3 IOException (java.io.IOException)3 Test (org.junit.Test)3 File (java.io.File)2 FontBoxFont (com.tom_roush.fontbox.FontBoxFont)1 CmapLookup (com.tom_roush.fontbox.ttf.CmapLookup)1 CmapSubtable (com.tom_roush.fontbox.ttf.CmapSubtable)1 CmapTable (com.tom_roush.fontbox.ttf.CmapTable)1 OTFParser (com.tom_roush.fontbox.ttf.OTFParser)1 PostScriptTable (com.tom_roush.fontbox.ttf.PostScriptTable)1 TrueTypeCollection (com.tom_roush.fontbox.ttf.TrueTypeCollection)1 TrueTypeFontProcessor (com.tom_roush.fontbox.ttf.TrueTypeCollection.TrueTypeFontProcessor)1 Type1Font (com.tom_roush.fontbox.type1.Type1Font)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 PDCIDFontType2 (com.tom_roush.pdfbox.pdmodel.font.PDCIDFontType2)1 PDFontDescriptor (com.tom_roush.pdfbox.pdmodel.font.PDFontDescriptor)1