Class BestMatchingMapper

java.lang.Object
org.docx4j.fonts.Mapper
org.docx4j.fonts.BestMatchingMapper

public class BestMatchingMapper extends Mapper
This mapper uses Panose to guess the physical font which is a closest fit for the font used in the document. It is most likely to be suitable on Linux or OSX systems which don't have Microsoft's fonts installed.
  • Field Details

    • log

      protected static org.slf4j.Logger log
    • msFontsFilenames

      private static final HashMap<String,MicrosoftFonts.Font> msFontsFilenames
    • explicitSubstitutionsMap

      private static final Map<String,FontSubstitutions.Replace> explicitSubstitutionsMap
      The substitutions listed in FontSubstitutions.xml Will be used only if there is no panose match.
    • physicalFontsByKey

      private static final Map<String,PhysicalFont> physicalFontsByKey
      Physical fonts remapped using the short key convention in FontSubstitutions.xml; For purpose, see comments below.
    • lastSeenNumberOfPhysicalFonts

      int lastSeenNumberOfPhysicalFonts
    • MATCH_THRESHOLD

      public static final int MATCH_THRESHOLD
      Max difference for it to be considered an acceptable match. Note that this value will depend on the weights in the difference function.
      See Also:
    • MATCH_THRESHOLD_INTRA_FAMILY

      private static final int MATCH_THRESHOLD_INTRA_FAMILY
      See Also:
  • Constructor Details

    • BestMatchingMapper

      public BestMatchingMapper()
  • Method Details

    • getMsFontsFilenames

      public static final Map<String,MicrosoftFonts.Font> getMsFontsFilenames()
    • setupMicrosoftFontFilenames

      private static final void setupMicrosoftFontFilenames() throws Exception
      Get Microsoft fonts We need these: 1. On Microsoft platform, to embed in PDF output 2. docx4all - all platforms - to populate font dropdown list
      Throws:
      Exception
    • generateKeysForPhysicalFonts

      private static void generateKeysForPhysicalFonts()
    • generateFontKey

      private static String generateFontKey(String fontName)
    • getPhysicalFontByKey

      private static PhysicalFont getPhysicalFontByKey(String key)
    • setupExplicitSubstitutionsMap

      private static final void setupExplicitSubstitutionsMap() throws Exception
      Get candidate substitutions On a non-MS platform, we need these for two things: 1. to embed this font in the PDF output, in place of MS font 2. in docx4all, use in editor but it will only be used if there is no panose match. Issues with FontSubstitutions.xml, as noted and addressed by Jeromy Evans http://www.docx4java.org/forums/docx-java-f6/bestmatchingmapper-bugs-handling-explicit-substitutions-t940.html (1) FontSubstutitions.xml uses the lowercase whitespace and punctuation removed name of the font. If the document contains "Times New Roman" it is not matched to the equivalent replace element for "timesnewroman". Similarly "Arial" is not matched to "arial". (2) When matched, the method searching PhysicalFonts for the substitution font also uses the short key, not the proper name used by PhysicalFonts. For example, if matching "arial" to a substitute it tries to find "freesans" in PhysicalFont's map instead of "Free Sans". (3) On the system tested, the SubsFonts value is inclusive of the leading whitespace (eg in the line above, the first token is "\n\t\tarial' instead of "arial" (seems odd that whitespace is included after unmarshalling). This means the first substitution always fails to match a font. As, by convention, the first token is usually the name of the font, this effectively means on systems where msttcorefonts are installed, the BestMatchingMapper fails to match the exact font. ie. it can't match "arial" to "arial" because the substitution is named "\n\t\tarial".
      Throws:
      Exception
    • populateFontMappings

      public void populateFontMappings(Set<String> documentFontNames, Fonts wmlFonts) throws Exception
      Populate the fontMappings object. We make an entry for each of the documentFontNames.
      Specified by:
      populateFontMappings in class Mapper
      Parameters:
      documentFontNames - - the fonts used in the document
      wmlFonts - - the content model for the fonts part
      Throws:
      Exception
    • getAssociatedPhysicalFont

      private PhysicalFont getAssociatedPhysicalFont(String documentFontName, String orignalKey, Panose soughtPanose)
      Parameters:
      fm -
      soughtPanose -
    • findClosestPanoseMatch

      private String findClosestPanoseMatch(String documentFontName, Panose documentFontPanose, Map<String,PhysicalFont> physicalFontSpace, int matchThreshold)
      Logic to search panose space for closest matching physical font file. Returns key of matching font in physicalFontMap.
    • main

      public static void main(String[] args) throws Exception
      Throws:
      Exception
    • panoseDebugReportOnPhysicalFonts

      private static void panoseDebugReportOnPhysicalFonts(Map<String,PhysicalFont> physicalFontMap)