001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/graphics/sld/Mark.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.graphics.sld; 045 046 import static org.deegree.framework.xml.XMLTools.escape; 047 048 import java.awt.BasicStroke; 049 import java.awt.Color; 050 import java.awt.FontMetrics; 051 import java.awt.Graphics2D; 052 import java.awt.Polygon; 053 import java.awt.image.BufferedImage; 054 055 import org.deegree.framework.util.StringTools; 056 import org.deegree.framework.xml.Marshallable; 057 import org.deegree.model.feature.Feature; 058 import org.deegree.model.filterencoding.FilterEvaluationException; 059 060 /** 061 * A Mark takes a "shape" and applies coloring to it. The shape can be derived either from a 062 * well-known name (such as "square"), an external URL in various formats (such as, perhaps GIF), or 063 * from a glyph of a font. Multiple external formats may be used with the semantic that they all 064 * contain the equivalent shape in different formats. If an image format is used that has inherent 065 * coloring, the coloring is discarded and only the opacity channel (or equivalent) is used. A Halo, 066 * Fill, and/or Stroke is applied as appropriate for the shape's source format. 067 * <p> 068 * 069 * @author <a href="mailto:k.lupp@web.de">Katharina Lupp </a> 070 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 071 * @version $Revision: 12167 $ $Date: 2008-06-04 16:06:48 +0200 (Mi, 04 Jun 2008) $ 072 */ 073 074 public class Mark implements Marshallable { 075 076 private BufferedImage image = null; 077 078 private Fill fill = null; 079 080 private String wellKnownName = null; 081 082 private Stroke stroke = null; 083 084 /** 085 * Constructor for the default <tt>Mark</tt>. 086 */ 087 Mark() { 088 } 089 090 /** 091 * constructor initializing the class with the <Mark> 092 */ 093 Mark( String wellKnownName, Stroke stroke, Fill fill ) { 094 setWellKnownName( wellKnownName ); 095 setStroke( stroke ); 096 setFill( fill ); 097 } 098 099 /** 100 * Gives the well known name of a Mark's shape. Allowed values include at least "square", 101 * "circle", "triangle", "star", "cross", and "x", though map servers may draw a different 102 * symbol instead if they don't have a shape for all of these. Renderings of these marks may be 103 * made solid or hollow depending on Fill and Stroke parameters. The default value is "square". 104 * 105 * @return the WK-Name of the mark 106 * 107 */ 108 public String getWellKnownName() { 109 return wellKnownName; 110 } 111 112 /** 113 * Sets the well known name of a Mark's shape. Allowed values include at least "square", 114 * "circle", "triangle", "star", "cross", and "x", though map servers may draw a different 115 * symbol instead if they don't have a shape for all of these. Renderings of these marks may be 116 * made solid or hollow depending on Fill and Stroke parameters. The default value is "square". 117 * 118 * @param wellKnownName 119 * the WK-Name of the mark 120 * 121 */ 122 public void setWellKnownName( String wellKnownName ) { 123 this.wellKnownName = wellKnownName; 124 } 125 126 /** 127 * A Fill allows area geometries to be filled. There are two types of fills: solid-color and 128 * repeated GraphicFill. In general, if a Fill element is omitted in its containing element, no 129 * fill will be rendered. The default is a solid 50%-gray (color "#808080") opaque fill. 130 * 131 * @return the fill of the mark 132 */ 133 public Fill getFill() { 134 return fill; 135 } 136 137 /** 138 * sets the <Fill> 139 * 140 * @param fill 141 * the fill of the mark 142 */ 143 public void setFill( Fill fill ) { 144 this.fill = fill; 145 } 146 147 /** 148 * A Stroke allows a string of line segments (or any linear geometry) to be rendered. There are 149 * three basic types of strokes: solid Color, GraphicFill (stipple), and repeated GraphicStroke. 150 * A repeated graphic is plotted linearly and has its graphic symbol bended around the curves of 151 * the line string. The default is a solid black line (Color "#000000"). 152 * 153 * @return the stroke of the mark 154 */ 155 public Stroke getStroke() { 156 return stroke; 157 } 158 159 /** 160 * sets <Stroke> 161 * 162 * @param stroke 163 * the stroke of the mark 164 */ 165 public void setStroke( Stroke stroke ) { 166 this.stroke = stroke; 167 } 168 169 /** 170 * DOCUMENT ME! 171 * 172 * @param size 173 * DOCUMENT ME! 174 * 175 * @return DOCUMENT ME! 176 */ 177 public BufferedImage getAsImage( Feature feature, int size ) 178 throws FilterEvaluationException { 179 double fillOpacity = 1.0; 180 double strokeOpacity = 1.0; 181 float[] dash = null; 182 float dashOffset = 0; 183 int cap = BasicStroke.CAP_ROUND; 184 int join = BasicStroke.JOIN_ROUND; 185 float width = 1; 186 Color fillColor = new Color( 128, 128, 128 ); 187 Color strokeColor = new Color( 0, 0, 0 ); 188 189 if ( fill != null ) { 190 fillOpacity = fill.getOpacity( feature ); 191 fillColor = fill.getFill( feature ); 192 } 193 194 if ( stroke != null ) { 195 strokeOpacity = stroke.getOpacity( feature ); 196 strokeColor = stroke.getStroke( feature ); 197 dash = stroke.getDashArray( feature ); 198 cap = stroke.getLineCap( feature ); 199 join = stroke.getLineJoin( feature ); 200 width = (float) stroke.getWidth( feature ); 201 dashOffset = stroke.getDashOffset( feature ); 202 } 203 204 if ( wellKnownName == null ) { 205 wellKnownName = "square"; 206 } 207 208 if ( wellKnownName.equalsIgnoreCase( "circle" ) ) { 209 image = drawCircle( size, fillOpacity, fillColor, strokeOpacity, strokeColor, dash, dashOffset, width, cap, 210 join ); 211 } else if ( wellKnownName.equalsIgnoreCase( "triangle" ) ) { 212 image = drawTriangle( size, fillOpacity, fillColor, strokeOpacity, strokeColor, dash, dashOffset, width, 213 cap, join ); 214 } else if ( wellKnownName.equalsIgnoreCase( "cross" ) ) { 215 image = drawCross1( size, strokeOpacity, strokeColor, dash, dashOffset, width, cap, join ); 216 } else if ( wellKnownName.equalsIgnoreCase( "x" ) ) { 217 image = drawCross2( size, strokeOpacity, strokeColor, dash, dashOffset, width, cap, join ); 218 } else if ( wellKnownName.startsWith( "CHAR" ) ) { 219 image = drawCharacter( size, fillOpacity, fillColor, strokeOpacity, strokeColor, wellKnownName ); 220 } else if ( wellKnownName.equalsIgnoreCase( "star" ) ) { 221 image = drawStar( size, fillOpacity, fillColor, strokeOpacity, strokeColor, dash, dashOffset, width, cap, 222 join ); 223 } else { 224 image = drawSquare( size, fillOpacity, fillColor, strokeOpacity, strokeColor, dash, dashOffset, width, cap, 225 join ); 226 } 227 228 return image; 229 } 230 231 /** 232 * Sets the mark as an image. Rhis method is not part of the sld specifications but it is added 233 * to speed up applications. 234 * 235 * @param bufferedImage 236 * the bufferedImage to be set for the mark 237 */ 238 public void setAsImage( BufferedImage bufferedImage ) { 239 this.image = bufferedImage; 240 } 241 242 /** 243 * 244 * @param dash 245 * @param dashOffset 246 * @param width 247 * @param cap 248 * @param join 249 * @return 250 * @throws FilterEvaluationException 251 */ 252 private BasicStroke createBasicStroke( float[] dash, float dashOffset, float width, int cap, int join ) { 253 BasicStroke bs2 = null; 254 if ( ( dash == null ) || ( dash.length < 2 ) ) { 255 bs2 = new BasicStroke( width, cap, join ); 256 } else { 257 bs2 = new BasicStroke( width, cap, join, 10.0f, dash, dashOffset ); 258 } 259 return bs2; 260 } 261 262 /** 263 * Draws a scaled instance of a triangle mark according to the given parameters. 264 * 265 * @param size 266 * resulting image's height and width 267 * @param fillOpacity 268 * opacity value for the filled parts of the image 269 * @param fillColor 270 * <tt>Color</tt> to be used for the fill 271 * @param strokeOpacity 272 * opacity value for the stroked parts of the image 273 * @param strokeColor 274 * <tt>Color</tt> to be used for the strokes 275 * @param dash 276 * dash array for rendering boundary line 277 * @param width 278 * of the boundary line 279 * @param cap 280 * of the boundary line 281 * @param join 282 * of the boundary line 283 * @param dashOffset 284 * 285 * @return image displaying a triangle 286 */ 287 public BufferedImage drawTriangle( int size, double fillOpacity, Color fillColor, double strokeOpacity, 288 Color strokeColor, float[] dash, float dashOffset, float width, int cap, int join ) { 289 290 int offset = (int) ( width * 2 + 1 ) / 2; 291 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 292 293 int[] x_ = new int[3]; 294 int[] y_ = new int[3]; 295 x_[0] = offset; 296 y_[0] = offset; 297 x_[1] = size / 2 + offset; 298 y_[1] = size - 1 + offset; 299 x_[2] = size - 1 + offset; 300 y_[2] = offset; 301 302 Graphics2D g2D = (Graphics2D) image.getGraphics(); 303 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 304 g2D.setStroke( bs ); 305 setColor( g2D, fillColor, fillOpacity ); 306 g2D.fillPolygon( x_, y_, 3 ); 307 setColor( g2D, strokeColor, strokeOpacity ); 308 g2D.drawPolygon( x_, y_, 3 ); 309 310 return image; 311 } 312 313 /** 314 * Draws a five-pointed star (pentagram) according to the given parameters. 315 * 316 * @param size 317 * resulting image's height and width 318 * @param fillOpacity 319 * opacity value for the filled parts of the image 320 * @param fillColor 321 * <tt>Color</tt> to be used for the fill 322 * @param strokeOpacity 323 * opacity value for the stroked parts of the image 324 * @param strokeColor 325 * <tt>Color</tt> to be used for the strokes 326 * @param dash 327 * dash array for rendering boundary line 328 * @param width 329 * of the boundary line 330 * @param cap 331 * of the boundary line 332 * @param join 333 * of the boundary line 334 * @param dashOffset 335 * 336 * @return an image of a pentagram 337 */ 338 public BufferedImage drawStar( int size, double fillOpacity, Color fillColor, double strokeOpacity, 339 Color strokeColor, float[] dash, float dashOffset, float width, int cap, int join ) { 340 int offset = (int) ( width * 2 + 1 ) / 2; 341 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 342 343 Graphics2D g2D = image.createGraphics(); 344 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 345 g2D.setStroke( bs ); 346 int s = size / 2; 347 int x0 = s; 348 int y0 = s; 349 double sin36 = Math.sin( Math.toRadians( 36 ) ); 350 double cos36 = Math.cos( Math.toRadians( 36 ) ); 351 double sin18 = Math.sin( Math.toRadians( 18 ) ); 352 double cos18 = Math.cos( Math.toRadians( 18 ) ); 353 int smallRadius = (int) ( s * sin18 / Math.sin( Math.toRadians( 54 ) ) ); 354 355 int p0X = x0; 356 int p0Y = y0 - s; 357 int p1X = x0 + (int) ( smallRadius * sin36 ); 358 int p1Y = y0 - (int) ( smallRadius * cos36 ); 359 int p2X = x0 + (int) ( s * cos18 ); 360 int p2Y = y0 - (int) ( s * sin18 ); 361 int p3X = x0 + (int) ( smallRadius * cos18 ); 362 int p3Y = y0 + (int) ( smallRadius * sin18 ); 363 int p4X = x0 + (int) ( s * sin36 ); 364 int p4Y = y0 + (int) ( s * cos36 ); 365 int p5Y = y0 + smallRadius; 366 int p6X = x0 - (int) ( s * sin36 ); 367 int p7X = x0 - (int) ( smallRadius * cos18 ); 368 int p8X = x0 - (int) ( s * cos18 ); 369 int p9X = x0 - (int) ( smallRadius * sin36 ); 370 371 int[] x = new int[] { p0X, p1X, p2X, p3X, p4X, p0X, p6X, p7X, p8X, p9X }; 372 int[] y = new int[] { p0Y, p1Y, p2Y, p3Y, p4Y, p5Y, p4Y, p3Y, p2Y, p1Y }; 373 for ( int i = 0; i < y.length; i++ ) { 374 x[i] = x[i] + offset; 375 y[i] = y[i] + offset; 376 } 377 Polygon shape = new Polygon( x, y, 10 ); 378 379 setColor( g2D, fillColor, fillOpacity ); 380 g2D.fill( shape ); 381 setColor( g2D, strokeColor, strokeOpacity ); 382 g2D.draw( shape ); 383 384 g2D.dispose(); 385 386 return image; 387 } 388 389 /** 390 * Draws a scaled instance of a circle mark according to the given parameters. 391 * 392 * @param size 393 * resulting image's height and widthh 394 * @param fillOpacity 395 * opacity value for the filled parts of the image 396 * @param fillColor 397 * <tt>Color</tt> to be used for the fill 398 * @param strokeOpacity 399 * opacity value for the stroked parts of the image 400 * @param strokeColor 401 * <tt>Color</tt> to be used for the strokes 402 * @param dash 403 * dash array for rendering boundary line 404 * @param width 405 * of the boundary line 406 * @param cap 407 * of the boundary line 408 * @param join 409 * of the boundary line 410 * @param dashOffset 411 * 412 * @return image displaying a circle 413 * @throws FilterEvaluationException 414 */ 415 public BufferedImage drawCircle( int size, double fillOpacity, Color fillColor, double strokeOpacity, 416 Color strokeColor, float[] dash, float dashOffset, float width, int cap, int join ) { 417 int offset = (int) ( width * 2 + 1 ) / 2; 418 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 419 420 Graphics2D g2D = (Graphics2D) image.getGraphics(); 421 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 422 g2D.setStroke( bs ); 423 setColor( g2D, fillColor, fillOpacity ); 424 g2D.fillOval( offset, offset, size, size ); 425 426 setColor( g2D, strokeColor, strokeOpacity ); 427 g2D.drawOval( offset, offset, size, size ); 428 429 return image; 430 } 431 432 /** 433 * Draws a scaled instance of a square mark according to the given parameters. 434 * 435 * @param size 436 * resulting image's height and widthh 437 * @param fillOpacity 438 * opacity value for the filled parts of the image 439 * @param fillColor 440 * <tt>Color</tt> to be used for the fill 441 * @param strokeOpacity 442 * opacity value for the stroked parts of the image 443 * @param strokeColor 444 * <tt>Color</tt> to be used for the strokes 445 * @param dash 446 * dash array for rendering boundary line 447 * @param width 448 * of the boundary line 449 * @param cap 450 * of the boundary line 451 * @param join 452 * of the boundary line 453 * @param dashOffset 454 * 455 * @return image displaying a square 456 */ 457 public BufferedImage drawSquare( int size, double fillOpacity, Color fillColor, double strokeOpacity, 458 Color strokeColor, float[] dash, float dashOffset, float width, int cap, int join ) { 459 int offset = (int) ( width * 2 + 1 ) / 2; 460 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 461 462 Graphics2D g2D = (Graphics2D) image.getGraphics(); 463 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 464 g2D.setStroke( bs ); 465 setColor( g2D, fillColor, fillOpacity ); 466 g2D.fillRect( offset, offset, size, size ); 467 468 setColor( g2D, strokeColor, strokeOpacity ); 469 g2D.drawRect( offset, offset, size - 1, size - 1 ); 470 471 return image; 472 } 473 474 /** 475 * Draws a scaled instance of a cross mark (a "+") according to the given parameters. 476 * 477 * @param size 478 * resulting image's height and widthh 479 * @param strokeOpacity 480 * opacity value for the stroked parts of the image 481 * @param strokeColor 482 * <tt>Color</tt> to be used for the strokes 483 * @param dash 484 * dash array for rendering boundary line 485 * @param width 486 * of the boundary line 487 * @param cap 488 * of the boundary line 489 * @param join 490 * of the boundary line 491 * @param dashOffset 492 * 493 * @return image displaying a cross (a "+") 494 */ 495 public BufferedImage drawCross1( int size, double strokeOpacity, Color strokeColor, float[] dash, float dashOffset, 496 float width, int cap, int join ) { 497 498 int offset = (int) ( width * 2 + 1 ) / 2; 499 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 500 501 Graphics2D g2D = (Graphics2D) image.getGraphics(); 502 503 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 504 g2D.setStroke( bs ); 505 506 setColor( g2D, strokeColor, strokeOpacity ); 507 g2D.drawLine( offset, size / 2 + offset, size - 1 + offset, size / 2 + offset ); 508 g2D.drawLine( size / 2 + offset, offset, size / 2 + offset, size - 1 + offset ); 509 510 return image; 511 } 512 513 /** 514 * Draws a scaled instance of a cross mark (an "X") according to the given parameters. 515 * 516 * @param size 517 * resulting image's height and widthh 518 * @param strokeOpacity 519 * opacity value for the stroked parts of the image 520 * @param strokeColor 521 * <tt>Color</tt> to be used for the strokes 522 * @param dash 523 * dash array for rendering boundary line 524 * @param width 525 * of the boundary line 526 * @param cap 527 * of the boundary line 528 * @param join 529 * of the boundary line 530 * @param dashOffset 531 * 532 * @return image displaying a cross (a "X") 533 */ 534 public BufferedImage drawCross2( int size, double strokeOpacity, Color strokeColor, float[] dash, float dashOffset, 535 float width, int cap, int join ) { 536 537 int offset = (int) ( width * 2 + 1 ) / 2; 538 BufferedImage image = new BufferedImage( size + offset * 2, size + offset * 2, BufferedImage.TYPE_INT_ARGB ); 539 540 Graphics2D g2D = (Graphics2D) image.getGraphics(); 541 542 BasicStroke bs = createBasicStroke( dash, dashOffset, width, cap, join ); 543 g2D.setStroke( bs ); 544 545 setColor( g2D, strokeColor, strokeOpacity ); 546 g2D.drawLine( offset, offset, size - 1 + offset, size - 1 + offset ); 547 g2D.drawLine( offset, size - 1 + offset, size - 1 + offset, offset ); 548 549 return image; 550 } 551 552 /** 553 * 554 * @param size 555 * @param fillOpacity 556 * @param fillColor 557 * @param strokeOpacity 558 * @param strokeColor 559 * @param charDesc 560 * e.g. CHAR:Times New Roman:45 561 */ 562 private BufferedImage drawCharacter( int size, double fillOpacity, Color fillColor, double strokeOpacity, 563 Color strokeColor, String charDesc ) { 564 565 String[] tmp = StringTools.toArray( charDesc, ":", false ); 566 567 BufferedImage image = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB ); 568 569 Graphics2D g2 = (Graphics2D) image.getGraphics(); 570 setColor( g2, fillColor, fillOpacity ); 571 g2.fillRect( 0, 0, size, size ); 572 573 java.awt.Font font = new java.awt.Font( tmp[1], java.awt.Font.PLAIN, size ); 574 g2.setFont( font ); 575 FontMetrics fm = g2.getFontMetrics(); 576 577 char c = (char) Integer.parseInt( tmp[2] ); 578 int w = fm.charWidth( c ); 579 int h = fm.getHeight(); 580 581 String s = "" + c; 582 setColor( g2, strokeColor, strokeOpacity ); 583 g2.drawString( s, size / 2 - w / 2, size / 2 + h / 2 - fm.getDescent() ); 584 g2.dispose(); 585 return image; 586 } 587 588 /** 589 * @param g2D 590 * @param color 591 * @param opacity 592 */ 593 private void setColor( Graphics2D g2D, Color color, double opacity ) { 594 if ( opacity < 0.999 ) { 595 final int alpha = (int) Math.round( opacity * 255 ); 596 final int red = color.getRed(); 597 final int green = color.getGreen(); 598 final int blue = color.getBlue(); 599 color = new Color( red, green, blue, alpha ); 600 } 601 602 g2D.setColor( color ); 603 } 604 605 /** 606 * exports the content of the Mark as XML formated String 607 * 608 * @return xml representation of the Mark 609 */ 610 public String exportAsXML() { 611 612 StringBuffer sb = new StringBuffer( 1000 ); 613 sb.append( "<Mark>" ); 614 if ( wellKnownName != null && !wellKnownName.equals( "" ) ) { 615 sb.append( "<WellKnownName>" ).append( escape( wellKnownName ) ); 616 sb.append( "</WellKnownName>" ); 617 } 618 if ( fill != null ) { 619 sb.append( ( (Marshallable) fill ).exportAsXML() ); 620 } 621 if ( stroke != null ) { 622 sb.append( ( (Marshallable) stroke ).exportAsXML() ); 623 } 624 625 sb.append( "</Mark>" ); 626 627 return sb.toString(); 628 } 629 630 // private void drawUnicode(Graphics2D g2, int x, int y, double rotation, 631 // double size, String m, Mark mark) { 632 // int sz = (int)size; 633 // double fo = mark.getFill().getOpacity(); 634 // double so = mark.getStroke().getOpacity(); 635 // 636 // java.awt.Font font = new java.awt.Font("sans serif", java.awt.Font.PLAIN, 637 // sz); 638 // g2.setFont( font ); 639 // FontMetrics fm = g2.getFontMetrics(); 640 // 641 // char c = (char)m.charAt(0); 642 // int w = fm.charWidth(c); 643 // int h = fm.getHeight(); 644 // 645 // g2 = setColor( g2, mark.getFill().getFill(), fo ); 646 // g2.fillRect( x-w/2, y-h/2, w, h); 647 // g2 = setColor( g2, mark.getStroke().getStroke(), so ); 648 // 649 // String s = "" + c; 650 // g2.drawString( s, x-w/2, y+h/2-fm.getDescent()); 651 // } 652 // else { 653 // 654 // Mark[] marks = sym.getGraphic().getMarks(); 655 // double rotation = sym.getGraphic().getRotation(); 656 // double size = sym.getGraphic().getSize(); 657 // if (marks != null) { 658 // 659 // for (int k = 0; k > marks.length; k++) { 660 // 661 // float w = (float)marks[k].getStroke().getWidth(); 662 // g2.setStroke( new BasicStroke( w ) ); 663 // 664 // if (marks[k].getWellKnownName().equalsIgnoreCase("triangle") ) { 665 // drawTriangle( g2, x, y, rotation, size, marks[k] ); 666 // } 667 // else 668 // if (marks[k].getWellKnownName().equalsIgnoreCase("circle") ) { 669 // drawCircle( g2, x, y, rotation, size, marks[k] ); 670 // } 671 // else 672 // if (marks[k].getWellKnownName().equalsIgnoreCase("square") ) { 673 // drawSquare( g2, x, y, rotation, size, marks[k] ); 674 // } 675 // else 676 // if (marks[k].getWellKnownName().equalsIgnoreCase("cross") ) { 677 // drawCross1( g2, x, y, rotation, size, marks[k] ); 678 // } 679 // else 680 // if (marks[k].getWellKnownName().equalsIgnoreCase("x") ) { 681 // drawCross2( g2, x, y, rotation, size, marks[k] ); 682 // } 683 // else 684 // if (marks[k].getWellKnownName().length() == 0 ) { 685 // drawSquare( g2, x, y, rotation, size, marks[k] ); 686 // } 687 // else { 688 // drawUnicode( g2, x, y, rotation, size, 689 // marks[k].getWellKnownName(), marks[k] ); 690 // } 691 // } 692 // } 693 // } 694 }