Skip to content

Commit

Permalink
GH-314 fix coordinate issue with Do content streams.
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Corless committed Feb 9, 2024
1 parent 3f345f7 commit 757a691
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,7 @@ public synchronized void init(ContentStreamRedactorCallback contentStreamRedacto
// try and find the form's resources dictionary.
Resources leafResources = library.getResources(entries, RESOURCES_KEY);
// apply parent resource, if the current resources is null
if (leafResources != null) {
} else {
if (leafResources == null) {
leafResources = parentResource;
}
// Build a new content parser for the content streams and apply the
Expand All @@ -184,11 +183,11 @@ public synchronized void init(ContentStreamRedactorCallback contentStreamRedacto
if (in != null) {
try {
logger.log(Level.FINER, () -> "Parsing form " + getPObjectReference());
shapes = cp.parse(Stream.fromByteArray(in, this.getPObjectReference()), null).getShapes();
shapes = cp.parse(Stream.fromByteArray(in, this), null).getShapes();
inited = true;
} catch (InterruptedException e) {
// the initialization was interrupted so we need to make sure we bubble up the exception
// as we need to let any chained forms know so we can invalidate the page correctly
// the initialization was interrupted so, we need to make sure we bubble up the exception
// as we need to let any chained forms know so, we can invalidate the page correctly
shapes = new Shapes();
logger.log(Level.FINE, "Parsing form interrupted parsing Form content stream.", e);
throw new InterruptedException(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,13 +342,13 @@ protected List<String> getNormalisedFilterNames() {
* that aren't specifically stream, but we want to parse some kind of state from the given bytes.
*
* @param contentBytes decompressed bytes to be treated as a stream
* @param reference parent objects reference, can be null
* @param dictionary parent objects to base new stream from
* @return mock stream object
*/
public static Stream[] fromByteArray(byte[] contentBytes, Reference reference) {
Stream stream = new Stream(new DictionaryEntries(), null);
public static Stream[] fromByteArray(byte[] contentBytes, Dictionary dictionary) {
Stream stream = new Stream(dictionary.getEntries(), null);
stream.setRawBytes(contentBytes);
stream.setPObjectReference(reference);
stream.setPObjectReference(dictionary.getPObjectReference());
return new Stream[]{stream};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ public VariableTextFieldDictionary(Library library, DictionaryEntries entries) {
if (resources != null) {
try {
ContentParser cp = new ContentParser(library, resources);
Stream[] possibleContentStream = Stream.fromByteArray(defaultAppearance.getBytes(),
this.getPObjectReference());
Stream[] possibleContentStream = Stream.fromByteArray(defaultAppearance.getBytes(), this);
cp.parseTextBlocks(possibleContentStream);
GraphicsState gs = cp.getGraphicsState();
if (gs != null) {
Expand Down Expand Up @@ -172,8 +171,7 @@ public String generateDefaultAppearance(String content, Resources resources) {
}
ContentParser cp = new ContentParser(library, resources);
// usefull parser so we parse the font color.
Stream[] possibleContentStream = Stream.fromByteArray(possibleContent.getBytes(),
this.getPObjectReference());
Stream[] possibleContentStream = Stream.fromByteArray(possibleContent.getBytes(), this);
cp.parse(possibleContentStream, null);
GraphicsState gs = cp.getGraphicsState();
if (gs != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void setContentStream(byte[] contentBytes) {
try {
ContentParser cp = new ContentParser(library, resources);
shapes = cp.parse(
Stream.fromByteArray(contentBytes, this.getPObjectReference()),
Stream.fromByteArray(contentBytes, this),
null).getShapes();
} catch (Exception e) {
shapes = new Shapes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ public void resetAppearanceStream(double dx, double dy, AffineTransform pageTran
try {
Resources resources = form.getResources();
ContentParser cp = new ContentParser(library, resources);
shapes = cp.parse(Stream.fromByteArray(iconContentString.getBytes(), this.getPObjectReference()),
shapes = cp.parse(Stream.fromByteArray(iconContentString.getBytes(), this),
null).getShapes();
} catch (Exception e) {
shapes = new Shapes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,9 @@ protected static GraphicsState consume_Do(GraphicsState graphicState, Stack<Obje
// need a new instance, so we don't corrupt the stream offset.
ContentStreamRedactorCallback formContentStreamRedactorCallback = null;
if (contentStreamRedactorCallback != null) {
formContentStreamRedactorCallback = contentStreamRedactorCallback.createChildInstance();
AffineTransform xObjectTransform = graphicState.getCTM();
xObjectTransform.concatenate(formXObject.getMatrix());
formContentStreamRedactorCallback = contentStreamRedactorCallback.createChildInstance(xObjectTransform);
}
formXObject.init(formContentStreamRedactorCallback);
// 2. concatenate matrix entry with the current CTM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.icepdf.core.util.redaction.InlineImageWriter;
import org.icepdf.core.util.redaction.StringObjectWriter;

import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -45,17 +46,28 @@ public class ContentStreamRedactorCallback {
private int lastTextPosition;
private float lastTjOffset;
private final Library library;
private final AffineTransform transform;
private boolean modifiedStream;

private final List<RedactionAnnotation> redactionAnnotations;

public ContentStreamRedactorCallback(Library library, List<RedactionAnnotation> redactionAnnotations) {
this.redactionAnnotations = redactionAnnotations;
this.library = library;
this.transform = new AffineTransform();
}

public ContentStreamRedactorCallback createChildInstance() {
return new ContentStreamRedactorCallback(this.library, this.redactionAnnotations);
private ContentStreamRedactorCallback(Library library, List<RedactionAnnotation> redactionAnnotations,
AffineTransform transform) {
this.redactionAnnotations = redactionAnnotations;
this.library = library;
// xObject text will have it's on transform that must be taken into when determining intersections of the
// redaction and glyph bounds.
this.transform = transform;
}

public ContentStreamRedactorCallback createChildInstance(AffineTransform transform) {
return new ContentStreamRedactorCallback(this.library, this.redactionAnnotations, transform);
}

public void startContentStream(Stream stream) throws IOException {
Expand Down Expand Up @@ -136,6 +148,7 @@ private boolean isTextLayoutToken(int token) {
public void checkAndRedactText(GlyphText glyphText) {
for (RedactionAnnotation annotation : redactionAnnotations) {
GeneralPath reactionPaths = annotation.getMarkupPath();
glyphText.normalizeToUserSpace(transform, null);
Rectangle2D glyphBounds = glyphText.getBounds();
if (reactionPaths != null && reactionPaths.contains(glyphBounds)) {
logger.finer(() -> "Redacting Text: " + glyphText.getCid() + " " + glyphText.getUnicode());
Expand Down

0 comments on commit 757a691

Please sign in to comment.