diff options
-rw-r--r-- | src/java/org/apache/fop/fo/FOPropertyMapping.java | 3 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/expr/PropertyParser.java | 20 | ||||
-rwxr-xr-x | src/java/org/apache/fop/fo/properties/CommonFont.java | 38 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/properties/FontFamilyProperty.java | 85 | ||||
-rw-r--r-- | src/java/org/apache/fop/fonts/FontInfo.java | 48 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/rtf/TextAttributesConverter.java | 2 | ||||
-rw-r--r-- | src/java/org/apache/fop/render/txt/TXTHandler.java | 2 | ||||
-rw-r--r-- | status.xml | 8 | ||||
-rw-r--r-- | test/fotree/testcases/demo-test-success.fo | 2 | ||||
-rw-r--r-- | test/fotree/testcases/no_namespace_prefix.fo | 2 | ||||
-rw-r--r-- | test/layoutengine/standard-testcases/block_font-family.xml | 6 |
11 files changed, 196 insertions, 20 deletions
diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index a47aaa4ad..168658a29 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -33,6 +33,7 @@ import org.apache.fop.fo.properties.CondLengthProperty; import org.apache.fop.fo.properties.CorrespondingPropertyMaker; import org.apache.fop.fo.properties.DimensionPropertyMaker; import org.apache.fop.fo.properties.EnumProperty; +import org.apache.fop.fo.properties.FontFamilyProperty; import org.apache.fop.fo.properties.FontSizePropertyMaker; import org.apache.fop.fo.properties.FontStretchPropertyMaker; import org.apache.fop.fo.properties.GenericShorthandParser; @@ -1074,7 +1075,7 @@ public class FOPropertyMapping implements Constants { PropertyMaker m; // font-family - m = new StringProperty.Maker(PR_FONT_FAMILY); + m = new FontFamilyProperty.Maker(PR_FONT_FAMILY); m.setInherited(true); m.setDefault("sans-serif"); addPropertyMaker("font-family", m); diff --git a/src/java/org/apache/fop/fo/expr/PropertyParser.java b/src/java/org/apache/fop/fo/expr/PropertyParser.java index f517c5f67..47b4584d6 100644 --- a/src/java/org/apache/fop/fo/expr/PropertyParser.java +++ b/src/java/org/apache/fop/fo/expr/PropertyParser.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. @@ -35,7 +35,7 @@ import java.util.HashMap; * This class is heavily based on the epxression parser in James Clark's * XT, an XSLT processor. */ -public class PropertyParser extends PropertyTokenizer { +public final class PropertyParser extends PropertyTokenizer { private PropertyInfo propInfo; // Maker and propertyList related info private static final String RELUNIT = "em"; @@ -156,8 +156,7 @@ public class PropertyParser extends PropertyTokenizer { break; case TOK_MINUS: next(); - prop = - evalSubtraction(prop.getNumeric(), + prop = evalSubtraction(prop.getNumeric(), parseMultiplicativeExpr().getNumeric()); break; default: @@ -215,7 +214,7 @@ public class PropertyParser extends PropertyTokenizer { * Checks that the current token is a right parenthesis * and throws an exception if this isn't the case. */ - private final void expectRpar() throws PropertyException { + private void expectRpar() throws PropertyException { if (currentToken != TOK_RPAR) { throw new PropertyException("expected )"); } @@ -232,6 +231,10 @@ public class PropertyParser extends PropertyTokenizer { */ private Property parsePrimaryExpr() throws PropertyException { Property prop; + if (currentToken == TOK_COMMA) { + //Simply skip commas, for example for font-family + next(); + } switch (currentToken) { case TOK_LPAR: next(); @@ -296,9 +299,8 @@ public class PropertyParser extends PropertyTokenizer { prop = new ColorTypeProperty(currentTokenValue); break; - case TOK_FUNCTION_LPAR: { - Function function = - (Function)FUNCTION_TABLE.get(currentTokenValue); + case TOK_FUNCTION_LPAR: + Function function = (Function)FUNCTION_TABLE.get(currentTokenValue); if (function == null) { throw new PropertyException("no such function: " + currentTokenValue); @@ -309,7 +311,7 @@ public class PropertyParser extends PropertyTokenizer { prop = function.eval(parseArgs(function.nbArgs()), propInfo); propInfo.popFunction(); return prop; - } + default: // TODO: add the token or the expr to the error message. throw new PropertyException("syntax error"); diff --git a/src/java/org/apache/fop/fo/properties/CommonFont.java b/src/java/org/apache/fop/fo/properties/CommonFont.java index fb1c53236..5664bd1b1 100755 --- a/src/java/org/apache/fop/fo/properties/CommonFont.java +++ b/src/java/org/apache/fop/fo/properties/CommonFont.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 The Apache Software Foundation. + * Copyright 2004-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. @@ -19,6 +19,8 @@ package org.apache.fop.fo.properties; // FOP +import java.util.List; + import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.Numeric; import org.apache.fop.datatypes.PercentBaseContext; @@ -37,7 +39,7 @@ public class CommonFont { /** * The "font-family" property. */ - public String fontFamily; + private String[] fontFamily; /** * The "font-selection-strategy" property. @@ -81,7 +83,15 @@ public class CommonFont { * @param pList The PropertyList to get properties from. */ public CommonFont(PropertyList pList) throws PropertyException { - fontFamily = pList.get(Constants.PR_FONT_FAMILY).getString(); + List lst = pList.get(Constants.PR_FONT_FAMILY).getList(); + fontFamily = new String[lst.size()]; + for (int i = 0, c = lst.size(); i < c; i++) { + fontFamily[i] = ((Property)lst.get(i)).getString(); + } + if (fontFamily.length == 0) { + //Shouldn't happen, but we never know. + fontFamily = new String[] {"any"}; + } fontSelectionStrategy = pList.get(Constants.PR_FONT_SELECTION_STRATEGY).getEnum(); fontSize = pList.get(Constants.PR_FONT_SIZE).getLength(); fontStretch = pList.get(Constants.PR_FONT_STRETCH).getEnum(); @@ -91,6 +101,25 @@ public class CommonFont { fontWeight = pList.get(Constants.PR_FONT_WEIGHT).getEnum(); } + /** @return the first font-family name in the list */ + public String getFirstFontFamily() { + return this.fontFamily[0]; + } + + /** @return the font-family names */ + public String[] getFontFamily() { + return this.fontFamily; + } + + /** + * Overrides the font-family. + * @param value the new font-family + */ + public void overrideFontFamily(String value) { + this.fontFamily = new String[] {value}; + + } + /** * Create and return a Font object based on the properties. * @@ -135,11 +164,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(fontFamily, style, + String fname = fontInfo.fontLookup(getFontFamily(), style, font_weight); FontMetrics metrics = fontInfo.getMetricsFor(fname); fontState = new Font(fname, metrics, fontSize.getValue(context)); } return fontState; } + } diff --git a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java new file mode 100644 index 000000000..d699ccf09 --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java @@ -0,0 +1,85 @@ +/* + * Copyright 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. + * 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.fo.properties; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; + +/** + * Property class for the font-family property. + */ +public class FontFamilyProperty extends ListProperty { + + /** + * Inner class for creating instances of ListProperty + */ + public static class Maker extends PropertyMaker { + + /** + * @param propId ID of the property for which Maker should be created + */ + public Maker(int propId) { + super(propId); + } + + /** + * @see PropertyMaker#convertProperty + */ + public Property convertProperty(Property p, + PropertyList propertyList, FObj fo) { + if (p instanceof FontFamilyProperty) { + return p; + } else { + return new FontFamilyProperty(p); + } + } + + } + + /** + * @param prop the first Property to be added to the list + */ + public FontFamilyProperty(Property prop) { + super(); + addProperty(prop); + } + + /** + * Add a new property to the list + * @param prop Property to be added to the list + */ + public void addProperty(Property prop) { + if (prop.getList() != null) { + list.addAll(prop.getList()); + } else { + super.addProperty(prop); + } + } + + /** @see org.apache.fop.fo.properties.Property#getString() */ + public String getString() { + if (list.size() > 0) { + Property first = (Property)list.get(0); + return first.getString(); + } else { + return super.getString(); + } + } + +} diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java index cb50804bf..e1bc87884 100644 --- a/src/java/org/apache/fop/fonts/FontInfo.java +++ b/src/java/org/apache/fop/fonts/FontInfo.java @@ -111,10 +111,11 @@ public class FontInfo { * @param family font family * @param style font style * @param weight font weight + * @param substFont true if the font may be substituted with the default font if not found * @return internal key */ - public String fontLookup(String family, String style, - int weight) { + private String fontLookup(String family, String style, + int weight, boolean substFont) { String key; // first try given parameters key = createFontKey(family, style, weight); @@ -123,6 +124,9 @@ public class FontInfo { // then adjust weight, favouring normal or bold f = findAdjustWeight(family, style, weight); + if (!substFont && f == null) { + return null; + } // then try any family with orig weight if (f == null) { notifyFontReplacement(key); @@ -141,6 +145,46 @@ public class FontInfo { return f; } + /** + * Lookup a font. + * <br> + * 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) { + return fontLookup(family, style, weight, true); + } + + /** + * Lookup a font. + * <br> + * 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 (priority list) + * @param style font style + * @param weight font weight + * @return internal key + */ + public String 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; + } + } + throw new IllegalStateException("fontLookup must return a key on the last call"); + } + private void notifyFontReplacement(String key) { if (loggedFontKeys == null) { loggedFontKeys = new java.util.HashSet(); diff --git a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java index ec8abe7b8..df6c0a1fe 100644 --- a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java +++ b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java @@ -132,7 +132,7 @@ class TextAttributesConverter { private static void attrFont(CommonFont font, FOPRtfAttributes rtfAttr) { rtfAttr.set(RtfText.ATTR_FONT_FAMILY, - RtfFontManager.getInstance().getFontNumber(font.fontFamily)); + RtfFontManager.getInstance().getFontNumber(font.getFirstFontFamily())); rtfAttr.setHalfPoints(RtfText.ATTR_FONT_SIZE, font.fontSize); if (font.fontWeight == Constants.EN_700 diff --git a/src/java/org/apache/fop/render/txt/TXTHandler.java b/src/java/org/apache/fop/render/txt/TXTHandler.java index 87e6defee..671f8aa58 100644 --- a/src/java/org/apache/fop/render/txt/TXTHandler.java +++ b/src/java/org/apache/fop/render/txt/TXTHandler.java @@ -385,7 +385,7 @@ public class TXTHandler extends AreaTreeHandler { */ private void modifyCommonFont(CommonFont cf) { if (cf != null) { - cf.fontFamily = "Courier"; + cf.overrideFontFamily("Courier"); cf.fontSize = new FixedLength(MODIFIED_FONT_SIZE); cf.fontStretch = Constants.EN_NORMAL; cf.fontWeight = Constants.EN_NORMAL; diff --git a/status.xml b/status.xml index f15cce4ba..ae285e105 100644 --- a/status.xml +++ b/status.xml @@ -27,6 +27,14 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="JM" type="add"> + font-family list still not fully supported but a comma-separated list is now properly tokenized. + FOP will now go through all fonts in the list to find one that is available, but it doesn't + do so per character, yet. + </action> + <action context="Code" dev="JM" type="add"> + Implemented "Overconstrained Geometry" rules (5.3.4, XSL 1.0) for the most important cases. + </action> <action context="Code" dev="JM" type="fix"> Bugfix: Relatively positioned BlockViewports (from block-containers) caused the paint cursor not be be properly advanced when space-before or space-after were present. diff --git a/test/fotree/testcases/demo-test-success.fo b/test/fotree/testcases/demo-test-success.fo index 7912c9114..b80ad7807 100644 --- a/test/fotree/testcases/demo-test-success.fo +++ b/test/fotree/testcases/demo-test-success.fo @@ -8,7 +8,7 @@ <fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<fo:block>Hello World!
- <test:assert property="font-family" expected="sans-serif"/>
+ <test:assert property="font-family" expected="[sans-serif]"/>
<test:assert property="font-size" expected="12000mpt"/>
</fo:block>
<fo:block font-family="ZapfDingbats">઎</fo:block>
diff --git a/test/fotree/testcases/no_namespace_prefix.fo b/test/fotree/testcases/no_namespace_prefix.fo index 53b53ec98..ed054e3cb 100644 --- a/test/fotree/testcases/no_namespace_prefix.fo +++ b/test/fotree/testcases/no_namespace_prefix.fo @@ -25,7 +25,7 @@ <page-sequence master-reference="A4"> <flow flow-name="xsl-region-body"> <block>Hello World! - <test:assert property="font-family" expected="sans-serif"/> + <test:assert property="font-family" expected="[sans-serif]"/> <test:assert property="font-size" expected="12000mpt"/> </block> </flow> diff --git a/test/layoutengine/standard-testcases/block_font-family.xml b/test/layoutengine/standard-testcases/block_font-family.xml index 2f7bb6a0e..9144048b4 100644 --- a/test/layoutengine/standard-testcases/block_font-family.xml +++ b/test/layoutengine/standard-testcases/block_font-family.xml @@ -36,6 +36,9 @@ <fo:block font-family="cursive">font-family="cursive"</fo:block> <fo:block font-family="fantasy">font-family="fantasy"</fo:block> <fo:block font-family="monospace">font-family="monospace"</fo:block> + <fo:block font-family="Helvetica,sans-serif,Symbol">font-family="Helvetica,sans-serif,Symbol"</fo:block> + <fo:block font-family="Helvetica, sans-serif, Symbol">font-family="Helvetica, sans-serif, Symbol"</fo:block> + <fo:block font-family="fantasy1,fantasy2,monospace,Symbol">font-family="fantasy1,fantasy2,monospace,Symbol"</fo:block> </fo:flow> </fo:page-sequence> </fo:root> @@ -47,5 +50,8 @@ <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="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"/> </checks> </testcase> |