diff --git a/src/main/java/org/verapdf/as/ASAtom.java b/src/main/java/org/verapdf/as/ASAtom.java index 402561b4..ea0d66de 100644 --- a/src/main/java/org/verapdf/as/ASAtom.java +++ b/src/main/java/org/verapdf/as/ASAtom.java @@ -66,6 +66,7 @@ public class ASAtom implements Comparable { public static final ASAtom ALT = new ASAtom("Alt"); public static final ASAtom ALTERNATE = new ASAtom("Alternate"); public static final ASAtom ALTERNATES = new ASAtom("Alternates"); + public static final ASAtom AND = new ASAtom("And"); public static final ASAtom ANNOT = new ASAtom("Annot"); public static final ASAtom ANNOTS = new ASAtom("Annots"); public static final ASAtom ANTI_ALIAS = new ASAtom("AntiAlias"); @@ -402,6 +403,7 @@ public class ASAtom implements Comparable { public static final ASAtom NON_EFONT_NO_WARN = new ASAtom("NonEFontNoWarn"); public static final ASAtom NON_FULL_SCREEN_PAGE_MODE = new ASAtom("NonFullScreenPageMode"); public static final ASAtom NONE = new ASAtom("None"); + public static final ASAtom NOT = new ASAtom("Not"); public static final ASAtom NOTE_TYPE = new ASAtom("NoteType"); public static final ASAtom NORMAL = new ASAtom("Normal"); public static final ASAtom NS = new ASAtom("NS"); @@ -426,6 +428,7 @@ public class ASAtom implements Comparable { public static final ASAtom OPI = new ASAtom("OPI"); public static final ASAtom OPM = new ASAtom("OPM"); public static final ASAtom OPT = new ASAtom("Opt"); + public static final ASAtom OR = new ASAtom("Or"); public static final ASAtom ORDER = new ASAtom("Order"); public static final ASAtom ORDERING = new ASAtom("Ordering"); public static final ASAtom OS = new ASAtom("OS"); @@ -603,6 +606,7 @@ public class ASAtom implements Comparable { public static final ASAtom USE_CMAP = new ASAtom("UseCMap"); // V public static final ASAtom V = new ASAtom("V"); + public static final ASAtom VE = new ASAtom("VE"); public static final ASAtom VERISIGN_PPKVS = new ASAtom("VeriSign.PPKVS"); public static final ASAtom VERSION = new ASAtom("Version"); public static final ASAtom VERTICES = new ASAtom("Vertices"); diff --git a/src/main/java/org/verapdf/pd/optionalcontent/PDOCMDDictionary.java b/src/main/java/org/verapdf/pd/optionalcontent/PDOCMDDictionary.java index d638a243..9c708bd5 100644 --- a/src/main/java/org/verapdf/pd/optionalcontent/PDOCMDDictionary.java +++ b/src/main/java/org/verapdf/pd/optionalcontent/PDOCMDDictionary.java @@ -1,12 +1,14 @@ package org.verapdf.pd.optionalcontent; import org.verapdf.as.ASAtom; -import org.verapdf.cos.COSArray; -import org.verapdf.cos.COSBase; -import org.verapdf.cos.COSObjType; -import org.verapdf.cos.COSObject; +import org.verapdf.cos.*; + +import java.util.logging.Level; +import java.util.logging.Logger; public class PDOCMDDictionary { + private static final Logger LOGGER = Logger.getLogger(PDOCMDDictionary.class.getCanonicalName()); + public static boolean isVisibleOCMDByP(COSBase property, PDOptionalContentProperties optProperties) { COSObject ocgProperty = property.getKey(ASAtom.OCGS); if (ocgProperty == null || ocgProperty.getType() != COSObjType.COS_ARRAY) { @@ -34,4 +36,67 @@ public static boolean isVisibleOCMDByP(COSBase property, PDOptionalContentProper } return ASAtom.ALL_OFF.equals(pValue) || ASAtom.ALL_ON.equals(pValue); } + + public static boolean isVisibleOCMD(COSBase property, PDOptionalContentProperties optProperties) { + COSObject veProperty = property.getKey(ASAtom.VE); + if (veProperty != null && veProperty.getType() == COSObjType.COS_ARRAY) { + COSArray veArray = (COSArray) veProperty.getDirectBase(); + return evaluateVE(veArray, optProperties); + } + + return isVisibleOCMDByP(property, optProperties); + } + + private static boolean evaluateVE(COSArray expr, PDOptionalContentProperties optProperties) { + if (expr.size() == 0) { + return true; + } + + COSBase first = expr.at(0).getDirectBase(); + + if (first instanceof COSName) { + ASAtom operator = first.getName(); + + if (ASAtom.OR.equals(operator)) { + for (int i = 1; i < expr.size(); i++) { + if (evaluateOperandOfVE(expr.at(i).getDirectBase(), optProperties)) { + return true; + } + } + return false; + } else if (ASAtom.AND.equals(operator)) { + for (int i = 1; i < expr.size(); i++) { + if (!evaluateOperandOfVE(expr.at(i).getDirectBase(), optProperties)) { + return false; + } + } + return true; + } else if (ASAtom.NOT.equals(operator)) { + if (expr.size() != 2) { + LOGGER.log(Level.WARNING, "/Not operator should have only 1 argument in VE array"); + return true; + } + return !evaluateOperandOfVE(expr.at(1).getDirectBase(), optProperties); + } + LOGGER.log(Level.WARNING, String.format("First element of VE array has value %s instead of /And, /Or or /Not", operator)); + } else { + LOGGER.log(Level.WARNING, "First element of VE array should have type name"); + } + + return true; + } + + + private static boolean evaluateOperandOfVE(COSBase operand, PDOptionalContentProperties optProperties) { + if (operand instanceof COSArray) { + return evaluateVE((COSArray) operand, optProperties); + + } else if (operand instanceof COSDictionary) { + COSDictionary dict = (COSDictionary) operand; + String name = dict.getStringKey(ASAtom.NAME); + return optProperties.isVisibleLayer(name); + } + + return true; + } }