Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guess font name and attribute from file nam is not correct, especially for CJK fonts. #6

Open
chunlinyao opened this issue Nov 15, 2019 · 5 comments

Comments

@chunlinyao
Copy link

CSSBoxPdf guess font file url by matching file name and font family name. It's not correct especially for CJK font. I suggest using FontMapper to get font.

Change PDFRender#setFont like this. It is still a POC.

    /**
     * Creates object describing font
     * 
     * @return the font object
     */
    private PDFont setFont(String fontFamily, boolean isItalic, boolean isBold)
    {
        COSDictionary dictionary = new COSDictionary();
        dictionary.setItem( COSName.TYPE, COSName.FONT_DESC );
        PDFontDescriptor desc = new PDFontDescriptor(dictionary);
        desc.setItalic(isItalic);
        desc.setFontWeight(isBold? 700: 400);
        desc.setFontFamily(fontFamily);
        FontMapping<TrueTypeFont> trueTypeFont = FontMappers.instance().getTrueTypeFont(fontFamily, desc);

        PDFont font = null;
        if (trueTypeFont != null) {
            try {
                font = PDType0Font.load(doc, trueTypeFont.getFont(), true);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return font;
    }
@chunlinyao
Copy link
Author

POC commit.

chunlinyao@3730044

@radkovo
Copy link
Owner

radkovo commented Nov 15, 2019

Thanks for submitting this, it look much better than the original solution (which was very old). I am really interested in including it in the project.

@radkovo
Copy link
Owner

radkovo commented Nov 18, 2019

Well, I did some more testing and it seems to me that this method is not able to find the bold and italic variants. E.g. for Arial it ends up with ArialMT in all cases independently on the isBold and isItalic arguments. I dived a bit into the getTrueTypeFont() code and it seems that descriptor is generally ignored for the common fonts and otherwise, the code is full of font name-based heuristics similarly to my original code. Or am I missing something?

@radkovo
Copy link
Owner

radkovo commented Nov 19, 2019

For your info, my current version that seems to work at least with the common fonts:

    private PDFont createFont(String fontFamily, boolean isItalic, boolean isBold)
    {
        //guess a postscript name
        String psname = fontFamily.replace(" ", "");
        if (isBold && isItalic) psname += ",BoldItalic";
        else if (isBold) psname += ",Bold";
        else if (isItalic) psname += ",Italic";
        //font descriptor is used only for finding fallback fonts when the mapping fails
        COSDictionary dictionary = new COSDictionary();
        dictionary.setItem(COSName.TYPE, COSName.FONT_DESC);
        PDFontDescriptor desc = new PDFontDescriptor(dictionary);
        desc.setItalic(isItalic);
        desc.setFontWeight(isBold ? 700 : 400);
        desc.setFontFamily(fontFamily);
        FontMapping<TrueTypeFont> trueTypeFont = FontMappers.instance().getTrueTypeFont(psname, desc);

        PDFont font = null;
        if (trueTypeFont != null) {
            try {
                font = PDType0Font.load(doc, trueTypeFont.getFont(), true);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return font;
    }

@chunlinyao
Copy link
Author

chunlinyao commented Dec 29, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants