Example: <fo:region-body margin="4pt+20%"/>, property being parsed: margin="4pt+20%", propId = 134.
PropertyParser.parseProperty
next(), which scans the next token; at its return:
this = {
propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 12
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: "4pt"
org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 0
org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 3
org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
}
i.e. the whole expression is a single token, it is of type PropertyTokenizer.TOK_NUMERIC (= 12), the unit is 2 chars long.
Loop forever.
Analyse the expression. Start with parseAdditiveExpr
parseMultiplicativeExpr
parseUnaryExpr
parsePrimaryExpr; the unit may be a relative unit (em) which must be resolved against the font size
construct a property value object:
prop = "4000mpt" prop.getClass() = "class org.apache.fop.fo.properties.FixedLength"
next(): scan for the next token;
this = {
propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 8
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: null
org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 3
org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 4
org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: false
}
the next token is of type currentToken = PropertyTokenizer.TOK_PLUS.
next(): scan for the next token;
this = {
propInfo: instance of org.apache.fop.fo.expr.PropertyInfo(id=736)
org.apache.fop.fo.expr.PropertyTokenizer.currentToken: 14
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenValue: "20%"
org.apache.fop.fo.expr.PropertyTokenizer.currentUnitLength: 2
org.apache.fop.fo.expr.PropertyTokenizer.currentTokenStartIndex: 4
org.apache.fop.fo.expr.PropertyTokenizer.expr: "4pt+20%"
org.apache.fop.fo.expr.PropertyTokenizer.exprIndex: 7
org.apache.fop.fo.expr.PropertyTokenizer.exprLength: 7
org.apache.fop.fo.expr.PropertyTokenizer.recognizeOperator: true
}
the next token is of type currentToken = PropertyTokenizer.TOK_PERCENT. The currentTokenValue 20% is analysed:
parseMultiplicativeExpr
parseUnaryExpr
parsePrimaryExpr
propInfo.getPercentBase: create a PercentBase property
propInfo.getFunctionPercentBase uses a stack of functions stkFunction, which currently == null
if (null) maker.getPercentBase(fo, plist): create and return a LengthBase property, which implements PercentBase
pcBase = "org.apache.fop.datatypes.LengthBase@171f189"
pcBase = {
parentFO: instance of org.apache.fop.fo.pagination.SimplePageMaster(id=786)
propertyList: instance of org.apache.fop.fo.PropertyList(id=807)
iBaseType: 5
}
the value of iBaseType is derived from maker.percentBase == 5 == LengthBase.BLOCK_WIDTH.
pcBase.getDimension; dimension: type of integer, int → 0, length → 1; used by PercentBase and NumericProperty; LengthBase has a dimension of 1
create a PercentLength(pcval, pcBase):
prop = "20.0%"
prop = {
factor: 0.2
lbase: instance of org.apache.fop.datatypes.LengthBase(id=751)
org.apache.fop.fo.properties.Property.specVal: null
}
factor comes from pcval, lbase = pcBase
next(): scan for the next token; the next token is of type currentToken = PropertyTokenizer.TOK_EOF.
return the LengthBase property value object
evalAddition(NumericProperty op1, NumericProperty op2). op1 and op2 are now Numeric, which is an interface implemented by LengthProperty, of which FixedLength and PercentLength are subclasses:
op1 = instance of org.apache.fop.fo.properties.FixedLength(id=744) op2 = instance of org.apache.fop.fo.properties.PercentLength(id=757)
NumericOp.addition
Construct a new RelativeNumericProperty by adding the two properties: RelativeNumericProperty(RelativeNumericProperty.ADDITION, op1, op2)
If currentToken = PropertyTokenizer.TOK_EOF, break the loop.
return the RelativeNumericProperty:
prop = "(4000mpt +20.0%)"
prop = {
operation: 1
op1: instance of org.apache.fop.fo.properties.FixedLength(id=744)
op2: instance of org.apache.fop.fo.properties.PercentLength(id=757)
dimension: 1
org.apache.fop.fo.properties.Property.specVal: null
}
The value 1 for the operation corresponds to RelativeProperty.ADDITION. The value 1 for the dimension indicates that this is a length. PropertyList:
this = "{margin=[(4000mpt +20.0%)]}"