Search in sources :

Example 16 with PDRectangle

use of com.tom_roush.pdfbox.pdmodel.common.PDRectangle in project PdfBox-Android by TomRoush.

the class PDType3CharProc method getGlyphBBox.

/**
 * Calculate the bounding box of this glyph. This will work only if the first operator in the
 * stream is d1.
 *
 * @return the bounding box of this glyph, or null if the first operator is not d1.
 * @throws IOException If an io error occurs while parsing the stream.
 */
public PDRectangle getGlyphBBox() throws IOException {
    List<COSBase> arguments = new ArrayList<COSBase>();
    PDFStreamParser parser = new PDFStreamParser(this);
    Object token = parser.parseNextToken();
    while (token != null) {
        if (token instanceof COSObject) {
            arguments.add(((COSObject) token).getObject());
        } else if (token instanceof Operator) {
            if (((Operator) token).getName().equals("d1") && arguments.size() == 6) {
                for (int i = 0; i < 6; ++i) {
                    if (!(arguments.get(i) instanceof COSNumber)) {
                        return null;
                    }
                }
                return new PDRectangle(((COSNumber) arguments.get(2)).floatValue(), ((COSNumber) arguments.get(3)).floatValue(), ((COSNumber) arguments.get(4)).floatValue() - ((COSNumber) arguments.get(2)).floatValue(), ((COSNumber) arguments.get(5)).floatValue() - ((COSNumber) arguments.get(3)).floatValue());
            } else {
                return null;
            }
        } else {
            arguments.add((COSBase) token);
        }
        token = parser.parseNextToken();
    }
    return null;
}
Also used : Operator(com.tom_roush.pdfbox.contentstream.operator.Operator) PDFStreamParser(com.tom_roush.pdfbox.pdfparser.PDFStreamParser) COSObject(com.tom_roush.pdfbox.cos.COSObject) ArrayList(java.util.ArrayList) COSNumber(com.tom_roush.pdfbox.cos.COSNumber) COSBase(com.tom_roush.pdfbox.cos.COSBase) COSObject(com.tom_roush.pdfbox.cos.COSObject) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle)

Example 17 with PDRectangle

use of com.tom_roush.pdfbox.pdmodel.common.PDRectangle in project PdfBox-Android by TomRoush.

the class PDType3Font method getFontBBox.

/**
 * This will get the fonts bounding box from its dictionary.
 *
 * @return The fonts bounding box.
 */
public PDRectangle getFontBBox() {
    COSBase base = dict.getDictionaryObject(COSName.FONT_BBOX);
    PDRectangle retval = null;
    if (base instanceof COSArray) {
        retval = new PDRectangle((COSArray) base);
    }
    return retval;
}
Also used : COSArray(com.tom_roush.pdfbox.cos.COSArray) COSBase(com.tom_roush.pdfbox.cos.COSBase) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle)

Example 18 with PDRectangle

use of com.tom_roush.pdfbox.pdmodel.common.PDRectangle in project PdfBox-Android by TomRoush.

the class TrueTypeEmbedder method createFontDescriptor.

/**
 * Creates a new font descriptor dictionary for the given TTF.
 */
private PDFontDescriptor createFontDescriptor(TrueTypeFont ttf) throws IOException {
    PDFontDescriptor fd = new PDFontDescriptor();
    fd.setFontName(ttf.getName());
    OS2WindowsMetricsTable os2 = ttf.getOS2Windows();
    PostScriptTable post = ttf.getPostScript();
    // Flags
    fd.setFixedPitch(post.getIsFixedPitch() > 0 || ttf.getHorizontalHeader().getNumberOfHMetrics() == 1);
    int fsSelection = os2.getFsSelection();
    fd.setItalic(((fsSelection & (ITALIC | OBLIQUE)) != 0));
    switch(os2.getFamilyClass()) {
        case OS2WindowsMetricsTable.FAMILY_CLASS_CLAREDON_SERIFS:
        case OS2WindowsMetricsTable.FAMILY_CLASS_FREEFORM_SERIFS:
        case OS2WindowsMetricsTable.FAMILY_CLASS_MODERN_SERIFS:
        case OS2WindowsMetricsTable.FAMILY_CLASS_OLDSTYLE_SERIFS:
        case OS2WindowsMetricsTable.FAMILY_CLASS_SLAB_SERIFS:
            fd.setSerif(true);
            break;
        case OS2WindowsMetricsTable.FAMILY_CLASS_SCRIPTS:
            fd.setScript(true);
            break;
        default:
            break;
    }
    fd.setFontWeight(os2.getWeightClass());
    fd.setSymbolic(true);
    fd.setNonSymbolic(false);
    // ItalicAngle
    fd.setItalicAngle(post.getItalicAngle());
    // FontBBox
    HeaderTable header = ttf.getHeader();
    PDRectangle rect = new PDRectangle();
    float scaling = 1000f / header.getUnitsPerEm();
    rect.setLowerLeftX(header.getXMin() * scaling);
    rect.setLowerLeftY(header.getYMin() * scaling);
    rect.setUpperRightX(header.getXMax() * scaling);
    rect.setUpperRightY(header.getYMax() * scaling);
    fd.setFontBoundingBox(rect);
    // Ascent, Descent
    HorizontalHeaderTable hHeader = ttf.getHorizontalHeader();
    fd.setAscent(hHeader.getAscender() * scaling);
    fd.setDescent(hHeader.getDescender() * scaling);
    // CapHeight, XHeight
    if (os2.getVersion() >= 1.2) {
        fd.setCapHeight(os2.getCapHeight() * scaling);
        fd.setXHeight(os2.getHeight() * scaling);
    } else {
        Path capHPath = ttf.getPath("H");
        if (capHPath != null) {
            RectF capHPathBounds = new RectF();
            capHPath.computeBounds(capHPathBounds, true);
            fd.setCapHeight(Math.round(capHPathBounds.bottom) * scaling);
        } else {
            // estimate by summing the typographical +ve ascender and -ve descender
            fd.setCapHeight((os2.getTypoAscender() + os2.getTypoDescender()) * scaling);
        }
        Path xPath = ttf.getPath("x");
        if (xPath != null) {
            RectF xPathBounds = new RectF();
            xPath.computeBounds(xPathBounds, true);
            fd.setXHeight(Math.round(xPathBounds.bottom) * scaling);
        } else {
            // estimate by halving the typographical ascender
            fd.setXHeight(os2.getTypoAscender() / 2.0f * scaling);
        }
    }
    // StemV - there's no true TTF equivalent of this, so we estimate it
    fd.setStemV(fd.getFontBoundingBox().getWidth() * .13f);
    return fd;
}
Also used : Path(android.graphics.Path) RectF(android.graphics.RectF) PostScriptTable(com.tom_roush.fontbox.ttf.PostScriptTable) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) HeaderTable(com.tom_roush.fontbox.ttf.HeaderTable) HorizontalHeaderTable(com.tom_roush.fontbox.ttf.HorizontalHeaderTable) OS2WindowsMetricsTable(com.tom_roush.fontbox.ttf.OS2WindowsMetricsTable) HorizontalHeaderTable(com.tom_roush.fontbox.ttf.HorizontalHeaderTable)

Example 19 with PDRectangle

use of com.tom_roush.pdfbox.pdmodel.common.PDRectangle in project PdfBox-Android by TomRoush.

the class PageDrawer method showAnnotation.

@Override
public void showAnnotation(PDAnnotation annotation) throws IOException {
    lastClip = null;
    // Device checks shouldn't be needed
    if (annotation.isNoView()) {
        return;
    }
    if (annotation.isHidden()) {
        return;
    }
    if (annotation.isInvisible() && annotation instanceof PDAnnotationUnknown) {
        // of the standard annotation types and no annotation handler is available."
        return;
    }
    if (isHiddenOCG(annotation.getOptionalContent())) {
        return;
    }
    PDAppearanceDictionary appearance = annotation.getAppearance();
    if (appearance == null || appearance.getNormalAppearance() == null) {
        annotation.constructAppearances(renderer.document);
    }
    if (annotation.isNoRotate() && getCurrentPage().getRotation() != 0) {
        PDRectangle rect = annotation.getRectangle();
        android.graphics.Matrix savedTransform = canvas.getMatrix();
        // "The upper-left corner of the annotation remains at the same point in
        // default user space; the annotation pivots around that point."
        canvas.rotate(getCurrentPage().getRotation(), rect.getLowerLeftX(), rect.getUpperRightY());
        super.showAnnotation(annotation);
        canvas.setMatrix(savedTransform);
    } else {
        super.showAnnotation(annotation);
    }
}
Also used : PDAppearanceDictionary(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) PDAnnotationUnknown(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationUnknown)

Example 20 with PDRectangle

use of com.tom_roush.pdfbox.pdmodel.common.PDRectangle in project PdfBox-Android by TomRoush.

the class PDFTextStripper method processTextPosition.

/**
 * This will process a TextPosition object and add the text to the list of characters on a page. It takes care of
 * overlapping text.
 *
 * @param text The text to process.
 */
@Override
protected void processTextPosition(TextPosition text) {
    boolean showCharacter = true;
    if (suppressDuplicateOverlappingText) {
        showCharacter = false;
        String textCharacter = text.getUnicode();
        float textX = text.getX();
        float textY = text.getY();
        TreeMap<Float, TreeSet<Float>> sameTextCharacters = characterListMapping.get(textCharacter);
        if (sameTextCharacters == null) {
            sameTextCharacters = new TreeMap<Float, TreeSet<Float>>();
            characterListMapping.put(textCharacter, sameTextCharacters);
        }
        // RDD - Here we compute the value that represents the end of the rendered
        // text. This value is used to determine whether subsequent text rendered
        // on the same line overwrites the current text.
        // 
        // We subtract any positive padding to handle cases where extreme amounts
        // of padding are applied, then backed off (not sure why this is done, but there
        // are cases where the padding is on the order of 10x the character width, and
        // the TJ just backs up to compensate after each character). Also, we subtract
        // an amount to allow for kerning (a percentage of the width of the last
        // character).
        boolean suppressCharacter = false;
        float tolerance = text.getWidth() / textCharacter.length() / 3.0f;
        SortedMap<Float, TreeSet<Float>> xMatches = sameTextCharacters.subMap(textX - tolerance, textX + tolerance);
        for (TreeSet<Float> xMatch : xMatches.values()) {
            SortedSet<Float> yMatches = xMatch.subSet(textY - tolerance, textY + tolerance);
            if (!yMatches.isEmpty()) {
                suppressCharacter = true;
                break;
            }
        }
        if (!suppressCharacter) {
            TreeSet<Float> ySet = sameTextCharacters.get(textX);
            if (ySet == null) {
                ySet = new TreeSet<Float>();
                sameTextCharacters.put(textX, ySet);
            }
            ySet.add(textY);
            showCharacter = true;
        }
    }
    if (showCharacter) {
        // if we are showing the character then we need to determine which article it belongs to
        int foundArticleDivisionIndex = -1;
        int notFoundButFirstLeftAndAboveArticleDivisionIndex = -1;
        int notFoundButFirstLeftArticleDivisionIndex = -1;
        int notFoundButFirstAboveArticleDivisionIndex = -1;
        float x = text.getX();
        float y = text.getY();
        if (shouldSeparateByBeads) {
            for (int i = 0; i < beadRectangles.size() && foundArticleDivisionIndex == -1; i++) {
                PDRectangle rect = beadRectangles.get(i);
                if (rect != null) {
                    if (rect.contains(x, y)) {
                        foundArticleDivisionIndex = i * 2 + 1;
                    } else if ((x < rect.getLowerLeftX() || y < rect.getUpperRightY()) && notFoundButFirstLeftAndAboveArticleDivisionIndex == -1) {
                        notFoundButFirstLeftAndAboveArticleDivisionIndex = i * 2;
                    } else if (x < rect.getLowerLeftX() && notFoundButFirstLeftArticleDivisionIndex == -1) {
                        notFoundButFirstLeftArticleDivisionIndex = i * 2;
                    } else if (y < rect.getUpperRightY() && notFoundButFirstAboveArticleDivisionIndex == -1) {
                        notFoundButFirstAboveArticleDivisionIndex = i * 2;
                    }
                } else {
                    foundArticleDivisionIndex = 0;
                }
            }
        } else {
            foundArticleDivisionIndex = 0;
        }
        int articleDivisionIndex;
        if (foundArticleDivisionIndex != -1) {
            articleDivisionIndex = foundArticleDivisionIndex;
        } else if (notFoundButFirstLeftAndAboveArticleDivisionIndex != -1) {
            articleDivisionIndex = notFoundButFirstLeftAndAboveArticleDivisionIndex;
        } else if (notFoundButFirstLeftArticleDivisionIndex != -1) {
            articleDivisionIndex = notFoundButFirstLeftArticleDivisionIndex;
        } else if (notFoundButFirstAboveArticleDivisionIndex != -1) {
            articleDivisionIndex = notFoundButFirstAboveArticleDivisionIndex;
        } else {
            articleDivisionIndex = charactersByArticle.size() - 1;
        }
        List<TextPosition> textList = charactersByArticle.get(articleDivisionIndex);
        // its associated character if the two are consecutive.
        if (textList.isEmpty()) {
            textList.add(text);
        } else {
            // test if we overlap the previous entry.
            // Note that we are making an assumption that we need to only look back
            // one TextPosition to find what we are overlapping.
            // This may not always be true. */
            TextPosition previousTextPosition = textList.get(textList.size() - 1);
            if (text.isDiacritic() && previousTextPosition.contains(text)) {
                previousTextPosition.mergeDiacritic(text);
            } else // one and remove it from the list.
            if (previousTextPosition.isDiacritic() && text.contains(previousTextPosition)) {
                text.mergeDiacritic(previousTextPosition);
                textList.remove(textList.size() - 1);
                textList.add(text);
            } else {
                textList.add(text);
            }
        }
    }
}
Also used : TreeSet(java.util.TreeSet) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle)

Aggregations

PDRectangle (com.tom_roush.pdfbox.pdmodel.common.PDRectangle)82 IOException (java.io.IOException)19 PDResources (com.tom_roush.pdfbox.pdmodel.PDResources)13 PDAppearanceContentStream (com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream)12 PDColor (com.tom_roush.pdfbox.pdmodel.graphics.color.PDColor)11 Matrix (com.tom_roush.pdfbox.util.Matrix)11 COSArray (com.tom_roush.pdfbox.cos.COSArray)10 PDPage (com.tom_roush.pdfbox.pdmodel.PDPage)10 PDAppearanceStream (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream)9 Path (android.graphics.Path)8 AffineTransform (com.tom_roush.harmony.awt.geom.AffineTransform)7 PDFormXObject (com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject)6 COSBase (com.tom_roush.pdfbox.cos.COSBase)5 PDDocument (com.tom_roush.pdfbox.pdmodel.PDDocument)5 PDPageContentStream (com.tom_roush.pdfbox.pdmodel.PDPageContentStream)5 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)4 COSName (com.tom_roush.pdfbox.cos.COSName)4 PDExtendedGraphicsState (com.tom_roush.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState)4 PDAnnotationTextMarkup (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup)4 PDAnnotationWidget (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget)4