From 341e9084b34314f83b40013c79d6b7ed83e8223c Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 10 Aug 2005 09:07:41 +0000 Subject: [PATCH] Bugzilla #36067 Support for relative font sizes. Submitted by: Manuel Mall git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@231198 13f79535-47bb-0310-9956-ffa450edef68 --- .../content/xdocs/compliance.ihtml | 42 +++-- .../org/apache/fop/fo/FOPropertyMapping.java | 8 +- .../fo/properties/FontSizePropertyMaker.java | 96 ++++++++++ .../properties/FontStretchPropertyMaker.java | 95 ++++++++++ test/layoutengine/disabled-testcases.txt | 1 - .../testcases/font-size-percentage.xml | 30 ++++ .../testcases/font-size-relative.xml | 164 ++++++++++-------- 7 files changed, 344 insertions(+), 92 deletions(-) create mode 100644 src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java create mode 100644 src/java/org/apache/fop/fo/properties/FontStretchPropertyMaker.java diff --git a/src/documentation/content/xdocs/compliance.ihtml b/src/documentation/content/xdocs/compliance.ihtml index b289d4589..3304ec7be 100644 --- a/src/documentation/content/xdocs/compliance.ihtml +++ b/src/documentation/content/xdocs/compliance.ihtml @@ -2854,19 +2854,16 @@ §7.8.4 - - yes - partial + + yes + @@ -2921,14 +2918,18 @@ §7.8.7 - - yes + + partial yes - -   + + @@ -2961,14 +2962,21 @@ §7.8.9 - - yes + + partial - - yes + + partial - -   + + 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]; + } + +} diff --git a/test/layoutengine/disabled-testcases.txt b/test/layoutengine/disabled-testcases.txt index 78c1965ec..73069a6d6 100644 --- a/test/layoutengine/disabled-testcases.txt +++ b/test/layoutengine/disabled-testcases.txt @@ -1,6 +1,5 @@ external-graphic1.xml external-graphic2.xml -font-size-relative.xml inline1.xml keep-with-previous2.xml keep-with-previous3.xml diff --git a/test/layoutengine/testcases/font-size-percentage.xml b/test/layoutengine/testcases/font-size-percentage.xml index d4ac26d9e..dc906e249 100644 --- a/test/layoutengine/testcases/font-size-percentage.xml +++ b/test/layoutengine/testcases/font-size-percentage.xml @@ -140,5 +140,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/layoutengine/testcases/font-size-relative.xml b/test/layoutengine/testcases/font-size-relative.xml index a46cb0f7b..8dc3dbf8c 100644 --- a/test/layoutengine/testcases/font-size-relative.xml +++ b/test/layoutengine/testcases/font-size-relative.xml @@ -24,124 +24,144 @@ - + - font-family="serif" font-size not specified - font-family="serif" font-size="smaller" - font-family="serif" font-size="smaller" - font-family="serif" font-size="smaller" - font-family="serif" font-size="smaller" - font-family="serif" font-size="smaller" - + font-size="36pt" + font-size="smaller" + font-size="smaller" + font-size="larger" + font-size="larger" - font-family="serif" font-size not specified - font-family="serif" font-size="larger" - font-family="serif" font-size="larger" - font-family="serif" font-size="larger" - font-family="serif" font-size="larger" - font-family="serif" font-size="larger" - + font-size="24pt" + font-size="smaller" + font-size="smaller" + font-size="larger" + font-size="larger" - font-family="sans-serif" font-size not specified - font-family="sans-serif" font-size="smaller" - font-family="sans-serif" font-size="smaller" - font-family="sans-serif" font-size="smaller" - font-family="sans-serif" font-size="smaller" - font-family="sans-serif" font-size="smaller" - + font-size="12pt" + font-size="smaller" + font-size="smaller" + font-size="larger" + font-size="larger" - font-family="sans-serif" font-size not specified - font-family="sans-serif" font-size="larger" - font-family="sans-serif" font-size="larger" - font-family="sans-serif" font-size="larger" - font-family="sans-serif" font-size="larger" - font-family="sans-serif" font-size="larger" - + font-size="6pt" + font-size="smaller" + font-size="smaller" + font-size="larger" + font-size="larger" - font-family="monospace" font-size not specified - font-family="monospace" font-size="smaller" - font-family="monospace" font-size="smaller" - font-family="monospace" font-size="smaller" - font-family="monospace" font-size="smaller" - font-family="monospace" font-size="smaller" - + font-size="6pt" + font-size="larger" + font-size="larger" + font-size="smaller" + font-size="smaller" - font-family="monospace" font-size not specified - font-family="monospace" font-size="larger" - font-family="monospace" font-size="larger" - font-family="monospace" font-size="larger" - font-family="monospace" font-size="larger" - font-family="monospace" font-size="larger" - + font-size="12pt" + font-size="larger" + font-size="larger" + font-size="smaller" + font-size="smaller" + font-size="24pt" + font-size="larger" + font-size="larger" + font-size="smaller" + font-size="smaller" + + + + + + font-size="36pt" + font-size="larger" + font-size="larger" + font-size="smaller" + font-size="smaller" + + + + + + font-size="larger" + font-size="larger" + font-size="smaller" + font-size="smaller" + + + + - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + + + + + + + + + + -- 2.39.5