aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/org/apache/fop/fo/FOPropertyMapping.java3
-rw-r--r--src/java/org/apache/fop/fo/expr/PropertyParser.java20
-rwxr-xr-xsrc/java/org/apache/fop/fo/properties/CommonFont.java38
-rw-r--r--src/java/org/apache/fop/fo/properties/FontFamilyProperty.java85
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java48
-rw-r--r--src/java/org/apache/fop/render/rtf/TextAttributesConverter.java2
-rw-r--r--src/java/org/apache/fop/render/txt/TXTHandler.java2
-rw-r--r--status.xml8
-rw-r--r--test/fotree/testcases/demo-test-success.fo2
-rw-r--r--test/fotree/testcases/no_namespace_prefix.fo2
-rw-r--r--test/layoutengine/standard-testcases/block_font-family.xml6
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">&#2702;</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>