blob: fe9c64cb73cc8ba7eb521a7bb1108f9aaea3cd87 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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);
}
/**
* {@inheritDoc}
* Contrary to basic lengths, percentages for font-size can be resolved
* here already: if the property evaluates to a {@link PercentLength},
* it is immediately replaced by the resolved {@link FixedLength}.
*/
public Property make(PropertyList propertyList, String value, FObj fo)
throws PropertyException {
Property p = super.make(propertyList, value, fo);
if (p instanceof PercentLength) {
Property pp = propertyList.getFromParent(this.propId);
p = FixedLength.getInstance(
pp.getLength().getValue() * ((PercentLength)p).getPercentage() / 100);
}
return p;
}
/**
* {@inheritDoc}
* 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.propId);
int baseFontSize = computeClosestAbsoluteFontSize(pp.getLength().getValue());
if (p.getEnum() == EN_LARGER) {
return FixedLength.getInstance(
Math.round(baseFontSize * FONT_SIZE_GROWTH_FACTOR));
} else {
return FixedLength.getInstance(
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);
if (nextStepFontSize == lastStepFontSize) {
break;
}
}
// 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;
}
}