use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processStream.
/**
* Process a content stream.
*
* @param contentStream the content stream
* @throws IOException if there is an exception while processing the stream
*/
private void processStream(PDContentStream contentStream) throws IOException {
PDResources parent = pushResources(contentStream);
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
Matrix parentMatrix = initialMatrix;
// transform the CTM using the stream's matrix
getGraphicsState().getCurrentTransformationMatrix().concatenate(contentStream.getMatrix());
// the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form
initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clone();
// clip to bounding box
PDRectangle bbox = contentStream.getBBox();
clipToRect(bbox);
processStreamOperators(contentStream);
initialMatrix = parentMatrix;
restoreGraphicsStack(savedStack);
popResources(parent);
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processTransparencyGroup.
/**
* Processes a transparency group stream.
*
* @param group the transparency group.
*
* @throws IOException
*/
protected void processTransparencyGroup(PDTransparencyGroup group) throws IOException {
if (currentPage == null) {
throw new IllegalStateException("No current page, call " + "#processChildStream(PDContentStream, PDPage) instead");
}
PDResources parent = pushResources(group);
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
Matrix parentMatrix = initialMatrix;
// the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form
initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clone();
// transform the CTM using the stream's matrix
getGraphicsState().getCurrentTransformationMatrix().concatenate(group.getMatrix());
// Before execution of the transparency group XObject’s content stream,
// the current blend mode in the graphics state shall be initialized to Normal,
// the current stroking and nonstroking alpha constants to 1.0, and the current soft mask to None.
getGraphicsState().setBlendMode(BlendMode.NORMAL);
getGraphicsState().setAlphaConstant(1);
getGraphicsState().setNonStrokeAlphaConstant(1);
getGraphicsState().setSoftMask(null);
// clip to bounding box
clipToRect(group.getBBox());
processStreamOperators(group);
initialMatrix = parentMatrix;
restoreGraphicsStack(savedStack);
popResources(parent);
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processTilingPattern.
/**
* Process the given tiling pattern. Allows the pattern matrix to be overridden for custom
* rendering.
*
* @param tilingPattern the tiling pattern
* @param color color to use, if this is an uncoloured pattern, otherwise null.
* @param colorSpace color space to use, if this is an uncoloured pattern, otherwise null.
* @param patternMatrix the pattern matrix, may be overridden for custom rendering.
* @throws IOException if there is an error reading or parsing the tiling pattern content stream.
*/
protected final void processTilingPattern(PDTilingPattern tilingPattern, PDColor color, PDColorSpace colorSpace, Matrix patternMatrix) throws IOException {
PDResources parent = pushResources(tilingPattern);
Matrix parentMatrix = initialMatrix;
initialMatrix = Matrix.concatenate(initialMatrix, patternMatrix);
// save the original graphics state
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
// save a clean state (new clipping path, line path, etc.)
RectF bbox = new RectF();
tilingPattern.getBBox().transform(patternMatrix).computeBounds(bbox, true);
PDRectangle rect = new PDRectangle((float) bbox.left, (float) bbox.top, (float) bbox.width(), (float) bbox.height());
graphicsStack.push(new PDGraphicsState(rect));
// non-colored patterns have to be given a color
if (colorSpace != null) {
color = new PDColor(color.getComponents(), colorSpace);
getGraphicsState().setNonStrokingColorSpace(colorSpace);
getGraphicsState().setNonStrokingColor(color);
getGraphicsState().setStrokingColorSpace(colorSpace);
getGraphicsState().setStrokingColor(color);
}
// transform the CTM using the stream's matrix
getGraphicsState().getCurrentTransformationMatrix().concatenate(patternMatrix);
// clip to bounding box
clipToRect(tilingPattern.getBBox());
processStreamOperators(tilingPattern);
initialMatrix = parentMatrix;
restoreGraphicsStack(savedStack);
popResources(parent);
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class PDAcroForm method flatten.
/**
* This will flatten the specified form fields.
*
* <p>Flattening a form field will take the current appearance and make that part
* of the pages content stream. All form fields and annotations associated are removed.</p>
*
* <p>Invisible and hidden fields will be skipped and will not become part of the
* page content stream</p>
*
* @param fields
* @param refreshAppearances if set to true the appearances for the form field widgets will be updated
* @throws IOException
*/
public void flatten(List<PDField> fields, boolean refreshAppearances) throws IOException {
// Nothing to flatten if there are no fields provided
if (fields.isEmpty()) {
return;
}
if (!refreshAppearances && getNeedAppearances()) {
Log.w("PdfBox-Android", "acroForm.getNeedAppearances() returns true, " + "visual field appearances may not have been set");
Log.w("PdfBox-Android", "call acroForm.refreshAppearances() or " + "use the flatten() method with refreshAppearances parameter");
}
// from the XFA content into a static PDF.
if (xfaIsDynamic()) {
Log.w("PdfBox-Android", "Flatten for a dynamix XFA form is not supported");
return;
}
// refresh the appearances if set
if (refreshAppearances) {
refreshAppearances(fields);
}
// the content stream to write to
PDPageContentStream contentStream;
// get the widgets per page
Map<COSDictionary, Set<COSDictionary>> pagesWidgetsMap = buildPagesWidgetsMap(fields);
// preserve all non widget annotations
for (PDPage page : document.getPages()) {
Set<COSDictionary> widgetsForPageMap = pagesWidgetsMap.get(page.getCOSObject());
// indicates if the original content stream
// has been wrapped in a q...Q pair.
boolean isContentStreamWrapped = false;
List<PDAnnotation> annotations = new ArrayList<PDAnnotation>();
for (PDAnnotation annotation : page.getAnnotations()) {
if (widgetsForPageMap != null && !widgetsForPageMap.contains(annotation.getCOSObject())) {
annotations.add(annotation);
} else if (!annotation.isInvisible() && !annotation.isHidden() && annotation.getNormalAppearanceStream() != null && annotation.getNormalAppearanceStream().getBBox() != null) {
contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, true, !isContentStreamWrapped);
isContentStreamWrapped = true;
PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();
PDFormXObject fieldObject = new PDFormXObject(appearanceStream.getCOSObject());
contentStream.saveGraphicsState();
// translate the appearance stream to the widget location if there is
// not already a transformation in place
boolean needsTranslation = resolveNeedsTranslation(appearanceStream);
// scale the appearance stream - mainly needed for images
// in buttons and signatures
boolean needsScaling = resolveNeedsScaling(annotation, page.getRotation());
Matrix transformationMatrix = new Matrix();
boolean transformed = false;
if (needsTranslation) {
transformationMatrix.translate(annotation.getRectangle().getLowerLeftX(), annotation.getRectangle().getLowerLeftY());
transformed = true;
}
// PDFBOX-4693: field could have a rotation matrix
Matrix m = appearanceStream.getMatrix();
int angle = (int) Math.round(Math.toDegrees(Math.atan2(m.getShearY(), m.getScaleY())));
int rotation = (angle + 360) % 360;
if (needsScaling) {
PDRectangle bbox = appearanceStream.getBBox();
PDRectangle fieldRect = annotation.getRectangle();
float xScale;
float yScale;
if (rotation == 90 || rotation == 270) {
xScale = fieldRect.getWidth() / bbox.getHeight();
yScale = fieldRect.getHeight() / bbox.getWidth();
} else {
xScale = fieldRect.getWidth() / bbox.getWidth();
yScale = fieldRect.getHeight() / bbox.getHeight();
}
Matrix scalingMatrix = Matrix.getScaleInstance(xScale, yScale);
transformationMatrix.concatenate(scalingMatrix);
transformed = true;
}
if (transformed) {
contentStream.transform(transformationMatrix);
}
contentStream.drawForm(fieldObject);
contentStream.restoreGraphicsState();
contentStream.close();
}
}
page.setAnnotations(annotations);
}
// remove the fields
removeFields(fields);
// remove XFA for hybrid forms
dictionary.removeItem(COSName.XFA);
}
use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.
the class AppearanceGeneratorHelper method calculateMatrix.
private AffineTransform calculateMatrix(PDRectangle bbox, int rotation) {
if (rotation == 0) {
return new AffineTransform();
}
float tx = 0, ty = 0;
switch(rotation) {
case 90:
tx = bbox.getUpperRightY();
break;
case 180:
tx = bbox.getUpperRightY();
ty = bbox.getUpperRightX();
break;
case 270:
ty = bbox.getUpperRightX();
break;
default:
break;
}
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), tx, ty);
return matrix.createAffineTransform();
}
Aggregations