Example usage for org.apache.pdfbox.cos COSArray getObject

List of usage examples for org.apache.pdfbox.cos COSArray getObject

Introduction

In this page you can find the example usage for org.apache.pdfbox.cos COSArray getObject.

Prototype

public COSBase getObject(int index) 

Source Link

Document

This will get an object from the array.

Usage

From source file:ShowSignature.java

License:Apache License

private void showSignature(String[] args) throws IOException, CertificateException {
    if (args.length != 2) {
        usage();//w  w  w  . j av  a 2 s . co  m
    } else {
        String password = args[0];
        String infile = args[1];
        PDDocument document = null;
        try {
            document = PDDocument.load(new File(infile), password);
            if (!document.isEncrypted()) {
                System.err.println("Warning: Document is not encrypted.");
            }

            COSDictionary trailer = document.getDocument().getTrailer();
            COSDictionary root = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT);
            COSDictionary acroForm = (COSDictionary) root.getDictionaryObject(COSName.ACRO_FORM);
            COSArray fields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS);
            for (int i = 0; i < fields.size(); i++) {
                COSDictionary field = (COSDictionary) fields.getObject(i);
                COSName type = field.getCOSName(COSName.FT);
                if (COSName.SIG.equals(type)) {
                    COSDictionary cert = (COSDictionary) field.getDictionaryObject(COSName.V);
                    if (cert != null) {
                        System.out.println("Certificate found");
                        System.out.println("Name=" + cert.getDictionaryObject(COSName.NAME));
                        System.out.println("Modified=" + cert.getDictionaryObject(COSName.M));
                        COSName subFilter = (COSName) cert.getDictionaryObject(COSName.SUB_FILTER);
                        if (subFilter != null) {
                            if (subFilter.getName().equals("adbe.x509.rsa_sha1")) {
                                COSString certString = (COSString) cert
                                        .getDictionaryObject(COSName.getPDFName("Cert"));
                                byte[] certData = certString.getBytes();
                                CertificateFactory factory = CertificateFactory.getInstance("X.509");
                                ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
                                Collection<? extends Certificate> certs = factory
                                        .generateCertificates(certStream);
                                System.out.println("certs=" + certs);
                            } else if (subFilter.getName().equals("adbe.pkcs7.sha1")) {
                                COSString certString = (COSString) cert.getDictionaryObject(COSName.CONTENTS);
                                byte[] certData = certString.getBytes();
                                CertificateFactory factory = CertificateFactory.getInstance("X.509");
                                ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
                                Collection<? extends Certificate> certs = factory
                                        .generateCertificates(certStream);
                                System.out.println("certs=" + certs);
                            } else {
                                System.err.println("Unknown certificate type:" + subFilter);
                            }
                        } else {
                            throw new IOException("Missing subfilter for cert dictionary");
                        }
                    } else {
                        System.out.println("Signature found, but no certificate");
                    }
                }
            }
        } finally {
            if (document != null) {
                document.close();
            }
        }
    }
}

From source file:com.fangxin365.core.utils.PDFMerger.java

License:Apache License

/**
 * append all pages from source to destination.
 * // w  w w  . j a v a 2s  . c  o m
 * @param destination
 *            the document to receive the pages
 * @param source
 *            the document originating the new pages
 * 
 * @throws IOException
 *             If there is an error accessing data from either document.
 */
public void appendDocument(PDDocument destination, PDDocument source) throws IOException {
    if (destination.isEncrypted()) {
        System.out.println("Error: destination PDF is encrypted, can't append encrypted PDF documents.");
    }
    if (source.isEncrypted()) {
        System.out.println("Error: source PDF is encrypted, can't append encrypted PDF documents.");
    }
    PDDocumentInformation destInfo = destination.getDocumentInformation();
    PDDocumentInformation srcInfo = source.getDocumentInformation();
    destInfo.getDictionary().mergeInto(srcInfo.getDictionary());

    PDDocumentCatalog destCatalog = destination.getDocumentCatalog();
    PDDocumentCatalog srcCatalog = source.getDocumentCatalog();

    // use the highest version number for the resulting pdf
    float destVersion = destination.getDocument().getVersion();
    float srcVersion = source.getDocument().getVersion();

    if (destVersion < srcVersion) {
        destination.getDocument().setVersion(srcVersion);
    }

    if (destCatalog.getOpenAction() == null) {
        destCatalog.setOpenAction(srcCatalog.getOpenAction());
    }

    // maybe there are some shared resources for all pages
    COSDictionary srcPages = (COSDictionary) srcCatalog.getCOSDictionary().getDictionaryObject(COSName.PAGES);
    COSDictionary srcResources = (COSDictionary) srcPages.getDictionaryObject(COSName.RESOURCES);
    COSDictionary destPages = (COSDictionary) destCatalog.getCOSDictionary().getDictionaryObject(COSName.PAGES);
    COSDictionary destResources = (COSDictionary) destPages.getDictionaryObject(COSName.RESOURCES);
    if (srcResources != null) {
        if (destResources != null) {
            destResources.mergeInto(srcResources);
        } else {
            destPages.setItem(COSName.RESOURCES, srcResources);
        }
    }

    PDFCloneUtility cloner = new PDFCloneUtility(destination);

    try {
        PDAcroForm destAcroForm = destCatalog.getAcroForm();
        PDAcroForm srcAcroForm = srcCatalog.getAcroForm();
        if (destAcroForm == null) {
            cloner.cloneForNewDocument(srcAcroForm);
            destCatalog.setAcroForm(srcAcroForm);
        } else {
            if (srcAcroForm != null) {
                mergeAcroForm(cloner, destAcroForm, srcAcroForm);
            }
        }
    } catch (Exception e) {
        // if we are not ignoring exceptions, we'll re-throw this
        if (!ignoreAcroFormErrors) {
            throw (IOException) e;
        }
    }

    COSArray destThreads = (COSArray) destCatalog.getCOSDictionary().getDictionaryObject(COSName.THREADS);
    COSArray srcThreads = (COSArray) cloner
            .cloneForNewDocument(destCatalog.getCOSDictionary().getDictionaryObject(COSName.THREADS));
    if (destThreads == null) {
        destCatalog.getCOSDictionary().setItem(COSName.THREADS, srcThreads);
    } else {
        destThreads.addAll(srcThreads);
    }

    PDDocumentNameDictionary destNames = destCatalog.getNames();
    PDDocumentNameDictionary srcNames = srcCatalog.getNames();
    if (srcNames != null) {
        if (destNames == null) {
            destCatalog.getCOSDictionary().setItem(COSName.NAMES, cloner.cloneForNewDocument(srcNames));
        } else {
            cloner.cloneMerge(srcNames, destNames);
        }

    }

    PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
    PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
    if (srcOutline != null) {
        if (destOutline == null) {
            PDDocumentOutline cloned = new PDDocumentOutline(
                    (COSDictionary) cloner.cloneForNewDocument(srcOutline));
            destCatalog.setDocumentOutline(cloned);
        } else {
            PDOutlineItem first = srcOutline.getFirstChild();
            if (first != null) {
                PDOutlineItem clonedFirst = new PDOutlineItem(
                        (COSDictionary) cloner.cloneForNewDocument(first));
                destOutline.appendChild(clonedFirst);
            }
        }
    }

    String destPageMode = destCatalog.getPageMode();
    String srcPageMode = srcCatalog.getPageMode();
    if (destPageMode == null) {
        destCatalog.setPageMode(srcPageMode);
    }

    COSDictionary destLabels = (COSDictionary) destCatalog.getCOSDictionary()
            .getDictionaryObject(COSName.PAGE_LABELS);
    COSDictionary srcLabels = (COSDictionary) srcCatalog.getCOSDictionary()
            .getDictionaryObject(COSName.PAGE_LABELS);
    if (srcLabels != null) {
        int destPageCount = destination.getNumberOfPages();
        COSArray destNums = null;
        if (destLabels == null) {
            destLabels = new COSDictionary();
            destNums = new COSArray();
            destLabels.setItem(COSName.NUMS, destNums);
            destCatalog.getCOSDictionary().setItem(COSName.PAGE_LABELS, destLabels);
        } else {
            destNums = (COSArray) destLabels.getDictionaryObject(COSName.NUMS);
        }
        COSArray srcNums = (COSArray) srcLabels.getDictionaryObject(COSName.NUMS);
        if (srcNums != null) {
            for (int i = 0; i < srcNums.size(); i += 2) {
                COSNumber labelIndex = (COSNumber) srcNums.getObject(i);
                long labelIndexValue = labelIndex.intValue();
                destNums.add(COSInteger.get(labelIndexValue + destPageCount));
                destNums.add(cloner.cloneForNewDocument(srcNums.getObject(i + 1)));
            }
        }
    }

    COSStream destMetadata = (COSStream) destCatalog.getCOSDictionary().getDictionaryObject(COSName.METADATA);
    COSStream srcMetadata = (COSStream) srcCatalog.getCOSDictionary().getDictionaryObject(COSName.METADATA);
    if (destMetadata == null && srcMetadata != null) {
        PDStream newStream = new PDStream(destination, srcMetadata.getUnfilteredStream(), false);
        newStream.getStream().mergeInto(srcMetadata);
        newStream.addCompression();
        destCatalog.getCOSDictionary().setItem(COSName.METADATA, newStream);
    }

    // finally append the pages
    @SuppressWarnings("unchecked")
    List<PDPage> pages = srcCatalog.getAllPages();
    Iterator<PDPage> pageIter = pages.iterator();
    while (pageIter.hasNext()) {
        PDPage page = pageIter.next();
        PDPage newPage = new PDPage((COSDictionary) cloner.cloneForNewDocument(page.getCOSDictionary()));
        newPage.setCropBox(page.findCropBox());
        newPage.setMediaBox(page.findMediaBox());
        newPage.setRotation(page.findRotation());
        destination.addPage(newPage);
    }
}

From source file:com.formkiq.core.service.generator.pdfbox.SigUtils.java

License:Apache License

/**
 * Get the access permissions granted for this document in the DocMDP
 * transform parameters dictionary. Details are described in the table
 * "Entries in the DocMDP transform parameters dictionary" in the PDF
 * specification./*from  w  ww .j  a  v a  2s . co m*/
 *
 * @param doc
 *            document.
 * @return the permission value. 0 means no DocMDP transform parameters
 *         dictionary exists. Other return values are 1, 2 or 3. 2 is also
 *         returned if the DocMDP transform parameters dictionary is found
 *         but did not contain a /P entry, or if the value is outside the
 *         valid range.
 */
public static int getMDPPermission(final PDDocument doc) {

    final int maxPerm = 3;
    COSBase base = doc.getDocumentCatalog().getCOSObject().getDictionaryObject(COSName.PERMS);
    if (base instanceof COSDictionary) {
        COSDictionary permsDict = (COSDictionary) base;
        base = permsDict.getDictionaryObject(COSName.DOCMDP);
        if (base instanceof COSDictionary) {
            COSDictionary signatureDict = (COSDictionary) base;
            base = signatureDict.getDictionaryObject("Reference");
            if (base instanceof COSArray) {
                COSArray refArray = (COSArray) base;
                for (int i = 0; i < refArray.size(); ++i) {
                    base = refArray.getObject(i);
                    if (base instanceof COSDictionary) {
                        COSDictionary sigRefDict = (COSDictionary) base;
                        if (COSName.DOCMDP.equals(sigRefDict.getDictionaryObject("TransformMethod"))) {
                            base = sigRefDict.getDictionaryObject("TransformParams");
                            if (base instanceof COSDictionary) {
                                COSDictionary dict = (COSDictionary) base;
                                int accessPermissions = dict.getInt(COSName.P, 2);
                                if (accessPermissions < 1 || accessPermissions > maxPerm) {
                                    accessPermissions = 2;
                                }
                                return accessPermissions;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}

From source file:com.itdhq.poc.ocrsign.ShowSignature.java

License:Apache License

private void showSignature(String[] args) throws IOException, CertificateException {
    if (args.length != 2) {
        usage();/* www  .  j ava 2s .  co m*/
    } else {
        String password = args[0];
        String infile = args[1];
        PDDocument document = null;
        try {
            document = PDDocument.load(new File(infile));
            if (!document.isEncrypted()) {
                System.err.println("Warning: Document is not encrypted.");
            }

            COSDictionary trailer = document.getDocument().getTrailer();
            COSDictionary root = (COSDictionary) trailer.getDictionaryObject(COSName.ROOT);
            COSDictionary acroForm = (COSDictionary) root.getDictionaryObject(COSName.ACRO_FORM);
            COSArray fields = (COSArray) acroForm.getDictionaryObject(COSName.FIELDS);
            for (int i = 0; i < fields.size(); i++) {
                COSDictionary field = (COSDictionary) fields.getObject(i);
                // FIXME
                /*
                COSName type = field.getCOSName( COSName.FT );
                if( COSName.SIG.equals( type ) )
                {
                COSDictionary cert = (COSDictionary)field.getDictionaryObject( COSName.V );
                if( cert != null )
                {
                    System.out.println( "Certificate found" );
                    System.out.println( "Name=" + cert.getDictionaryObject( COSName.NAME ) );
                    System.out.println( "Modified=" + cert.getDictionaryObject( COSName.M ) );
                    COSName subFilter = (COSName)cert.getDictionaryObject( COSName.SUB_FILTER );
                    if( subFilter != null )
                    {
                        if( subFilter.getName().equals( "adbe.x509.rsa_sha1" ) )
                        {
                            COSString certString = (COSString)cert.getDictionaryObject(
                                    COSName.getPDFName( "Cert" ) );
                            byte[] certData = certString.getBytes();
                            CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
                            ByteArrayInputStream certStream = new ByteArrayInputStream( certData );
                            Collection<? extends Certificate> certs = factory.generateCertificates( certStream );
                            System.out.println( "certs=" + certs );
                        }
                        else if( subFilter.getName().equals( "adbe.pkcs7.sha1" ) )
                        {
                            COSString certString = (COSString)cert.getDictionaryObject(
                                    COSName.CONTENTS );
                            byte[] certData = certString.getBytes();
                            CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
                            ByteArrayInputStream certStream = new ByteArrayInputStream( certData );
                            Collection<? extends Certificate> certs = factory.generateCertificates( certStream );
                            System.out.println( "certs=" + certs );
                        }
                        else
                        {
                            System.err.println( "Unknown certificate type:" + subFilter );
                        }
                    }
                    else
                    {
                        throw new IOException( "Missing subfilter for cert dictionary" );
                    }
                }
                else
                {
                    System.out.println( "Signature found, but no certificate" );
                }
                }
                */
            }
        } finally {
            if (document != null) {
                document.close();
            }
        }
    }
}

From source file:com.modemo.javase.signature.SigUtils.java

License:Apache License

/**
 * Get the access permissions granted for this document in the DocMDP transform parameters
 * dictionary. Details are described in the table "Entries in the DocMDP transform parameters
 * dictionary" in the PDF specification.
 *
 * @param doc document./*  www  .ja  va 2  s  .co m*/
 * @return the permission value. 0 means no DocMDP transform parameters dictionary exists. Other
 * return values are 1, 2 or 3. 2 is also returned if the DocMDP transform parameters dictionary
 * is found but did not contain a /P entry, or if the value is outside the valid range.
 */
public static int getMDPPermission(PDDocument doc) {
    COSBase base = doc.getDocumentCatalog().getCOSObject().getDictionaryObject(COSName.PERMS);
    if (base instanceof COSDictionary) {
        COSDictionary permsDict = (COSDictionary) base;
        base = permsDict.getDictionaryObject(COSName.DOCMDP);
        if (base instanceof COSDictionary) {
            COSDictionary signatureDict = (COSDictionary) base;
            base = signatureDict.getDictionaryObject("Reference");
            if (base instanceof COSArray) {
                COSArray refArray = (COSArray) base;
                for (int i = 0; i < refArray.size(); ++i) {
                    base = refArray.getObject(i);
                    if (base instanceof COSDictionary) {
                        COSDictionary sigRefDict = (COSDictionary) base;
                        if (COSName.DOCMDP.equals(sigRefDict.getDictionaryObject("TransformMethod"))) {
                            base = sigRefDict.getDictionaryObject("TransformParams");
                            if (base instanceof COSDictionary) {
                                COSDictionary transformDict = (COSDictionary) base;
                                int accessPermissions = transformDict.getInt(COSName.P, 2);
                                if (accessPermissions < 1 || accessPermissions > 3) {
                                    accessPermissions = 2;
                                }
                                return accessPermissions;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}

From source file:fixture.pdfboxeg.CreateSignatureBase.java

License:Apache License

/**
 * Get the access permissions granted for this document in the DocMDP transform parameters
 * dictionary. Details are described in the table "Entries in the DocMDP transform parameters
 * dictionary" in the PDF specification.
 *
 * @param doc document.//w ww .  j a  va 2s .c om
 * @return the permission value. 0 means no DocMDP transform parameters dictionary exists. Other
 * return values are 1, 2 or 3. 2 is also returned if the DocMDP transform parameters dictionary
 * is found but did not contain a /P entry, or if the value is outside the valid range.
 */
public int getMDPPermission(PDDocument doc) {
    COSBase base = doc.getDocumentCatalog().getCOSObject().getDictionaryObject(COSName.PERMS);
    if (base instanceof COSDictionary) {
        COSDictionary permsDict = (COSDictionary) base;
        base = permsDict.getDictionaryObject(COSName.DOCMDP);
        if (base instanceof COSDictionary) {
            COSDictionary signatureDict = (COSDictionary) base;
            base = signatureDict.getDictionaryObject("Reference");
            if (base instanceof COSArray) {
                COSArray refArray = (COSArray) base;
                for (int i = 0; i < refArray.size(); ++i) {
                    base = refArray.getObject(i);
                    if (base instanceof COSDictionary) {
                        COSDictionary sigRefDict = (COSDictionary) base;
                        if (COSName.DOCMDP.equals(sigRefDict.getDictionaryObject("TransformMethod"))) {
                            base = sigRefDict.getDictionaryObject("TransformParams");
                            if (base instanceof COSDictionary) {
                                COSDictionary transformDict = (COSDictionary) base;
                                int accessPermissions = transformDict.getInt(COSName.P, 2);
                                if (accessPermissions < 1 || accessPermissions > 3) {
                                    accessPermissions = 2;
                                }
                                return accessPermissions;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}

From source file:net.padaf.preflight.font.CompositeFontValidator.java

License:Apache License

/**
 * For a CIDFont the width array, there are two formats of width array :
 * <UL>//from  w  w w.  j a  va2  s . co m
 * <li>C [W1...Wn] : C is an integer specifying a starting CID value and the
 * array of n numbers specify widths for n consecutive CIDs.
 * <li>Cf Cl W : Defines the same width W for the range Cf to Cl
 * </UL>
 * This method gets a linked hash map of width where the key is a CID and the
 * value is the Width.
 * 
 * @return
 * @throws ValidationException
 */
protected LinkedHashMap<Integer, Integer> getWidthsArray() throws ValidationException {
    LinkedHashMap<Integer, Integer> widthsMap = new LinkedHashMap<Integer, Integer>();
    COSDocument cDoc = handler.getDocument().getDocument();
    COSBase cBase = this.cidFont.getItem(COSName.getPDFName("W"));
    COSArray wArr = COSUtils.getAsArray(cBase, cDoc);

    for (int i = 0; i < wArr.size();) {

        int firstCid = wArr.getInt(i);

        if (i + 1 >= wArr.size()) {
            throw new ValidationException("Invalid format of the W entry");
        }

        COSBase cb = wArr.getObject(i + 1);
        if (COSUtils.isArray(cb, cDoc)) {

            // ---- First Format
            COSArray seqWidths = COSUtils.getAsArray(cb, cDoc);
            widthsMap.put(firstCid, seqWidths.getInt(0));
            for (int jw = 1; jw < seqWidths.size(); jw++) {
                widthsMap.put((firstCid + jw), seqWidths.getInt(jw));
            }

            i = i + 2;

        } else {

            // ---- Second Format
            if (i + 2 >= wArr.size()) {
                throw new ValidationException("Invalid format of the W entry");
            }

            int lastCid = wArr.getInt(i + 1);
            int commonWidth = wArr.getInt(i + 2);
            for (int jw = firstCid; jw <= lastCid; ++jw) {
                widthsMap.put((firstCid + jw), commonWidth);
            }

            i = i + 3;

        }

    }

    return widthsMap;
}

From source file:org.apache.fop.render.pdf.pdfbox.FOPPDFSingleByteFont.java

License:Apache License

private Map<Integer, String> getCodeToName(Encoding encoding) {
    Map<Integer, String> codeToName = new HashMap<Integer, String>();
    if (encoding != null) {
        COSBase cos = null;//from   w w w  .j av a 2 s.  c  om
        if (!(encoding instanceof BuiltInEncoding)) {
            cos = encoding.getCOSObject();
        }
        if (cos instanceof COSDictionary) {
            COSDictionary enc = (COSDictionary) cos;
            COSName baseEncodingName = (COSName) enc.getDictionaryObject(COSName.BASE_ENCODING);
            if (baseEncodingName != null) {
                Encoding baseEncoding = Encoding.getInstance(baseEncodingName);
                codeToName.putAll(baseEncoding.getCodeToNameMap());
            }
            COSArray differences = (COSArray) enc.getDictionaryObject(COSName.DIFFERENCES);
            int currentIndex = -1;
            for (int i = 0; differences != null && i < differences.size(); i++) {
                COSBase next = differences.getObject(i);
                if (next instanceof COSNumber) {
                    currentIndex = ((COSNumber) next).intValue();
                } else if (next instanceof COSName) {
                    COSName name = (COSName) next;
                    codeToName.put(currentIndex++, name.getName());
                }
            }
        } else {
            return encoding.getCodeToNameMap();
        }
    }
    return codeToName;
}

From source file:org.apache.fop.render.pdf.pdfbox.PageParentTreeFinder.java

License:Apache License

private void traverseKids(COSBase kids, int position, List<COSArray> numList) {
    COSArray pageParentTree;/*w  w w.  j av  a  2 s. c  o  m*/
    if (!numList.isEmpty()) {
        return;
    }
    if (kids instanceof COSArray) {
        COSArray kidsArray = (COSArray) kids;
        for (COSBase kid : kidsArray) {
            COSObject kidCOSObj = (COSObject) kid;
            traverseKids(kidCOSObj, position, numList);
        }
    } else if (kids instanceof COSObject) {
        COSObject kidCOSObj = (COSObject) kids;
        if (kidCOSObj.getDictionaryObject(COSName.NUMS) == null) {
            traverseKids(kidCOSObj.getDictionaryObject(COSName.KIDS), position, numList);

        } else {
            if (kidCOSObj.getDictionaryObject(COSName.LIMITS) != null) {
                COSArray kidCOSArray = (COSArray) kidCOSObj.getDictionaryObject(COSName.LIMITS);
                int lowerLimit = ((COSInteger) kidCOSArray.get(0)).intValue();
                int upperLimit = ((COSInteger) kidCOSArray.get(1)).intValue();
                if (lowerLimit <= position && position <= upperLimit) {
                    COSArray nums = (COSArray) kidCOSObj.getDictionaryObject(COSName.NUMS);
                    pageParentTree = (COSArray) nums.getObject(((position - lowerLimit) * 2) + 1);
                    numList.add(pageParentTree);
                }
            } else {
                COSArray nums = (COSArray) kidCOSObj.getDictionaryObject(COSName.NUMS);
                numList.add(extractMarkedContentParents(nums, position));
            }
        }
    }
}

From source file:org.xmlcml.font.NonStandardFontManager.java

License:Apache License

private AMIFont lookupOrCreateFont(int level, COSDictionary dict) {
    /**//  ww w .  j av a 2s  .c o m
    Type = COSName{Font}
    Subtype = COSName{Type1}
    BaseFont = COSName{Times-Roman}
    Name = COSName{arXivStAmP}      
    LastChar = COSInt{32}
    Widths = COSArray{[COSInt{19}]}
    FirstChar = COSInt{32}
    FontMatrix = COSArray{[COSFloat{0.0121}, COSInt{0}, COSInt{0}, COSFloat{-0.0121}, COSInt{0}, COSInt{0}]}
    ToUnicode = COSDictionary{(COSName{Length}:COSInt{212}) (COSName{Filter}:COSName{FlateDecode}) }
    FontBBox = COSArray{[COSInt{0}, COSInt{0}, COSInt{1}, COSInt{1}]}
    Resources = COSDictionary{(COSName{ProcSet}:COSArray{[COSName{PDF}, COSName{ImageB}]}) }
    Encoding = COSDictionary{(COSName{Differences}:COSArray{[COSInt{32}, COSName{space}]}) (COSName{Type}:COSName{Encoding}) }
    CharProcs = COSDictionary{(COSName{space}:COSDictionary{(COSName{Length}:COSInt{67}) (COSName{Filter}:COSName{FlateDecode}) }) }*/

    AMIFont amiFont = null;
    String fontName = AMIFont.getFontName(dict);

    String typeS = null;
    amiFont = getAmiFontByFontName(fontName);
    if (amiFont == null) {
        // some confusion here between fontName and fontFamilyName
        amiFont = new AMIFont(fontName, null, typeS, dict);
        amiFont.setFontName(fontName);
        amiFontByFontNameMap.put(fontName, amiFont);

        String indent = "";
        for (int i = 0; i < level; i++) {
            indent += " ";
        }

        LOG.debug(String.format("%s****************** level %d font dict:", indent, level));

        level++;
        indent += "    ";

        for (COSName key : dict.keySet()) {
            String keyName = key.getName();
            Object object = dict.getDictionaryObject(key);
            LOG.debug(String.format("%s****************** %s = %s", indent, keyName, object));
        }

        COSArray array = (COSArray) dict.getDictionaryObject(COSName.DESCENDANT_FONTS);
        if (array != null) {
            LOG.debug(String.format("%s****************** descendant fonts (%d):", indent, array.size()));
            amiFont = lookupOrCreateFont(level, (COSDictionary) array.getObject(0));
        }
    }
    return amiFont;
}