]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
As announced, I brought FontTriplet to more life by making it Serializable and using...
authorJeremias Maerki <jeremias@apache.org>
Thu, 22 Dec 2005 20:10:54 +0000 (20:10 +0000)
committerJeremias Maerki <jeremias@apache.org>
Thu, 22 Dec 2005 20:10:54 +0000 (20:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@358613 13f79535-47bb-0310-9956-ffa450edef68

18 files changed:
src/java/org/apache/fop/area/Trait.java
src/java/org/apache/fop/fo/properties/CommonFont.java
src/java/org/apache/fop/fonts/Font.java
src/java/org/apache/fop/fonts/FontInfo.java
src/java/org/apache/fop/fonts/FontSetup.java
src/java/org/apache/fop/fonts/FontTriplet.java
src/java/org/apache/fop/layoutmgr/TraitSetter.java
src/java/org/apache/fop/render/PrintRenderer.java
src/java/org/apache/fop/render/java2d/Java2DRenderer.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/java/org/apache/fop/render/ps/PSGraphics2D.java
src/java/org/apache/fop/render/ps/PSRenderer.java
src/java/org/apache/fop/render/ps/PSTextPainter.java
src/java/org/apache/fop/render/xml/XMLRenderer.java
src/java/org/apache/fop/svg/PDFGraphics2D.java
src/java/org/apache/fop/svg/PDFTextPainter.java
test/layoutengine/standard-testcases/block_font-family.xml
test/layoutengine/standard-testcases/block_font-style.xml

index 57a6d1a2d1fd8b4d350db2b8d566cfeddf97a5ce..0dd1c56817f9c16ce0828d0f2639b1cc093a6238 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.datatypes.ColorType;
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.traits.BorderProps;
 
@@ -59,9 +60,9 @@ public class Trait implements Serializable {
     public static final Integer EXTERNAL_LINK = new Integer(2);
 
     /**
-     * The font name from the font setup.
+     * The font triplet for the current font.
      */
-    public static final Integer FONT_NAME = new Integer(3);
+    public static final Integer FONT = new Integer(3);
 
     /**
      * Font size for the current font.
@@ -227,8 +228,8 @@ public class Trait implements Serializable {
                           new TraitInfo("internal-link", String.class));
         TRAIT_INFO.put(EXTERNAL_LINK,
                           new TraitInfo("external-link", String.class));
-        TRAIT_INFO.put(FONT_NAME,
-                          new TraitInfo("font-family", String.class));
+        TRAIT_INFO.put(FONT,
+                          new TraitInfo("font", FontTriplet.class));
         TRAIT_INFO.put(FONT_SIZE,
                           new TraitInfo("font-size", Integer.class));
         TRAIT_INFO.put(COLOR, new TraitInfo("color", String.class));
index 5664bd1b1dcf0f31d8b46deee1e249f44ceb3563..581126cea4a0e75628135b0873126ea620f4db3b 100755 (executable)
@@ -30,6 +30,7 @@ import org.apache.fop.fo.expr.PropertyException;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
 
 /**
  * Collection of properties used in
@@ -164,10 +165,12 @@ public class CommonFont {
             // NOTE: this is incomplete. font-size may be specified with
             // various kinds of keywords too
             //int fontVariant = propertyList.get("font-variant").getEnum();
-            String fname = fontInfo.fontLookup(getFontFamily(), style,
+            FontTriplet triplet = fontInfo.fontLookup(getFontFamily(), style,
                                                font_weight);
+            String fname = fontInfo.getInternalFontKey(triplet);
+            fontInfo.useFont(fname);
             FontMetrics metrics = fontInfo.getMetricsFor(fname);
-            fontState = new Font(fname, metrics, fontSize.getValue(context));
+            fontState = new Font(fname, triplet, metrics, fontSize.getValue(context));
         }
         return fontState;
     }
index d2e58c7757b3ee7cbbfc670adce4f7a5ee3efc82..cbbc81b212255cf687d8be06098a069d17e368ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
@@ -20,9 +20,6 @@ package org.apache.fop.fonts;
 
 import java.util.Map;
 
-
-
-
 /**
  * This class holds font state information and provides access to the font
  * metrics.
@@ -30,17 +27,15 @@ import java.util.Map;
 public class Font {
 
     /** Default fallback key */
-    public static final String DEFAULT_FONT = "any,normal,400";
+    public static final FontTriplet DEFAULT_FONT = new FontTriplet("any", "normal", 400);
     /** Normal font weight */
     public static final int NORMAL = 400;
     /** Bold font weight */
     public static final int BOLD = 700;
 
     private String fontName;
+    private FontTriplet triplet;
     private int fontSize;
-    //private String fontFamily;
-    //private String fontStyle;
-    //private int fontWeight;
 
     /**
      * normal or small-caps font
@@ -52,11 +47,13 @@ public class Font {
     /**
      * Main constructor
      * @param key key of the font
+     * @param triplet the font triplet that was used to lookup this font (may be null)
      * @param met font metrics
      * @param fontSize font size
      */
-    public Font(String key, FontMetrics met, int fontSize) {
+    public Font(String key, FontTriplet triplet, FontMetrics met, int fontSize) {
         this.fontName = key;
+        this.triplet = triplet;
         this.metric = met;
         this.fontSize = fontSize;
     }
@@ -92,6 +89,11 @@ public class Font {
     public String getFontName() {
         return fontName;
     }
+    
+    /** @return the font triplet that selected this font */
+    public FontTriplet getFontTriplet() {
+        return this.triplet;
+    }
 
     /**
      * Returns the font size
index 59e7bdbd58366e94045b12484fd7f5bfea2e7d77..38059c6baf1dc90bbae5b17bf9a381339d7cb0d1 100644 (file)
@@ -79,15 +79,21 @@ public class FontInfo {
      * @param style font style (normal, italic, oblique...)
      * @param weight font weight
      */
-    public void addFontProperties(String name, String family, String style,
-                                  int weight) {
+    public void addFontProperties(String name, String family, String style, int weight) {
+        addFontProperties(name, new FontTriplet(family, style, weight));
+    }
+
+    /**
+     * Adds a new font triplet.
+     * @param name internal key
+     * @param triplet the font triplet to associate with the internal key
+     */
+    public void addFontProperties(String name, FontTriplet triplet) {
         /*
          * 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);
+        this.triplets.put(triplet, name);
     }
 
     /**
@@ -114,37 +120,49 @@ public class FontInfo {
      * @param substFont true if the font may be substituted with the default font if not found
      * @return internal key
      */
-    private String fontLookup(String family, String style,
+    private FontTriplet fontLookup(String family, String style,
                              int weight, boolean substFont) {
-        String key;
+        FontTriplet startKey = createFontKey(family, style, weight); 
+        FontTriplet key = startKey;
         // first try given parameters
-        key = createFontKey(family, style, weight);
-        String f = (String)triplets.get(key);
+        String f = getInternalFontKey(key);
         if (f == null) {
             // then adjust weight, favouring normal or bold
-            f = findAdjustWeight(family, style, weight);
+            key = findAdjustWeight(family, style, weight);
+            f = getInternalFontKey(key);
 
             if (!substFont && f == null) {
                 return null;
             }
             // then try any family with orig weight
             if (f == null) {
-                notifyFontReplacement(key);
+                notifyFontReplacement(startKey);
                 key = createFontKey("any", style, weight);
-                f = (String)triplets.get(key);
+                f = getInternalFontKey(key);
             }
 
             // then use default
             if (f == null) {
-                f = (String)triplets.get(Font.DEFAULT_FONT);
+                key = Font.DEFAULT_FONT;
+                f = getInternalFontKey(key);
             }
-
         }
 
-        usedFonts.put(f, fonts.get(f));
-        return f;
+        if (f != null) {
+            return key;
+        } else {
+            return null;
+        }
     }
 
+    /**
+     * Tells this class that the font with the given internal name has been used.
+     * @param internalName the internal font name (F1, F2 etc.)
+     */
+    public void useFont(String internalName) {
+        usedFonts.put(internalName, fonts.get(internalName));
+    }
+    
     /**
      * Lookup a font.
      * <br>
@@ -155,9 +173,9 @@ public class FontInfo {
      * @param family font family
      * @param style font style
      * @param weight font weight
-     * @return internal key
+     * @return the font triplet of the font chosen
      */
-    public String fontLookup(String family, String style,
+    public FontTriplet fontLookup(String family, String style,
                              int weight) {
         return fontLookup(family, style, weight, true);
     }
@@ -172,20 +190,20 @@ public class FontInfo {
      * @param family font family (priority list)
      * @param style font style
      * @param weight font weight
-     * @return internal key
+     * @return font triplet of the font chosen
      */
-    public String fontLookup(String[] family, String style,
+    public FontTriplet fontLookup(String[] family, String style,
                              int weight) {
         for (int i = 0; i < family.length; i++) {
-            String key = fontLookup(family[i], style, weight, (i >= family.length - 1));
-            if (key != null) {
-                return key;
+            FontTriplet triplet = fontLookup(family[i], style, weight, (i >= family.length - 1));
+            if (triplet != null) {
+                return triplet;
             }
         }
         throw new IllegalStateException("fontLookup must return a key on the last call");
     }
     
-    private void notifyFontReplacement(String key) {
+    private void notifyFontReplacement(FontTriplet key) {
         if (loggedFontKeys == null) {
             loggedFontKeys = new java.util.HashSet();
         }
@@ -203,39 +221,43 @@ public class FontInfo {
      * @param weight font weight
      * @return internal key
      */
-    public String findAdjustWeight(String family, String style,
+    public FontTriplet findAdjustWeight(String family, String style,
                              int weight) {
-        String key;
+        FontTriplet key = null;
         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);
+                f = getInternalFontKey(key);
             }
         } else if (newWeight == 500) {
             key = createFontKey(family, style, 400);
-            f = (String)triplets.get(key);
+            f = getInternalFontKey(key);
         } else if (newWeight > 500) {
             while (f == null && newWeight < 1000) {
                 newWeight += 100;
                 key = createFontKey(family, style, newWeight);
-                f = (String)triplets.get(key);
+                f = getInternalFontKey(key);
             }
             newWeight = weight;
             while (f == null && newWeight > 400) {
                 newWeight -= 100;
                 key = createFontKey(family, style, newWeight);
-                f = (String)triplets.get(key);
+                f = getInternalFontKey(key);
             }
         }
-        if (f == null) {
+        if (f == null && weight != 400) {
             key = createFontKey(family, style, 400);
-            f = (String)triplets.get(key);
+            f = getInternalFontKey(key);
         }
 
-        return f;
+        if (f != null) {
+            return key;
+        } else {
+            return null;
+        }
     }
 
     /**
@@ -246,10 +268,19 @@ public class FontInfo {
      * @return True if available
      */
     public boolean hasFont(String family, String style, int weight) {
-        String key = createFontKey(family, style, weight);
+        FontTriplet key = createFontKey(family, style, weight);
         return this.triplets.containsKey(key);
     }
 
+    /**
+     * Returns the internal font key (F1, F2, F3 etc.) for a given triplet.
+     * @param triplet the font triplet
+     * @return the associated internal key or null, if not found
+     */
+    public String getInternalFontKey(FontTriplet triplet) {
+        return (String)triplets.get(triplet);
+    }
+    
     /**
      * Creates a key from the given strings.
      * @param family font family
@@ -257,9 +288,9 @@ public class FontInfo {
      * @param weight font weight
      * @return internal key
      */
-    public static String createFontKey(String family, String style,
+    public static FontTriplet createFontKey(String family, String style,
                                        int weight) {
-        return family + "," + style + "," + weight;
+        return new FontTriplet(family, style, weight);
     }
 
     /**
@@ -298,7 +329,7 @@ public class FontInfo {
      * @param fontName The font name we are looking for
      * @return The first triplet for the given font name
      */
-    private String getTripletFor(String fontName) {
+    public FontTriplet getTripletFor(String fontName) {
         List foundTriplets = new ArrayList();
         for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) {
             Map.Entry tripletEntry = (Map.Entry) iter.next();
@@ -308,7 +339,7 @@ public class FontInfo {
         }
         if (foundTriplets.size() > 0) {
             Collections.sort(foundTriplets);
-            return (String)foundTriplets.get(0);
+            return (FontTriplet)foundTriplets.get(0);
         }
         return null;
     }
@@ -322,11 +353,12 @@ public class FontInfo {
      * @return font style
      */
     public String getFontStyleFor(String fontName) {
-        String triplet = getTripletFor(fontName);
+        FontTriplet triplet = getTripletFor(fontName);
         if (triplet != null) {
-            return triplet.substring(triplet.indexOf(',') + 1, triplet.lastIndexOf(','));
+            return triplet.getStyle();
+        } else {
+            return "";
         }
-        return "";
     }
     
     /**
@@ -337,12 +369,13 @@ public class FontInfo {
      * @param fontName internal key
      * @return font weight
      */
-    public String getFontWeightFor(String fontName) {
-        String triplet = getTripletFor(fontName);
+    public int getFontWeightFor(String fontName) {
+        FontTriplet triplet = getTripletFor(fontName);
         if (triplet != null) {
-            return triplet.substring(triplet.lastIndexOf(',') + 1);
+            return triplet.getWeight();
+        } else {
+            return 0;
         }
-        return "";
     }
     
 }
index dde3313c9c51aff3cefddd880b6647f5c3ab3516..1fb153919f622d0ac7181590a2ca11206ab9d9c8 100644 (file)
@@ -199,14 +199,10 @@ public class FontSetup {
                 for (int c = 0; c < triplets.size(); c++) {
                     FontTriplet triplet = (FontTriplet) triplets.get(c);
 
-                    int weight = FontUtil.parseCSS2FontWeight(triplet.getWeight());
                     if (log.isDebugEnabled()) {
-                        log.debug("Registering: " + triplet + " weight=" + weight);
+                        log.debug("Registering: " + triplet + " under " + internalName);
                     }
-                    fontInfo.addFontProperties(internalName,
-                                               triplet.getName(),
-                                               triplet.getStyle(),
-                                               weight);
+                    fontInfo.addFontProperties(internalName, triplet);
                 }
             }
         }
@@ -226,9 +222,10 @@ public class FontSetup {
             Configuration[] triple = font[i].getChildren("font-triplet");
             List tripleList = new java.util.ArrayList();
             for (int j = 0; j < triple.length; j++) {
+                int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
                 tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
-                                               triple[j].getAttribute("weight"),
-                                               triple[j].getAttribute("style")));
+                                               triple[j].getAttribute("style"),
+                                               weight));
             }
 
             EmbedFontInfo efi;
@@ -243,8 +240,8 @@ public class FontSetup {
                     FontTriplet triplet = (FontTriplet) tripleList.get(j);
                     log.debug("Font triplet "
                               + triplet.getName() + ", "
-                              + triplet.getWeight() + ", "
-                              + triplet.getStyle());
+                              + triplet.getStyle() + ", "
+                              + triplet.getWeight());
                 }
             }
 
index ed7e13f834a4a70bcaae3ac3592fcff7f47f469f..378bfaeb0bce12c91e012cf81cda7acde9ececea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
  
 package org.apache.fop.fonts;
 
+import java.io.Serializable;
+
 /**
- * FontTriplet contains information on name, weight, style of one font
+ * FontTriplet contains information on name, style and weight of one font
  */
-public class FontTriplet {
+public class FontTriplet implements Comparable, Serializable {
+    
+    /** serial version UID */
+    private static final long serialVersionUID = 1168991106658033508L;
     
-    private String name, weight, style;
+    private String name;
+    private String style;
+    private int weight;
+    
+    //This is only a cache
+    private transient String key;
     
     /**
      * Creates a new font triplet.
      * @param name font name
-     * @param weight font weight (normal, bold etc.)
      * @param style font style (normal, italic etc.)
+     * @param weight font weight (100, 200, 300...800, 900)
      */
-    public FontTriplet(String name, String weight, String style) {
+    public FontTriplet(String name, String style, int weight) {
         this.name = name;
-        this.weight = weight;
         this.style = style;
+        this.weight = weight;
     }
 
-    /**
-     * Returns the font name.
-     * @return the font name
-     */
+    /** @return the font name */
     public String getName() {
         return name;
     }
 
-    /**
-     * Returns the font weight.
-     * @return the font weight
-     */
-    public String getWeight() {
+    /** @return the font style */
+    public String getStyle() {
+        return style;
+    }
+    
+    /** @return the font weight */
+    public int getWeight() {
         return weight;
     }
 
-    /**
-     * Returns the font style.
-     * @return the font style
-     */
-    public String getStyle() {
-        return style;
+    private String getKey() {
+        if (this.key == null) {
+            //This caches the combined key
+            this.key = getName() + "," + getStyle() + "," + getWeight();
+        }
+        return this.key;
     }
     
-    /**
-     * @see java.lang.Object#toString()
-     */
+    /** @see java.lang.Comparable#compareTo(java.lang.Object) */
+    public int compareTo(Object o) {
+        return getKey().compareTo(((FontTriplet)o).getKey());
+    }
+
+    /** @see java.lang.Object#hashCode() */
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    /** @see java.lang.Object#equals(java.lang.Object) */
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj == this) {
+            return true;
+        } else {
+            if (obj instanceof FontTriplet) {
+                FontTriplet other = (FontTriplet)obj;
+                return (getName().equals(other.getName())
+                        && getStyle().equals(other.getStyle()) 
+                        && (getWeight() == other.getWeight()));
+            }
+        }
+        return false;
+    }
+
+    /** @see java.lang.Object#toString() */
     public String toString() {
-        return getName() + "," + getStyle() + "," + getWeight();
+        return getKey();
     }
+
 }
 
index 482373ad7a92e7c5039cc2ecf21da8230bb79622..e8790173bacd55850aa8b8fab5a8640125a92fed 100644 (file)
@@ -32,6 +32,8 @@ import org.apache.fop.fo.properties.CommonMarginBlock;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonTextDecoration;
 import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 
 /**
  * This is a helper class used for setting common traits on areas.
@@ -407,6 +409,13 @@ public class TraitSetter {
         addMargins(area, bpProps, startIndent, endIndent, context);
     }
 
+    /**
+     * Returns the effective space length of a resolved space specifier based on the adjustment 
+     * value.
+     * @param adjust the adjustment value
+     * @param space the space specifier
+     * @return the effective space length
+     */
     public static int getEffectiveSpace(double adjust, MinOptMax space) {
         if (space == null) {
             return 0;
@@ -420,6 +429,13 @@ public class TraitSetter {
         return sp;
     }
     
+    /**
+     * Adds traits for space-before and space-after to an area.
+     * @param area the target area
+     * @param adjust the adjustment value
+     * @param spaceBefore the space-before space specifier
+     * @param spaceAfter the space-after space specifier
+     */
     public static void addSpaceBeforeAfter(Area area, double adjust, 
             MinOptMax spaceBefore, MinOptMax spaceAfter) {
         int space;
@@ -444,8 +460,13 @@ public class TraitSetter {
         area.addTrait(Trait.BREAK_BEFORE, new Integer(breakBefore));
     }
     
+    /**
+     * Adds font traits to an area
+     * @param area the target are
+     * @param font the font to use
+     */
     public static void addFontTraits(Area area, Font font) {
-        area.addTrait(Trait.FONT_NAME, font.getFontName());
+        area.addTrait(Trait.FONT, font.getFontTriplet());
         area.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize()));
     }
     
index 596b91de4fe659c7b572dda476ccdb84f233e131..7b6b646f7d8a80e1d4b66bebda0a871924543d80 100644 (file)
 package org.apache.fop.render;
 
 // FOP
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Trait;
+import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontMetrics;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.fonts.FontTriplet;
 
 // Java
 import java.awt.Color;
@@ -45,6 +50,35 @@ public abstract class PrintRenderer extends AbstractRenderer {
         FontSetup.setup(fontInfo, fontList);
     }
 
+    /**
+     * Returns the internal font key fot a font triplet coming from the area tree
+     * @param area the area from which to retrieve the font triplet information
+     * @return the internal font key (F1, F2 etc.) or null if not found
+     */
+    protected String getInternalFontNameForArea(Area area) {
+        FontTriplet triplet = (FontTriplet)area.getTrait(Trait.FONT);
+        return fontInfo.getInternalFontKey(triplet);
+    }
+    
+    /**
+     * Returns a Font object constructed based on the font traits in an area
+     * @param area the area from which to retrieve the font triplet information
+     * @return the requested Font instance or null if not found
+     * @todo This would make a nice opportunity for a cache!
+     */
+    protected Font getFontFromArea(Area area) {
+        FontTriplet triplet = (FontTriplet)area.getTrait(Trait.FONT);
+        String name = fontInfo.getInternalFontKey(triplet);
+        if (name != null) {
+            int size = ((Integer)area.getTrait(Trait.FONT_SIZE)).intValue();
+            FontMetrics metrics = fontInfo.getMetricsFor(name);
+            Font font = new Font(name, null, metrics, size);
+            return font;
+        } else {
+            return null;
+        }
+    }
+    
     /**
      * Lightens up a color for groove, ridge, inset and outset border effects.
      * @param col the color to lighten up
index 9b0e76f33e5fdfd27843c45cd054df2dfddc3974..6bff76bb44a3e438eda538969fcf839f1b2ddd18 100644 (file)
@@ -70,6 +70,7 @@ import org.apache.fop.fo.Constants;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.ImageFactory;
 import org.apache.fop.image.XMLImage;
@@ -821,6 +822,25 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
         drawBackAndBorders(block, startx, starty, width, height);
     }
 
+    /**
+     * Returns a Font object constructed based on the font traits in an area
+     * @param area the area from which to retrieve the font triplet information
+     * @return the requested Font instance or null if not found
+     * @todo This would make a nice opportunity for a cache!
+     */
+    protected Font getFontFromArea(Area area) {
+        FontTriplet triplet = (FontTriplet)area.getTrait(Trait.FONT);
+        String name = fontInfo.getInternalFontKey(triplet);
+        if (name != null) {
+            int size = ((Integer)area.getTrait(Trait.FONT_SIZE)).intValue();
+            FontMetrics metrics = fontInfo.getMetricsFor(name);
+            Font font = new Font(name, null, metrics, size);
+            return font;
+        } else {
+            return null;
+        }
+    }
+    
     /**
      * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
      */
@@ -830,9 +850,8 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
         float x = currentIPPosition + text.getBorderAndPaddingWidthStart();
         float y = currentBPPosition + text.getOffset() + text.getBaselineOffset(); // baseline
 
-        String name = (String) text.getTrait(Trait.FONT_NAME);
-        int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
-        state.updateFont(name, size, null);
+        Font font = getFontFromArea(text);
+        state.updateFont(font.getFontName(), font.getFontSize(), null);
 
         ColorType ct = (ColorType) text.getTrait(Trait.COLOR);
         state.updateColor(ct, false, null);
@@ -844,12 +863,10 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
         // + x + ", y: " + y + state);
 
         // rendering text decorations
-        FontMetrics metrics = fontInfo.getMetricsFor(name);
-        Font fs = new Font(name, metrics, size);
 
         super.renderText(text);
 
-        renderTextDecoration(fs, text, y, x);
+        renderTextDecoration(font, text, y, x);
     }
 
     /**
@@ -861,9 +878,8 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
         float x = currentIPPosition + ch.getBorderAndPaddingWidthStart();
         float y = currentBPPosition + ch.getOffset() + ch.getBaselineOffset(); // baseline
 
-        String name = (String) ch.getTrait(Trait.FONT_NAME);
-        int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue();
-        state.updateFont(name, size, null);
+        Font font = getFontFromArea(ch);
+        state.updateFont(font.getFontName(), font.getFontSize(), null);
 
         ColorType ct = (ColorType) ch.getTrait(Trait.COLOR);
         state.updateColor(ct, false, null);
@@ -875,9 +891,7 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab
         // + x + ", y: " + y + state);
 
         // rendering text decorations
-        FontMetrics metrics = fontInfo.getMetricsFor(name);
-        Font fs = new Font(name, metrics, size);
-        renderTextDecoration(fs, ch, y, x);
+        renderTextDecoration(font, ch, y, x);
 
         super.renderCharacter(ch);
     }
index 70c94dcdbf5575e2396aa939d217a3ff17416aef..90d56fc64adecbe26ca815df0b011f6e169552cc 100644 (file)
@@ -39,6 +39,7 @@ import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.area.Area;
 import org.apache.fop.area.CTM;
 import org.apache.fop.area.LineArea;
 import org.apache.fop.area.Page;
@@ -56,6 +57,7 @@ import org.apache.fop.area.inline.InlineParent;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.datatypes.ColorType;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontSetup;
@@ -1011,18 +1013,17 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
         beginTextObject();
         StringBuffer pdf = new StringBuffer();
 
-        String name = (String) ch.getTrait(Trait.FONT_NAME);
-        int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue();
+        Font font = getFontFromArea(ch);
 
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
-        Typeface tf = (Typeface) fontInfo.getFonts().get(name);
+        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
         boolean useMultiByte = tf.isMultiByte();
 
         // String startText = useMultiByte ? "<FEFF" : "(";
         String startText = useMultiByte ? "<" : "(";
         String endText = useMultiByte ? "> " : ") ";
 
-        updateFont(name, size, pdf);
+        updateFont(font.getFontName(), font.getFontSize(), pdf);
         ColorType ct = (ColorType) ch.getTrait(Trait.COLOR);
         if (ct != null) {
             updateColor(ct, true, pdf);
@@ -1066,14 +1067,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
         String s = ch.getChar();
 
 
-        FontMetrics metrics = fontInfo.getMetricsFor(name);
-        Font fs = new Font(name, metrics, size);
-        escapeText(s, fs, useMultiByte, pdf);
+        escapeText(s, font, useMultiByte, pdf);
         pdf.append(endText);
 
         currentStream.add(pdf.toString());
 
-        renderTextDecoration(tf, size, ch, bl, rx);
+        renderTextDecoration(tf, font.getFontSize(), ch, bl, rx);
         
         super.renderCharacter(ch);
     }
@@ -1086,14 +1085,14 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
         beginTextObject();
         StringBuffer pdf = new StringBuffer();
 
-        String name = (String) text.getTrait(Trait.FONT_NAME);
+        String fontName = getInternalFontNameForArea(text);
         int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
         
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
-        Typeface tf = (Typeface) fontInfo.getFonts().get(name);
+        Typeface tf = (Typeface) fontInfo.getFonts().get(fontName);
         boolean useMultiByte = tf.isMultiByte();
         
-        updateFont(name, size, pdf);
+        updateFont(fontName, size, pdf);
         ColorType ct = (ColorType) text.getTrait(Trait.COLOR);
         updateColor(ct, true, pdf);
 
@@ -1143,9 +1142,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      * @see org.apache.fop.render.AbstractRenderer#renderWord(WordArea)
      */
     public void renderWord(WordArea word) {
-        String name = (String) word.getParentArea().getTrait(Trait.FONT_NAME);
-        int size = ((Integer) word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
-        Typeface tf = (Typeface) fontInfo.getFonts().get(name);
+        Font font = getFontFromArea(word.getParentArea());
+        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
         boolean useMultiByte = tf.isMultiByte();
 
         String startText = useMultiByte ? "<" : "(";
@@ -1157,9 +1155,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
 
         String s = word.getWord();
         
-        FontMetrics metrics = fontInfo.getMetricsFor(name);
-        Font fs = new Font(name, metrics, size);
-        escapeText(s, fs, useMultiByte, pdf);
+        escapeText(s, font, useMultiByte, pdf);
         pdf.append(endText);
         
         currentStream.add(pdf.toString());
@@ -1171,9 +1167,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      * @see org.apache.fop.render.AbstractRenderer#renderSpace(SpaceArea)
      */
     public void renderSpace(SpaceArea space) {
-        String name = (String) space.getParentArea().getTrait(Trait.FONT_NAME);
-        int size = ((Integer) space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
-        Typeface tf = (Typeface) fontInfo.getFonts().get(name);
+        Font font = getFontFromArea(space.getParentArea());
+        Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
         boolean useMultiByte = tf.isMultiByte();
 
         String startText = useMultiByte ? "<" : "(";
@@ -1185,13 +1180,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
 
         String s = space.getSpace();
         
-        FontMetrics metrics = fontInfo.getMetricsFor(name);
-        Font fs = new Font(name, metrics, size);
-        escapeText(s, fs, useMultiByte, pdf);
+        escapeText(s, font, useMultiByte, pdf);
         pdf.append(endText);
         
         if (useMultiByte) {
-            pdf.append(-(((TextArea) space.getParentArea()).getTextWordSpaceAdjust() / (size / 1000)) + " ");
+            pdf.append(-(((TextArea) space.getParentArea()).getTextWordSpaceAdjust() 
+                    / (font.getFontSize() / 1000)) + " ");
         }
         
         currentStream.add(pdf.toString());
index 02354dbc7bce774d1ce39570b94afbbed8884248..f85d0474a91924a17fdef23ce64fd72b97d7b10c 100644 (file)
@@ -62,6 +62,7 @@ import org.apache.commons.logging.LogFactory;
 //FOP
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.image.FopImage;
 
 /**
@@ -915,11 +916,13 @@ public class PSGraphics2D extends AbstractGraphics2D {
         String style = f.isItalic() ? "italic" : "normal";
         int weight = f.isBold() ? Font.BOLD : Font.NORMAL;
                 
-        String fontKey = fontInfo.findAdjustWeight(fontFamily, style, weight);
-        if (fontKey == null) {
-            fontKey = fontInfo.findAdjustWeight("sans-serif", style, weight);
+        FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight);
+        if (triplet == null) {
+            triplet = fontInfo.findAdjustWeight("sans-serif", style, weight);
         }
-        return new Font(fontKey, fontInfo.getMetricsFor(fontKey), fontSize);
+        String fontKey = fontInfo.getInternalFontKey(triplet);
+        fontInfo.useFont(fontKey);
+        return new Font(fontKey, triplet, fontInfo.getMetricsFor(fontKey), fontSize);
     }
 
     private void establishCurrentFont() throws IOException {
index 8d7dfd207e1fc59c4ab087f5b3d195b856b49be9..71a9489492714b12499470389d07b3f87bacbf3d 100644 (file)
@@ -55,6 +55,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.image.EPSImage;
 import org.apache.fop.image.FopImage;
@@ -808,7 +809,7 @@ public class PSRenderer extends AbstractPathOrientedRenderer {
     
     private void renderText(AbstractTextArea area, String text) {
         renderInlineAreaBackAndBorders(area);
-        String fontname = (String)area.getTrait(Trait.FONT_NAME);
+        String fontname = getInternalFontNameForArea(area);
         int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE);
 
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
index 7153ea4f527385e62cb2561b17877866d6a2fdfe..aba67759c0ff657896465ef44ff6c9a383287f79 100644 (file)
@@ -48,6 +48,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.fop.fonts.FontMetrics;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 
 /**
  * Renders the attributed character iterator of a <tt>TextNode</tt>.
@@ -384,19 +385,22 @@ public class PSTextPainter implements TextPainter {
                 }*/
                 fontFamily = fam.getFamilyName();
                 if (fontInfo.hasFont(fontFamily, style, weight)) {
-                    String fname = fontInfo.fontLookup(
+                    FontTriplet triplet = fontInfo.fontLookup(
                             fontFamily, style, weight);
+                    String fname = fontInfo.getInternalFontKey(triplet);
+                    fontInfo.useFont(fname);
                     FontMetrics metrics = fontInfo.getMetricsFor(fname);
                     int fsize = (int)(fontSize.floatValue() * 1000);
-                    return new Font(fname, metrics, fsize);
+                    return new Font(fname, triplet, metrics, fsize);
                 }
             }
         }
-        String fname = fontInfo.fontLookup(
-                "any", style, Font.NORMAL);
+        FontTriplet triplet = fontInfo.fontLookup("any", style, Font.NORMAL);
+        String fname = fontInfo.getInternalFontKey(triplet);
+        fontInfo.useFont(fname);
         FontMetrics metrics = fontInfo.getMetricsFor(fname);
         int fsize = (int)(fontSize.floatValue() * 1000);
-        return new Font(fname, metrics, fsize);
+        return new Font(fname, triplet, metrics, fsize);
     }
 
     private java.awt.Font makeAWTFont(AttributedCharacterIterator aci, Font font) {
index 80431b6c5d4f6ecaeb6fb1404098a693f4ca1d1b..37945306b027a87295c8b8477c99db2f008b54c3 100644 (file)
@@ -73,6 +73,7 @@ import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.fonts.FontTriplet;
 
 /**
  * Renderer that renders areas to XML for debugging purposes.
@@ -120,6 +121,7 @@ public class XMLRenderer extends PrintRenderer {
      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
      */
     public void configure(Configuration cfg) throws ConfigurationException {
+        super.configure(cfg);
         //Font configuration
         List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg);
         if (this.fontList == null) {
@@ -281,12 +283,14 @@ public class XMLRenderer extends PrintRenderer {
                 if ("break-before".equals(name) || "break-after".equals(name)) {
                     continue;
                 }
-                String value = traitEntry.getValue().toString();
-                addAttribute(name, value);
-                if ("font-family".equals(name)) {
-                    addAttribute("font-name", fontInfo.getMetricsFor(value).getFontName());
-                    addAttribute("font-style", fontInfo.getFontStyleFor(value));
-                    addAttribute("font-weight", fontInfo.getFontWeightFor(value));
+                Object value = traitEntry.getValue();
+                if (Trait.getTraitName(Trait.FONT).equals(name)) {
+                    FontTriplet triplet = (FontTriplet)value;
+                    addAttribute("font-name", triplet.getName());
+                    addAttribute("font-style", triplet.getStyle());
+                    addAttribute("font-weight", triplet.getWeight());
+                } else {
+                    addAttribute(name, value.toString());
                 }
             }
         }
index 81795984b5ff8690f2372d3d7d1bf33ccc00f776..edb538df486248ea786650dac113f3029863ab45 100644 (file)
@@ -36,6 +36,7 @@ import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.image.JpegImage;
 import org.apache.fop.fonts.CIDFont;
@@ -1394,12 +1395,14 @@ public class PDFGraphics2D extends AbstractGraphics2D {
             int siz = gFont.getSize();
             String style = gFont.isItalic() ? "italic" : "normal";
             int weight = gFont.isBold() ? Font.BOLD : Font.NORMAL;
-            String fname = fontInfo.fontLookup(n, style, weight);
+            FontTriplet triplet = fontInfo.fontLookup(n, style, weight);
+            String fname = fontInfo.getInternalFontKey(triplet);
+            fontInfo.useFont(fname);
             FontMetrics metrics = fontInfo.getMetricsFor(fname);
-            fontState = new Font(fname, metrics, siz * 1000);
+            fontState = new Font(fname, triplet, metrics, siz * 1000);
         } else {
             FontMetrics metrics = fontInfo.getMetricsFor(ovFontState.getFontName());
-            fontState = new Font(ovFontState.getFontName(),
+            fontState = new Font(ovFontState.getFontName(), ovFontState.getFontTriplet(),
                                       metrics, ovFontState.getFontSize());
             ovFontState = null;
         }
index 7dcdc283d8eb35f438f593087f47f3103a78ad14..c9c4a0c642de442ec90fa3bbd83bfd95620f1150 100644 (file)
@@ -44,6 +44,7 @@ import org.apache.batik.gvt.renderer.StrokingTextPainter;
 import org.apache.fop.fonts.FontMetrics;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
 
 /**
  * Renders the attributed character iterator of a <tt>TextNode</tt>.
@@ -176,22 +177,25 @@ public class PDFTextPainter implements TextPainter {
                 }
                 fontFamily = fam.getFamilyName();
                 if (fi.hasFont(fontFamily, style, weight)) {
-                    String fname = fontInfo.fontLookup(fontFamily, style,
+                    FontTriplet triplet = fontInfo.fontLookup(fontFamily, style,
                                                        weight);
+                    String fname = fontInfo.getInternalFontKey(triplet);
+                    fontInfo.useFont(fname);
                     FontMetrics metrics = fontInfo.getMetricsFor(fname);
                     int fsize = (int)(size.floatValue() * 1000);
-                    fontState = new Font(fname, metrics, fsize);
+                    fontState = new Font(fname, triplet, metrics, fsize);
                     found = true;
                     break;
                 }
             }
         }
         if (!found) {
-            String fname =
-              fontInfo.fontLookup("any", style, Font.NORMAL);
+            FontTriplet triplet = fontInfo.fontLookup("any", style, Font.NORMAL);
+            String fname = fontInfo.getInternalFontKey(triplet);
+            fontInfo.useFont(fname);
             FontMetrics metrics = fontInfo.getMetricsFor(fname);
             int fsize = (int)(size.floatValue() * 1000);
-            fontState = new Font(fname, metrics, fsize);
+            fontState = new Font(fname, triplet, metrics, fsize);
         } else {
             if (g2d instanceof PDFGraphics2D) {
                 ((PDFGraphics2D) g2d).setOverrideFontState(fontState);
index 9729b7d42d8c77f95979d175414eb5985d3ec372..9cb9eee23b40e5f8237d54aaf439efb3891d7e1a 100644 (file)
     </fo:root>
   </fo>
   <checks>
-    <eval expected="Helvetica" xpath="//flow/block[1]/lineArea/text/@font-name"/>
-    <eval expected="Times-Roman" xpath="//flow/block[2]/lineArea/text/@font-name"/>
-    <eval expected="Helvetica" xpath="//flow/block[3]/lineArea/text/@font-name"/>
-    <eval expected="Times-Roman" xpath="//flow/block[4]/lineArea/text/@font-name"/>
-    <eval expected="Times-Roman" xpath="//flow/block[5]/lineArea/text/@font-name"/>
-    <eval expected="Courier" xpath="//flow/block[6]/lineArea/text/@font-name"/>
+    <eval expected="sans-serif" xpath="//flow/block[1]/lineArea/text/@font-name"/>
+    <eval expected="serif" xpath="//flow/block[2]/lineArea/text/@font-name"/>
+    <eval expected="sans-serif" xpath="//flow/block[3]/lineArea/text/@font-name"/>
+    <eval expected="any" xpath="//flow/block[4]/lineArea/text/@font-name"/>
+    <eval expected="any" xpath="//flow/block[5]/lineArea/text/@font-name"/>
+    <eval expected="monospace" xpath="//flow/block[6]/lineArea/text/@font-name"/>
     <eval expected="Helvetica" xpath="//flow/block[7]/lineArea/text/@font-name"/>
     <eval expected="Helvetica" xpath="//flow/block[8]/lineArea/text/@font-name"/>
-    <eval expected="Courier" xpath="//flow/block[9]/lineArea/text/@font-name"/>
+    <eval expected="monospace" xpath="//flow/block[9]/lineArea/text/@font-name"/>
   </checks>
 </testcase>
index 32666471743da27d48376c57c522207f4538e177..20eebf5c1953a3011ea262a3ae358ef31bbea22e 100644 (file)
@@ -42,7 +42,7 @@
           <fo:block font-family="sans-serif" font-style="italic">font-family="sans-serif" font-style="italic"</fo:block>
           <fo:block font-family="sans-serif" font-style="oblique">font-family="sans-serif" font-style="oblique"</fo:block>
           <fo:block font-family="sans-serif" font-style="backslant">font-family="sans-serif" font-style="backslant"</fo:block>
-          <fo:block font-family="sans-serif" font-style="obscure">font-family="serif" font-style="obscure"</fo:block>
+          <fo:block font-family="sans-serif" font-style="obscure">font-family="sans-serif" font-style="obscure"</fo:block>
 
           <fo:block font-family="monospace">font-family="monospace" font-style not given</fo:block>
           <fo:block font-family="monospace" font-style="normal">font-family="monospace" font-style="normal"</fo:block>
     <eval expected="normal" xpath="//flow/block[1]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[2]/lineArea/text/@font-style"/>
     <eval expected="italic" xpath="//flow/block[3]/lineArea/text/@font-style"/>
-    <eval expected="italic" xpath="//flow/block[4]/lineArea/text/@font-style"/>
+    <eval expected="oblique" xpath="//flow/block[4]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[5]/lineArea/text/@font-style"/>
+    <eval expected="any" xpath="//flow/block[5]/lineArea/text/@font-name"/> <!-- style not registered -> any, normal -->
     <eval expected="normal" xpath="//flow/block[6]/lineArea/text/@font-style"/>
+    <eval expected="serif" xpath="//flow/block[6]/lineArea/text/@font-name"/> <!-- illegal style -> back to default=serif, normal -->
 
     <eval expected="normal" xpath="//flow/block[7]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[8]/lineArea/text/@font-style"/>
     <eval expected="italic" xpath="//flow/block[9]/lineArea/text/@font-style"/>
-    <eval expected="italic" xpath="//flow/block[10]/lineArea/text/@font-style"/>
+    <eval expected="oblique" xpath="//flow/block[10]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[11]/lineArea/text/@font-style"/>
+    <eval expected="any" xpath="//flow/block[11]/lineArea/text/@font-name"/> <!-- style not registered -> any, normal -->
     <eval expected="normal" xpath="//flow/block[12]/lineArea/text/@font-style"/>
+    <eval expected="sans-serif" xpath="//flow/block[12]/lineArea/text/@font-name"/> <!-- illegal style -> back to default=sans-serif, normal -->
 
     <eval expected="normal" xpath="//flow/block[13]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[14]/lineArea/text/@font-style"/>
     <eval expected="italic" xpath="//flow/block[15]/lineArea/text/@font-style"/>
-    <eval expected="italic" xpath="//flow/block[16]/lineArea/text/@font-style"/>
+    <eval expected="oblique" xpath="//flow/block[16]/lineArea/text/@font-style"/>
     <eval expected="normal" xpath="//flow/block[17]/lineArea/text/@font-style"/>
+    <eval expected="any" xpath="//flow/block[17]/lineArea/text/@font-name"/> <!-- style not registered -> any, normal -->
     <eval expected="normal" xpath="//flow/block[18]/lineArea/text/@font-style"/>
+    <eval expected="monospace" xpath="//flow/block[18]/lineArea/text/@font-name"/> <!-- illegal style -> back to default=monospace, normal -->
   </checks>
 </testcase>