Skip to content

Commit

Permalink
GH-173 clean up object deletion and some paint clipping issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Corless committed Apr 19, 2023
1 parent 587e556 commit 2e8f93d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public MarkupGlueAnnotation(Library l, MarkupAnnotation markupAnnotation, PopupA
}

protected void renderAppearanceStream(Graphics2D g2d) {
if (this.popupAnnotation == null || this.markupAnnotation == null) return;

GraphicsConfiguration graphicsConfiguration = g2d.getDeviceConfiguration();
boolean isPrintingAllowed = this.markupAnnotation.getFlagPrint();
if (graphicsConfiguration.getDevice().getType() == GraphicsDevice.TYPE_PRINTER &&
Expand All @@ -38,7 +40,8 @@ protected void renderAppearanceStream(Graphics2D g2d) {
}

public Rectangle2D.Float getUserSpaceRectangle() {
if (userSpaceRectangle == null) {
// make sure we always update this to get the correct clip during painting
if (this.markupAnnotation != null && this.popupAnnotation != null) {
Rectangle rect = this.markupAnnotation.getUserSpaceRectangle().getBounds().union(
this.popupAnnotation.getUserSpaceRectangle().getBounds());
userSpaceRectangle = new Rectangle2D.Float(rect.x, rect.y, rect.width, rect.height);
Expand All @@ -54,4 +57,8 @@ public boolean allowPrintNormalMode() {
public void resetAppearanceStream(double dx, double dy, AffineTransform pageSpace, boolean isNew) {

}

public MarkupAnnotation getMarkupAnnotation() {
return markupAnnotation;
}
}
55 changes: 48 additions & 7 deletions core/core-awt/src/main/java/org/icepdf/core/pobjects/Page.java
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,7 @@ else if (annotObj instanceof HashMap) { // HashMap lacks "Type"->"Annot" entry
}
// create synthetic annotation to paint the glue between a markup annotation and the popup
// this is only used for print purposes. A similar pattern is also used in the Viewer RI
if (a instanceof MarkupAnnotation) {
MarkupAnnotation markupAnnotation = (MarkupAnnotation) a;
PopupAnnotation popupAnnotation = markupAnnotation.getPopupAnnotation();
annotations.add(new MarkupGlueAnnotation(library, markupAnnotation, popupAnnotation));
}
createPrintableMarkupAnnotationGlue(a);
}
} catch (IllegalStateException e) {
logger.warning("Malformed annotation could not be initialized. " +
Expand Down Expand Up @@ -814,15 +810,33 @@ public Shape getPageShape(int boundary, float userRotation, float userZoom) {
return path.createTransformedShape(at);
}

private void createPrintableMarkupAnnotationGlue(Annotation annotation) {
// create synthetic annotation to paint the glue between a markup annotation and the popup
// this is only used for print purposes. A similar pattern is also used in the Viewer RI
if (annotation instanceof PopupAnnotation) {
PopupAnnotation popupAnnotation = (PopupAnnotation) annotation;
MarkupAnnotation markupAnnotation = popupAnnotation.getParent();
// insert glue before popup is painted, so we don't over paint
Annotation annot;
for (int i = 0; i < annotations.size(); i++) {
annot = annotations.get(i);
if (annot instanceof PopupAnnotation && annot.equals(popupAnnotation)) {
annotations.add(i, new MarkupGlueAnnotation(library, markupAnnotation, popupAnnotation));
break;
}
}
}
}

/**
* Adds an annotation that was previously added to the document. It is
* assumed that the annotation has a valid object reference. This
* is commonly used with the undo/redo state manager in the RI. Use
* the method @link{#createAnnotation} for creating new annotations.
*
* @param newAnnotation annotation object to add
* @param isNew annotation is new and should be added to stateManager, otherwise change will be part of the document
* but not yet added to the stateManager as the change was likely a missing content stream or popup.
* @param isNew annotation is new and should be added to stateManager, otherwise change will be part of the document
* but not yet added to the stateManager as the change was likely a missing content stream or popup.
* @return reference to annotation that was added.
*/
@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -888,6 +902,9 @@ public Annotation addAnnotation(Annotation newAnnotation, boolean isNew) {
// add the annotations to the parsed annotations list
this.annotations.add(newAnnotation);

// add visual glue for markup annotation
createPrintableMarkupAnnotationGlue(newAnnotation);

// add the new annotations to the library
library.addObject(newAnnotation, newAnnotation.getPObjectReference());

Expand Down Expand Up @@ -976,6 +993,30 @@ else if (annot.isNew()) {
if (annotations != null) {
annotations.remove(annot);
}
// todo clean up orphaned popup annotations
// remove any corresponding popup annotation.
if (annot instanceof MarkupAnnotation) {
MarkupAnnotation markupAnnotation = (MarkupAnnotation) annot;
for (Annotation annotation : annotations) {
if (annotation instanceof PopupAnnotation &&
annotation.equals(markupAnnotation.getPopupAnnotation())) {
annotations.remove(annotation);
break;
}
}
}
// remove any markupGlue so that it doesn't get painted. Glue is never added to the document, it created
// dynamically for print purposes.
if (annot instanceof MarkupAnnotation) {
MarkupAnnotation markupAnnotation = (MarkupAnnotation) annot;
for (Annotation annotation : annotations) {
if (annotation instanceof MarkupGlueAnnotation &&
((MarkupGlueAnnotation) annotation).getMarkupAnnotation().equals(markupAnnotation)) {
annotations.remove(annotation);
break;
}
}
}
// finally remove it from the library to free up the memory
library.removeObject(annot.getPObjectReference());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,10 @@ public void render(Graphics2D origG, int renderHintType,
g.setRenderingHints(grh.getRenderingHints(renderHintType));
g.setTransform(at);
Shape preAppearanceStreamClip = g.getClip();
g.clip(deriveDrawingRectangle());
Rectangle2D.Float derivedClip = deriveDrawingRectangle();
if (derivedClip != null) {
g.clip(deriveDrawingRectangle());
}

renderAppearanceStream(g);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ protected void renderAppearanceStream(Graphics2D g2d) {
if (graphicsConfiguration.getDevice().getType() == GraphicsDevice.TYPE_PRINTER &&
isOpen() &&
isPrintingAllowed) {
String contents = getParent() != null ? getParent().getContents() : "";
if (contents != null && resetPopupPaintables) {
if (resetPopupPaintables) {
buildPopupPaintables();
}
paintPopupPaintables(g2d);
Expand Down

0 comments on commit 2e8f93d

Please sign in to comment.