/* * Copyright 2004 The Apache Software Foundation. * * Licensed 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$ */ package org.apache.fop.fonts; // Java import java.util.Map; /** * The FontInfo 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 { /** Map containing fonts that have been used */ private Map usedFonts; /** look up a font-triplet to find a font-name */ private Map triplets; /** look up a font-name to get a font (that implements FontMetrics at least) */ private Map fonts; /** * Main constructor */ public FontInfo() { this.triplets = new java.util.HashMap(); this.fonts = new java.util.HashMap(); this.usedFonts = new java.util.HashMap(); } /** * Checks if the font setup is valid (At least the ultimate fallback font * must be registered.) * @return True if valid */ public boolean isSetupValid() { return triplets.containsKey(Font.DEFAULT_FONT); } /** * Adds a new font triplet. * @param name internal key * @param family font family name * @param style font style (normal, italic, oblique...) * @param weight font weight */ public void addFontProperties(String name, String family, String style, int weight) { /* * add the given family, style and weight as a lookup for the font * with the given name */ String key = createFontKey(family, style, weight); this.triplets.put(key, name); } /** * Adds font metrics for a specific font. * @param name internal key * @param metrics metrics to register */ public void addMetrics(String name, FontMetrics metrics) { // add the given metrics as a font with the given name this.fonts.put(name, metrics); } /** * 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. * @param family font family * @param style font style * @param weight font weight * @return internal key */ public String fontLookup(String family, String style, int weight) { String key; // first try given parameters key = createFontKey(family, style, weight); String f = (String)triplets.get(key); if (f == null) { // then adjust weight, favouring normal or bold f = findAdjustWeight(family, style, weight); // then try any family with orig weight if (f == null) { key = createFontKey("any", style, weight); f = (String)triplets.get(key); } // then try any family with adjusted weight if (f == null) { f = findAdjustWeight(family, style, weight); } // then use default if (f == null) { f = (String)triplets.get(Font.DEFAULT_FONT); } } usedFonts.put(f, fonts.get(f)); return f; } /** * Find a font with a given family and style by trying * different font weights according to the spec. * @param family font family * @param style font style * @param weight font weight * @return internal key */ public String findAdjustWeight(String family, String style, int weight) { String key; String f = null; int newWeight = weight; if (newWeight < 400) { while (f == null && newWeight > 0) { newWeight -= 100; key = createFontKey(family, style, newWeight); f = (String)triplets.get(key); } } else if (newWeight == 500) { key = createFontKey(family, style, 400); f = (String)triplets.get(key); } else if (newWeight > 500) { while (f == null && newWeight < 1000) { newWeight += 100; key = createFontKey(family, style, newWeight); f = (String)triplets.get(key); } newWeight = weight; while (f == null && newWeight > 400) { newWeight -= 100; key = createFontKey(family, style, newWeight); f = (String)triplets.get(key); } } if (f == null) { key = createFontKey(family, style, 400); f = (String)triplets.get(key); } return f; } /** * Determines if a particular font is available. * @param family font family * @param style font style * @param weight font weight * @return True if available */ public boolean hasFont(String family, String style, int weight) { String key = createFontKey(family, style, weight); return this.triplets.containsKey(key); } /** * Creates a key from the given strings. * @param family font family * @param style font style * @param weight font weight * @return internal key */ public static String createFontKey(String family, String style, int weight) { return family + "," + style + "," + weight; } /** * Gets a Map of all registred fonts. * @return a read-only Map with font key/FontMetrics pairs */ public Map getFonts() { return java.util.Collections.unmodifiableMap(this.fonts); } /** * 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. * @return a read-only Map with font key/FontMetrics pairs */ public Map getUsedFonts() { return this.usedFonts; } /** * Returns the FontMetrics for a particular font * @param fontName internal key * @return font metrics */ public FontMetrics getMetricsFor(String fontName) { usedFonts.put(fontName, fonts.get(fontName)); return (FontMetrics)fonts.get(fontName); } }