001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2002, Centre for Computational Geography
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.styling;
018:
019: import java.awt.Color;
020: import org.opengis.filter.expression.Expression;
021: import org.geotools.event.GTComponent;
022: import org.geotools.event.GTConstant;
023: import org.geotools.feature.Feature;
024: import org.geotools.filter.ConstantExpression;
025:
026: /**
027: * The Stroke object encapsulates the graphical-symbolization parameters for
028: * linear geometries.
029: * <p>
030: * There are three basic types of stroke: solid color, graphic fill (stipple),
031: * and repeated linear graphic stroke.
032: * A repeated linear graphic is plotted linearly and has its graphic symbol
033: * bent around the curves of the line string. A GraphicFill has the pixels
034: * of the line rendered with a repeating area-fill pattern.<p>
035: * If neither a graphic fill nor graphic stroke element are given, then the
036: * line symbolizer should render a solid color.
037: * <p>
038: * The details of this object are taken from the
039: * <a href="https://portal.opengeospatial.org/files/?artifact_id=1188">
040: * OGC Styled-Layer Descriptor Report (OGC 02-070) version 1.0.0.</a>:
041: * <pre><code>
042: * <xsd:element name="Stroke">
043: * <xsd:annotation>
044: * <xsd:documentation>
045: * A "Stroke" specifies the appearance of a linear geometry. It is
046: * defined in parallel with SVG strokes. The following CssParameters
047: * may be used: "stroke" (color), "stroke-opacity", "stroke-width",
048: * "stroke-linejoin", "stroke-linecap", "stroke-dasharray", and
049: * "stroke-dashoffset".
050: * </xsd:documentation>
051: * </xsd:annotation>
052: * <xsd:complexType>
053: * <xsd:sequence>
054: * <xsd:choice minOccurs="0">
055: * <xsd:element ref="sld:GraphicFill"/>
056: * <xsd:element ref="sld:GraphicStroke"/>
057: * </xsd:choice>
058: * <xsd:element ref="sld:CssParameter" minOccurs="0"
059: * maxOccurs="unbounded"/>
060: * </xsd:sequence>
061: * </xsd:complexType>
062: * </xsd:element>
063: * </code></pre>
064: * <p>
065: * Renderers can use this information when displaying styled features,
066: * though it must be remembered that not all renderers will be able to
067: * fully represent strokes as set out by this interface. For example, opacity
068: * may not be supported.
069: * <p>
070: * Notes:
071: * <ul>
072: * <li>The graphical parameters and their values are derived from SVG/CSS2
073: * standards with names and semantics which are as close as possible.
074: * </ul>
075: * </p>
076: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/styling/Stroke.java $
077: * @version $Id: Stroke.java 25459 2007-05-08 05:19:25Z jgarnett $
078: * @author James Macgill
079: */
080: public interface Stroke extends GTComponent {
081: /**
082: * Default Stroke capturing the defaults indicated by the standard.
083: * <p>
084: * For some attributes the standard does not define a default, so a
085: * reasonable value is supplied.
086: * </p>
087: */
088: static final Stroke DEFAULT = new ConstantStroke() {
089: public Expression getColor() {
090: return ConstantExpression.BLACK;
091: }
092:
093: public Color getColor(Feature f) {
094: return Color.BLACK;
095: }
096:
097: public Expression getWidth() {
098: return ConstantExpression.ONE;
099: }
100:
101: public Expression getOpacity() {
102: return ConstantExpression.ONE;
103: }
104:
105: public Expression getLineJoin() {
106: return ConstantExpression.constant("butt");
107: }
108:
109: public Expression getLineCap() {
110: return ConstantExpression.constant("miter");
111: }
112:
113: public float[] getDashArray() {
114: return new float[] { 1, 0 };
115: }
116:
117: public Expression getDashOffset() {
118: return ConstantExpression.ZERO;
119: }
120:
121: public Graphic getGraphicFill() {
122: return Graphic.DEFAULT;
123: }
124:
125: public Graphic getGraphicStroke() {
126: return Graphic.NULL;
127: }
128:
129: public Object clone() {
130: return this ; // we are constant
131: }
132: };
133:
134: /**
135: * Null Stroke capturing the defaults indicated by the standard.
136: * <p>
137: * This is a NullObject, it purpose is to prevent client code from having
138: * to do null checking.
139: * </p>
140: */
141: static final Stroke NULL = new ConstantStroke() {
142: public Expression getColor() {
143: return ConstantExpression.NULL;
144: }
145:
146: public Color getColor(Feature f) {
147: return Color.BLACK;
148: }
149:
150: public Expression getWidth() {
151: return ConstantExpression.NULL;
152: }
153:
154: public Expression getOpacity() {
155: return ConstantExpression.NULL;
156: }
157:
158: public Expression getLineJoin() {
159: return ConstantExpression.NULL;
160: }
161:
162: public Expression getLineCap() {
163: return ConstantExpression.NULL;
164: }
165:
166: public float[] getDashArray() {
167: return new float[] {};
168: }
169:
170: public Expression getDashOffset() {
171: return ConstantExpression.NULL;
172: }
173:
174: public Graphic getGraphicFill() {
175: return Graphic.NULL;
176: }
177:
178: public Graphic getGraphicStroke() {
179: return Graphic.NULL;
180: }
181: };
182:
183: /**
184: * This parameter gives the solid color that will be used for a stroke.<br>
185: * The color value is RGB-encoded using two hexidecimal digits per
186: * primary-color component in the order Red, Green, Blue, prefixed wih
187: * the hash (#) sign. The hexidecimal digits between A and F may be in
188: * either upper or lower case. For example, full red is encoded as
189: * "#ff0000" (with no quotation marks).
190: * The default color is defined to be black ("#000000").
191: *
192: * Note: in CSS this parameter is just called Stroke and not Color.
193: *
194: * @return The color of the stroke encoded as a hexidecimal RGB value.
195: **/
196: Expression getColor();
197:
198: /**
199: * This parameter gives the solid color that will be used for a stroke.<br>
200: * The color value returned here as a Java Color object, this is a convinence method
201: * that goes above
202: * The default color is defined to be Color.BLACK
203: *
204: * Note: in CSS this parameter is just called Stroke and not Color.
205: *
206: * @return The color of the stroke as a Color object
207: **/
208: Color getColor(Feature f);
209:
210: /**
211: * This parameter gives the solid color that will be used for a stroke.<br>
212: * The color value is RGB-encoded using two hexidecimal digits per
213: * primary-color component in the order Red, Green, Blue, prefixed wih
214: * the hash (#) sign. The hexidecimal digits between A and F may be in
215: * either upper or lower case. For example, full red is encoded as
216: * "#ff0000" (with no quotation marks).
217: *
218: * Note: in CSS this parameter is just called Stroke and not Color.
219: */
220: void setColor(Expression color);
221:
222: /**
223: * This parameter gives the absolute width (thickness) of a stroke in
224: * pixels encoded as a float.
225: * The default is 1.0. Fractional numbers are allowed but negative
226: * numbers are not.
227: *
228: * @return The width of the stroke in pixels.
229: * This may be fractional but not negative.
230: **/
231: Expression getWidth();
232:
233: /**
234: * This parameter gives the absolute width (thickness) of a stroke in
235: * pixels encoded as a float.
236: * Fractional numbers are allowed but negative
237: * numbers are not.
238: */
239: void setWidth(Expression width);
240:
241: /**
242: * This specifies the level of translucency to use when rendering the
243: * stroke.<br>
244: * The value is encoded as a floating-point value between 0.0 and
245: * 1.0 with 0.0 representing totally transparent and 1.0 representing
246: * totally opaque. A linear scale of translucency is used for intermediate
247: * values.<br>
248: * For example, "0.65" would represent 65% opacity. The default value
249: * is 1.0 (opaque).
250: *
251: * @return The opacity of the stroke, where 0.0 is completely transparent
252: * and 1.0 is completely opaque.
253: */
254: Expression getOpacity();
255:
256: /**
257: * This specifies the level of translucency to use when rendering the
258: * stroke.<br>
259: * The value is encoded as a floating-point value between 0.0 and
260: * 1.0 with 0.0 representing totally transparent and 1.0 representing
261: * totally opaque. A linear scale of translucency is used for intermediate
262: * values.<br>
263: * For example, "0.65" would represent 65% opacity.
264: */
265: void setOpacity(Expression opacity);
266:
267: /**
268: * This parameter controls how line strings should be joined together.
269: *
270: * @return The join style. This will be one of "mitre", "round" and
271: * "bevel". There is no defined default.
272: */
273: Expression getLineJoin();
274:
275: /**
276: * This parameter controls how line strings should be joined together.
277: */
278: void setLineJoin(Expression lineJoin);
279:
280: /**
281: * This parameter controls how line strings should be capped.
282: *
283: * @return The cap style. This will be one of "butt", "round" and
284: * "square". There is no defined default.
285: */
286: Expression getLineCap();
287:
288: /**
289: * This parameter controls how line strings should be capped.
290: */
291: void setLineCap(Expression lineCap);
292:
293: /**
294: * This parameter encodes the dash pattern as a seqeuence of floats.<br>
295: * The first number gives the length in pixels of the dash to draw, the
296: * second gives the amount of space to leave, and this pattern repeats.<br>
297: * If an odd number of values is given, then the pattern is expanded by
298: * repeating it twice to give an even number of values.
299: * The default is to draw an unbroken line.<br>
300: *
301: * For example, "2 1 3 2" would produce:<br>
302: * <code>-- --- -- --- -- ---
303: * -- --- -- --- --</code>
304: *
305: * @return The dash pattern as an array of float values in the form
306: * "dashlength gaplength ..."
307: */
308: float[] getDashArray();
309:
310: /**
311: * This parameter encodes the dash pattern as a seqeuence of floats.<br>
312: * The first number gives the length in pixels of the dash to draw, the
313: * second gives the amount of space to leave, and this pattern repeats.<br>
314: * If an odd number of values is given, then the pattern is expanded by
315: * repeating it twice to give an even number of values.
316: *
317: * For example, "2 1 3 2" would produce:<br>
318: * <code>-- --- -- --- -- ---
319: * -- --- -- --- --</code>
320: */
321: void setDashArray(float[] dashArray);
322:
323: /**
324: * A dash array need not start from the beginning. This method allows for
325: * an offset into the dash array before starting it.
326: *
327: * @return The distance, in pixels, that any dash array should start from.
328: */
329: Expression getDashOffset();
330:
331: /**
332: * A dash array need not start from the beginning. This method allows for
333: * an offset into the dash array before starting it.
334: */
335: void setDashOffset(Expression dashOffset);
336:
337: /**
338: * This parameter indicates that a stipple-fill repeated graphic will be
339: * used and specifies the fill graphic to use.
340: *
341: * @return The graphic to use as a stipple fill.
342: * If null, then no Stipple fill should be used.
343: */
344: Graphic getGraphicFill();
345:
346: /**
347: * This parameter indicates that a stipple-fill repeated graphic will be
348: * used and specifies the fill graphic to use.
349: */
350: void setGraphicFill(Graphic graphicFill);
351:
352: /**
353: * This parameter indicates that a repeated-linear-graphic graphic stroke
354: * type will be used and specifies the graphic to use.
355: *
356: * Proper stroking with a linear graphic requires two "hot-spot" points
357: * within the space of the graphic to indicate where the rendering line
358: * starts and stops.
359: * In the case of raster images with no special mark-up, this line will
360: * be assumed to be the middle pixel row of the image, starting from the
361: * first pixel column and ending at the last pixel column.
362: *
363: * @return The graphic to use as a linear graphic.
364: * If null, then no graphic stroke should be used.
365: */
366: Graphic getGraphicStroke();
367:
368: /**
369: * This parameter indicates that a repeated-linear-graphic graphic stroke
370: * type will be used and specifies the graphic to use.
371: *
372: * Proper stroking with a linear graphic requires two "hot-spot" points
373: * within the space of the graphic to indicate where the rendering line
374: * starts and stops.
375: * In the case of raster images with no special mark-up, this line will
376: * be assumed to be the middle pixel row of the image, starting from the
377: * first pixel column and ending at the last pixel column.
378: */
379: void setGraphicStroke(Graphic graphicStroke);
380:
381: void accept(StyleVisitor visitor);
382:
383: /** Creates a clone of the Stroke.
384: *
385: * @return A clone of the stroke object.
386: */
387: Object clone();
388: }
389:
390: abstract class ConstantStroke extends GTConstant implements Stroke {
391: private void cannotModifyConstant() {
392: throw new UnsupportedOperationException(
393: "Constant Stroke may not be modified");
394: }
395:
396: public void setColor(Expression color) {
397: cannotModifyConstant();
398: }
399:
400: public void setWidth(Expression width) {
401: cannotModifyConstant();
402: ;
403: }
404:
405: public void setOpacity(Expression opacity) {
406: cannotModifyConstant();
407: }
408:
409: public void setLineJoin(Expression lineJoin) {
410: cannotModifyConstant();
411: }
412:
413: public void setLineCap(Expression lineCap) {
414: cannotModifyConstant();
415: }
416:
417: public void setDashArray(float[] dashArray) {
418: cannotModifyConstant();
419: }
420:
421: public void setDashOffset(Expression dashOffset) {
422: cannotModifyConstant();
423: }
424:
425: public void setGraphicFill(Graphic graphicFill) {
426: cannotModifyConstant();
427: }
428:
429: public void setGraphicStroke(Graphic graphicStroke) {
430: cannotModifyConstant();
431: }
432:
433: public void accept(StyleVisitor visitor) {
434: cannotModifyConstant();
435: }
436: };
437: /*
438: * $Log: Stroke.java,v $
439: * Revision 1.13 2003/08/10 08:33:39 seangeo
440: * Added clone methods
441: *
442: * Revision 1.12 2003/08/03 03:28:15 seangeo
443: * Removed unneeded imports.
444: *
445: * Revision 1.11 2003/08/01 16:54:21 ianturton
446: * implemented visitor pattern
447: *
448: * Revision 1.10 2003/05/12 22:07:57 jmacgill
449: * added getColor method which returns an actual Color object.
450: *
451: * Revision 1.9 2002/10/14 17:08:01 ianturton
452: * expanded interfaces to include set methods
453: *
454: * Revision 1.8 2002/07/12 15:35:13 loxnard
455: *
456: * Removed redundant public modifiers
457: *
458: * Revision 1.7 2002/06/04 16:08:34 loxnard
459: *
460: * Misc JavaDoc
461: *
462: * Revision 1.6 2002/05/30 18:10:49 ianturton
463: * added expressions to stroke
464: *
465: * Revision 1.5 2002/05/27 09:07:40 jmacgill
466: * fixed a number of checkstyle errors
467: * improved javadoc comments
468: *
469: * Revision 1.4 2002/05/01 16:51:53 jmacgill
470: * dash array is now returned as a float array and not a string of space
471: * separated floats
472: *
473: * Revision 1.3 2002/03/28 10:54:10 jmacgill
474: * work in progress
475: *
476: * Revision 1.2 2002/03/25 22:14:41 jmacgill
477: * Updated JavaDocs
478: *
479: */
|