use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class Concatenate method process.
@Override
public void process(Operator operator, List<COSBase> arguments) throws IOException {
if (arguments.size() < 6) {
throw new MissingOperandException(operator, arguments);
}
if (!checkArrayTypesClass(arguments, COSNumber.class)) {
return;
}
// concatenate matrix to current transformation matrix
COSNumber a = (COSNumber) arguments.get(0);
COSNumber b = (COSNumber) arguments.get(1);
COSNumber c = (COSNumber) arguments.get(2);
COSNumber d = (COSNumber) arguments.get(3);
COSNumber e = (COSNumber) arguments.get(4);
COSNumber f = (COSNumber) arguments.get(5);
Matrix matrix = new Matrix(a.floatValue(), b.floatValue(), c.floatValue(), d.floatValue(), e.floatValue(), f.floatValue());
context.getGraphicsState().getCurrentTransformationMatrix().concatenate(matrix);
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class LayerUtility method importPageAsForm.
/**
* Imports a page from some PDF file as a Form XObject so it can be placed on another page
* in the target document.
* <p>
* You may want to call {@link #wrapInSaveRestore(PDPage) wrapInSaveRestore(PDPage)} before invoking the Form XObject to
* make sure that the graphics state is reset.
*
* @param sourceDoc the source PDF document that contains the page to be copied
* @param page the page in the source PDF document to be copied
* @return a Form XObject containing the original page's content
* @throws IOException if an I/O error occurs
*/
public PDFormXObject importPageAsForm(PDDocument sourceDoc, PDPage page) throws IOException {
importOcProperties(sourceDoc);
PDStream newStream = new PDStream(targetDoc, page.getContents(), COSName.FLATE_DECODE);
PDFormXObject form = new PDFormXObject(newStream);
// Copy resources
PDResources pageRes = page.getResources();
PDResources formRes = new PDResources();
cloner.cloneMerge(pageRes, formRes);
form.setResources(formRes);
// Transfer some values from page to form
transferDict(page.getCOSObject(), form.getCOSObject(), PAGE_TO_FORM_FILTER, true);
Matrix matrix = form.getMatrix();
AffineTransform at = matrix.createAffineTransform();
PDRectangle mediaBox = page.getMediaBox();
PDRectangle cropBox = page.getCropBox();
PDRectangle viewBox = (cropBox != null ? cropBox : mediaBox);
// Handle the /Rotation entry on the page dict
int rotation = page.getRotation();
// Transform to FOP's user space
// at.scale(1 / viewBox.getWidth(), 1 / viewBox.getHeight());
at.translate(mediaBox.getLowerLeftX() - viewBox.getLowerLeftX(), mediaBox.getLowerLeftY() - viewBox.getLowerLeftY());
switch(rotation) {
case 90:
at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
at.translate(0, viewBox.getWidth());
at.rotate(-Math.PI / 2.0);
break;
case 180:
at.translate(viewBox.getWidth(), viewBox.getHeight());
at.rotate(-Math.PI);
break;
case 270:
at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
at.translate(viewBox.getHeight(), 0);
at.rotate(-Math.PI * 1.5);
break;
default:
}
// Compensate for Crop Boxes not starting at 0,0
at.translate(-viewBox.getLowerLeftX(), -viewBox.getLowerLeftY());
if (!at.isIdentity()) {
form.setMatrix(at);
}
BoundingBox bbox = new BoundingBox();
bbox.setLowerLeftX(viewBox.getLowerLeftX());
bbox.setLowerLeftY(viewBox.getLowerLeftY());
bbox.setUpperRightX(viewBox.getUpperRightX());
bbox.setUpperRightY(viewBox.getUpperRightY());
form.setBBox(new PDRectangle(bbox));
return form;
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDCaretAppearanceHandler method generateNormalAppearance.
@Override
public void generateNormalAppearance() {
PDAnnotationMarkup annotation = (PDAnnotationMarkup) getAnnotation();
PDAppearanceContentStream contentStream = null;
try {
contentStream = getNormalAppearanceAsContentStream();
contentStream.setStrokingColor(getColor());
contentStream.setNonStrokingColor(getColor());
setOpacity(contentStream, annotation.getConstantOpacity());
PDRectangle rect = getRectangle();
PDRectangle bbox = new PDRectangle(rect.getWidth(), rect.getHeight());
if (!annotation.getCOSObject().containsKey(COSName.RD)) {
// Adobe creates the /RD entry with a number that is decided
// by dividing the height by 10, with a maximum result of 5.
// That number is then used to enlarge the bbox and the rectangle and added to the
// translation values in the matrix and also used for the line width
// (not here because it has no effect, see comment near fill() ).
// The curves are based on the original rectangle.
float rd = Math.min(rect.getHeight() / 10, 5);
annotation.setRectDifferences(rd);
bbox = new PDRectangle(-rd, -rd, rect.getWidth() + 2 * rd, rect.getHeight() + 2 * rd);
Matrix matrix = annotation.getNormalAppearanceStream().getMatrix();
matrix.transformPoint(rd, rd);
annotation.getNormalAppearanceStream().setMatrix(matrix.createAffineTransform());
PDRectangle rect2 = new PDRectangle(rect.getLowerLeftX() - rd, rect.getLowerLeftY() - rd, rect.getWidth() + 2 * rd, rect.getHeight() + 2 * rd);
annotation.setRectangle(rect2);
}
annotation.getNormalAppearanceStream().setBBox(bbox);
float halfX = rect.getWidth() / 2;
float halfY = rect.getHeight() / 2;
contentStream.moveTo(0, 0);
contentStream.curveTo(halfX, 0, halfX, halfY, halfX, rect.getHeight());
contentStream.curveTo(halfX, halfY, halfX, 0, rect.getWidth(), 0);
contentStream.closePath();
contentStream.fill();
// Adobe has an additional stroke, but it has no effect
// because fill "consumes" the path.
} catch (IOException e) {
Log.e("PdfBox-Android", e.getMessage(), e);
} finally {
IOUtils.closeQuietly(contentStream);
}
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processSoftMask.
/**
* Processes a soft mask transparency group stream.
*
* @param group the transparency group.
*
* @throws IOException
*/
protected void processSoftMask(PDTransparencyGroup group) throws IOException {
saveGraphicsState();
Matrix softMaskCTM = getGraphicsState().getSoftMask().getInitialTransformationMatrix();
getGraphicsState().setCurrentTransformationMatrix(softMaskCTM);
processTransparencyGroup(group);
restoreGraphicsState();
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processAnnotation.
/**
* Process the given annotation with the specified appearance stream.
*
* @param annotation The annotation containing the appearance stream to process.
* @param appearance The appearance stream to process.
* @throws IOException If there is an error reading or parsing the appearance content stream.
*/
protected void processAnnotation(PDAnnotation annotation, PDAppearanceStream appearance) throws IOException {
PDResources parent = pushResources(appearance);
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
PDRectangle bbox = appearance.getBBox();
PDRectangle rect = annotation.getRectangle();
Matrix matrix = appearance.getMatrix();
// zero-sized rectangles are not valid
if (rect != null && rect.getWidth() > 0 && rect.getHeight() > 0 && bbox != null) {
// transformed appearance box fixme: may be an arbitrary shape
RectF transformedBox = new RectF();
bbox.transform(matrix).computeBounds(transformedBox, true);
// compute a matrix which scales and translates the transformed appearance box to align
// with the edges of the annotation's rectangle
Matrix a = Matrix.getTranslateInstance(rect.getLowerLeftX(), rect.getLowerLeftY());
a.concatenate(Matrix.getScaleInstance((float) (rect.getWidth() / transformedBox.width()), (float) (rect.getHeight() / transformedBox.height())));
a.concatenate(Matrix.getTranslateInstance((float) -transformedBox.left, (float) -transformedBox.top));
// Matrix shall be concatenated with A to form a matrix AA that maps from the appearance's
// coordinate system to the annotation's rectangle in default user space
//
// HOWEVER only the opposite order works for rotated pages with
// filled fields / annotations that have a matrix in the appearance stream, see PDFBOX-3083
Matrix aa = Matrix.concatenate(a, matrix);
// make matrix AA the CTM
getGraphicsState().setCurrentTransformationMatrix(aa);
// clip to bounding box
clipToRect(bbox);
// needed for patterns in appearance streams, e.g. PDFBOX-2182
initialMatrix = aa.clone();
processStreamOperators(appearance);
}
restoreGraphicsStack(savedStack);
popResources(parent);
}
Aggregations