diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-08-10 09:07:41 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-08-10 09:07:41 +0000 |
commit | 341e9084b34314f83b40013c79d6b7ed83e8223c (patch) | |
tree | fe41c322c377326e881b7eae8712fa3b9d21ba15 /src/java/org/apache | |
parent | 1b8626e3a320588315ec0ae788ae0c3103a97fd3 (diff) | |
download | xmlgraphics-fop-341e9084b34314f83b40013c79d6b7ed83e8223c.tar.gz xmlgraphics-fop-341e9084b34314f83b40013c79d6b7ed83e8223c.zip |
Bugzilla #36067
Support for relative font sizes.
Submitted by: Manuel Mall <mm.at.arcus.com.au>
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@231198 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
3 files changed, 197 insertions, 2 deletions
diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index b90256632..5cf6d2bdc 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -32,6 +32,8 @@ 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.FontSizePropertyMaker; +import org.apache.fop.fo.properties.FontStretchPropertyMaker; import org.apache.fop.fo.properties.GenericShorthandParser; import org.apache.fop.fo.properties.IndentPropertyMaker; import org.apache.fop.fo.properties.KeepProperty; @@ -1081,7 +1083,7 @@ public class FOPropertyMapping implements Constants { addPropertyMaker("font-selection-strategy", m); // font-size - m = new LengthProperty.Maker(PR_FONT_SIZE); + m = new FontSizePropertyMaker(PR_FONT_SIZE); m.setInherited(true); m.setDefault("12pt"); m.addKeyword("xx-small", "6.944pt"); @@ -1091,11 +1093,13 @@ public class FOPropertyMapping implements Constants { m.addKeyword("large", "14.4pt"); m.addKeyword("x-large", "17.28pt"); m.addKeyword("xx-large", "20.736pt"); + m.addEnum("larger", getEnumProperty(EN_LARGER, "LARGER")); + m.addEnum("smaller", getEnumProperty(EN_SMALLER, "SMALLER")); m.setPercentBase(LengthBase.INH_FONTSIZE); addPropertyMaker("font-size", m); // font-stretch - m = new EnumProperty.Maker(PR_FONT_STRETCH); + m = new FontStretchPropertyMaker(PR_FONT_STRETCH); m.addEnum("normal", getEnumProperty(EN_NORMAL, "NORMAL")); m.addEnum("wider", getEnumProperty(EN_WIDER, "WIDER")); m.addEnum("narrower", getEnumProperty(EN_NARROWER, "NARROWER")); diff --git a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java new file mode 100644 index 000000000..83379dfa4 --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java @@ -0,0 +1,96 @@ +/* + * 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.Constants; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +/** + * This subclass of LengthProperty.Maker handles the special treatment of + * relative font sizes described in 7.8.4. + */ +public class FontSizePropertyMaker + extends LengthProperty.Maker implements Constants { + + /** The default normal font size in mpt */ + private static final int FONT_SIZE_NORMAL = 12000; + /** The factor to be applied when stepping font sizes upwards */ + private static final double FONT_SIZE_GROWTH_FACTOR = 1.2; + + /** + * Create a length property which can handle relative font sizes + * @param propId the font size property id. + */ + public FontSizePropertyMaker(int propId) { + super(propId); + } + + /** + * @see PropertyMaker#convertProperty + * Implements the parts of 7.8.4 relevant to relative font sizes + */ + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) throws PropertyException { + if (p.getEnum() == EN_LARGER || p.getEnum() == EN_SMALLER) { + // get the corresponding property from parent + Property pp = propertyList.getFromParent(this.getPropId()); + int baseFontSize = computeClosestAbsoluteFontSize(pp.getLength().getValue()); + if (p.getEnum() == EN_LARGER) { + return new FixedLength((int)Math.round((baseFontSize * FONT_SIZE_GROWTH_FACTOR))); + } else { + return new FixedLength((int)Math.round((baseFontSize / FONT_SIZE_GROWTH_FACTOR))); + } + } + return super.convertProperty(p, propertyList, fo); + } + + /** + * Calculates the nearest absolute font size to the given + * font size. + * @param baseFontSize the font size in mpt of the parent fo + * @return the closest absolute font size + */ + private int computeClosestAbsoluteFontSize(int baseFontSize) { + double scale = FONT_SIZE_GROWTH_FACTOR; + int lastStepFontSize = FONT_SIZE_NORMAL; + if (baseFontSize < FONT_SIZE_NORMAL) { + // Need to shrink the font sizes = scale downwards + scale = 1 / FONT_SIZE_GROWTH_FACTOR; + } + // Calculate the inital next step font size + int nextStepFontSize = (int)Math.round(lastStepFontSize * scale); + while (scale < 1 && nextStepFontSize > baseFontSize + || scale > 1 && nextStepFontSize < baseFontSize) { + // baseFontSize is still bigger (if we grow) or smaller (if we shrink) + // than the last caculated step + lastStepFontSize = nextStepFontSize; + nextStepFontSize = (int)Math.round(lastStepFontSize * scale); + } + // baseFontSize is between last and next step font size + // Return the step value closer to the baseFontSize + if (Math.abs(lastStepFontSize - baseFontSize) + <= Math.abs(baseFontSize - nextStepFontSize)) { + return lastStepFontSize; + } + return nextStepFontSize; + } + +} diff --git a/src/java/org/apache/fop/fo/properties/FontStretchPropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontStretchPropertyMaker.java new file mode 100644 index 000000000..825633206 --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/FontStretchPropertyMaker.java @@ -0,0 +1,95 @@ +/* + * 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.Constants; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +/** + * This subclass of EnumProperty.Maker handles the special treatment of + * relative font stretch values described in 7.8.5. + */ +public class FontStretchPropertyMaker + extends EnumProperty.Maker implements Constants { + + /* Ordered list of absolute font stretch properties so we can easily find the next / + * previous one */ + private Property[] orderedFontStretchValues = null; + + /** + * Create an enum property which can handle relative font stretches + * @param propId the font size property id. + */ + public FontStretchPropertyMaker(int propId) { + super(propId); + } + + /** + * @see PropertyMaker#convertProperty + * Implements the parts of 7.8.5 relevant to relative font stretches + */ + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) throws PropertyException { + // if it is a relative font stretch value get current parent value and step + // up or down accordingly + if (p.getEnum() == EN_NARROWER) { + return computeNextAbsoluteFontStretch(propertyList.getFromParent(this.getPropId()), -1); + } else if (p.getEnum() == EN_WIDER) { + return computeNextAbsoluteFontStretch(propertyList.getFromParent(this.getPropId()), 1); + } + return super.convertProperty(p, propertyList, fo); + } + + /** + * Calculates the nearest absolute font stretch property to the given + * font stretch + * @param baseProperty the font stretch property as set on the parent fo + * @param direction should be -1 to get the next narrower value or +1 for the next wider value + */ + private Property computeNextAbsoluteFontStretch(Property baseProperty, int direction) { + // Create the table entries the first time around + // @todo is this thread safe, do we need to worry about this here? + if (orderedFontStretchValues == null) { + orderedFontStretchValues = new Property[] { + checkEnumValues("ultra-condensed"), + checkEnumValues("extra-condensed"), + checkEnumValues("condensed"), + checkEnumValues("semi-condensed"), + checkEnumValues("normal"), + checkEnumValues("semi-expanded"), + checkEnumValues("expanded"), + checkEnumValues("extra-expanded"), + checkEnumValues("ultra-expanded") + }; + } + int baseValue = baseProperty.getEnum(); + for (int i = 0; i < orderedFontStretchValues.length; i++) { + if (baseValue == orderedFontStretchValues[i].getEnum()) { + // increment/decrement the index and make sure its within the array bounds + i = Math.min(Math.max(0, i + direction), orderedFontStretchValues.length - 1); + return orderedFontStretchValues[i]; + } + } + // return the normal value + return orderedFontStretchValues[4]; + } + +} |