001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * BoxDefinitionFactory.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.layout.model.context;
030:
031: import java.awt.Color;
032: import java.util.HashMap;
033:
034: import org.jfree.report.layout.model.Border;
035: import org.jfree.report.layout.model.BorderCorner;
036: import org.jfree.report.layout.model.BorderEdge;
037: import org.jfree.report.layout.model.RenderLength;
038: import org.jfree.report.style.BandStyleKeys;
039: import org.jfree.report.style.BorderStyle;
040: import org.jfree.report.style.BoxSizing;
041: import org.jfree.report.style.ElementStyleKeys;
042: import org.jfree.report.style.StyleKey;
043: import org.jfree.report.style.StyleSheet;
044: import org.jfree.report.util.InstanceID;
045: import org.jfree.report.util.geom.StrictGeomUtility;
046:
047: /**
048: * Creation-Date: 27.04.2007, 22:09:05
049: *
050: * @author Thomas Morgner
051: */
052: public class BoxDefinitionFactory {
053: private static class CacheCarrier {
054: private long changeTracker;
055: private BoxDefinition boxDefinition;
056:
057: protected CacheCarrier(final long changeTracker,
058: final BoxDefinition border) {
059: this .changeTracker = changeTracker;
060: this .boxDefinition = border;
061: }
062:
063: public long getChangeTracker() {
064: return changeTracker;
065: }
066:
067: public BoxDefinition getBoxDefinition() {
068: return boxDefinition;
069: }
070: }
071:
072: private HashMap cache;
073:
074: public BoxDefinitionFactory() {
075: this .cache = new HashMap();
076: }
077:
078: public BoxDefinition getBoxDefinition(final StyleSheet es) {
079: final InstanceID id = es.getId();
080: final CacheCarrier cc = (CacheCarrier) cache.get(id);
081: if (cc == null) {
082: final BoxDefinition boxDefinition = createBoxDefinition(es);
083: cache.put(id, new CacheCarrier(es.getChangeTracker(),
084: boxDefinition));
085: return boxDefinition;
086: }
087:
088: if (cc.getChangeTracker() != es.getChangeTracker()) {
089: final BoxDefinition boxDefinition = createBoxDefinition(es);
090: cache.put(id, new CacheCarrier(es.getChangeTracker(),
091: boxDefinition));
092: return boxDefinition;
093: }
094:
095: return cc.getBoxDefinition();
096: }
097:
098: private BoxDefinition createBoxDefinition(final StyleSheet style) {
099: final BoxDefinition box = new BoxDefinition();
100: box.setPreferredWidth(produceFromStyle(style,
101: ElementStyleKeys.WIDTH, RenderLength.AUTO));
102: box.setPreferredHeight(produceFromStyle(style,
103: ElementStyleKeys.HEIGHT, RenderLength.AUTO));
104: box.setMinimumWidth(produceFromStyle(style,
105: ElementStyleKeys.MIN_WIDTH, RenderLength.EMPTY));
106: box.setMinimumHeight(produceFromStyle(style,
107: ElementStyleKeys.MIN_HEIGHT, RenderLength.EMPTY));
108: box.setSizeSpecifiesBorderBox(BoxSizing.BORDER_BOX.equals(style
109: .getStyleProperty(ElementStyleKeys.BOX_SIZING)));
110:
111: box.setMaximumWidth(produceFromStyle(style,
112: ElementStyleKeys.MAX_WIDTH, RenderLength.AUTO));
113: box.setMaximumHeight(produceFromStyle(style,
114: ElementStyleKeys.MAX_HEIGHT, RenderLength.AUTO));
115: box.setFixedPosition(produceFromStyle(style,
116: BandStyleKeys.FIXED_POSITION, RenderLength.AUTO));
117:
118: box.setPaddingTop(Math.max(0, StrictGeomUtility
119: .toInternalValue(style.getDoubleStyleProperty(
120: ElementStyleKeys.PADDING_TOP, 0))));
121: box.setPaddingLeft(Math.max(0, StrictGeomUtility
122: .toInternalValue(style.getDoubleStyleProperty(
123: ElementStyleKeys.PADDING_LEFT, 0))));
124: box.setPaddingBottom(Math.max(0, StrictGeomUtility
125: .toInternalValue(style.getDoubleStyleProperty(
126: ElementStyleKeys.PADDING_BOTTOM, 0))));
127: box.setPaddingRight(Math.max(0, StrictGeomUtility
128: .toInternalValue(style.getDoubleStyleProperty(
129: ElementStyleKeys.PADDING_RIGHT, 0))));
130:
131: final BorderEdge edgeTop = createEdge(style,
132: ElementStyleKeys.BORDER_TOP_STYLE,
133: ElementStyleKeys.BORDER_TOP_COLOR,
134: ElementStyleKeys.BORDER_TOP_WIDTH);
135: final BorderEdge edgeLeft = createEdge(style,
136: ElementStyleKeys.BORDER_LEFT_STYLE,
137: ElementStyleKeys.BORDER_LEFT_COLOR,
138: ElementStyleKeys.BORDER_LEFT_WIDTH);
139: final BorderEdge edgeBottom = createEdge(style,
140: ElementStyleKeys.BORDER_BOTTOM_STYLE,
141: ElementStyleKeys.BORDER_BOTTOM_COLOR,
142: ElementStyleKeys.BORDER_BOTTOM_WIDTH);
143: final BorderEdge edgeRight = createEdge(style,
144: ElementStyleKeys.BORDER_RIGHT_STYLE,
145: ElementStyleKeys.BORDER_RIGHT_COLOR,
146: ElementStyleKeys.BORDER_RIGHT_WIDTH);
147: final BorderEdge edgeBreak = createEdge(style,
148: ElementStyleKeys.BORDER_BREAK_STYLE,
149: ElementStyleKeys.BORDER_BREAK_COLOR,
150: ElementStyleKeys.BORDER_BREAK_WIDTH);
151:
152: if (edgeBottom == BorderEdge.EMPTY
153: && edgeLeft == BorderEdge.EMPTY
154: && edgeBreak == BorderEdge.EMPTY
155: && edgeRight == BorderEdge.EMPTY
156: && edgeTop == BorderEdge.EMPTY) {
157: box.setBorder(Border.EMPTY_BORDER);
158: } else {
159: final BorderCorner topLeftCorner = createCorner(style,
160: ElementStyleKeys.BORDER_TOP_LEFT_RADIUS_WIDTH,
161: ElementStyleKeys.BORDER_TOP_LEFT_RADIUS_HEIGHT);
162: final BorderCorner topRightCorner = createCorner(style,
163: ElementStyleKeys.BORDER_TOP_RIGHT_RADIUS_WIDTH,
164: ElementStyleKeys.BORDER_TOP_RIGHT_RADIUS_HEIGHT);
165: final BorderCorner bottmLeftCorner = createCorner(style,
166: ElementStyleKeys.BORDER_BOTTOM_LEFT_RADIUS_WIDTH,
167: ElementStyleKeys.BORDER_BOTTOM_LEFT_RADIUS_HEIGHT);
168: final BorderCorner bottomRightCorner = createCorner(style,
169: ElementStyleKeys.BORDER_BOTTOM_RIGHT_RADIUS_WIDTH,
170: ElementStyleKeys.BORDER_BOTTOM_RIGHT_RADIUS_HEIGHT);
171: box
172: .setBorder(new Border(edgeTop, edgeLeft,
173: edgeBottom, edgeRight, edgeBreak,
174: topLeftCorner, topRightCorner,
175: bottmLeftCorner, bottomRightCorner));
176: }
177: return box;
178: }
179:
180: private BorderCorner createCorner(final StyleSheet style,
181: final StyleKey radiusKeyX, final StyleKey radiusKeyY) {
182: final float dimX = (float) style.getDoubleStyleProperty(
183: radiusKeyX, 0);
184: final float dimY = (float) style.getDoubleStyleProperty(
185: radiusKeyY, 0);
186: if (dimX <= 0 || dimY <= 0) {
187: return BorderCorner.EMPTY;
188: }
189: return new BorderCorner(
190: StrictGeomUtility.toInternalValue(dimX),
191: StrictGeomUtility.toInternalValue(dimY));
192: }
193:
194: private BorderEdge createEdge(final StyleSheet style,
195: final StyleKey borderStyleKey,
196: final StyleKey borderColorKey, final StyleKey borderWidthKey) {
197: final BorderStyle styleRight = (BorderStyle) style
198: .getStyleProperty(borderStyleKey);
199: if (styleRight == null || BorderStyle.NONE.equals(styleRight)) {
200: return BorderEdge.EMPTY;
201: }
202:
203: final Color color = (Color) style
204: .getStyleProperty(borderColorKey);
205: final double width = style.getDoubleStyleProperty(
206: borderWidthKey, 0);
207: if (color == null || width <= 0) {
208: return BorderEdge.EMPTY;
209: }
210:
211: return new BorderEdge(styleRight, color, StrictGeomUtility
212: .toInternalValue(width));
213: }
214:
215: private RenderLength produceFromStyle(final StyleSheet styleSheet,
216: final StyleKey key, final RenderLength retval) {
217: final Float value = (Float) styleSheet.getStyleProperty(key);
218: if (value == null) {
219: return retval;
220: }
221: return RenderLength.createFromRaw(value.doubleValue());
222: }
223:
224: }
|