From 250a5e5363af3462693c80227e0666d0b5b75a8f Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 22 Dec 2005 20:10:54 +0000 Subject: [PATCH] As announced, I brought FontTriplet to more life by making it Serializable and using it to transport the information about the font in use through the area tree. This has small effects on the test cases as the values in the generated XML are slightly different. While refactoring I saw that there's some room for optimization. Too many objects are still created. It should be quite easy now with the FontTriplet to create a small cache. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@358613 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/area/Trait.java | 9 +- .../apache/fop/fo/properties/CommonFont.java | 7 +- src/java/org/apache/fop/fonts/Font.java | 20 +-- src/java/org/apache/fop/fonts/FontInfo.java | 123 +++++++++++------- src/java/org/apache/fop/fonts/FontSetup.java | 17 +-- .../org/apache/fop/fonts/FontTriplet.java | 87 +++++++++---- .../org/apache/fop/layoutmgr/TraitSetter.java | 23 +++- .../org/apache/fop/render/PrintRenderer.java | 34 +++++ .../fop/render/java2d/Java2DRenderer.java | 38 ++++-- .../apache/fop/render/pdf/PDFRenderer.java | 42 +++--- .../apache/fop/render/ps/PSGraphics2D.java | 11 +- .../org/apache/fop/render/ps/PSRenderer.java | 3 +- .../apache/fop/render/ps/PSTextPainter.java | 14 +- .../apache/fop/render/xml/XMLRenderer.java | 16 ++- .../org/apache/fop/svg/PDFGraphics2D.java | 9 +- .../org/apache/fop/svg/PDFTextPainter.java | 14 +- .../standard-testcases/block_font-family.xml | 14 +- .../standard-testcases/block_font-style.xml | 14 +- 18 files changed, 327 insertions(+), 168 deletions(-) diff --git a/src/java/org/apache/fop/area/Trait.java b/src/java/org/apache/fop/area/Trait.java index 57a6d1a2d..0dd1c5681 100644 --- a/src/java/org/apache/fop/area/Trait.java +++ b/src/java/org/apache/fop/area/Trait.java @@ -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)); diff --git a/src/java/org/apache/fop/fo/properties/CommonFont.java b/src/java/org/apache/fop/fo/properties/CommonFont.java index 5664bd1b1..581126cea 100755 --- a/src/java/org/apache/fop/fo/properties/CommonFont.java +++ b/src/java/org/apache/fop/fo/properties/CommonFont.java @@ -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; } diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java index d2e58c775..cbbc81b21 100644 --- a/src/java/org/apache/fop/fonts/Font.java +++ b/src/java/org/apache/fop/fonts/Font.java @@ -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 diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java index 59e7bdbd5..38059c6ba 100644 --- a/src/java/org/apache/fop/fonts/FontInfo.java +++ b/src/java/org/apache/fop/fonts/FontInfo.java @@ -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. *
@@ -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 ""; } } diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java index dde3313c9..1fb153919 100644 --- a/src/java/org/apache/fop/fonts/FontSetup.java +++ b/src/java/org/apache/fop/fonts/FontSetup.java @@ -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()); } } diff --git a/src/java/org/apache/fop/fonts/FontTriplet.java b/src/java/org/apache/fop/fonts/FontTriplet.java index ed7e13f83..378bfaeb0 100644 --- a/src/java/org/apache/fop/fonts/FontTriplet.java +++ b/src/java/org/apache/fop/fonts/FontTriplet.java @@ -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. @@ -18,54 +18,89 @@ 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(); } + } diff --git a/src/java/org/apache/fop/layoutmgr/TraitSetter.java b/src/java/org/apache/fop/layoutmgr/TraitSetter.java index 482373ad7..e8790173b 100644 --- a/src/java/org/apache/fop/layoutmgr/TraitSetter.java +++ b/src/java/org/apache/fop/layoutmgr/TraitSetter.java @@ -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())); } diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java index 596b91de4..7b6b646f7 100644 --- a/src/java/org/apache/fop/render/PrintRenderer.java +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -19,8 +19,13 @@ 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 diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 9b0e76f33..6bff76bb4 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -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); } diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 70c94dcdb..90d56fc64 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -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 ? " " : ") "; - 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()); diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2D.java b/src/java/org/apache/fop/render/ps/PSGraphics2D.java index 02354dbc7..f85d0474a 100644 --- a/src/java/org/apache/fop/render/ps/PSGraphics2D.java +++ b/src/java/org/apache/fop/render/ps/PSGraphics2D.java @@ -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 { diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index 8d7dfd207..71a948949 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -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 diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java index 7153ea4f5..aba67759c 100644 --- a/src/java/org/apache/fop/render/ps/PSTextPainter.java +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -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 TextNode. @@ -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) { diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index 80431b6c5..37945306b 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -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()); } } } diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 81795984b..edb538df4 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -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; } diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java index 7dcdc283d..c9c4a0c64 100644 --- a/src/java/org/apache/fop/svg/PDFTextPainter.java +++ b/src/java/org/apache/fop/svg/PDFTextPainter.java @@ -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 TextNode. @@ -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); diff --git a/test/layoutengine/standard-testcases/block_font-family.xml b/test/layoutengine/standard-testcases/block_font-family.xml index 9729b7d42..9cb9eee23 100644 --- a/test/layoutengine/standard-testcases/block_font-family.xml +++ b/test/layoutengine/standard-testcases/block_font-family.xml @@ -44,14 +44,14 @@ - - - - - - + + + + + + - + diff --git a/test/layoutengine/standard-testcases/block_font-style.xml b/test/layoutengine/standard-testcases/block_font-style.xml index 326664717..20eebf5c1 100644 --- a/test/layoutengine/standard-testcases/block_font-style.xml +++ b/test/layoutengine/standard-testcases/block_font-style.xml @@ -42,7 +42,7 @@ font-family="sans-serif" font-style="italic" font-family="sans-serif" font-style="oblique" font-family="sans-serif" font-style="backslant" - font-family="serif" font-style="obscure" + font-family="sans-serif" font-style="obscure" font-family="monospace" font-style not given font-family="monospace" font-style="normal" @@ -58,22 +58,28 @@ - + + + - + + + - + + + -- 2.39.5