Skip to content

Commit

Permalink
PDFBOX-5884: support OCG visibility expressions
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1921203 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
THausherr committed Oct 9, 2024
1 parent 8e43dc9 commit f11151f
Showing 1 changed file with 106 additions and 3 deletions.
109 changes: 106 additions & 3 deletions pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2099,10 +2099,10 @@ else if (propertyList instanceof PDOptionalContentMembershipDictionary)

private boolean isHiddenOCMD(PDOptionalContentMembershipDictionary ocmd)
{
if (ocmd.getCOSObject().getCOSArray(COSName.VE) != null)
COSArray veArray = ocmd.getCOSObject().getCOSArray(COSName.VE);
if (veArray != null && !veArray.isEmpty())
{
// support seems to be optional, and is approximated by /P and /OCGS
LOG.info("/VE entry ignored in Optional Content Membership Dictionary");
return isHiddenVisibilityExpression(veArray);
}
List<PDPropertyList> oCGs = ocmd.getOCGs();
if (oCGs.isEmpty())
Expand Down Expand Up @@ -2136,6 +2136,109 @@ private boolean isHiddenOCMD(PDOptionalContentMembershipDictionary ocmd)
return visibles.stream().noneMatch(v -> v);
}

private boolean isHiddenVisibilityExpression(COSArray veArray)
{
if (veArray.isEmpty())
{
return false;
}
String op = veArray.getName(0);
if (op == null)
{
return false;
}
switch (op)
{
case "And":
return isHiddenAndVisibilityExpression(veArray);
case "Or":
return isHiddenOrVisibilityExpression(veArray);
case "Not":
return isHiddenNotVisibilityExpression(veArray);
default:
return false;
}
}

private boolean isHiddenAndVisibilityExpression(COSArray veArray)
{
// hidden if at least one isn't visible
for (int i = 1; i < veArray.size(); ++i)
{
COSBase base = veArray.getObject(i);
if (base instanceof COSArray)
{
// Another VE
boolean isHidden = isHiddenVisibilityExpression((COSArray) base);
if (isHidden)
{
return true;
}
}
else if (base instanceof COSDictionary)
{
// Another OCG
PDPropertyList prop = PDOptionalContentGroup.create((COSDictionary) base);
boolean isHidden = isHiddenOCG(prop);
if (isHidden)
{
return true;
}
}
}
return false;
}

private boolean isHiddenOrVisibilityExpression(COSArray veArray)
{
// hidden only if all are hidden
for (int i = 1; i < veArray.size(); ++i)
{
COSBase base = veArray.getObject(i);
if (base instanceof COSArray)
{
// Another VE
boolean isHidden = isHiddenVisibilityExpression((COSArray) base);
if (!isHidden)
{
return false;
}
}
else if (base instanceof COSDictionary)
{
// Another OCG
PDPropertyList prop = PDOptionalContentGroup.create((COSDictionary) base);
boolean isHidden = isHiddenOCG(prop);
if (!isHidden)
{
return false;
}
}
}
return true;
}

private boolean isHiddenNotVisibilityExpression(COSArray veArray)
{
if (veArray.size() != 2)
{
return false;
}
COSBase base = veArray.getObject(1);
if (base instanceof COSArray)
{
// Another VE
return !isHiddenVisibilityExpression((COSArray) base);
}
else if (base instanceof COSDictionary)
{
// Another OCG
PDPropertyList prop = PDOptionalContentGroup.create((COSDictionary) base);
return !isHiddenOCG(prop);
}
return false;
}

private LookupTable getInvLookupTable()
{
if (invTable == null)
Expand Down

0 comments on commit f11151f

Please sign in to comment.