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