diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/cos/GFCosAlt.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/cos/GFCosAlt.java new file mode 100644 index 000000000..196c684e7 --- /dev/null +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/cos/GFCosAlt.java @@ -0,0 +1,36 @@ +/** + * This file is part of veraPDF Validation, a module of the veraPDF project. + * Copyright (c) 2015, veraPDF Consortium + * All rights reserved. + * + * veraPDF Validation is free software: you can redistribute it and/or modify + * it under the terms of either: + * + * The GNU General public license GPLv3+. + * You should have received a copy of the GNU General Public License + * along with veraPDF Validation as the LICENSE.GPL file in the root of the source + * tree. If not, see http://www.gnu.org/licenses/ or + * https://www.gnu.org/licenses/gpl-3.0.en.html. + * + * The Mozilla Public License MPLv2+. + * You should have received a copy of the Mozilla Public License along with + * veraPDF Validation as the LICENSE.MPL file in the root of the source tree. + * If a copy of the MPL was not distributed with this file, you can obtain one at + * http://mozilla.org/MPL/2.0/. + */ +package org.verapdf.gf.model.impl.cos; + +import org.verapdf.cos.COSString; +import org.verapdf.model.coslayer.CosAlt; + +/** + * @author Maxim Plushchov + */ +public class GFCosAlt extends GFCosString implements CosAlt { + + public static final String COS_ALT_TYPE = "CosAlt"; + + public GFCosAlt(COSString cosString) { + super(cosString, COS_ALT_TYPE); + } +} diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/GFOpMarkedContent.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/GFOpMarkedContent.java index a97d46ed1..690038733 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/GFOpMarkedContent.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/GFOpMarkedContent.java @@ -22,17 +22,11 @@ import org.verapdf.as.ASAtom; import org.verapdf.cos.*; -import org.verapdf.gf.model.impl.cos.GFCosActualText; -import org.verapdf.gf.model.impl.cos.GFCosDict; -import org.verapdf.gf.model.impl.cos.GFCosLang; -import org.verapdf.gf.model.impl.cos.GFCosName; +import org.verapdf.gf.model.impl.cos.*; import org.verapdf.gf.model.impl.operator.base.GFOperator; import org.verapdf.gf.model.impl.pd.util.PDResourcesHandler; import org.verapdf.model.baselayer.Object; -import org.verapdf.model.coslayer.CosActualText; -import org.verapdf.model.coslayer.CosDict; -import org.verapdf.model.coslayer.CosLang; -import org.verapdf.model.coslayer.CosName; +import org.verapdf.model.coslayer.*; import org.verapdf.model.operator.OpMarkedContent; import org.verapdf.pd.PDResource; @@ -53,6 +47,7 @@ public abstract class GFOpMarkedContent extends GFOperator implements OpMarkedCo public static final String LANG = "Lang"; /** Name of link to ActualText value from the properties dictionary */ public static final String ACTUAL_TEXT = "actualText"; + public static final String ALT = "alt"; private COSDictionary propertiesDict; private final GFOpMarkedContent markedContent; @@ -88,6 +83,8 @@ public List getLinkedObjects(String link) { switch (link) { case ACTUAL_TEXT: return this.getactualText(); + case ALT: + return this.getalt(); default: return super.getLinkedObjects(link); } @@ -184,18 +181,15 @@ public String getParentStructureTag() { * @return ActualText value or null if it is not present. */ public COSString getActualText() { - COSObject actualText = getAttribute(ASAtom.ACTUAL_TEXT, COSObjType.COS_STRING); - return actualText == null ? null : (COSString) actualText.get(); + return getStringAttribute(ASAtom.ACTUAL_TEXT); } public COSString getE() { - COSObject e = getAttribute(ASAtom.E, COSObjType.COS_STRING); - return e == null ? null : (COSString) e.get(); + return getStringAttribute(ASAtom.E); } public COSString getAlt() { - COSObject alt = getAttribute(ASAtom.ALT, COSObjType.COS_STRING); - return alt == null ? null : (COSString) alt.get(); + return getStringAttribute(ASAtom.ALT); } /** @@ -233,16 +227,40 @@ private List getactualText() { return Collections.emptyList(); } + private List getalt() { + COSString alt = getAlt(); + if (alt != null) { + List list = new ArrayList<>(MAX_NUMBER_OF_ELEMENTS); + list.add(new GFCosAlt(alt)); + return list; + } + return Collections.emptyList(); + } + public COSString getInheritedActualText() { + return getInheritedStringAttribute(ASAtom.ACTUAL_TEXT); + } + + public COSString getInheritedAlt() { + return getInheritedStringAttribute(ASAtom.ALT); + } + + public COSString getInheritedStringAttribute(ASAtom key) { if (markedContent != null) { - COSString actualText = markedContent.getInheritedActualText(); - if (actualText != null) { - return actualText; + COSString string = markedContent.getInheritedStringAttribute(key); + if (string != null) { + return string; } } - return getActualText(); + return getStringAttribute(key); } + public COSString getStringAttribute(ASAtom key) { + COSObject attribute = getAttribute(key, COSObjType.COS_STRING); + return attribute == null ? null : (COSString) attribute.get(); + } + + public Long getInheritedMCID() { if (markedContent != null) { Long mcid = markedContent.getInheritedMCID(); diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/MarkedContentHelper.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/MarkedContentHelper.java index 14bf1439e..bcb6e7eee 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/MarkedContentHelper.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/markedcontent/MarkedContentHelper.java @@ -33,10 +33,10 @@ */ public class MarkedContentHelper { - public static boolean containsActualText(GFOpMarkedContent markedContent, - StructureElementAccessObject accessObject) { + public static boolean containsStringKey(ASAtom key, GFOpMarkedContent markedContent, + StructureElementAccessObject accessObject) { if (markedContent != null) { - if (markedContent.getInheritedActualText() != null) { + if (markedContent.getInheritedStringAttribute(key) != null) { return true; } @@ -47,7 +47,7 @@ public static boolean containsActualText(GFOpMarkedContent markedContent, Long mcid = markedContent.getInheritedMCID(); COSObject structureElement = accessObject.getStructureElement(parentTreeRoot, mcid); if (structureElement != null && !structureElement.empty()) { - COSObject actualText = structureElement.getKey(ASAtom.ACTUAL_TEXT); + COSObject actualText = structureElement.getKey(key); return actualText != null && !actualText.empty() && actualText.getType() == COSObjType.COS_STRING; } diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/textshow/GFGlyph.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/textshow/GFGlyph.java index 005e21526..d187b07bb 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/textshow/GFGlyph.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/operator/textshow/GFGlyph.java @@ -112,7 +112,6 @@ protected GFGlyph(PDFont font, int glyphCode, int renderingMode, String id, } else { this.toUnicode = font.toUnicode(glyphCode); } - getactualTextPresent(); this.id = id; } @@ -249,6 +248,11 @@ public Boolean getunicodePUA() { @Override public Boolean getactualTextPresent() { - return MarkedContentHelper.containsActualText(markedContent, structureElementAccessObject); + return MarkedContentHelper.containsStringKey(ASAtom.ACTUAL_TEXT, markedContent, structureElementAccessObject); + } + + @Override + public Boolean getaltPresent() { + return MarkedContentHelper.containsStringKey(ASAtom.ALT, markedContent, structureElementAccessObject); } } diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDOutline.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDOutline.java index 02b250959..6182c2367 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDOutline.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDOutline.java @@ -87,7 +87,7 @@ private List getAction() { private List getDestination() { COSObject destination = ((PDOutlineItem) simplePDObject).getDestination(); - if (!destination.empty()) { + if (!destination.empty() && !simplePDObject.knownKey(ASAtom.A)) { List destinations = new ArrayList<>(MAX_NUMBER_OF_ELEMENTS); destinations.add(new GFPDDestination(destination)); return Collections.unmodifiableList(destinations); diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructElem.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructElem.java index 3d32d7d09..970185015 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructElem.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructElem.java @@ -30,11 +30,13 @@ import org.verapdf.exceptions.LoopedException; import org.verapdf.gf.model.impl.containers.StaticContainers; import org.verapdf.gf.model.impl.cos.GFCosActualText; +import org.verapdf.gf.model.impl.cos.GFCosAlt; import org.verapdf.gf.model.impl.cos.GFCosLang; import org.verapdf.gf.model.impl.cos.GFCosUnicodeName; import org.verapdf.gf.model.impl.pd.gfse.GFSEFactory; import org.verapdf.model.baselayer.Object; import org.verapdf.model.coslayer.CosActualText; +import org.verapdf.model.coslayer.CosAlt; import org.verapdf.model.coslayer.CosLang; import org.verapdf.model.coslayer.CosUnicodeName; import org.verapdf.model.pdlayer.PDStructElem; @@ -71,6 +73,7 @@ public class GFPDStructElem extends GFPDStructTreeNode implements PDStructElem { * Link name for {@code ActualText} key */ public static final String ACTUAL_TEXT = "actualText"; + public static final String ALT = "alt"; private final String standardType; @@ -211,6 +214,8 @@ public List getLinkedObjects(String link) { return this.getLang(); case ACTUAL_TEXT: return this.getactualText(); + case ALT: + return this.getalt(); default: return super.getLinkedObjects(link); } @@ -286,4 +291,14 @@ private void fillStructElemRefs() { } } } + + private List getalt() { + COSObject alt = simplePDObject.getKey(ASAtom.ALT); + if (alt != null && COSObjType.COS_STRING == alt.getType()) { + List list = new ArrayList<>(MAX_NUMBER_OF_ELEMENTS); + list.add(new GFCosAlt((COSString)alt.getDirectBase())); + return list; + } + return Collections.emptyList(); + } } diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeNode.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeNode.java index 3033aa2f7..282fbe515 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeNode.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeNode.java @@ -111,7 +111,7 @@ private static List getChildrenStandardTypes(GFPDStructTreeNode element) return Collections.unmodifiableList(res); } - public List getChildren() { + private List getChildren() { if (children == null) { List elements = ((org.verapdf.pd.structure.PDStructTreeNode) simplePDObject).getStructChildren(); if (!elements.isEmpty()) { @@ -126,4 +126,17 @@ public List getChildren() { } return children; } + + public List getStructuralSignificanceChildren() { + List children = getChildren(); + List result = new LinkedList<>(); + for (GFPDStructElem child : children) { + if (TaggedPDFConstants.NON_STRUCT.equals(child.getstandardType()) || TaggedPDFConstants.DIV.equals(child.getstandardType())) { + result.addAll(child.getStructuralSignificanceChildren()); + } else { + result.add(child); + } + } + return result; + } } diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeRoot.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeRoot.java index 81b8cce3f..a3fdc431f 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeRoot.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/GFPDStructTreeRoot.java @@ -76,16 +76,18 @@ private List getRoleMapNames() { @Override public String gettopLevelFirstElementStandardType() { - if (!getChildren().isEmpty()) { - return getChildren().get(0).getstandardType(); + List children = getStructuralSignificanceChildren(); + if (!children.isEmpty()) { + return children.get(0).getstandardType(); } return null; } @Override public String getfirstChildStandardTypeNamespaceURL() { - if (!getChildren().isEmpty()) { - return getChildren().get(0).getStandardTypeNamespaceURL(); + List children = getStructuralSignificanceChildren(); + if (!children.isEmpty()) { + return children.get(0).getStandardTypeNamespaceURL(); } return null; } diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/annotations/GFPDLinkAnnot.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/annotations/GFPDLinkAnnot.java index b4d706ea4..3dc55611b 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/annotations/GFPDLinkAnnot.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/annotations/GFPDLinkAnnot.java @@ -20,6 +20,7 @@ */ package org.verapdf.gf.model.impl.pd.annotations; +import org.verapdf.as.ASAtom; import org.verapdf.cos.COSObject; import org.verapdf.gf.model.impl.pd.GFPDAnnot; import org.verapdf.gf.model.impl.pd.GFPDDestination; @@ -59,7 +60,7 @@ public List getLinkedObjects(String link) { private List getDestination() { COSObject destination = ((PDAnnotation) simplePDObject).getDestination(); - if (!destination.empty()) { + if (!destination.empty() && !simplePDObject.knownKey(ASAtom.A)) { List destinations = new ArrayList<>(MAX_NUMBER_OF_ELEMENTS); destinations.add(new GFPDDestination(destination)); return Collections.unmodifiableList(destinations); diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSEL.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSEL.java index 9ff0b6520..a5c9ee20c 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSEL.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSEL.java @@ -41,7 +41,7 @@ public String getListNumbering() { @Override public Boolean getcontainsLabels() { - for (GFPDStructElem child : getChildren()) { + for (GFPDStructElem child : getStructuralSignificanceChildren()) { if (TaggedPDFConstants.LI.equals(child.getstandardType()) && child.getChildrenStandardTypes().contains(TaggedPDFConstants.LBL)) { return true; diff --git a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSETable.java b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSETable.java index 6a47c0587..493f77f1b 100644 --- a/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSETable.java +++ b/validation-model/src/main/java/org/verapdf/gf/model/impl/pd/gfse/GFSETable.java @@ -101,7 +101,7 @@ private boolean checkRegular(List listTR, GFSETableCell[][] cell int numberOfRows, int numberOfColumns) { for (int rowNumber = 0; rowNumber < numberOfRows; rowNumber++) { int columnNumber = 0; - for (PDStructElem elem : listTR.get(rowNumber).getChildren()) { + for (PDStructElem elem : listTR.get(rowNumber).getStructuralSignificanceChildren()) { String type = elem.getstandardType(); if (!TaggedPDFConstants.TD.equals(type) && !TaggedPDFConstants.TH.equals(type)) { continue; @@ -232,13 +232,13 @@ private boolean hasScope(GFSETableCell cell, int rowNumber, int columnNumber, St private List getTR() { List listTR = new LinkedList<>(); - for (GFPDStructElem elem : getChildren()) { + for (GFPDStructElem elem : getStructuralSignificanceChildren()) { String type = elem.getstandardType(); if (TaggedPDFConstants.TR.equals(type)) { listTR.add(elem); } else if (TaggedPDFConstants.THEAD.equals(type) || TaggedPDFConstants.TBODY.equals(type) || TaggedPDFConstants.TFOOT.equals(type)) { - for (GFPDStructElem child : elem.getChildren()) { + for (GFPDStructElem child : elem.getStructuralSignificanceChildren()) { if (TaggedPDFConstants.TR.equals(child.getstandardType())) { listTR.add(child); } @@ -250,7 +250,7 @@ private List getTR() { private Integer getNumberOfColumns(GFPDStructElem firstTR) { int numberOfColumns = 0; - for (PDStructElem elem : firstTR.getChildren()) { + for (PDStructElem elem : firstTR.getStructuralSignificanceChildren()) { String type = elem.getstandardType(); if (TaggedPDFConstants.TH.equals(type) || TaggedPDFConstants.TD.equals(type)) { numberOfColumns += ((GFSETableCell)elem).getColSpan(); diff --git a/wcag-validation/src/main/java/org/verapdf/gf/model/impl/sa/GFSAStructElem.java b/wcag-validation/src/main/java/org/verapdf/gf/model/impl/sa/GFSAStructElem.java index ec39b9bed..4cb3c165f 100644 --- a/wcag-validation/src/main/java/org/verapdf/gf/model/impl/sa/GFSAStructElem.java +++ b/wcag-validation/src/main/java/org/verapdf/gf/model/impl/sa/GFSAStructElem.java @@ -277,7 +277,7 @@ private static List getChildrenStandardTypes(GFSAStructElem element) { for (Object child : element.children) { if (child instanceof GFSAStructElem) { String elementStandardType = ((GFSAStructElem) child).getstandardType(); - if (TaggedPDFConstants.NON_STRUCT.equals(elementStandardType)) { + if (TaggedPDFConstants.NON_STRUCT.equals(elementStandardType) || TaggedPDFConstants.DIV.equals(elementStandardType)) { res.addAll(getChildrenStandardTypes((GFSAStructElem) child)); } else { res.add(elementStandardType); @@ -292,7 +292,7 @@ public String getparentStandardType() { org.verapdf.pd.structure.PDStructElem parent = this.structElemDictionary.getParent(); if (parent != null) { String parentStandardType = GFSAFactory.getStructureElementStandardType(parent); - while (TaggedPDFConstants.NON_STRUCT.equals(parentStandardType)) { + while (TaggedPDFConstants.NON_STRUCT.equals(parentStandardType) || TaggedPDFConstants.DIV.equals(parentStandardType)) { parent = parent.getParent(); if (parent == null) { return null;