Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* NOTICE: This file has been changed by Plutext Pty Ltd for use in docx4j.
   * The package name has been changed; there may also be other changes.
   * 
   * This notice is included to meet the condition in clause 4(b) of the License. 
   */
  
   /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 /* $Id: FontInfo.java 721430 2008-11-28 11:13:12Z acumiskey $ */
 
 package org.docx4j.fonts.fop.fonts;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
The FontInfo holds font information for the layout and rendering of a fo document. This stores the list of available fonts that are setup by the renderer. The font name can be retrieved for the family style and weight.
Currently font supported font-variant small-caps is not implemented.
 
 public class FontInfo {

    
logging instance
 
     protected static Logger log = LoggerFactory.getLogger(FontInfo.class);

    
Map containing fonts that have been used
 
     private Map/*<String,FontMetrics>*/ usedFonts = null//(String = font key)
 
    
look up a font-triplet to find a font-name
 
     private Map/*<FontTriplet,String>*/ triplets = null//(String = font key)
 
    
look up a font-triplet to find its priority (only used inside addFontProperties())
 
     private Map/*<FontTriplet,Integer>*/ tripletPriorities = null//Map<FontTriplet,Integer>
 
    
look up a font-name to get a font (that implements FontMetrics at least)
 
     private Map/*<String,FontMetrics>*/ fonts = null//(String = font key)
 
    
a collection of missing fonts; used to make sure the user gets a warning for a missing font only once (not every time the font is used)
 
     private Set/*<FontTriplet>*/ loggedFontKeys = null;

    
Cache for Font instances.
 
     private Map/*<FontTriplet, Map>*/ fontInstanceCache = null;

    
Event listener for font events
 
     private FontEventListener eventListener = null;

    
Main constructor
 
     public FontInfo() {
         this. = new java.util.HashMap/*<FontTriplet, String>*/();
         this. = new java.util.HashMap/*<FontTriplet, Integer>*/();
         this. = new java.util.HashMap/*<String, FontMetrics>*/();
         this. = new java.util.HashMap/*<String,FontMetrics>*/();
     }

    
Sets the font event listener that can be used to receive events about particular events in this class.

Parameters:
listener the font event listener
 
     public void setEventListener(FontEventListener listener) {
         this. = listener;
     }

    
Checks if the font setup is valid (At least the ultimate fallback font must be registered.)

Returns:
True if valid
    public boolean isSetupValid() {
        //We're only called when font setup is done:
         = null// candidate for garbage collection
        return .containsKey(.);
    }

    
Adds a new font triplet.

Parameters:
name internal key
family font family name
style font style (normal, italic, oblique...)
weight font weight
    public void addFontProperties(String nameString familyString styleint weight) {
        addFontProperties(namecreateFontKey(familystyleweight));
    }

    
Adds a series of new font triplets given an array of font family names.

Parameters:
name internal key
families an array of font family names
style font style (normal, italic, oblique...)
weight font weight
    public void addFontProperties(String nameString[] familiesString styleint weight) {
        for (int i = 0; i < families.lengthi++) {
            addFontProperties(namefamilies[i], styleweight);
        }
    }

    
Adds a new font triplet.

Parameters:
internalFontKey internal font key
triplet the font triplet to associate with the internal key
    public void addFontProperties(String internalFontKeyFontTriplet triplet) {
        /*
         * add the given family, style and weight as a lookup for the font
         * with the given name
         */
        if (.isDebugEnabled()) {
            .debug("Registering: " + triplet + " under " + internalFontKey);
        }
        String oldName = (String).get(triplet);
        int newPriority = triplet.getPriority();
        if (oldName != null) {
            int oldPriority = ((Integer).get(triplet)).intValue();
            if (oldPriority < newPriority) {
                logDuplicateFont(tripletfalseoldNameoldPriority,
                            internalFontKeynewPriority);
                return;
            } else {
                logDuplicateFont(triplettrueoldNameoldPriority,
                            internalFontKeynewPriority);
            }
        }
        this..put(tripletinternalFontKey);
        this..put(tripletnew Integer(newPriority));
    }

    
Logger warning about duplicate font triplets.

Parameters:
triplet the duplicate font triplet
replacing true iff the new font will replace the old one
oldKey the old internal font name
oldPriority the priority of the existing font mapping
newKey the new internal font name
newPriority the priority of the duplicate font mapping
    private void logDuplicateFont(FontTriplet tripletboolean replacing,
                                  String oldKeyint oldPriority,
                                  String newKeyint newPriority) {
        if (.isDebugEnabled()) {
            .debug(triplet
                    + (replacing ? ": Replacing " : ": Not replacing ")
                    + ((FontMetrics).get(.get(triplet))).getFullName()
                    + " (priority=" + oldPriority + ") by "
                    + ((FontMetrics).get(newKey)).getFullName()
                    + " (priority=" + newPriority + ")");
        }
    }

    
Adds font metrics for a specific font.

Parameters:
internalFontKey internal key
metrics metrics to register
    public void addMetrics(String internalFontKeyFontMetrics metrics) {
        // add the given metrics as a font with the given name
        if (metrics instanceof Typeface) {
            ((Typeface)metrics).setEventListener(this.);
        }
        this..put(internalFontKeymetrics);
    }

    
Lookup a font.
Locate the font name for a given family, style and weight. The font name can then be used as a key as it is unique for the associated document. This also adds the font to the list of used fonts.

Parameters:
family font family
style font style
weight font weight
substitutable true if the font may be substituted with the default font if not found
Returns:
internal font triplet key
    private FontTriplet fontLookup(String familyString style,
                             int weightboolean substitutable) {
        if (.isTraceEnabled()) {
            .trace("Font lookup: " + family + " " + style + " " + weight
                    + (substitutable ? " substitutable" : ""));
        }
        FontTriplet startKey = createFontKey(familystyleweight);
        FontTriplet fontTriplet = startKey;
        // first try given parameters
        String internalFontKey = getInternalFontKey(fontTriplet);
        if (internalFontKey == null) {
            fontTriplet = fuzzyFontLookup(familystyleweightstartKeysubstitutable);
        }
        if (fontTriplet != null) {
            if (fontTriplet != startKey) {
                notifyFontReplacement(startKeyfontTriplet);
            }
            return fontTriplet;
        } else {
            return null;
        }
    }
    private FontTriplet fuzzyFontLookup(String familyString style,
            int weightFontTriplet startKeyboolean substitutable) {
        FontTriplet key;
        String internalFontKey = null;
        if (!family.equals(startKey.getName())) {
            key = createFontKey(familystyleweight);
            internalFontKey = getInternalFontKey(key);
            if (internalFontKey != null) {
                return key;
            }
        }
        // adjust weight, favouring normal or bold
        key = findAdjustWeight(familystyleweight);
        if (key != null) {
            internalFontKey = getInternalFontKey(key);
        }
        // return null if not found and not substitutable
        if (!substitutable && internalFontKey == null) {
            return null;
        }
        // only if the font may be substituted
        // fallback 1: try the same font-family and weight with default style
        if (internalFontKey == null && style != .) {
            key = createFontKey(family.weight);
            internalFontKey = getInternalFontKey(key);
        }
        if (internalFontKey == null && weight != .) {
            int diffWeight = (. - weight) / 100;
            int direction = diffWeight > 0 ? 1 : -1;
            int tryWeight = weight;
            while (tryWeight != .) {
                tryWeight += 100 * direction;
                key = createFontKey(familystyleweight);
                internalFontKey = getInternalFontKey(key);
                if (internalFontKey == null) {
                    key = createFontKey(family.weight);
                    internalFontKey = getInternalFontKey(key);
                }
                if (internalFontKey != null) {
                    break;
                }
            }
        }
        // fallback 2: try the same font-family with default style and weight
        /* obsolete: replaced by the loop above
        if (internalFontKey == null) {
            key = createFontKey(family, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
            internalFontKey = getInternalFontKey(key);
        }*/
        // fallback 3: try any family with original style/weight
        if (internalFontKey == null) {
            return fuzzyFontLookup("any"styleweightstartKeyfalse);
        }
        // last resort: use default
        if (key == null && internalFontKey == null) {
            key = .;
            internalFontKey = getInternalFontKey(key);
        }
        if (internalFontKey != null) {
            return key;
        } else {
            return null;
        }
    }

    
Tells this class that the font with the given internal name has been used.

Parameters:
internalName the internal font name (F1, F2 etc.)
    public void useFont(String internalName) {
        .put(internalName.get(internalName));
    }
    private Map/*<FontTriplet,Map<Integer,Font>>*/ getFontInstanceCache() {
        if ( == null) {
             = new java.util.HashMap/*<FontTriplet, Map<Integer,Font>>*/();
        }
        return ;
    }

    
Retrieves a (possibly cached) Font instance based on a FontTriplet and a font size.

Parameters:
triplet the font triplet designating the requested font
fontSize the font size
Returns:
the requested Font instance
    public Font getFontInstance(FontTriplet tripletint fontSize) {
        Map/*<Integer,Font>*/ sizes
            = (Map/*<Integer,Font>*/)getFontInstanceCache().get(triplet);
        if (sizes == null) {
            sizes = new java.util.HashMap/*<Integer,Font>*/();
            getFontInstanceCache().put(tripletsizes);
        }
        Integer size = new Integer(fontSize);
        Font font = (Font)sizes.get(size);
        if (font == null) {
            String fontKey = getInternalFontKey(triplet);
            useFont(fontKey);
            FontMetrics metrics = getMetricsFor(fontKey);
            font = new Font(fontKeytripletmetricsfontSize);
            sizes.put(sizefont);
        }
        return font;
    }
    private List/*<FontTriplet>*/ getTripletsForName(String fontName) {
        List/*<FontTriplet>*/ matchedTriplets = new java.util.ArrayList/*<FontTriplet>*/();
        Iterator it = .keySet().iterator();
        while (it.hasNext()) {
            FontTriplet triplet = (FontTriplet)it.next();
            String tripletName = triplet.getName();
            if (tripletName.toLowerCase().equals(fontName.toLowerCase())) {
                matchedTriplets.add(triplet);
            }
        }
        return matchedTriplets;
    }

    
Returns a suitable internal font given an AWT Font instance.

Parameters:
awtFont the AWT font
Returns:
a best matching internal Font
    public Font getFontInstanceForAWTFont(java.awt.Font awtFont) {
        String awtFontName = awtFont.getName();
        String awtFontFamily = awtFont.getFamily();
        String awtFontStyle = awtFont.isItalic() ? . : .;
        int awtFontWeight = awtFont.isBold() ? . : .;
        FontTriplet matchedTriplet = null;
        List/*<FontTriplet>*/ triplets = getTripletsForName(awtFontName);
        if (!triplets.isEmpty()) {
            Iterator it = triplets.iterator();
            while (it.hasNext()) {
                FontTriplet triplet = (FontTriplet)it.next();
                boolean styleMatched = triplet.getStyle().equals(awtFontStyle);
                boolean weightMatched = triplet.getWeight() == awtFontWeight;
                if (styleMatched && weightMatched) {
                    matchedTriplet = triplet;
                    break;
                }
            }
        }
        // not matched on font name so do a lookup using family
        if (matchedTriplet == null) {
            if (awtFontFamily.equals("sanserif")) {
                awtFontFamily = "sans-serif";
            }
            matchedTriplet = fontLookup(awtFontFamilyawtFontStyleawtFontWeight);
        }
        int fontSize = Math.round(awtFont.getSize2D() * 1000);
        return getFontInstance(matchedTripletfontSize);
    }

    
Lookup a font.
Locate the font name for a given family, style and weight. The font name can then be used as a key as it is unique for the associated document. This also adds the font to the list of used fonts.

Parameters:
family font family
style font style
weight font weight
Returns:
the font triplet of the font chosen
    public FontTriplet fontLookup(String familyString style,
                             int weight) {
        return fontLookup(familystyleweighttrue);
    }
    private List/*<FontTriplet>*/ fontLookup(String[] familiesString style,
            int weightboolean substitutable) {
        List/*<FontTriplet>*/ matchingTriplets = new java.util.ArrayList/*<FontTriplet>*/();
        FontTriplet triplet = null;
        for (int i = 0; i < families.lengthi++) {
            triplet = fontLookup(families[i], styleweightsubstitutable);
            if (triplet != null) {
                matchingTriplets.add(triplet);
            }
        }
        return matchingTriplets;
    }

    
Looks up a set of fonts.
Locate the font name(s) for the given families, style and weight. The font name(s) can then be used as a key as they are unique for the associated document. This also adds the fonts to the list of used fonts.

Parameters:
families font families (priority list)
style font style
weight font weight
Returns:
the set of font triplets of all supported and chosen font-families in the specified style and weight.
    public FontTriplet[] fontLookup(String[] familiesString style,
                             int weight) {
        if (families.length == 0) {
            throw new IllegalArgumentException("Specify at least one font family");
        }
        // try matching without substitutions
        List/*<FontTriplet>*/ matchedTriplets = fontLookup(familiesstyleweightfalse);
        // if there are no matching font triplets found try with substitutions
        if (matchedTriplets.size() == 0) {
            matchedTriplets = fontLookup(familiesstyleweighttrue);
        }
        // no matching font triplets found!
        if (matchedTriplets.size() == 0) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0, c = families.lengthi < ci++) {
                if (i > 0) {
                    sb.append(", ");
                }
                sb.append(families[i]);
            }
            throw new IllegalStateException(
                        "fontLookup must return an array with at least one "
                        + "FontTriplet on the last call. Lookup: " + sb.toString());
        }
        FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
        matchedTriplets.toArray(fontTriplets);
        // found some matching fonts so return them
        return fontTriplets;
    }
    private Set/*<FontTriplet>*/ getLoggedFontKeys() {
        if ( == null) {
             = new java.util.HashSet/*<FontTriplet>*/();
        }
        return ;
    }
    private void notifyFontReplacement(FontTriplet replacedKeyFontTriplet newKey) {
        if (!getLoggedFontKeys().contains(replacedKey)) {
            getLoggedFontKeys().add(replacedKey);
            if (this. != null) {
                this..fontSubstituted(thisreplacedKeynewKey);
            } else {
                .warn("Font '" + replacedKey + "' not found. "
                        + "Substituting with '" + newKey + "'.");
            }
        }
    }

    
Find a font with a given family and style by trying different font weights according to the spec.

Parameters:
family font family
style font style
weight font weight
Returns:
internal key
    public FontTriplet findAdjustWeight(String familyString style,
                             int weight) {
        FontTriplet key = null;
        String f = null;
        int newWeight = weight;
        if (newWeight <= 400) {
            while (f == null && newWeight > 100) {
                newWeight -= 100;
                key = createFontKey(familystylenewWeight);
                f = getInternalFontKey(key);
            }
            newWeight = weight;
            while (f == null && newWeight < 400) {
                newWeight += 100;
                key = createFontKey(familystylenewWeight);
                f = getInternalFontKey(key);
            }
        } else if (newWeight == 500) {
            key = createFontKey(familystyle, 400);
            f = getInternalFontKey(key);
        } else if (newWeight > 500) {
            while (f == null && newWeight < 1000) {
                newWeight += 100;
                key = createFontKey(familystylenewWeight);
                f = getInternalFontKey(key);
            }
            newWeight = weight;
            while (f == null && newWeight > 400) {
                newWeight -= 100;
                key = createFontKey(familystylenewWeight);
                f = getInternalFontKey(key);
            }
        }
        if (f == null && weight != 400) {
            key = createFontKey(familystyle, 400);
            f = getInternalFontKey(key);
        }
        if (f != null) {
            return key;
        } else {
            return null;
        }
    }

    
Determines if a particular font is available.

Parameters:
family font family
style font style
weight font weight
Returns:
True if available
    public boolean hasFont(String familyString styleint weight) {
        FontTriplet key = createFontKey(familystyleweight);
        return this..containsKey(key);
    }

    
Returns the internal font key (F1, F2, F3 etc.) for a given triplet.

Parameters:
triplet the font triplet
Returns:
the associated internal key or null, if not found
    public String getInternalFontKey(FontTriplet triplet) {
        return (String).get(triplet);
    }

    
Creates a key from the given strings.

Parameters:
family font family
style font style
weight font weight
Returns:
internal key
    public static FontTriplet createFontKey(String familyString style,
                                       int weight) {
        return new FontTriplet(familystyleweight);
    }

    
Gets a Map of all registered fonts.

Returns:
a read-only Map with font key/FontMetrics pairs
    public Map/*<String,FontMetrics>*/ getFonts() {
        return java.util.Collections.unmodifiableMap(this.);
    }

    
Gets a Map of all registered font triplets.

Returns:
a Map with FontTriplet/font key pairs
    public Map/*<FontTriplet,String>*/ getFontTriplets() {
        return this.;
    }

    
This is used by the renderers to retrieve all the fonts used in the document. This is for embedded font or creating a list of used fonts.

Returns:
a read-only Map with font key/FontMetrics pairs
    public Map/*<String,FontMetrics>*/ getUsedFonts() {
        return this.;
    }

    
Returns the FontMetrics for a particular font

Parameters:
fontName internal key
Returns:
font metrics
    public FontMetrics getMetricsFor(String fontName) {
        FontMetrics metrics = (FontMetrics).get(fontName);
        .put(fontNamemetrics);
        return metrics;
    }

    
Returns all font triplet matching the given font name.

Parameters:
fontName The font name we are looking for
Returns:
A list of matching font triplets
    public List/*<FontTriplet>*/ getTripletsFor(String fontName) {
        List/*<FontTriplet>*/ foundTriplets = new java.util.ArrayList();
        for (Iterator iter = .entrySet().iterator(); iter.hasNext();) {
            Map.Entry tripletEntry = (Map.Entryiter.next();
            if (fontName.equals((tripletEntry.getValue()))) {
                foundTriplets.add(tripletEntry.getKey());
            }
        }
        return foundTriplets;
    }

    
Returns the first triplet matching the given font name. As there may be multiple triplets matching the font name the result set is sorted first to guarantee consistent results.

Parameters:
fontName The font name we are looking for
Returns:
The first triplet for the given font name
    public FontTriplet getTripletFor(String fontName) {
        List/*<FontTriplet>*/ foundTriplets = getTripletsFor(fontName);
        if (foundTriplets.size() > 0) {
            Collections.sort(foundTriplets);
            return (FontTriplet)foundTriplets.get(0);
        }
        return null;
    }

    
Returns the font style for a particular font. There may be multiple font styles matching this font. Only the first found is returned. Searching is done on a sorted list to guarantee consistent results.

Parameters:
fontName internal key
Returns:
font style
    public String getFontStyleFor(String fontName) {
        FontTriplet triplet = getTripletFor(fontName);
        if (triplet != null) {
            return triplet.getStyle();
        } else {
            return "";
        }
    }

    
Returns the font weight for a particular font. There may be multiple font weights matching this font. Only the first found is returned. Searching is done on a sorted list to guarantee consistent results.

Parameters:
fontName internal key
Returns:
font weight
    public int getFontWeightFor(String fontName) {
        FontTriplet triplet = getTripletFor(fontName);
        if (triplet != null) {
            return triplet.getWeight();
        } else {
            return 0;
        }
    }

    
Diagnostic method for logging all registered fonts to System.out.
    public void dumpAllTripletsToSystemOut() {
        ..print(toString());
    }

    
    public String toString() {
        Collection entries = new java.util.TreeSet();
        Iterator iter = this..keySet().iterator();
        while (iter.hasNext()) {
            FontTriplet triplet = (FontTriplet)iter.next();
            String key = getInternalFontKey(triplet);
            FontMetrics metrics = getMetricsFor(key);
            entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName() + "\n");
        }
        StringBuffer stringBuffer = new StringBuffer();
        for (iter = entries.iterator(); iter.hasNext();) {
            stringBuffer.append(iter.next());
        }
        return stringBuffer.toString();
    }
New to GrepCode? Check out our FAQ X