git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@351734 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_91-beta
@@ -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); |
@@ -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"); |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); |
@@ -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 |
@@ -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; |
@@ -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. |
@@ -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> |
@@ -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> |
@@ -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> |