public PDFFont makeFont()

in fop-core/src/main/java/org/apache/fop/pdf/PDFFactory.java [937:1153]


    public PDFFont makeFont(String fontname, String basefont,
                            String encoding, FontMetrics metrics,
                            FontDescriptor descriptor) {
        PDFFont preRegisteredfont = getDocument().findFont(fontname);
        if (preRegisteredfont != null) {
            return preRegisteredfont;
        }

        boolean forceToUnicode = true;

        if (descriptor == null) {
            //Usually Base 14 fonts
            PDFFont font = new PDFFont(fontname, FontType.TYPE1, basefont, encoding);
            getDocument().registerObject(font);
            if (forceToUnicode && !PDFEncoding.isPredefinedEncoding(encoding)) {
                SingleByteEncoding mapping;
                if (encoding != null) {
                    mapping = CodePointMapping.getMapping(encoding);
                } else {
                    //for Symbol and ZapfDingbats where encoding must be null in PDF
                    Typeface tf = (Typeface)metrics;
                    mapping = CodePointMapping.getMapping(tf.getEncodingName());
                }
                generateToUnicodeCmap(font, mapping);
            }
            return font;
        } else {
            FontType fonttype = metrics.getFontType();

            String fontPrefix = descriptor.isSubsetEmbedded() ? createSubsetFontPrefix() : "";

            String subsetFontName = fontPrefix + basefont;

            PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor, fontPrefix);

            PDFFont font = null;

            font = PDFFont.createFont(fontname, fonttype, subsetFontName, null);
            if (descriptor instanceof RefPDFFont) {
                font.setObjectNumber(((RefPDFFont)descriptor).getRef().getObjectNumber());
                font.setDocument(getDocument());
                getDocument().addObject(font);
            } else {
                getDocument().registerObject(font);
            }

            if ((fonttype == FontType.TYPE0 || fonttype == FontType.CIDTYPE0)) {
                font.setEncoding(encoding);
                CIDFont cidMetrics;
                if (metrics instanceof LazyFont) {
                    cidMetrics = (CIDFont)((LazyFont) metrics).getRealFont();
                } else {
                    cidMetrics = (CIDFont)metrics;
                }
                PDFCIDSystemInfo sysInfo = new PDFCIDSystemInfo(cidMetrics.getRegistry(),
                        cidMetrics.getOrdering(), cidMetrics.getSupplement());
                sysInfo.setDocument(document);
                assert pdfdesc instanceof PDFCIDFontDescriptor;
                PDFCIDFont cidFont = new PDFCIDFont(subsetFontName, cidMetrics.getCIDType(),
                        cidMetrics.getDefaultWidth(), getFontWidths(cidMetrics), sysInfo,
                        (PDFCIDFontDescriptor) pdfdesc);
                getDocument().registerObject(cidFont);

                PDFCMap cmap;
                if (cidMetrics instanceof MultiByteFont && ((MultiByteFont) cidMetrics).getCmapStream() != null) {
                    cmap = new PDFCMap("fop-ucs-H", null);
                    try {
                        cmap.setData(IOUtils.toByteArray(((MultiByteFont) cidMetrics).getCmapStream()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    cmap = new PDFToUnicodeCMap(cidMetrics.getCIDSet().getChars(), "fop-ucs-H",
                        new PDFCIDSystemInfo("Adobe", "Identity", 0), false, eventBroadcaster);
                }
                getDocument().registerObject(cmap);
                assert font instanceof PDFFontType0;
                ((PDFFontType0)font).setCMAP(cmap);
                ((PDFFontType0)font).setDescendantFonts(cidFont);
            } else if (fonttype == FontType.TYPE1C
                    && (metrics instanceof LazyFont || metrics instanceof MultiByteFont)) {
                handleType1CFont(pdfdesc, font, metrics, fontname, basefont, descriptor);
            } else {
                assert font instanceof PDFFontNonBase14;
                PDFFontNonBase14 nonBase14 = (PDFFontNonBase14)font;
                nonBase14.setDescriptor(pdfdesc);

                SingleByteFont singleByteFont;
                if (metrics instanceof LazyFont) {
                    singleByteFont = (SingleByteFont)((LazyFont)metrics).getRealFont();
                } else {
                    singleByteFont = (SingleByteFont)metrics;
                }

                int firstChar = 0;
                int lastChar = 0;
                boolean defaultChars = false;
                if (singleByteFont.getEmbeddingMode() == EmbeddingMode.SUBSET) {
                    Map<Integer, Integer> usedGlyphs = singleByteFont.getUsedGlyphs();
                    if (fonttype == FontType.TYPE1 && usedGlyphs.size() > 0) {
                        SortedSet<Integer> keys = new TreeSet<Integer>(usedGlyphs.keySet());
                        keys.remove(0);
                        if (keys.size() > 0) {
                            firstChar = keys.first();
                            lastChar = keys.last();
                            int[] newWidths = new int[(lastChar - firstChar) + 1];
                            for (int i = firstChar; i < lastChar + 1; i++) {
                                if (usedGlyphs.get(i) != null) {
                                    if (i - singleByteFont.getFirstChar() < metrics.getWidths().length) {
                                        newWidths[i - firstChar] = metrics.getWidths()[i
                                        - singleByteFont.getFirstChar()];
                                    } else {
                                        defaultChars = true;
                                        break;
                                    }
                                } else {
                                    newWidths[i - firstChar] = 0;
                                }
                            }
                            nonBase14.setWidthMetrics(firstChar,
                                    lastChar,
                                    new PDFArray(null, newWidths));
                        }
                    } else {
                        defaultChars = true;
                    }
                } else {
                    defaultChars = true;
                }

                if (defaultChars) {
                    firstChar = singleByteFont.getFirstChar();
                    lastChar = singleByteFont.getLastChar();
                    nonBase14.setWidthMetrics(firstChar,
                            lastChar,
                            new PDFArray(null, metrics.getWidths()));
                }

                //Handle encoding
                SingleByteEncoding mapping = singleByteFont.getEncoding();
                if (singleByteFont.isSymbolicFont()) {
                    //no encoding, use the font's encoding
                    if (forceToUnicode) {
                        generateToUnicodeCmap(nonBase14, mapping);
                    }
                } else if (PDFEncoding.isPredefinedEncoding(mapping.getName())) {
                    font.setEncoding(mapping.getName());
                    //No ToUnicode CMap necessary if PDF 1.4, chapter 5.9 (page 368) is to be
                    //believed.
                } else if (mapping.getName().equals("FOPPDFEncoding")) {
                    if (fonttype == FontType.TRUETYPE) {
                        font.setEncoding(encoding);
                    } else {
                        String[] charNameMap = mapping.getCharNameMap();
                        char[] intmap = mapping.getUnicodeCharMap();
                        PDFArray differences = new PDFArray();
                        int len = intmap.length;
                        if (charNameMap.length < len) {
                            len = charNameMap.length;
                        }
                        int last = Integer.MIN_VALUE;
                        for (int i = 0; i < len; i++) {
                            if (intmap[i] - 1 != last) {
                                differences.add(intmap[i]);
                            }
                            last = intmap[i];
                            differences.add(new PDFName(charNameMap[i]));
                        }
                        PDFEncoding pdfEncoding = new PDFEncoding(singleByteFont.getEncodingName());
                        getDocument().registerObject(pdfEncoding);
                        pdfEncoding.setDifferences(differences);
                        font.setEncoding(pdfEncoding);
                        if (mapping.getUnicodeCharMap() != null) {
                            generateToUnicodeCmap(nonBase14, mapping);
                        }
                    }
                } else {
                    Object pdfEncoding = createPDFEncoding(mapping,
                    singleByteFont.getFontName());
                    if (pdfEncoding instanceof PDFEncoding) {
                        font.setEncoding((PDFEncoding)pdfEncoding);
                    } else {
                        font.setEncoding((String)pdfEncoding);
                    }
                    if (forceToUnicode) {
                        generateToUnicodeCmap(nonBase14, mapping);
                    }
                }

                //Handle additional encodings (characters outside the primary encoding)
                if (singleByteFont.hasAdditionalEncodings()) {
                    for (int i = 0, c = singleByteFont.getAdditionalEncodingCount(); i < c; i++) {
                        SimpleSingleByteEncoding addEncoding
                            = singleByteFont.getAdditionalEncoding(i);
                        String name = fontname + "_" + (i + 1);
                        Object pdfenc = createPDFEncoding(addEncoding,
                                singleByteFont.getFontName());
                        PDFFontNonBase14 addFont = (PDFFontNonBase14)PDFFont.createFont(
                                name, fonttype,
                                basefont, pdfenc);
                        addFont.setDescriptor(pdfdesc);
                        addFont.setWidthMetrics(
                                addEncoding.getFirstChar(),
                                addEncoding.getLastChar(),
                                new PDFArray(null, singleByteFont.getAdditionalWidths(i)));
                        getDocument().registerObject(addFont);
                        getDocument().getResources().addFont(addFont);
                        if (forceToUnicode) {
                            generateToUnicodeCmap(addFont, addEncoding);
                        }
                    }
                }
            }

            return font;
        }
    }