PDFStreamEngine.java (pdfbox-2.0.23-src) | : | PDFStreamEngine.java (pdfbox-2.0.24-src) | ||
---|---|---|---|---|
skipping to change at line 41 | skipping to change at line 41 | |||
import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | |||
import org.apache.pdfbox.contentstream.operator.MissingOperandException; | import org.apache.pdfbox.contentstream.operator.MissingOperandException; | |||
import org.apache.pdfbox.contentstream.operator.state.EmptyGraphicsStackExceptio n; | import org.apache.pdfbox.contentstream.operator.state.EmptyGraphicsStackExceptio n; | |||
import org.apache.pdfbox.cos.COSArray; | import org.apache.pdfbox.cos.COSArray; | |||
import org.apache.pdfbox.cos.COSBase; | import org.apache.pdfbox.cos.COSBase; | |||
import org.apache.pdfbox.cos.COSDictionary; | import org.apache.pdfbox.cos.COSDictionary; | |||
import org.apache.pdfbox.cos.COSName; | import org.apache.pdfbox.cos.COSName; | |||
import org.apache.pdfbox.cos.COSNumber; | import org.apache.pdfbox.cos.COSNumber; | |||
import org.apache.pdfbox.cos.COSObject; | ||||
import org.apache.pdfbox.cos.COSString; | import org.apache.pdfbox.cos.COSString; | |||
import org.apache.pdfbox.filter.MissingImageReaderException; | import org.apache.pdfbox.filter.MissingImageReaderException; | |||
import org.apache.pdfbox.pdfparser.PDFStreamParser; | import org.apache.pdfbox.pdfparser.PDFStreamParser; | |||
import org.apache.pdfbox.pdmodel.MissingResourceException; | import org.apache.pdfbox.pdmodel.MissingResourceException; | |||
import org.apache.pdfbox.pdmodel.PDPage; | import org.apache.pdfbox.pdmodel.PDPage; | |||
import org.apache.pdfbox.pdmodel.PDResources; | import org.apache.pdfbox.pdmodel.PDResources; | |||
import org.apache.pdfbox.pdmodel.common.PDRectangle; | import org.apache.pdfbox.pdmodel.common.PDRectangle; | |||
import org.apache.pdfbox.pdmodel.font.PDFont; | import org.apache.pdfbox.pdmodel.font.PDFont; | |||
import org.apache.pdfbox.pdmodel.font.PDType1Font; | import org.apache.pdfbox.pdmodel.font.PDType1Font; | |||
import org.apache.pdfbox.pdmodel.font.PDType3CharProc; | import org.apache.pdfbox.pdmodel.font.PDType3CharProc; | |||
skipping to change at line 226 | skipping to change at line 225 | |||
if (currentPage == null) | if (currentPage == null) | |||
{ | { | |||
throw new IllegalStateException("No current page, call " + | throw new IllegalStateException("No current page, call " + | |||
"#processChildStream(PDContentStream, PDPage) instead"); | "#processChildStream(PDContentStream, PDPage) instead"); | |||
} | } | |||
PDResources parent = pushResources(group); | PDResources parent = pushResources(group); | |||
Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | |||
Matrix parentMatrix = initialMatrix; | Matrix parentMatrix = initialMatrix; | |||
PDGraphicsState graphicsState = getGraphicsState(); | ||||
// the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form | // the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form | |||
initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clon e(); | initialMatrix = graphicsState.getCurrentTransformationMatrix().clone(); | |||
// transform the CTM using the stream's matrix | // transform the CTM using the stream's matrix | |||
getGraphicsState().getCurrentTransformationMatrix().concatenate(group.ge tMatrix()); | graphicsState.getCurrentTransformationMatrix().concatenate(group.getMatr ix()); | |||
// Before execution of the transparency group XObject’s content stream, | // 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 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. | // the current stroking and nonstroking alpha constants to 1.0, and the current soft mask to None. | |||
getGraphicsState().setBlendMode(BlendMode.NORMAL); | graphicsState.setBlendMode(BlendMode.NORMAL); | |||
getGraphicsState().setAlphaConstant(1); | graphicsState.setAlphaConstant(1); | |||
getGraphicsState().setNonStrokeAlphaConstant(1); | graphicsState.setNonStrokeAlphaConstant(1); | |||
getGraphicsState().setSoftMask(null); | graphicsState.setSoftMask(null); | |||
// clip to bounding box | // clip to bounding box | |||
clipToRect(group.getBBox()); | clipToRect(group.getBBox()); | |||
processStreamOperators(group); | processStreamOperators(group); | |||
initialMatrix = parentMatrix; | initialMatrix = parentMatrix; | |||
restoreGraphicsStack(savedStack); | restoreGraphicsStack(savedStack); | |||
popResources(parent); | popResources(parent); | |||
skipping to change at line 310 | skipping to change at line 310 | |||
* @throws IOException If there is an error reading or parsing the appearanc e content stream. | * @throws IOException If there is an error reading or parsing the appearanc e content stream. | |||
*/ | */ | |||
protected void processAnnotation(PDAnnotation annotation, PDAppearanceStream appearance) | protected void processAnnotation(PDAnnotation annotation, PDAppearanceStream appearance) | |||
throws IOException | throws IOException | |||
{ | { | |||
PDResources parent = pushResources(appearance); | PDResources parent = pushResources(appearance); | |||
Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | |||
PDRectangle bbox = appearance.getBBox(); | PDRectangle bbox = appearance.getBBox(); | |||
PDRectangle rect = annotation.getRectangle(); | PDRectangle rect = annotation.getRectangle(); | |||
Matrix matrix = appearance.getMatrix(); | ||||
// zero-sized rectangles are not valid | // zero-sized rectangles are not valid | |||
if (rect != null && rect.getWidth() > 0 && rect.getHeight() > 0 && | if (rect != null && rect.getWidth() > 0 && rect.getHeight() > 0 && | |||
bbox != null && bbox.getWidth() > 0 && bbox.getHeight() > 0) | bbox != null && bbox.getWidth() > 0 && bbox.getHeight() > 0) | |||
{ | { | |||
Matrix matrix = appearance.getMatrix(); | ||||
// transformed appearance box fixme: may be an arbitrary shape | // transformed appearance box fixme: may be an arbitrary shape | |||
Rectangle2D transformedBox = bbox.transform(matrix).getBounds2D(); | Rectangle2D transformedBox = bbox.transform(matrix).getBounds2D(); | |||
// compute a matrix which scales and translates the transformed appe arance box to align | // compute a matrix which scales and translates the transformed appe arance box to align | |||
// with the edges of the annotation's rectangle | // with the edges of the annotation's rectangle | |||
Matrix a = Matrix.getTranslateInstance(rect.getLowerLeftX(), rect.ge tLowerLeftY()); | Matrix a = Matrix.getTranslateInstance(rect.getLowerLeftX(), rect.ge tLowerLeftY()); | |||
a.concatenate(Matrix.getScaleInstance((float)(rect.getWidth() / tran sformedBox.getWidth()), | a.concatenate(Matrix.getScaleInstance((float)(rect.getWidth() / tran sformedBox.getWidth()), | |||
(float)(rect.getHeight() / transformedBox.getHeight()))); | (float)(rect.getHeight() / transformedBox.getHeight()))); | |||
a.concatenate(Matrix.getTranslateInstance((float) -transformedBox.ge tX(), | a.concatenate(Matrix.getTranslateInstance((float) -transformedBox.ge tX(), | |||
(float) -transformedBox.getY())); | (float) -transformedBox.getY())); | |||
skipping to change at line 391 | skipping to change at line 392 | |||
initialMatrix = Matrix.concatenate(initialMatrix, patternMatrix); | initialMatrix = Matrix.concatenate(initialMatrix, patternMatrix); | |||
// save the original graphics state | // save the original graphics state | |||
Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | |||
// save a clean state (new clipping path, line path, etc.) | // save a clean state (new clipping path, line path, etc.) | |||
Rectangle2D bbox = tilingPattern.getBBox().transform(patternMatrix).getB ounds2D(); | Rectangle2D bbox = tilingPattern.getBBox().transform(patternMatrix).getB ounds2D(); | |||
PDRectangle rect = new PDRectangle((float)bbox.getX(), (float)bbox.getY( ), | PDRectangle rect = new PDRectangle((float)bbox.getX(), (float)bbox.getY( ), | |||
(float)bbox.getWidth(), (float)bbox.getHeight()); | (float)bbox.getWidth(), (float)bbox.getHeight()); | |||
graphicsStack.push(new PDGraphicsState(rect)); | graphicsStack.push(new PDGraphicsState(rect)); | |||
PDGraphicsState graphicsState = getGraphicsState(); | ||||
// non-colored patterns have to be given a color | // non-colored patterns have to be given a color | |||
if (colorSpace != null) | if (colorSpace != null) | |||
{ | { | |||
color = new PDColor(color.getComponents(), colorSpace); | color = new PDColor(color.getComponents(), colorSpace); | |||
getGraphicsState().setNonStrokingColorSpace(colorSpace); | graphicsState.setNonStrokingColorSpace(colorSpace); | |||
getGraphicsState().setNonStrokingColor(color); | graphicsState.setNonStrokingColor(color); | |||
getGraphicsState().setStrokingColorSpace(colorSpace); | graphicsState.setStrokingColorSpace(colorSpace); | |||
getGraphicsState().setStrokingColor(color); | graphicsState.setStrokingColor(color); | |||
} | } | |||
// transform the CTM using the stream's matrix | // transform the CTM using the stream's matrix | |||
getGraphicsState().getCurrentTransformationMatrix().concatenate(patternM atrix); | graphicsState.getCurrentTransformationMatrix().concatenate(patternMatrix ); | |||
// clip to bounding box | // clip to bounding box | |||
clipToRect(tilingPattern.getBBox()); | clipToRect(tilingPattern.getBBox()); | |||
// save text matrices (pattern stream may contain BT/ET, see PDFBOX-4896 ) | // save text matrices (pattern stream may contain BT/ET, see PDFBOX-4896 ) | |||
Matrix textMatrixSave = textMatrix; | Matrix textMatrixSave = textMatrix; | |||
Matrix textLineMatrixSave = textLineMatrix; | Matrix textLineMatrixSave = textLineMatrix; | |||
processStreamOperators(tilingPattern); | processStreamOperators(tilingPattern); | |||
textMatrix = textMatrixSave; | textMatrix = textMatrixSave; | |||
textLineMatrix = textLineMatrixSave; | textLineMatrix = textLineMatrixSave; | |||
skipping to change at line 478 | skipping to change at line 480 | |||
* Process a content stream. | * Process a content stream. | |||
* | * | |||
* @param contentStream the content stream | * @param contentStream the content stream | |||
* @throws IOException if there is an exception while processing the stream | * @throws IOException if there is an exception while processing the stream | |||
*/ | */ | |||
private void processStream(PDContentStream contentStream) throws IOException | private void processStream(PDContentStream contentStream) throws IOException | |||
{ | { | |||
PDResources parent = pushResources(contentStream); | PDResources parent = pushResources(contentStream); | |||
Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | Deque<PDGraphicsState> savedStack = saveGraphicsStack(); | |||
Matrix parentMatrix = initialMatrix; | Matrix parentMatrix = initialMatrix; | |||
PDGraphicsState graphicsState = getGraphicsState(); | ||||
// transform the CTM using the stream's matrix | // transform the CTM using the stream's matrix | |||
getGraphicsState().getCurrentTransformationMatrix().concatenate(contentS tream.getMatrix()); | graphicsState.getCurrentTransformationMatrix().concatenate(contentStream .getMatrix()); | |||
// the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form | // the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form | |||
initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clon e(); | initialMatrix = graphicsState.getCurrentTransformationMatrix().clone(); | |||
// clip to bounding box | // clip to bounding box | |||
PDRectangle bbox = contentStream.getBBox(); | PDRectangle bbox = contentStream.getBBox(); | |||
clipToRect(bbox); | clipToRect(bbox); | |||
processStreamOperators(contentStream); | processStreamOperators(contentStream); | |||
initialMatrix = parentMatrix; | initialMatrix = parentMatrix; | |||
restoreGraphicsStack(savedStack); | restoreGraphicsStack(savedStack); | |||
popResources(parent); | popResources(parent); | |||
skipping to change at line 509 | skipping to change at line 512 | |||
* @param contentStream to content stream to parse. | * @param contentStream to content stream to parse. | |||
* @throws IOException if there is an error reading or parsing the content s tream. | * @throws IOException if there is an error reading or parsing the content s tream. | |||
*/ | */ | |||
private void processStreamOperators(PDContentStream contentStream) throws IO Exception | private void processStreamOperators(PDContentStream contentStream) throws IO Exception | |||
{ | { | |||
List<COSBase> arguments = new ArrayList<COSBase>(); | List<COSBase> arguments = new ArrayList<COSBase>(); | |||
PDFStreamParser parser = new PDFStreamParser(contentStream); | PDFStreamParser parser = new PDFStreamParser(contentStream); | |||
Object token = parser.parseNextToken(); | Object token = parser.parseNextToken(); | |||
while (token != null) | while (token != null) | |||
{ | { | |||
if (token instanceof COSObject) | if (token instanceof Operator) | |||
{ | ||||
arguments.add(((COSObject) token).getObject()); | ||||
} | ||||
else if (token instanceof Operator) | ||||
{ | { | |||
processOperator((Operator) token, arguments); | processOperator((Operator) token, arguments); | |||
arguments = new ArrayList<COSBase>(); | arguments = new ArrayList<COSBase>(); | |||
} | } | |||
else | else | |||
{ | { | |||
arguments.add((COSBase) token); | arguments.add((COSBase) token); | |||
} | } | |||
token = parser.parseNextToken(); | token = parser.parseNextToken(); | |||
} | } | |||
skipping to change at line 657 | skipping to change at line 656 | |||
applyTextAdjustment(tx, ty); | applyTextAdjustment(tx, ty); | |||
} | } | |||
else if(obj instanceof COSString) | else if(obj instanceof COSString) | |||
{ | { | |||
byte[] string = ((COSString)obj).getBytes(); | byte[] string = ((COSString)obj).getBytes(); | |||
showText(string); | showText(string); | |||
} | } | |||
else | else | |||
{ | { | |||
throw new IOException("Unknown type in array for TJ operation:" | throw new IOException("Unknown type " + obj.getClass().getSimple | |||
+ obj); | Name() + | |||
" in array for TJ operation:" + obj); | ||||
} | } | |||
} | } | |||
} | } | |||
/** | /** | |||
* Applies a text position adjustment from the TJ operator. May be overridde n in subclasses. | * Applies a text position adjustment from the TJ operator. May be overridde n in subclasses. | |||
* | * | |||
* @param tx x-translation | * @param tx x-translation | |||
* @param ty y-translation | * @param ty y-translation | |||
* | * | |||
End of changes. 15 change blocks. | ||||
22 lines changed or deleted | 22 lines changed or added |