Example usage for org.apache.pdfbox.pdmodel.interactive.annotation PDAnnotation getRectangle

List of usage examples for org.apache.pdfbox.pdmodel.interactive.annotation PDAnnotation getRectangle

Introduction

In this page you can find the example usage for org.apache.pdfbox.pdmodel.interactive.annotation PDAnnotation getRectangle.

Prototype

public PDRectangle getRectangle() 

Source Link

Document

The annotation rectangle, defining the location of the annotation on the page in default user space units.

Usage

From source file:airviewer.AbstractDocumentCommandWrapper.java

License:Apache License

/**
 * This method finds and returns the "last" (upper most) annotation in
 * annotations that contains the specified x and y coordinates
 *
 * @param annotations A list of candidate annotations
 * @param x An X coordinate in the PDF coordinate system
 * @param y A Y coordinate in the PDF coordinate system
 * @return The annotation if any that was found at {x,y} on the page with
 * pageIndex// ww  w  . j  a  va2 s .  c  om
 */
protected PDAnnotation getLastAnnotationAtPoint(List<PDAnnotation> annotations, float x, float y) {
    PDAnnotation result = null;

    for (int i = annotations.size() - 1; i >= 0; --i) {
        PDAnnotation candidate = annotations.get(i);
        if (!candidate.isHidden() && !candidate.isReadOnly()) {
            PDRectangle boundingBox = candidate.getRectangle();

            if (boundingBox.contains(x, y)) {
                return candidate;

            }
        }
    }

    return result;
}

From source file:airviewer.AnnotationGenerator.java

/**
 *
 * @param a//from   w w w.j  a  va2  s . com
 * @throws IOException
 */
public static void resizeAnnotationToContent(PDAnnotation a) throws IOException {
    assert null != a;

    final String contents = a.getContents();
    final boolean hasContents = null != contents && 0 < contents.length();
    if (hasContents) {
        float borderWidth = 0;
        if (null != a.getColor() && a instanceof PDAnnotationMarkup) {
            final PDBorderStyleDictionary borderStyle = ((PDAnnotationMarkup) a).getBorderStyle();
            if (null != borderStyle) {
                borderWidth = Math.abs(borderStyle.getWidth());
            }
        }
        final float margin = MARGIN_SIZE_PDF_POINTS;
        final float fontSize = FONT_SIZE_PDF_POINTS;
        final float textHeight = fontSize + LINE_SPACE_SIZE_PDF_POINTS;
        PDRectangle position = a.getRectangle();
        final float lowerLeftX = position.getLowerLeftX();
        final float lowerLeftY = position.getLowerLeftY();

        float width = FONT.getStringWidth(contents) * fontSize / SIZE_UNITS_PER_PDF_POINT;
        float height = textHeight;

        // Reserve enough width for border and margin at start and end
        width += (borderWidth + MARGIN_SIZE_PDF_POINTS) * 2.0f;
        height += (borderWidth + MARGIN_SIZE_PDF_POINTS) * 2.0f;

        // Replace the annotations existing rectangle
        a.setRectangle(new PDRectangle(lowerLeftX, lowerLeftY, width, height));
    }

}

From source file:airviewer.AnnotationGenerator.java

/**
 *
 * @param a//from w ww . j a  v a2  s. co m
 * @param d
 * @param p
 * @param shouldResize
 * @return
 */
public static PDAppearanceStream generateSquareAppearance(PDAnnotation a, PDDocument d, PDPage p,
        boolean shouldResize) {
    assert null != a;
    assert null != d;
    assert null != p;

    PDAppearanceStream annotationAppearanceStream = null;

    try {
        if (shouldResize) {
            resizeAnnotationToContent(a);
        }

        final String contents = a.getContents();
        final boolean hasContents = null != contents && 0 < contents.length();
        float borderWidth = 0;
        if (a instanceof PDAnnotationMarkup) {
            final PDBorderStyleDictionary borderStyle = ((PDAnnotationMarkup) a).getBorderStyle();
            if (null != a.getColor() && null != borderStyle) {
                borderWidth = Math.abs(borderStyle.getWidth());
            }
        }
        final float fontSize = FONT_SIZE_PDF_POINTS;
        final float textHeight = fontSize;
        final float margin = MARGIN_SIZE_PDF_POINTS;

        PDRectangle position = a.getRectangle();
        final float lowerLeftX = position.getLowerLeftX();
        final float lowerLeftY = position.getLowerLeftY();
        float width = position.getWidth();
        float height = position.getHeight();

        annotationAppearanceStream = new PDAppearanceStream(d);

        annotationAppearanceStream.setBBox(position);
        annotationAppearanceStream.setMatrix(new AffineTransform());
        annotationAppearanceStream.setResources(p.getResources());

        try (PDPageContentStream appearanceContent = new PDPageContentStream(d, annotationAppearanceStream)) {
            appearanceContent.transform(new Matrix()); // Identity transform

            // Rect is inset by half border width to prevent border leaking
            // outside bounding box
            final float insetLowerLeftX = lowerLeftX + borderWidth * 0.5f;
            final float insetLowerLeftY = lowerLeftY + borderWidth * 0.5f;
            final float insetWidth = width - borderWidth;
            final float insetheight = height - borderWidth;
            appearanceContent.addRect(insetLowerLeftX, insetLowerLeftY, insetWidth, insetheight);
            appearanceContent.setLineWidth(borderWidth);
            appearanceContent.setNonStrokingColor(GRAY);

            if (null != a.getColor() && 0 < borderWidth) {
                appearanceContent.setStrokingColor(a.getColor());
                appearanceContent.fillAndStroke();
            } else {
                appearanceContent.fill();

            }

            if (hasContents) {
                appearanceContent.moveTo(0, 0);
                appearanceContent.beginText();

                // Center vertically, left justified inside border with margin
                appearanceContent.newLineAtOffset(lowerLeftX + borderWidth + margin,
                        lowerLeftY + (height + LINE_SPACE_SIZE_PDF_POINTS) * 0.5f - textHeight * 0.5f);
                appearanceContent.setFont(FONT, fontSize);
                if (null != a.getColor()) {
                    appearanceContent.setNonStrokingColor(a.getColor()); // Sets color of text
                } else {
                    appearanceContent.setNonStrokingColor(BLACK); // Sets color of text

                }
                appearanceContent.showText(a.getContents());
                appearanceContent.endText();
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(AnnotationGenerator.class.getName()).log(Level.SEVERE, null, ex);
    }

    return annotationAppearanceStream;
}

From source file:airviewer.AnnotationGenerator.java

/**
 *
 * @param a/*from w  ww.ja va2  s. co m*/
 * @param d
 * @param p
 * @param shouldResize
 * @return
 */
public static PDAppearanceStream generateCircleAppearance(PDAnnotation a, PDDocument d, PDPage p,
        boolean shouldResize) {
    assert null != a;
    assert null != d;
    assert null != p;

    PDAppearanceStream annotationAppearanceStream = null;

    try {
        if (shouldResize) {
            resizeAnnotationToContent(a);
        }

        final String contents = a.getContents();
        final boolean hasContents = null != contents && 0 < contents.length();
        float borderWidth = 0;
        if (a instanceof PDAnnotationMarkup) {
            final PDBorderStyleDictionary borderStyle = ((PDAnnotationMarkup) a).getBorderStyle();
            if (null != a.getColor() && null != borderStyle) {
                borderWidth = Math.abs(borderStyle.getWidth());
            }
        }
        final float fontSize = FONT_SIZE_PDF_POINTS;
        final float textHeight = fontSize;
        final float margin = MARGIN_SIZE_PDF_POINTS;

        PDRectangle position = a.getRectangle();
        final float lowerLeftX = position.getLowerLeftX();
        final float lowerLeftY = position.getLowerLeftY();
        float width = position.getWidth();
        float height = position.getHeight();

        annotationAppearanceStream = new PDAppearanceStream(d);

        annotationAppearanceStream.setBBox(position);
        annotationAppearanceStream.setMatrix(new AffineTransform());
        annotationAppearanceStream.setResources(p.getResources());

        try (PDPageContentStream appearanceContent = new PDPageContentStream(d, annotationAppearanceStream)) {
            appearanceContent.transform(new Matrix()); // Identity transform

            // Rect is inset by half border width to prevent border leaking
            // outside bounding box
            final float insetLowerLeftX = lowerLeftX + borderWidth * 0.5f;
            final float insetLowerLeftY = lowerLeftY + borderWidth * 0.5f;
            final float insetWidth = width - borderWidth;
            final float insetheight = height - borderWidth;

            if (null != a.getColor()) {
                appearanceContent.setLineWidth(borderWidth);
                appearanceContent.moveTo(insetLowerLeftX, insetLowerLeftY + insetheight * 0.5f);
                appearanceContent.curveTo(insetLowerLeftX, insetLowerLeftY + insetheight * 0.75f,
                        insetLowerLeftX + insetWidth * 0.25f, insetLowerLeftY + insetheight,
                        insetLowerLeftX + insetWidth * 0.5f, insetLowerLeftY + insetheight);
                appearanceContent.curveTo(insetLowerLeftX + insetWidth * 0.75f, insetLowerLeftY + insetheight,
                        insetLowerLeftX + insetWidth, insetLowerLeftY + insetheight * 0.75f,
                        insetLowerLeftX + insetWidth, insetLowerLeftY + insetheight * 0.5f);
                appearanceContent.curveTo(insetLowerLeftX + insetWidth, insetLowerLeftY + insetheight * 0.25f,
                        insetLowerLeftX + insetWidth * 0.75f, insetLowerLeftY,
                        insetLowerLeftX + insetWidth * 0.5f, insetLowerLeftY);
                appearanceContent.curveTo(insetLowerLeftX + insetWidth * 0.25f, insetLowerLeftY,
                        insetLowerLeftX, insetLowerLeftY + insetheight * 0.25f, insetLowerLeftX,
                        insetLowerLeftY + insetheight * 0.5f);
            }
            appearanceContent.setNonStrokingColor(GRAY);

            if (null != a.getColor() && 0 < borderWidth) {
                appearanceContent.setStrokingColor(a.getColor());
                appearanceContent.fillAndStroke();
            } else {
                appearanceContent.fill();

            }

            if (hasContents) {
                appearanceContent.moveTo(0, 0);
                appearanceContent.beginText();

                // Center text vertically, left justified inside border with margin
                appearanceContent.newLineAtOffset(lowerLeftX + borderWidth + margin,
                        lowerLeftY + (height + LINE_SPACE_SIZE_PDF_POINTS) * 0.5f - textHeight * 0.5f);
                appearanceContent.setFont(FONT, fontSize);
                appearanceContent.setNonStrokingColor(BLACK); // Sets color of text
                appearanceContent.showText(a.getContents());
                appearanceContent.endText();
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(AnnotationGenerator.class.getName()).log(Level.SEVERE, null, ex);
    }

    return annotationAppearanceStream;
}

From source file:at.knowcenter.wag.egov.egiz.pdf.PDFPage.java

License:EUPL

public void processAnnotation(PDAnnotation anno) {
    float current_y = anno.getRectangle().getLowerLeftY();
    float upper_y = 0;
    PDPage page = anno.getPage();//from   w w w .  j a v  a 2  s.c o  m

    if (page == null) {
        page = getCurrentPage();
    }

    if (page == null) {
        logger.warn("Annotation without page! The position might not be correct!");
        return;
    }

    int pageRotation = page.findRotation();
    // logger_.debug("PageRotation = " + pageRotation);
    if (pageRotation == 0) {
        float page_height = page.findMediaBox().getHeight();
        current_y = page_height - anno.getRectangle().getLowerLeftY();
        upper_y = page_height - anno.getRectangle().getUpperRightY();
    }
    if (pageRotation == 90) {
        current_y = anno.getRectangle().getUpperRightX();
        upper_y = anno.getRectangle().getLowerLeftX();
    }
    if (pageRotation == 180) {
        current_y = anno.getRectangle().getUpperRightY();
        upper_y = anno.getRectangle().getLowerLeftY();
    }
    if (pageRotation == 270) {
        float page_width = page.findMediaBox().getWidth();
        current_y = page_width - anno.getRectangle().getLowerLeftX();
        upper_y = page_width - anno.getRectangle().getUpperRightX();
    }

    if (current_y > this.effectivePageHeight) {
        if (!this.legacy40 && upper_y < this.effectivePageHeight) {
            // Bottom of annotation is below footer line, 
            // but top of annotation is above footer line!
            // so no place left on this page!
            this.max_character_ypos = this.effectivePageHeight;
        }
        return;
    }

    // store ypos of the char if it is not empty
    if (current_y > this.max_character_ypos) {
        this.max_character_ypos = current_y;
    }
}

From source file:at.knowcenter.wag.egov.egiz.pdfbox2.pdf.PDFPage.java

License:EUPL

public void processAnnotation(PDAnnotation anno) {
    float current_y = anno.getRectangle().getLowerLeftY();
    float upper_y = 0;
    PDPage page = anno.getPage();//w  ww  .  j a  va  2 s  .  c o m

    if (page == null) {
        page = getCurrentPage();
    }

    if (page == null) {
        logger.warn("Annotation without page! The position might not be correct!");
        return;
    }

    int pageRotation = page.getRotation();
    // logger_.debug("PageRotation = " + pageRotation);
    if (pageRotation == 0) {
        float page_height = page.getMediaBox().getHeight();
        current_y = page_height - anno.getRectangle().getLowerLeftY();
        upper_y = page_height - anno.getRectangle().getUpperRightY();
    }
    if (pageRotation == 90) {
        current_y = anno.getRectangle().getUpperRightX();
        upper_y = anno.getRectangle().getLowerLeftX();
    }
    if (pageRotation == 180) {
        current_y = anno.getRectangle().getUpperRightY();
        upper_y = anno.getRectangle().getLowerLeftY();
    }
    if (pageRotation == 270) {
        float page_width = page.getMediaBox().getWidth();
        current_y = page_width - anno.getRectangle().getLowerLeftX();
        upper_y = page_width - anno.getRectangle().getUpperRightX();
    }

    if (current_y > this.effectivePageHeight) {
        if (!this.legacy40 && upper_y < this.effectivePageHeight) {
            // Bottom of annotation is below footer line, 
            // but top of annotation is above footer line!
            // so no place left on this page!
            this.max_character_ypos = this.effectivePageHeight;
        }
        return;
    }

    // store ypos of the char if it is not empty
    if (current_y > this.max_character_ypos) {
        this.max_character_ypos = current_y;
    }
}

From source file:chiliad.parser.pdf.extractor.vectorgraphics.VectorGraphicsExtractor.java

License:Apache License

@Override
public MPage extract(PDPage pageToExtract, MPage pageContent) {
    try {//from   w  ww.j a  va2  s.  c  om
        if (pageToExtract.getContents() == null) {
            throw new ExtractorException("Contents is null.");
        }

        pageSize = pageToExtract.findMediaBox().createDimension();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        // initialize the used stroke with CAP_BUTT instead of CAP_SQUARE
        graphics.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
        // Only if there is some content, we have to process it.
        // Otherwise we are done here and we will produce an empty page

        PDResources resources = pageToExtract.findResources();
        processStream(pageToExtract, resources, pageToExtract.getContents().getStream());

        List<PDAnnotation> annotations = pageToExtract.getAnnotations();
        for (PDAnnotation annotation : annotations) {
            PDAnnotation annot = (PDAnnotation) annotation;
            PDRectangle rect = annot.getRectangle();
            String appearanceName = annot.getAppearanceStream();
            PDAppearanceDictionary appearDictionary = annot.getAppearance();
            if (appearDictionary != null) {
                if (appearanceName == null) {
                    appearanceName = "default";
                }
                Map<String, PDAppearanceStream> appearanceMap = appearDictionary.getNormalAppearance();
                if (appearanceMap != null) {
                    PDAppearanceStream appearance = (PDAppearanceStream) appearanceMap.get(appearanceName);
                    if (appearance != null) {
                        Point2D point = new Point2D.Float(rect.getLowerLeftX(), rect.getLowerLeftY());
                        Matrix matrix = appearance.getMatrix();
                        if (matrix != null) {
                            // transform the rectangle using the given matrix
                            AffineTransform at = matrix.createAffineTransform();
                            at.transform(point, point);
                        }
                        graphics.translate((int) point.getX(), -(int) point.getY());
                        processSubStream(pageToExtract, appearance.getResources(), appearance.getStream());
                        graphics.translate(-(int) point.getX(), (int) point.getY());
                    }
                }
            }
        }
        return handleResult(graphics, pageContent);
    } catch (IOException ex) {
        throw new ExtractorException("Failed to extract vector graphics.", ex);
    }
}

From source file:net.bookinaction.ExtractAnnotations.java

License:Apache License

public void doJob(String job, Float[] pA) throws IOException {

    PDDocument document = null;//from   w  w w . ja v  a2 s. co m

    Stamper s = new Stamper(); // utility class

    final String job_file = job + ".pdf";
    final String dic_file = job + "-dict.txt";
    final String new_job = job + "-new.pdf";

    PrintWriter writer = new PrintWriter(dic_file);

    ImageLocationListener imageLocationsListener = new ImageLocationListener();
    AnnotationMaker annotMaker = new AnnotationMaker();

    try {
        document = PDDocument.load(new File(job_file));

        int pageNum = 0;
        for (PDPage page : document.getPages()) {
            pageNum++;

            PDRectangle cropBox = page.getCropBox();

            List<PDAnnotation> annotations = page.getAnnotations();

            // extract image locations
            List<Rectangle2D> imageRects = new ArrayList<Rectangle2D>();
            imageLocationsListener.setImageRects(imageRects);
            imageLocationsListener.processPage(page);

            int im = 0;
            for (Rectangle2D pdImageRect : imageRects) {
                s.recordImage(writer, pageNum, "[im" + im + "]", (Rectangle2D.Float) pdImageRect);
                annotations.add(annotMaker.squareAnnotation(Color.YELLOW, (Rectangle2D.Float) pdImageRect,
                        "[im" + im + "]"));
                im++;
            }

            PDFTextStripperByArea stripper = new PDFTextStripperByArea();

            int j = 0;
            List<PDAnnotation> viableAnnots = new ArrayList();

            for (PDAnnotation annot : annotations) {
                if (annot instanceof PDAnnotationTextMarkup || annot instanceof PDAnnotationLink) {

                    stripper.addRegion(Integer.toString(j++), s.getAwtRect(
                            s.adjustedRect(annot.getRectangle(), pA[0], pA[1], pA[2], pA[3]), cropBox));
                    viableAnnots.add(annot);

                } else if (annot instanceof PDAnnotationPopup || annot instanceof PDAnnotationText) {
                    viableAnnots.add(annot);

                }
            }

            stripper.extractRegions(page);

            List<PDRectangle> rects = new ArrayList<PDRectangle>();

            List<String> comments = new ArrayList<String>();
            List<String> highlightTexts = new ArrayList<String>();

            j = 0;
            for (PDAnnotation viableAnnot : viableAnnots) {

                if (viableAnnot instanceof PDAnnotationTextMarkup) {
                    String highlightText = stripper.getTextForRegion(Integer.toString(j++));
                    String withoutCR = highlightText.replace((char) 0x0A, '^');

                    String comment = viableAnnot.getContents();

                    String colorString = String.format("%06x", viableAnnot.getColor().toRGB());

                    PDRectangle aRect = s.adjustedRect(viableAnnot.getRectangle(), pA[4], pA[5], pA[6], pA[7]);
                    rects.add(aRect);
                    comments.add(comment);
                    highlightTexts.add(highlightText);

                    s.recordTextMarkup(writer, pageNum, comment, withoutCR, aRect, colorString);

                } else if (viableAnnot instanceof PDAnnotationText) {
                    String comment = viableAnnot.getContents();
                    String colorString = String.format("%06x", viableAnnot.getColor().toRGB());

                    for (Rectangle2D pdImageRect : imageRects) {
                        if (pdImageRect.contains(viableAnnot.getRectangle().getLowerLeftX(),
                                viableAnnot.getRectangle().getLowerLeftY())) {
                            s.recordTextMarkup(writer, pageNum, comment, "", (Rectangle2D.Float) pdImageRect,
                                    colorString);
                            annotations.add(annotMaker.squareAnnotation(Color.GREEN,
                                    (Rectangle2D.Float) pdImageRect, comment));
                        }
                        ;
                    }
                }
            }
            PDPageContentStream canvas = new PDPageContentStream(document, page, true, true, true);

            int i = 0;
            for (PDRectangle pdRect : rects) {
                String comment = comments.get(i);
                String highlightText = highlightTexts.get(i);
                //annotations.add(linkAnnotation(pdRect, comment, highlightText));
                //annotations.add(annotationSquareCircle(pdRect, BLUE));
                s.showBox(canvas, new Rectangle2D.Float(pdRect.getLowerLeftX(), pdRect.getUpperRightY(),
                        pdRect.getWidth(), pdRect.getHeight()), cropBox, Color.BLUE);

                i++;
            }
            canvas.close();
        }
        writer.close();
        document.save(new_job);

    } finally {
        if (document != null) {
            document.close();
        }

    }

}

From source file:org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter.java

License:Apache License

private void moveAnnotations(PDPage page, List pageAnnotations, AffineTransform at) {
    PDRectangle mediaBox = page.getMediaBox();
    PDRectangle cropBox = page.getCropBox();
    PDRectangle viewBox = cropBox != null ? cropBox : mediaBox;
    for (Object obj : pageAnnotations) {
        PDAnnotation annot = (PDAnnotation) obj;
        PDRectangle rect = annot.getRectangle();
        float translateX = (float) (at.getTranslateX() - viewBox.getLowerLeftX());
        float translateY = (float) (at.getTranslateY() - viewBox.getLowerLeftY());
        if (rect != null) {
            rect.setUpperRightX(rect.getUpperRightX() + translateX);
            rect.setLowerLeftX(rect.getLowerLeftX() + translateX);
            rect.setUpperRightY(rect.getUpperRightY() + translateY);
            rect.setLowerLeftY(rect.getLowerLeftY() + translateY);
            annot.setRectangle(rect);/*from   www  .j a  v a2  s  .  co m*/
        }
        //            COSArray vertices = (COSArray) annot.getCOSObject().getDictionaryObject("Vertices");
        //            if (vertices != null) {
        //                Iterator iter = vertices.iterator();
        //                while (iter.hasNext()) {
        //                    COSFloat x = (COSFloat) iter.next();
        //                    COSFloat y = (COSFloat) iter.next();
        //                    x.setValue(x.floatValue() + translateX);
        //                    y.setValue(y.floatValue() + translateY);
        //                }
        //            }
    }
}

From source file:org.apache.pdflens.views.pagesview.PageDrawer.java

License:Apache License

/**
 * This will draw the page to the requested context.
 *
 * @param g The graphics context to draw onto.
 * @param p The page to draw.//from w  ww . j  a  v  a  2  s  .  c o m
 * @param pageDimension The size of the page to draw.
 *
 * @throws IOException If there is an IO error while drawing the page.
 */
public void drawPage(Graphics g, PDPage p, Dimension pageDimension) throws IOException {
    graphics = (Graphics2D) g;
    page = p;
    pageSize = pageDimension;
    graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    // Only if there is some content, we have to process it. 
    // Otherwise we are done here and we will produce an empty page
    if (page.getContents() != null) {
        PDResources resources = page.findResources();
        processStream(page, resources, page.getContents().getStream());
    }
    List annotations = page.getAnnotations();
    for (int i = 0; i < annotations.size(); i++) {
        PDAnnotation annot = (PDAnnotation) annotations.get(i);
        PDRectangle rect = annot.getRectangle();
        String appearanceName = annot.getAppearanceStream();
        PDAppearanceDictionary appearDictionary = annot.getAppearance();
        if (appearDictionary != null) {
            if (appearanceName == null) {
                appearanceName = "default";
            }
            Map appearanceMap = appearDictionary.getNormalAppearance();
            PDAppearanceStream appearance = (PDAppearanceStream) appearanceMap.get(appearanceName);
            if (appearance != null) {
                g.translate((int) rect.getLowerLeftX(), (int) -rect.getLowerLeftY());
                processSubStream(page, appearance.getResources(), appearance.getStream());
                g.translate((int) -rect.getLowerLeftX(), (int) +rect.getLowerLeftY());
            }
        }
    }

}