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: * StrokeUtility.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.util;
030:
031: import java.awt.BasicStroke;
032: import java.awt.Stroke;
033: import java.util.Arrays;
034:
035: import org.jfree.report.JFreeReportBoot;
036: import org.jfree.util.Configuration;
037:
038: /**
039: * This class provides helper methods to work with Strokes and line-styles.
040: *
041: * @author Thomas Morgner
042: */
043: public class StrokeUtility {
044: /** A constant defining a stroke-type. */
045: public static final int STROKE_SOLID = 0;
046: /** A constant defining a stroke-type. */
047: public static final int STROKE_DASHED = 1;
048: /** A constant defining a stroke-type. */
049: public static final int STROKE_DOTTED = 2;
050: /** A constant defining a stroke-type. */
051: public static final int STROKE_DOT_DASH = 3;
052: /** A constant defining a stroke-type. */
053: public static final int STROKE_DOT_DOT_DASH = 4;
054: /** A constant defining a stroke-type. */
055: public static final int STROKE_NONE = 5;
056:
057: /**
058: * Default Constructor. Private to prevent Object-creation.
059: */
060: private StrokeUtility() {
061: }
062:
063: /**
064: * Creates a new Stroke-Object for the given type and with.
065: *
066: * @param type the stroke-type. (Must be one of the constants defined in this class.)
067: * @param width the stroke's width.
068: * @return the stroke, never null.
069: */
070: public static Stroke createStroke(final int type, final float width) {
071: final Configuration repoConf = JFreeReportBoot.getInstance()
072: .getGlobalConfig();
073: final boolean useWidthForStrokes = "true"
074: .equals(repoConf
075: .getConfigProperty("org.jfree.report.DynamicStrokeDashes"));
076:
077: final float effectiveWidth;
078: if (useWidthForStrokes) {
079: effectiveWidth = width;
080: } else {
081: effectiveWidth = 1;
082: }
083:
084: switch (type) {
085: case STROKE_DASHED:
086: return new BasicStroke(width, BasicStroke.CAP_SQUARE,
087: BasicStroke.JOIN_MITER, 10.0f, new float[] {
088: 6 * effectiveWidth, 6 * effectiveWidth },
089: 0.0f);
090: case STROKE_DOTTED:
091: return new BasicStroke(width, BasicStroke.CAP_SQUARE,
092: BasicStroke.JOIN_MITER, 5.0f, new float[] { 0.0f,
093: 2 * effectiveWidth }, 0.0f);
094: case STROKE_DOT_DASH:
095: return new BasicStroke(width, BasicStroke.CAP_SQUARE,
096: BasicStroke.JOIN_MITER, 10.0f, new float[] { 0,
097: 2 * effectiveWidth, 6 * effectiveWidth,
098: 2 * effectiveWidth }, 0.0f);
099: case STROKE_DOT_DOT_DASH:
100: return new BasicStroke(width, BasicStroke.CAP_SQUARE,
101: BasicStroke.JOIN_MITER, 10.0f, new float[] { 0,
102: 2 * effectiveWidth, 0, 2 * effectiveWidth,
103: 6 * effectiveWidth, 2 * effectiveWidth },
104: 0.0f);
105: default:
106: return new BasicStroke(width);
107: }
108: }
109:
110: /**
111: * Tries to extract the stroke-width from the given stroke object.
112: * @param s the stroke.
113: * @return the stroke's width.
114: */
115: public static float getStrokeWidth(final Stroke s) {
116: if (s instanceof BasicStroke) {
117: final BasicStroke bs = (BasicStroke) s;
118: return bs.getLineWidth();
119: }
120: return 1;
121: }
122:
123: /**
124: * Tries to deduct the stroke-type from the given stroke object. This will result in funny return values if the
125: * stroke was not created by the {@link #createStroke(int, float)} method.
126: *
127: * @param s the stroke.
128: * @return the stroke's width.
129: */
130: public static int getStrokeType(final Stroke s) {
131: if (s instanceof BasicStroke == false) {
132: return STROKE_SOLID;
133: }
134: final BasicStroke bs = (BasicStroke) s;
135: if (bs.getLineWidth() <= 0) {
136: return STROKE_NONE;
137: }
138:
139: final float[] dashes = bs.getDashArray();
140: if (dashes == null) {
141: return STROKE_SOLID;
142: }
143: if (dashes.length < 2) {
144: return STROKE_SOLID;
145: }
146: if (dashes.length == 3 || dashes.length == 5) {
147: return STROKE_SOLID;
148: }
149:
150: if (dashes.length == 2) {
151: // maybe dashed or dotted ...
152: // if (dashes[0] < 2 && dashes[1] < 2) {
153: // return STROKE_DOTTED;
154: // }
155: final float factor = dashes[0] / dashes[1];
156: if (factor > 0.9 && factor < 1.1) {
157: return STROKE_DASHED;
158: } else if (factor < 0.1) {
159: return STROKE_DOTTED;
160: }
161:
162: // else ... not recognized ...
163: return STROKE_SOLID;
164: } else if (dashes.length == 4) {
165: // maybe a dot-dashed stroke ...
166: final float[] copyDashes = (float[]) dashes.clone();
167: Arrays.sort(copyDashes);
168:
169: // the first value should be near zero ..
170: if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
171: // not recognized ..
172: return STROKE_SOLID;
173: }
174:
175: // test that the first two values have the same size
176: final float factor1 = (2 * bs.getLineWidth())
177: / copyDashes[1];
178: final float factor2 = (2 * bs.getLineWidth())
179: / copyDashes[2];
180: final float factorBig = (2 * bs.getLineWidth())
181: / copyDashes[3];
182:
183: if ((factor1 < 0.9 || factor1 > 1.1)
184: || (factor2 < 0.9 || factor2 > 1.1)) {
185: // not recognized ...
186: return STROKE_SOLID;
187: }
188:
189: if (factorBig < 0.4 || factorBig > 2.5) {
190: return STROKE_DOT_DASH;
191: }
192: if (factorBig < 0.9 || factorBig > 1.1) {
193: return STROKE_DOTTED;
194: }
195: return STROKE_DASHED;
196: } else if (dashes.length == 6) {
197: // maybe a dot-dashed stroke ...
198: final float[] copyDashes = (float[]) dashes.clone();
199: Arrays.sort(copyDashes);
200: // test that the first three values have the same size
201:
202: // the first two values should be near zero ..
203: if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
204: // not recognized ..
205: return STROKE_SOLID;
206: }
207: if (Math.abs(copyDashes[1] / bs.getLineWidth()) > 0.5) {
208: // not recognized ..
209: return STROKE_SOLID;
210: }
211:
212: final float factor2 = (2 * bs.getLineWidth())
213: / copyDashes[2];
214: final float factor3 = (2 * bs.getLineWidth())
215: / copyDashes[3];
216: final float factor4 = (2 * bs.getLineWidth())
217: / copyDashes[4];
218: final float factorBig = (2 * bs.getLineWidth())
219: / copyDashes[5];
220:
221: if ((factor2 < 0.9 || factor2 > 1.1)
222: || (factor3 < 0.9 || factor3 > 1.1)
223: || (factor4 < 0.9 || factor4 > 1.1)) {
224: return STROKE_SOLID;
225: }
226:
227: if (factorBig < 0.4 || factorBig > 2.5) {
228: return STROKE_DOT_DOT_DASH;
229: }
230: if ((factorBig < 0.9 || factorBig > 1.1)) {
231: return STROKE_DOTTED;
232: }
233: return STROKE_DASHED;
234: }
235: // not recognized ...
236: return STROKE_SOLID;
237: }
238: }
|