001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.css.engine.value;
020:
021: import org.apache.batik.css.engine.CSSContext;
022: import org.apache.batik.css.engine.CSSEngine;
023: import org.apache.batik.css.engine.CSSStylableElement;
024: import org.apache.batik.css.engine.StyleMap;
025: import org.w3c.css.sac.LexicalUnit;
026: import org.w3c.dom.DOMException;
027: import org.w3c.dom.css.CSSPrimitiveValue;
028: import org.w3c.dom.css.CSSValue;
029:
030: /**
031: * This class provides a manager for the property with support for
032: * length values.
033: *
034: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
035: * @version $Id: LengthManager.java 480490 2006-11-29 09:02:20Z dvholten $
036: */
037: public abstract class LengthManager extends AbstractValueManager {
038:
039: /**
040: * precomputed square-root of 2.0
041: */
042: static final double SQRT2 = Math.sqrt(2.0);
043:
044: /**
045: * Implements {@link ValueManager#createValue(LexicalUnit,CSSEngine)}.
046: */
047: public Value createValue(LexicalUnit lu, CSSEngine engine)
048: throws DOMException {
049: switch (lu.getLexicalUnitType()) {
050: case LexicalUnit.SAC_EM:
051: return new FloatValue(CSSPrimitiveValue.CSS_EMS, lu
052: .getFloatValue());
053:
054: case LexicalUnit.SAC_EX:
055: return new FloatValue(CSSPrimitiveValue.CSS_EXS, lu
056: .getFloatValue());
057:
058: case LexicalUnit.SAC_PIXEL:
059: return new FloatValue(CSSPrimitiveValue.CSS_PX, lu
060: .getFloatValue());
061:
062: case LexicalUnit.SAC_CENTIMETER:
063: return new FloatValue(CSSPrimitiveValue.CSS_CM, lu
064: .getFloatValue());
065:
066: case LexicalUnit.SAC_MILLIMETER:
067: return new FloatValue(CSSPrimitiveValue.CSS_MM, lu
068: .getFloatValue());
069:
070: case LexicalUnit.SAC_INCH:
071: return new FloatValue(CSSPrimitiveValue.CSS_IN, lu
072: .getFloatValue());
073:
074: case LexicalUnit.SAC_POINT:
075: return new FloatValue(CSSPrimitiveValue.CSS_PT, lu
076: .getFloatValue());
077:
078: case LexicalUnit.SAC_PICA:
079: return new FloatValue(CSSPrimitiveValue.CSS_PC, lu
080: .getFloatValue());
081:
082: case LexicalUnit.SAC_INTEGER:
083: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, lu
084: .getIntegerValue());
085:
086: case LexicalUnit.SAC_REAL:
087: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, lu
088: .getFloatValue());
089:
090: case LexicalUnit.SAC_PERCENTAGE:
091: return new FloatValue(CSSPrimitiveValue.CSS_PERCENTAGE, lu
092: .getFloatValue());
093: }
094: throw createInvalidLexicalUnitDOMException(lu
095: .getLexicalUnitType());
096: }
097:
098: /**
099: * Implements {@link ValueManager#createFloatValue(short,float)}.
100: */
101: public Value createFloatValue(short type, float floatValue)
102: throws DOMException {
103: switch (type) {
104: case CSSPrimitiveValue.CSS_PERCENTAGE:
105: case CSSPrimitiveValue.CSS_EMS:
106: case CSSPrimitiveValue.CSS_EXS:
107: case CSSPrimitiveValue.CSS_PX:
108: case CSSPrimitiveValue.CSS_CM:
109: case CSSPrimitiveValue.CSS_MM:
110: case CSSPrimitiveValue.CSS_IN:
111: case CSSPrimitiveValue.CSS_PT:
112: case CSSPrimitiveValue.CSS_PC:
113: case CSSPrimitiveValue.CSS_NUMBER:
114: return new FloatValue(type, floatValue);
115: }
116: throw createInvalidFloatTypeDOMException(type);
117: }
118:
119: /**
120: * Implements {@link
121: * ValueManager#computeValue(CSSStylableElement,String,CSSEngine,int,StyleMap,Value)}.
122: */
123: public Value computeValue(CSSStylableElement elt, String pseudo,
124: CSSEngine engine, int idx, StyleMap sm, Value value) {
125: if (value.getCssValueType() != CSSValue.CSS_PRIMITIVE_VALUE) {
126: return value;
127: }
128:
129: switch (value.getPrimitiveType()) {
130: case CSSPrimitiveValue.CSS_NUMBER:
131: case CSSPrimitiveValue.CSS_PX:
132: return value;
133:
134: case CSSPrimitiveValue.CSS_MM:
135: CSSContext ctx = engine.getCSSContext();
136: float v = value.getFloatValue();
137: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v
138: / ctx.getPixelUnitToMillimeter());
139:
140: case CSSPrimitiveValue.CSS_CM:
141: ctx = engine.getCSSContext();
142: v = value.getFloatValue();
143: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v * 10f
144: / ctx.getPixelUnitToMillimeter());
145:
146: case CSSPrimitiveValue.CSS_IN:
147: ctx = engine.getCSSContext();
148: v = value.getFloatValue();
149: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v
150: * 25.4f / ctx.getPixelUnitToMillimeter());
151:
152: case CSSPrimitiveValue.CSS_PT:
153: ctx = engine.getCSSContext();
154: v = value.getFloatValue();
155: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v
156: * 25.4f / (72f * ctx.getPixelUnitToMillimeter()));
157:
158: case CSSPrimitiveValue.CSS_PC:
159: ctx = engine.getCSSContext();
160: v = value.getFloatValue();
161: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER,
162: (v * 25.4f / (6f * ctx.getPixelUnitToMillimeter())));
163:
164: case CSSPrimitiveValue.CSS_EMS:
165: sm.putFontSizeRelative(idx, true);
166:
167: v = value.getFloatValue();
168: int fsidx = engine.getFontSizeIndex();
169: float fs;
170: fs = engine.getComputedStyle(elt, pseudo, fsidx)
171: .getFloatValue();
172: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v * fs);
173:
174: case CSSPrimitiveValue.CSS_EXS:
175: sm.putFontSizeRelative(idx, true);
176:
177: v = value.getFloatValue();
178: fsidx = engine.getFontSizeIndex();
179: fs = engine.getComputedStyle(elt, pseudo, fsidx)
180: .getFloatValue();
181: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, v * fs
182: * 0.5f);
183:
184: case CSSPrimitiveValue.CSS_PERCENTAGE:
185: ctx = engine.getCSSContext();
186: switch (getOrientation()) {
187: case HORIZONTAL_ORIENTATION:
188: sm.putBlockWidthRelative(idx, true);
189: fs = value.getFloatValue() * ctx.getBlockWidth(elt)
190: / 100f;
191: break;
192: case VERTICAL_ORIENTATION:
193: sm.putBlockHeightRelative(idx, true);
194: fs = value.getFloatValue() * ctx.getBlockHeight(elt)
195: / 100f;
196: break;
197: default: // Both
198: sm.putBlockWidthRelative(idx, true);
199: sm.putBlockHeightRelative(idx, true);
200: double w = ctx.getBlockWidth(elt);
201: double h = ctx.getBlockHeight(elt);
202: fs = (float) (value.getFloatValue()
203: * (Math.sqrt(w * w + h * h) / SQRT2) / 100.0);
204: }
205: return new FloatValue(CSSPrimitiveValue.CSS_NUMBER, fs);
206: }
207: return value;
208: }
209:
210: //
211: // Orientation enumeration
212: //
213: protected static final int HORIZONTAL_ORIENTATION = 0;
214: protected static final int VERTICAL_ORIENTATION = 1;
215: protected static final int BOTH_ORIENTATION = 2;
216:
217: /**
218: * Indicates the orientation of the property associated with
219: * this manager.
220: */
221: protected abstract int getOrientation();
222: }
|