List of usage examples for org.apache.pdfbox.cos COSArray get
public COSBase get(int index)
From source file:com.esri.geoportal.commons.pdf.PdfUtils.java
License:Apache License
/** * Extracts the geospatial metadata from a GeoPDF * /*from ww w.j a v a 2 s . c o m*/ * @param page the PDF page to read geospatial metadata from * @param geometryServiceUrl url of a <a href="https://developers.arcgis.com/rest/services-reference/geometry-service.htm">geometry service</a> for reprojecting coordinates. * * @see <a href="https://www.loc.gov/preservation/digital/formats/fdd/fdd000312.shtml">Library of Congress information on GeoPDF</a> * @see <a href="https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf">The PDF specification</a>, section 8, for instructions for translating coordinates. * * @returns the bounding box of the GeoPDF as "yMin xMin, yMax xMax" */ private static String extractGeoPDFProps(PDPage page, String geometryServiceUrl) { // The LGI dictionary is an array, we'll loop through all entries and pull the first one for a bounding box COSArray lgi = (COSArray) page.getCOSObject().getDictionaryObject("LGIDict"); List<String> bBoxes = new ArrayList<>(); lgi.iterator().forEachRemaining(item -> { String currentBbox = null; // Set up the Coordinate Transformation Matrix (used to translate PDF coords to geo coords) Double[][] ctmValues = null; COSDictionary dictionary = (COSDictionary) item; if (dictionary.containsKey("CTM")) { ctmValues = new Double[3][3]; // The last column in the matrix is always constant ctmValues[0][2] = 0.0; ctmValues[1][2] = 0.0; ctmValues[2][2] = 1.0; COSArray ctm = (COSArray) dictionary.getDictionaryObject("CTM"); for (int i = 0; i < ctm.toList().size(); i += 2) { int ctmRow = i / 2; ctmValues[ctmRow][0] = Double.parseDouble(((COSString) ctm.get(i)).getString()); ctmValues[ctmRow][1] = Double.parseDouble(((COSString) ctm.get(i + 1)).getString()); } } // Get the neatline (i.e. the bounding box in *PDF* coordinates) Double[][] neatLineValues = null; int neatLineLength = 0; if (dictionary.containsKey("Neatline")) { COSArray neatline = (COSArray) dictionary.getDictionaryObject("Neatline"); neatLineLength = neatline.toList().size(); neatLineValues = new Double[neatLineLength / 2][3]; for (int i = 0; i < neatline.toList().size(); i += 2) { int neatLineRow = i / 2; neatLineValues[neatLineRow][0] = Double.parseDouble(((COSString) neatline.get(i)).getString()); neatLineValues[neatLineRow][1] = Double .parseDouble(((COSString) neatline.get(i + 1)).getString()); neatLineValues[neatLineRow][2] = 1.0; } } // Translate the PDF coordinates to Geospatial coordintates by multiplying the two matricies MultiPoint mp = new MultiPoint(); if (ctmValues != null && neatLineValues != null) { Double[][] resultCoords = new Double[neatLineLength / 2][3]; for (int z = 0; z < neatLineLength / 2; z++) { for (int i = 0; i < 3; i++) { resultCoords[z][i] = neatLineValues[z][0] * ctmValues[0][i] + neatLineValues[z][1] * ctmValues[1][i] + neatLineValues[z][2] * ctmValues[2][i]; } mp.add(resultCoords[z][0], resultCoords[z][1]); } } // Project the geospatial coordinates to WGS84 for the Dublin-Core metadata if (dictionary.containsKey("Projection")) { COSDictionary projectionDictionary = (COSDictionary) dictionary.getDictionaryObject("Projection"); String projectionType = projectionDictionary.getString("ProjectionType"); try (GeometryService svc = new GeometryService(HttpClients.custom().useSystemProperties().build(), new URL(geometryServiceUrl));) { // UTM projections require slightly different processing if ("UT".equals(projectionType)) { String zone = Integer.toString(projectionDictionary.getInt("Zone")); String hemisphere = projectionDictionary.getString("Hemisphere"); // Get the wkt for the geospatial coordinate system String wkt = datumTranslation(projectionDictionary.getItem("Datum")); if (zone != null && hemisphere != null && wkt != null) { // Generate a list of UTM strings List<String> utmCoords = new ArrayList<>(); for (Point2D pt : mp.getCoordinates2D()) { String coord = String.format("%s%s %s %s", zone, hemisphere, Math.round(pt.x), Math.round(pt.y)); utmCoords.add(coord); } MultiPoint reproj = svc.fromGeoCoordinateString(utmCoords, WGS84_WKID); currentBbox = generateBbox(reproj); } else { LOG.warn("Missing UTM argument: zone: {}, hemisphere: {}, datum: {}", zone, hemisphere, wkt); LOG.debug("Projection dictionary {}", projectionDictionary); } } else { // Generate Well Known Text for projection and re-projects the points to WGS 84 String wkt = getProjectionWKT(projectionDictionary, projectionType); if (wkt != null) { MultiPoint reproj = svc.project(mp, wkt, WGS84_WKID); currentBbox = generateBbox(reproj); } else if (LOG.isDebugEnabled()) { // Print out translated coordinates for debugging purposes LOG.debug("Translated Coordinates"); for (Point2D pt : mp.getCoordinates2D()) { LOG.debug(String.format("\t%s, %s", pt.x, pt.y)); } } } } catch (Exception e) { // If something goes wrong, just try the next set of coordinates LOG.error("Exception reprojecting geometry, skipping this geopdf dictionary instance...", e); } } if (currentBbox != null) { bBoxes.add(currentBbox); } }); return bBoxes.get(0); }
From source file:com.santaanna.friendlyreader.pdfstod.pdfstod3.ReplaceStringStreamEngine.java
License:Apache License
public COSArray arraycopy(COSArray carr) { COSArray retcarr = new COSArray(); for (int cind = 0; cind < carr.size(); cind++) { retcarr.add(carr.get(cind)); }/*w ww. j a v a 2 s .com*/ return retcarr; }
From source file:ddf.catalog.transformer.input.pdf.GeoPdfParserImpl.java
License:Open Source License
/** * Parses a given NeatLine and Transformation matrix into a WKT String * * @param lgidict - The PDF's LGIDict object * @param neatLineArray - The NeatLine array of points for the PDF * @param toDoubleVisitor - A visitor that converts PDF Strings / Ints / Longs into doubles. * @return the generated WKT Lat/Lon set * @throws IOException/*from w ww .j a v a2s .c om*/ */ private String getWktFromNeatLine(COSDictionary lgidict, COSArray neatLineArray, ICOSVisitor toDoubleVisitor) throws IOException { List<Double> neatline = new LinkedList<>(); List<String> coordinateList = new LinkedList<>(); String firstCoordinate = null; double[] points = new double[CTM_SIZE]; for (int i = 0; i < CTM_SIZE; i++) { points[i] = (Double) lgidict.getObjectFromPath(CTM + "/[" + i + "]").accept(toDoubleVisitor); } AffineTransform affineTransform = new AffineTransform(points); for (int i = 0; i < neatLineArray.size(); i++) { neatline.add((Double) neatLineArray.get(i).accept(toDoubleVisitor)); } for (int i = 0; i < neatline.size(); i += 2) { double x = neatline.get(i); double y = neatline.get(i + 1); Point2D p = new Point2D.Double(x, y); Point2D pprime = affineTransform.transform(p, null); String xySet = point2dToWkt(pprime); if (firstCoordinate == null) { firstCoordinate = xySet; } coordinateList.add(xySet); } coordinateList.add(firstCoordinate); String wktString = StringUtils.join(coordinateList, ", "); LOGGER.debug("{}", wktString); return wktString.toString(); }
From source file:net.padaf.preflight.actions.ActionManagerFactory.java
License:Apache License
/** * Returns all actions contained by the Next entry. If the action dictionary * doesn't have Next action, the result is an empty list. * //from w w w . ja va 2 s .c o m * @param actionDictionary * the action dictionary which contains Next entry * @param cDoc * the COSDocument which contains actions. * @return * @throws ValidationException */ public final List<AbstractActionManager> getNextActions(COSDictionary actionDictionary, COSDocument cDoc) throws ValidationException { List<AbstractActionManager> result = new ArrayList<AbstractActionManager>(0); Map<COSObjectKey, Boolean> alreadyCreated = new HashMap<COSObjectKey, Boolean>(); COSBase nextDict = actionDictionary.getDictionaryObject(ACTION_DICTIONARY_KEY_NEXT); if (nextDict != null) { if (COSUtils.isArray(nextDict, cDoc)) { COSArray array = COSUtils.getAsArray(nextDict, cDoc); // ---- Next may contains an array of Action dictionary for (int i = 0; i < array.size(); ++i) { callCreateAction(array.get(i), cDoc, result, alreadyCreated); } } else { // ---- Next field contains a Dictionary or a reference to a Dictionary callCreateAction(nextDict, cDoc, result, alreadyCreated); } } return result; }
From source file:net.padaf.preflight.font.CompositeFontValidator.java
License:Apache License
/** * This method validates the CIDFont dictionary. * /*from w w w . j a v a2s . c o m*/ * This method returns false and updates the list of errors in the * FontContainer if some mandatory fields are missing. * * This method calls the processCIDFontTypeX method to check if the font is * damaged or not. If the font is damaged, the errors list is updated and the * method return false. * * @return * @throws ValidationException */ protected boolean checkCIDFont() throws ValidationException { // ---- a CIDFont is contained in the DescendantFonts array COSDocument cDoc = this.handler.getDocument().getDocument(); COSArray array = COSUtils.getAsArray(descendantFonts, cDoc); if (array == null) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "CIDFont is missing from the DescendantFonts array")); return false; } // ---- in PDF 1.4, this array must contain only one element, // because of a PDF/A should be a PDF 1.4, this method returns an error if // the array // has more than one element. if (array.size() != 1) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "The DescendantFonts array should have one element.")); return false; } this.cidFont = COSUtils.getAsDictionary(array.get(0), cDoc); if (this.cidFont == null) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_CIDKEYED_INVALID, "The DescendantFonts array should have one element with is a dictionary.")); return false; } String type = cidFont.getNameAsString(COSName.getPDFName(DICTIONARY_KEY_TYPE)); String subtype = cidFont.getNameAsString(COSName.getPDFName(DICTIONARY_KEY_SUBTYPE)); if ((type == null || "".equals(type)) || (subtype == null || "".equals(subtype))) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Type and/or Subtype keys are missing")); return false; } boolean isT0 = FONT_DICTIONARY_VALUE_TYPE0.equals(subtype); boolean isT2 = FONT_DICTIONARY_VALUE_TYPE2.equals(subtype); // ---- Even if these entries are present, values must be checked. if (!FONT_DICTIONARY_VALUE_FONT.equals(type) || !(isT0 || isT2)) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Type and/or Subtype keys are missing")); return false; } // ---- BaseFont is mandatory String bf = cidFont.getNameAsString(COSName.getPDFName(FONT_DICTIONARY_KEY_BASEFONT)); if (bf == null || "".equals(bf)) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "BaseFont is missing")); return false; } // ---- checks others mandatory fields COSBase sysinfo = cidFont.getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CID_SYSINFO)); COSBase fontDesc = cidFont.getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_FONT_DESC)); COSBase cidToGid = cidFont.getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_CID_GIDMAP)); boolean result = checkCIDSystemInfo(sysinfo, cDoc); if (isT0) { result = result && checkCIDToGIDMap(cidToGid, cDoc, false); result = result && processCIDFontType0(fontDesc); } else { result = result && checkCIDToGIDMap(cidToGid, cDoc, true); result = result && processCIDFontType2(fontDesc); } return result; }
From source file:net.padaf.preflight.font.Type3FontValidator.java
License:Apache License
/** * FontBBox and FontMatrix are required. This method checks the type and the * content of the FontBBox and FontMatrix element (Array of 4/6 number). If a * type is invalid, the FontContainer is updated and the method returns false. * /*from w w w . j a v a 2 s . co m*/ * @return */ private boolean checkFontBBoxMatrix() { COSDocument cDoc = this.handler.getDocument().getDocument(); // ---- both elements are an array if (!COSUtils.isArray(this.fontBBox, cDoc)) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The FontBBox element isn't an array")); return false; } if (!COSUtils.isArray(this.fontMatrix, cDoc)) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The FontMatrix element isn't an array")); return false; } // ---- check the content of the FontBBox. // ---- Should be an array with 4 numbers COSArray bbox = COSUtils.getAsArray(fontBBox, cDoc); if (bbox.size() != 4) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The FontBBox element is invalid")); return false; } else { for (int i = 0; i < 4; i++) { COSBase elt = bbox.get(i); if (!(COSUtils.isFloat(elt, cDoc) || COSUtils.isInteger(elt, cDoc))) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "An element of FontBBox isn't a number")); return false; } } } // ---- check the content of the FontMatrix. // ---- Should be an array with 6 numbers COSArray matrix = COSUtils.getAsArray(fontMatrix, cDoc); if (matrix.size() != 6) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The FontMatrix element is invalid")); return false; } else { for (int i = 0; i < 6; i++) { COSBase elt = matrix.get(i); if (!(COSUtils.isFloat(elt, cDoc) || COSUtils.isInteger(elt, cDoc))) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "An element of FontMatrix isn't a number")); return false; } } } return true; }
From source file:net.padaf.preflight.font.Type3FontValidator.java
License:Apache License
/** * For a Type3 font, the mapping between the Character Code and the Character * name is entirely defined in the Encoding Entry. The Encoding Entry can be a * Name (For the 5 predefined Encoding) or a Dictionary. If it is a * dictionary, the "Differences" array contains the correspondence between a * character code and a set of character name which are different from the * encoding entry of the dictionary./*from w w w. j a v a 2s. c o m*/ * * This method checks that the encoding is : * <UL> * <li>An existing encoding name. * <li>A dictionary with an existing encoding name (the name is optional) and * a well formed "Differences" array (the array is optional) * </UL> * * @return */ private boolean checkEncoding() { COSDocument cDoc = this.handler.getDocument().getDocument(); EncodingManager emng = new EncodingManager(); if (COSUtils.isString(this.fontEncoding, cDoc)) { // ---- Encoding is a Name, check if it is an Existing Encoding String enc = COSUtils.getAsString(this.fontEncoding, cDoc); try { type3Encoding = emng.getEncoding(COSName.getPDFName(enc)); } catch (IOException e) { // ---- the encoding doesn't exist this.fontContainer.addError(new ValidationError(ERROR_FONTS_ENCODING)); return false; } } else if (COSUtils.isDictionary(this.fontEncoding, cDoc)) { COSDictionary encodingDictionary = COSUtils.getAsDictionary(this.fontEncoding, cDoc); try { type3Encoding = new DictionaryEncoding(encodingDictionary); } catch (IOException e) { // ---- the encoding doesn't exist this.fontContainer.addError(new ValidationError(ERROR_FONTS_ENCODING)); return false; } COSBase diff = encodingDictionary.getItem(COSName.getPDFName(FONT_DICTIONARY_KEY_DIFFERENCES)); if (diff != null) { if (!COSUtils.isArray(diff, cDoc)) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_TYPE3_DAMAGED, "The differences element of the encoding dictionary isn't an array")); return false; } // ---- The DictionaryEncoding object doesn't throw exception if the // Differences isn't well formed. // So check if the array has the right format. COSArray differences = COSUtils.getAsArray(diff, cDoc); for (int i = 0; i < differences.size(); ++i) { COSBase item = differences.get(i); if (!(item instanceof COSInteger || item instanceof COSName)) { // ---- Error, the Differences array is invalid this.fontContainer.addError(new ValidationError(ERROR_FONTS_TYPE3_DAMAGED, "Differences Array should contain COSInt or COSName, no other type")); return false; } } } } else { // ---- the encoding entry is invalid this.fontContainer.addError(new ValidationError(ERROR_FONTS_TYPE3_DAMAGED, "The Encoding entry doesn't have the right type")); return false; } return true; }
From source file:net.padaf.preflight.font.Type3FontValidator.java
License:Apache License
/** * CharProcs is a dictionary where the key is a character name and the value * is a Stream which contains the glyph representation of the key. * /*from w w w . ja va 2 s. co m*/ * This method checks that all character code defined in the Widths Array * exist in the CharProcs dictionary. If the CharProcs doesn't know the * Character, it is mapped with the .notdef one. * * For each character, the Glyph width must be the same as the Width value * declared in the Widths array. * * @param errors * @return */ private boolean checkCharProcsAndMetrics() throws ValidationException { COSDocument cDoc = this.handler.getDocument().getDocument(); // ---- the Widths value can be a reference to an object // ---- Access the object using the COSkey COSArray wArr = COSUtils.getAsArray(this.widths, cDoc); if (wArr == null) { this.fontContainer.addError( new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The Witdhs array is unreachable")); return false; } COSDictionary charProcsDictionary = COSUtils.getAsDictionary(this.charProcs, cDoc); if (charProcsDictionary == null) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The CharProcs element isn't a dictionary")); return false; } // ---- firstChar and lastChar must be integer. int fc = ((COSInteger) this.firstChar).intValue(); int lc = ((COSInteger) this.lastChar).intValue(); // ---- wArr length = (lc - fc) +1 and it is an array of int. // ---- If FirstChar is greater than LastChar, the validation will fail // because of // ---- the array will have an expected size <= 0. int expectedLength = (lc - fc) + 1; if (wArr.size() != expectedLength) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The length of Witdhs array is invalid. Expected : \"" + expectedLength + "\" Current : \"" + wArr.size() + "\"")); return false; } // ---- Check width consistency for (int i = 0; i < expectedLength; i++) { int cid = fc + i; COSBase arrContent = wArr.get(i); if (COSUtils.isNumeric(arrContent, cDoc)) { float width = COSUtils.getAsFloat(arrContent, cDoc); String charName = null; try { charName = this.type3Encoding.getName(cid); } catch (IOException e) { // shouldn't occur throw new ValidationException("Unable to check Widths consistency", e); } COSBase item = charProcsDictionary.getItem(COSName.getPDFName(charName)); COSStream charStream = COSUtils.getAsStream(item, cDoc); if (charStream == null && width != 0) { GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, cid, "The CharProcs \"" + charName + "\" doesn't exist but the width is " + width); GlyphDetail glyphDetail = new GlyphDetail(cid, glyphEx); this.fontContainer.addKnownCidElement(glyphDetail); } else { try { // --- Parse the Glyph description to obtain the Width PDFAType3StreamParser parser = new PDFAType3StreamParser(this.handler); PDResources pRes = null; if (this.resources != null) { COSDictionary resAsDict = COSUtils.getAsDictionary(this.resources, cDoc); if (resAsDict != null) { pRes = new PDResources(resAsDict); } } parser.resetEngine(); parser.processSubStream(null, pRes, charStream); if (width != parser.getWidth()) { GlyphException glyphEx = new GlyphException(ERROR_FONTS_METRICS, cid, "The CharProcs \"" + charName + "\" should have a width equals to " + width); GlyphDetail glyphDetail = new GlyphDetail(cid, glyphEx); this.fontContainer.addKnownCidElement(glyphDetail); } else { // Glyph is OK, we keep the CID. GlyphDetail glyphDetail = new GlyphDetail(cid); this.fontContainer.addKnownCidElement(glyphDetail); } } catch (ContentStreamException e) { this.fontContainer.addError(new ValidationError(e.getValidationError())); return false; } catch (IOException e) { this.fontContainer.addError(new ValidationError(ERROR_FONTS_TYPE3_DAMAGED, "The CharProcs references an element which can't be read")); return false; } } } else { this.fontContainer.addError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "The Witdhs array is invalid. (some element aren't integer)")); return false; } } return true; }
From source file:net.padaf.preflight.helpers.CatalogValidationHelper.java
License:Apache License
/** * This method checks the content of each OutputIntent. The S entry must * contain GTS_PDFA1. The DestOuputProfile must contain a valid ICC Profile * Stream./* w w w. j a v a2s. c o m*/ * * If there are more than one OutputIntent, they have to use the same ICC * Profile. * * This method returns a list of ValidationError. It is empty if no errors * have been found. * * @param handler * @return * @throws ValidationException */ public List<ValidationError> validateOutputIntent(DocumentHandler handler) throws ValidationException { List<ValidationError> result = new ArrayList<ValidationError>(0); PDDocument pdDocument = handler.getDocument(); PDDocumentCatalog catalog = pdDocument.getDocumentCatalog(); COSDocument cDoc = pdDocument.getDocument(); COSBase cBase = catalog.getCOSDictionary() .getItem(COSName.getPDFName(DOCUMENT_DICTIONARY_KEY_OUTPUT_INTENTS)); COSArray outputIntents = COSUtils.getAsArray(cBase, cDoc); Map<COSObjectKey, Boolean> tmpDestOutputProfile = new HashMap<COSObjectKey, Boolean>(); for (int i = 0; outputIntents != null && i < outputIntents.size(); ++i) { COSDictionary dictionary = COSUtils.getAsDictionary(outputIntents.get(i), cDoc); if (dictionary == null) { result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY, "OutputIntent object is null or isn't a dictionary")); } else { // ---- S entry is mandatory and must be equals to GTS_PDFA1 String sValue = dictionary.getNameAsString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_S)); if (!OUTPUT_INTENT_DICTIONARY_VALUE_GTS_PDFA1.equals(sValue)) { result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_S_VALUE_INVALID, "The S entry of the OutputIntent isn't GTS_PDFA1")); continue; } // ---- OutputConditionIdentifier is a mandatory field String outputConditionIdentifier = dictionary .getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_OUTPUT_CONDITION_IDENTIFIER)); if (outputConditionIdentifier == null || "".equals(outputConditionIdentifier)) { result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY, "The OutputIntentCondition is missing")); continue; } // ---- If OutputConditionIdentifier is "Custom" : // ---- DestOutputProfile and Info are mandatory // ---- DestOutputProfile must be a ICC Profile // ---- Because of PDF/A conforming file needs to specify the color // characteristics, the DestOutputProfile // is checked even if the OutputConditionIdentifier isn't "Custom" COSBase dop = dictionary .getItem(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_DEST_OUTPUT_PROFILE)); ValidationError valer = validateICCProfile(dop, cDoc, tmpDestOutputProfile, handler); if (valer != null) { result.add(valer); continue; } if (OUTPUT_INTENT_DICTIONARY_VALUE_OUTPUT_CONDITION_IDENTIFIER_CUSTOM .equals(outputConditionIdentifier)) { String info = dictionary.getString(COSName.getPDFName(OUTPUT_INTENT_DICTIONARY_KEY_INFO)); if (info == null || "".equals(info)) { result.add(new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY, "The Info entry of a OutputIntent dictionary is missing")); continue; } } } } return result; }
From source file:org.apache.fop.render.pdf.PageParentTreeFinderTestCase.java
License:Apache License
@Test public void testGetPageParentTreeArray() throws IOException { File resource = new File(getClass().getResource(LINK).getFile()); PDDocument doc = PDDocument.load(resource); PDPage srcPage = doc.getPage(0);//w w w .j a v a 2 s . com PageParentTreeFinder finder = new PageParentTreeFinder(srcPage); COSArray markedContentParents = finder.getPageParentTreeArray(doc); Assert.assertEquals(markedContentParents.size(), 3); COSObject firstObj = (COSObject) markedContentParents.get(0); COSObject secObj = (COSObject) markedContentParents.get(1); COSArray firstKids = (COSArray) firstObj.getDictionaryObject(COSName.K); COSDictionary firstKid = (COSDictionary) firstKids.get(0); int test = firstKid.getInt("MCID"); int expected = 0; Assert.assertEquals(test, expected); COSDictionary firstKidBrother = (COSDictionary) firstKids.get(2); test = firstKidBrother.getInt("MCID"); expected = 2; Assert.assertEquals(test, expected); COSArray secKidsArray = (COSArray) secObj.getDictionaryObject(COSName.K); COSDictionary secondKid = (COSDictionary) secKidsArray.get(0); test = secondKid.getInt("MCID"); expected = 1; Assert.assertEquals(test, expected); }