All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openhtmltopdf.pdfboxout.fontstore.MainFontStore Maven / Gradle / Ivy

Go to download

Openhtmltopdf is a CSS 2.1 renderer written in Java. This artifact supports PDF output with Apache PDF-BOX 2.

The newest version!
package com.openhtmltopdf.pdfboxout.fontstore;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.fontbox.ttf.TrueTypeCollection.TrueTypeFontProcessor;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;

import com.openhtmltopdf.css.constants.IdentValue;
import com.openhtmltopdf.extend.FSCacheEx;
import com.openhtmltopdf.extend.FSCacheValue;
import com.openhtmltopdf.extend.FSSupplier;
import com.openhtmltopdf.layout.SharedContext;
import com.openhtmltopdf.outputdevice.helper.FontFaceFontSupplier;
import com.openhtmltopdf.outputdevice.helper.FontFamily;
import com.openhtmltopdf.outputdevice.helper.FontResolverHelper;
import com.openhtmltopdf.pdfboxout.PDFontSupplier;
import com.openhtmltopdf.pdfboxout.PdfBoxFontResolver.FontDescription;

public class MainFontStore extends AbstractFontStore implements Closeable {
    private final Map> _fontFamilies = new HashMap<>();
    private final FSCacheEx _fontMetricsCache;
    private final PDDocument _doc;
    private final SharedContext _sharedContext;
    private final List _collectionsToClose = new ArrayList<>();

    public MainFontStore(
       SharedContext sharedContext,
       PDDocument doc, 
       FSCacheEx pdfMetricsCache) {

        this._sharedContext = sharedContext;
        this._doc = doc;
        this._fontMetricsCache = pdfMetricsCache;
    }

    @Override
    public void close() throws IOException {
        // Close all still open TrueTypeCollections
        for (TrueTypeCollection collection : _collectionsToClose) {
            FontUtil.tryClose(collection);
        }
        _collectionsToClose.clear();
    }

    /**
     * Add a font using a FontBox TrueTypeFont.
     */
    void addFont(TrueTypeFont trueTypeFont, String fontFamilyNameOverride,
                 Integer fontWeightOverride, IdentValue fontStyleOverride, boolean subset) throws IOException {

        PDFont font = PDType0Font.load(_doc, trueTypeFont, subset);

        addFontLazy(new PDFontSupplier(font), fontFamilyNameOverride, fontWeightOverride, fontStyleOverride, subset);
    }

    /**
     * Add a font with a lazy loaded PDFont
     */
    public void addFontLazy(FSSupplier font, String fontFamilyNameOverride, Integer fontWeightOverride, IdentValue fontStyleOverride, boolean subset) {
        FontFamily fontFamily = getFontFamily(fontFamilyNameOverride);
        FontDescription descr = new FontDescription(
                _doc,
                font,
                FontUtil.normalizeFontStyle(fontStyleOverride),
                FontUtil.normalizeFontWeight(fontWeightOverride),
                fontFamilyNameOverride,
                false,   // isFromFontFace
                subset,
                _fontMetricsCache);

        addFontToFamily(subset, fontFamily, descr);
    }

    /**
     * Add fonts using a FontBox TrueTypeCollection.
     */
    public void addFontCollection(TrueTypeCollection collection, final String fontFamilyNameOverride,
            final Integer fontWeightOverride, final IdentValue fontStyleOverride, final boolean subset)
            throws IOException {
        collection.processAllFonts(new TrueTypeFontProcessor() {
            @Override
            public void process(TrueTypeFont ttf) throws IOException {
                addFont(ttf, fontFamilyNameOverride, fontWeightOverride, fontStyleOverride, subset);
            }
        });
        _collectionsToClose.add(collection);
    }

    public void addFontFaceFont(String fontFamilyName, IdentValue fontWeight, IdentValue fontStyle, String uri, boolean subset) {
        FSSupplier fontSupplier = new FontFaceFontSupplier(_sharedContext, uri);
        FontFamily fontFamily = getFontFamily(fontFamilyName);

        FontDescription description = new FontDescription(
                    _doc,
                    fontSupplier,
                    FontUtil.normalizeFontWeight(fontWeight),
                    FontUtil.normalizeFontStyle(fontStyle),
                    fontFamilyName,
                    true,  // isFromFontFace
                    subset,
                    _fontMetricsCache);

        addFontToFamily(subset, fontFamily, description);
    }

    public void addFont(
            FSSupplier supplier,
            String fontFamilyNameOverride,
            Integer fontWeightOverride,
            IdentValue fontStyleOverride,
            boolean subset) {

        FontFamily fontFamily = getFontFamily(fontFamilyNameOverride);

        FontDescription descr = new FontDescription(
                _doc,
                supplier,
                FontUtil.normalizeFontWeight(fontWeightOverride),
                FontUtil.normalizeFontStyle(fontStyleOverride),
                fontFamilyNameOverride,
                false, // isFromFontFace
                subset,
                _fontMetricsCache);

        addFontToFamily(subset, fontFamily, descr);
    }

    public void addFont(
            PDFontSupplier supplier,
            String fontFamilyNameOverride,
            Integer fontWeightOverride,
            IdentValue fontStyleOverride,
            boolean subset) {

        // would have prefered to used FSSupplier but sadly that would give us an error
        // because the type-ereasure clashes with addFont(FSSupplier ...)
        FontFamily fontFamily = getFontFamily(fontFamilyNameOverride);

        FontDescription descr = new FontDescription(
                _doc,
                supplier,
                FontUtil.normalizeFontStyle(fontStyleOverride),
                FontUtil.normalizeFontWeight(fontWeightOverride),
                fontFamilyNameOverride,
                false, // isFromFontFace
                subset,
                _fontMetricsCache);

        addFontToFamily(subset, fontFamily, descr);
    }

    @Override
    public FontDescription resolveFont(
            SharedContext ctx, String fontFamily, float size, IdentValue weight, IdentValue style, IdentValue variant) {

        String normalizedFontFamily = FontUtil.normalizeFontFamily(fontFamily);
        FontFamily family = _fontFamilies.get(normalizedFontFamily);

        if (family != null) {
            return family.match(FontResolverHelper.convertWeightToInt(weight), style);
        }

        return null;
    }

    private void addFontToFamily(boolean subset, FontFamily fontFamily, FontDescription descr) {
        if (!subset) {
            if (descr.realizeFont()) {
                fontFamily.addFontDescription(descr);
            }
        } else {
            fontFamily.addFontDescription(descr);
        }
    }

    private FontFamily getFontFamily(String fontFamilyName) {
        return _fontFamilies.computeIfAbsent(fontFamilyName, name -> new FontFamily<>(fontFamilyName));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy