001: /*
002:
003: ============================================================================
004: The Apache Software License, Version 1.1
005: ============================================================================
006:
007: Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
008:
009: Redistribution and use in source and binary forms, with or without modifica-
010: tion, are permitted provided that the following conditions are met:
011:
012: 1. Redistributions of source code must retain the above copyright notice,
013: this list of conditions and the following disclaimer.
014:
015: 2. Redistributions in binary form must reproduce the above copyright notice,
016: this list of conditions and the following disclaimer in the documentation
017: and/or other materials provided with the distribution.
018:
019: 3. The end-user documentation included with the redistribution, if any, must
020: include the following acknowledgment: "This product includes software
021: developed by the Apache Software Foundation (http://www.apache.org/)."
022: Alternately, this acknowledgment may appear in the software itself, if
023: and wherever such third-party acknowledgments normally appear.
024:
025: 4. The names "Batik" and "Apache Software Foundation" must not be
026: used to endorse or promote products derived from this software without
027: prior written permission. For written permission, please contact
028: apache@apache.org.
029:
030: 5. Products derived from this software may not be called "Apache", nor may
031: "Apache" appear in their name, without prior written permission of the
032: Apache Software Foundation.
033:
034: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
035: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
036: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
037: APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
038: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
039: DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
040: OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
041: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
042: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
043: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045: This software consists of voluntary contributions made by many individuals
046: on behalf of the Apache Software Foundation. For more information on the
047: Apache Software Foundation, please see <http://www.apache.org/>.
048:
049: */
050:
051: package org.apache.batik.css.engine;
052:
053: import org.apache.batik.css.engine.value.Value;
054:
055: /**
056: * This class represents objects which contains property/value mappings.
057: *
058: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
059: * @version $Id$
060: */
061: public class StyleMap {
062:
063: //
064: // The masks
065: //
066: public final static short IMPORTANT_MASK = 0x0001;
067: public final static short COMPUTED_MASK = 0x0002;
068: public final static short NULL_CASCADED_MASK = 0x0004;
069:
070: public final static short LINE_HEIGHT_RELATIVE_MASK = 0x0008;
071: public final static short FONT_SIZE_RELATIVE_MASK = 0x0010;
072:
073: // BEGIN RAVE MODIFICATIONS
074: // We need a bit in this bitmask.... and the bitmask is full!! (I don't
075: // want to grow from 16 bits to 32)
076: // However it turns out COLOR_RELATIVE_MASK is unused... so I'll snag
077: // it for my own purposes
078: // See also putColorRelative which is commented out as well
079: //public final static short COLOR_RELATIVE_MASK = 0x0020;
080: public final static short INHERITED_MASK = 0x0020;
081: // END RAVE MODIFICATIONS
082:
083: public final static short PARENT_RELATIVE_MASK = 0x0040;
084: public final static short BLOCK_WIDTH_RELATIVE_MASK = 0x0080;
085: public final static short BLOCK_HEIGHT_RELATIVE_MASK = 0x0100;
086: public final static short BOX_RELATIVE_MASK = 0x0200;
087:
088: public final static short ORIGIN_MASK = (short) 0xE000; // 3 last bits
089:
090: //
091: // The origin values.
092: //
093: public final static short USER_AGENT_ORIGIN = 0;
094: public final static short USER_ORIGIN = 0x2000; // 0010
095: public final static short NON_CSS_ORIGIN = 0x4000; // 0100
096: public final static short AUTHOR_ORIGIN = 0x6000; // 0110
097: public final static short INLINE_AUTHOR_ORIGIN = (short) 0x8000; // 1000
098:
099: /**
100: * The values.
101: */
102: protected Value[] values;
103:
104: /**
105: * To store the value masks.
106: */
107: protected short[] masks;
108:
109: /**
110: * Whether the values of this map cannot be re-cascaded.
111: */
112: protected boolean fixedCascadedValues;
113:
114: /**
115: * Creates a new StyleMap.
116: */
117: public StyleMap(int size) {
118: values = new Value[size];
119: masks = new short[size];
120: }
121:
122: /**
123: * Whether this map has fixed cascaded value.
124: */
125: public boolean hasFixedCascadedValues() {
126: return fixedCascadedValues;
127: }
128:
129: /**
130: * Sets the fixedCascadedValues property.
131: */
132: public void setFixedCascadedStyle(boolean b) {
133: fixedCascadedValues = b;
134: }
135:
136: /**
137: * Returns the value at the given index, null if unspecified.
138: */
139: public Value getValue(int i) {
140: return values[i];
141: }
142:
143: /**
144: * Returns the mask of the given property value.
145: */
146: public short getMask(int i) {
147: return masks[i];
148: }
149:
150: /**
151: * Tells whether the given property value is important.
152: */
153: public boolean isImportant(int i) {
154: return (masks[i] & IMPORTANT_MASK) != 0;
155: }
156:
157: /**
158: * Tells whether the given property value is computed.
159: */
160: public boolean isComputed(int i) {
161: return (masks[i] & COMPUTED_MASK) != 0;
162: }
163:
164: /**
165: * Tells whether the given cascaded property value is null.
166: */
167: public boolean isNullCascaded(int i) {
168: return (masks[i] & NULL_CASCADED_MASK) != 0;
169: }
170:
171: /**
172: * Returns the origin value.
173: */
174: public short getOrigin(int i) {
175: return (short) (masks[i] & ORIGIN_MASK);
176: }
177:
178: /**
179: * Tells whether the given property value is relative to 'color'.
180: */
181: public boolean isColorRelative(int i) {
182: // BEGIN RAVE MODIFICATIONS
183: //return (masks[i] & COLOR_RELATIVE_MASK) != 0;
184: // Nobody was setting it (putColorRelative was unused)
185: // so I've reused the bitmask position for color relative
186: // and I'm just returning false here
187: return false;
188: // END RAVE MODIFICATIONS
189: }
190:
191: /**
192: * Tells whether the given property value is relative to the parent's
193: * property value.
194: */
195: public boolean isParentRelative(int i) {
196: return (masks[i] & PARENT_RELATIVE_MASK) != 0;
197: }
198:
199: /**
200: * Tells whether the given property value is relative to 'line-height'.
201: */
202: public boolean isLineHeightRelative(int i) {
203: return (masks[i] & LINE_HEIGHT_RELATIVE_MASK) != 0;
204: }
205:
206: /**
207: * Tells whether the given property value is relative to 'font-size'.
208: */
209: public boolean isFontSizeRelative(int i) {
210: return (masks[i] & FONT_SIZE_RELATIVE_MASK) != 0;
211: }
212:
213: /**
214: * Tells whether the given property value is relative to the
215: * width of the containing block.
216: */
217: public boolean isBlockWidthRelative(int i) {
218: return (masks[i] & BLOCK_WIDTH_RELATIVE_MASK) != 0;
219: }
220:
221: /**
222: * Tells whether the given property value is relative to the
223: * height of the containing block.
224: */
225: public boolean isBlockHeightRelative(int i) {
226: return (masks[i] & BLOCK_HEIGHT_RELATIVE_MASK) != 0;
227: }
228:
229: /**
230: * Puts a property value, given the property index.
231: * @param i The property index.
232: * @param v The property value.
233: */
234: public void putValue(int i, Value v) {
235: values[i] = v;
236: }
237:
238: /**
239: * Puts a property mask, given the property index.
240: * @param i The property index.
241: * @param m The property mask.
242: */
243: public void putMask(int i, short m) {
244: masks[i] = m;
245: }
246:
247: /**
248: * Sets the priority of a property value.
249: */
250: public void putImportant(int i, boolean b) {
251: masks[i] &= ~IMPORTANT_MASK;
252: masks[i] |= (b) ? IMPORTANT_MASK : 0;
253: }
254:
255: /**
256: * Sets the origin of the given value.
257: */
258: public void putOrigin(int i, short val) {
259: masks[i] &= ~ORIGIN_MASK;
260: masks[i] |= (short) (val & ORIGIN_MASK);
261: }
262:
263: /**
264: * Sets the computed flag of a property value.
265: */
266: public void putComputed(int i, boolean b) {
267: masks[i] &= ~COMPUTED_MASK;
268: masks[i] |= (b) ? COMPUTED_MASK : 0;
269: }
270:
271: /**
272: * Sets the null-cascaded flag of a property value.
273: */
274: public void putNullCascaded(int i, boolean b) {
275: masks[i] &= ~NULL_CASCADED_MASK;
276: masks[i] |= (b) ? NULL_CASCADED_MASK : 0;
277: }
278:
279: // BEGIN RAVE MODIFICATIONS
280: // Color relative was unused so I'm reusing the bit position
281: // for tracking whether a property is inherited.
282: // /**
283: // * Sets the color-relative flag of a property value.
284: // */
285: // public void putColorRelative(int i, boolean b) {
286: // masks[i] &= ~COLOR_RELATIVE_MASK;
287: // masks[i] |= (b) ? COLOR_RELATIVE_MASK : 0;
288: // }
289:
290: /**
291: * Tells whether the given property has been inherited
292: */
293: public boolean isInherited(int i) {
294: return (masks[i] & INHERITED_MASK) != 0;
295: }
296:
297: /**
298: * Sets the color-relative flag of a property value.
299: */
300: public void putInherited(int i, boolean b) {
301: masks[i] &= ~INHERITED_MASK;
302: masks[i] |= (b) ? INHERITED_MASK : 0;
303: }
304:
305: // END RAVE MODIFICATIONS
306:
307: /**
308: * Sets the parent-relative flag of a property value.
309: */
310: public void putParentRelative(int i, boolean b) {
311: masks[i] &= ~PARENT_RELATIVE_MASK;
312: masks[i] |= (b) ? PARENT_RELATIVE_MASK : 0;
313: }
314:
315: /**
316: * Sets the line-height-relative flag of a property value.
317: */
318: public void putLineHeightRelative(int i, boolean b) {
319: masks[i] &= ~LINE_HEIGHT_RELATIVE_MASK;
320: masks[i] |= (b) ? LINE_HEIGHT_RELATIVE_MASK : 0;
321: }
322:
323: /**
324: * Sets the font-size-relative flag of a property value.
325: */
326: public void putFontSizeRelative(int i, boolean b) {
327: masks[i] &= ~FONT_SIZE_RELATIVE_MASK;
328: masks[i] |= (b) ? FONT_SIZE_RELATIVE_MASK : 0;
329: }
330:
331: /**
332: * Sets the block-width-relative flag of a property value.
333: */
334: public void putBlockWidthRelative(int i, boolean b) {
335: masks[i] &= ~BLOCK_WIDTH_RELATIVE_MASK;
336: masks[i] |= (b) ? BLOCK_WIDTH_RELATIVE_MASK : 0;
337: }
338:
339: /**
340: * Sets the block-height-relative flag of a property value.
341: */
342: public void putBlockHeightRelative(int i, boolean b) {
343: masks[i] &= ~BLOCK_HEIGHT_RELATIVE_MASK;
344: masks[i] |= (b) ? BLOCK_HEIGHT_RELATIVE_MASK : 0;
345: }
346:
347: /**
348: * Returns a printable representation of this style map.
349: */
350: public String toString(CSSEngine eng) {
351: StringBuffer sb = new StringBuffer();
352: for (int i = 0; i < values.length; i++) {
353: Value v = values[i];
354: if (v != null) {
355: sb.append(eng.getPropertyName(i));
356: sb.append(": ");
357: sb.append(v);
358: if (isImportant(i)) {
359: sb.append(" !important");
360: }
361: sb.append(";\n");
362: }
363: }
364: return sb.toString();
365: }
366:
367: // BEGIN RAVE MODIFICATIONS
368: /** Return the size of the stylemap.
369: * @param total If true, return the number of available slots, not necessarily set in this map.
370: * If false, return only the number of non-null entries in the map.
371: */
372: public int getSize(boolean total) {
373: if (total) {
374: return values.length;
375: } else {
376: int count = 0;
377: for (int i = 0, n = values.length; i < n; i++) {
378: Value v = values[i];
379: if (v != null) {
380: count++;
381: }
382: }
383: return count;
384: }
385: }
386:
387: /**
388: * Returns a single line string suitable as a "style" attribute
389: * for an element. Note - this is not for debugging so don't put
390: * arbitrary info in here.
391: */
392: public String toStyleString(CSSEngine eng) {
393: StringBuffer sb = new StringBuffer();
394: boolean first = true;
395: for (int i = 0, n = values.length; i < n; i++) {
396: Value v = values[i];
397: if (v != null) {
398: if (first) {
399: first = false;
400: } else {
401: sb.append("; ");
402: }
403: sb.append(eng.getPropertyName(i));
404: sb.append(": ");
405: sb.append(v);
406: if (isImportant(i)) {
407: sb.append(" !important");
408: }
409: }
410: }
411: return sb.toString();
412: }
413:
414: // END RAVE MODIFICATIONS
415:
416: /**
417: * Returns a printable representation of this style map.
418: */
419: public String toString() {
420: StringBuffer sb = new StringBuffer();
421: sb.append(super .toString());
422: sb.append('\n');
423: for (int i = 0; i < values.length; i++) {
424: Value v = values[i];
425: if (v != null) {
426: //sb.append(eng.getPropertyName(i));
427: sb.append("prop");
428: sb.append(Integer.toString(i));
429: sb.append(": ");
430: sb.append(v);
431: if (isImportant(i)) {
432: sb.append(" !important");
433: }
434: sb.append(";\n");
435: }
436: }
437: return sb.toString();
438: }
439:
440: }
|