private PriorityQueue getFontMatches()

in pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontMapperImpl.java [553:644]


    private PriorityQueue<FontMatch> getFontMatches(PDFontDescriptor fontDescriptor,
                                                           PDCIDSystemInfo cidSystemInfo)
    {
        PriorityQueue<FontMatch> queue = new PriorityQueue<>(20);
        
        for (FontInfo info : fontInfoByName.values())
        {
            // filter by CIDSystemInfo, if given
            if (cidSystemInfo != null && !isCharSetMatch(cidSystemInfo, info))
            {
                continue;
            }

            FontMatch match = new FontMatch(info);

            // Panose is the most reliable
            if (fontDescriptor.getPanose() != null && info.getPanose() != null)
            {
                PDPanoseClassification panose = fontDescriptor.getPanose().getPanose();
                if (panose.getFamilyKind() == info.getPanose().getFamilyKind())
                {
                    if (panose.getFamilyKind() == 0 && 
                        (info.getPostScriptName().toLowerCase().contains("barcode") ||
                         info.getPostScriptName().startsWith("Code")) && 
                        !probablyBarcodeFont(fontDescriptor))
                    {
                        // PDFBOX-4268: ignore barcode font if we aren't searching for one.
                        continue;
                    }
                    // serifs
                    if (panose.getSerifStyle() == info.getPanose().getSerifStyle())
                    {
                        // exact match
                        match.score += 2;
                    }
                    else if (panose.getSerifStyle() >= 2 && panose.getSerifStyle() <= 5 &&
                             info.getPanose().getSerifStyle() >= 2 &&
                             info.getPanose().getSerifStyle() <= 5)
                    {
                        // cove (serif)
                        match.score += 1;
                    }
                    else if (panose.getSerifStyle() >= 11 && panose.getSerifStyle() <= 13 &&
                             info.getPanose().getSerifStyle() >= 11 &&
                             info.getPanose().getSerifStyle() <= 13)
                    {
                        // sans-serif
                        match.score += 1;
                    }
                    else if (panose.getSerifStyle() != 0 && info.getPanose().getSerifStyle() != 0)
                    {
                        // mismatch
                        match.score -= 1;
                    }
                    
                    // weight
                    int weight = info.getPanose().getWeight();
                    int weightClass = info.getWeightClassAsPanose();
                    if (Math.abs(weight - weightClass) > 2)
                    {
                        // inconsistent data in system font, usWeightClass wins
                        weight = weightClass;
                    }
                    
                    if (panose.getWeight() == weight)
                    {
                        // exact match
                        match.score += 2;
                    }
                    else if (panose.getWeight() > 1 && weight > 1)
                    {
                        float dist = Math.abs(panose.getWeight() - weight);
                        match.score += 1 - dist * 0.5;
                    }
                    
                    // todo: italic
                    // ...
                }
            }
            else if (fontDescriptor.getFontWeight() > 0 && info.getWeightClass() > 0)
            {
                // usWeightClass is pretty reliable
                float dist = Math.abs(fontDescriptor.getFontWeight() - info.getWeightClass());
                match.score += 1 - (dist / 100) * 0.5;
            }
            // todo: italic
            // ...

            queue.add(match);
        }
        return queue;
    }