1 18 package org.apache.batik.bridge; 19 20 import java.awt.BasicStroke ; 21 import java.awt.Color ; 22 import java.awt.Paint ; 23 import java.awt.Shape ; 24 import java.awt.Stroke ; 25 26 import org.apache.batik.css.engine.SVGCSSEngine; 27 import org.apache.batik.css.engine.value.ListValue; 28 import org.apache.batik.css.engine.value.Value; 29 import org.apache.batik.css.engine.value.svg.ICCColor; 30 import org.apache.batik.ext.awt.color.ICCColorSpaceExt; 31 import org.apache.batik.gvt.CompositeShapePainter; 32 import org.apache.batik.gvt.FillShapePainter; 33 import org.apache.batik.gvt.GraphicsNode; 34 import org.apache.batik.gvt.Marker; 35 import org.apache.batik.gvt.MarkerShapePainter; 36 import org.apache.batik.gvt.ShapeNode; 37 import org.apache.batik.gvt.ShapePainter; 38 import org.apache.batik.gvt.StrokeShapePainter; 39 import org.apache.batik.util.CSSConstants; 40 import org.apache.batik.util.SVGConstants; 41 import org.w3c.dom.Element ; 42 import org.w3c.dom.css.CSSPrimitiveValue; 43 import org.w3c.dom.css.CSSValue; 44 45 54 public abstract class PaintServer 55 implements SVGConstants, CSSConstants, ErrorConstants { 56 57 60 protected PaintServer() {} 61 62 63 67 75 public static ShapePainter convertMarkers(Element e, 76 ShapeNode node, 77 BridgeContext ctx) { 78 Value v; 79 v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.MARKER_START_INDEX); 80 Marker startMarker = convertMarker(e, v, ctx); 81 v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.MARKER_MID_INDEX); 82 Marker midMarker = convertMarker(e, v, ctx); 83 v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.MARKER_END_INDEX); 84 Marker endMarker = convertMarker(e, v, ctx); 85 86 if (startMarker != null || midMarker != null || endMarker != null) { 87 MarkerShapePainter p = new MarkerShapePainter(node.getShape()); 88 p.setStartMarker(startMarker); 89 p.setMiddleMarker(midMarker); 90 p.setEndMarker(endMarker); 91 return p; 92 } else { 93 return null; 94 } 95 } 96 97 101 109 public static Marker convertMarker(Element e, 110 Value v, 111 BridgeContext ctx) { 112 113 if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) { 114 return null; } else { 116 String uri = v.getStringValue(); 117 Element markerElement = ctx.getReferencedElement(e, uri); 118 Bridge bridge = ctx.getBridge(markerElement); 119 if (bridge == null || !(bridge instanceof MarkerBridge)) { 120 throw new BridgeException(e, ERR_CSS_URI_BAD_TARGET, 121 new Object [] {uri}); 122 } 123 return ((MarkerBridge)bridge).createMarker(ctx, markerElement, e); 124 } 125 } 126 127 131 140 public static ShapePainter convertFillAndStroke(Element e, 141 ShapeNode node, 142 BridgeContext ctx) { 143 Shape shape = node.getShape(); 144 if (shape == null) return null; 145 146 Paint fillPaint = convertFillPaint (e, node, ctx); 147 FillShapePainter fp = new FillShapePainter(shape); 148 fp.setPaint(fillPaint); 149 150 Stroke stroke = convertStroke (e); 151 if (stroke == null) 152 return fp; 153 154 Paint strokePaint = convertStrokePaint(e, node, ctx); 155 StrokeShapePainter sp = new StrokeShapePainter(shape); 156 sp.setStroke(stroke); 157 sp.setPaint(strokePaint); 158 159 CompositeShapePainter cp = new CompositeShapePainter(shape); 160 cp.addShapePainter(fp); 161 cp.addShapePainter(sp); 162 return cp; 163 } 164 165 166 public static ShapePainter convertStrokePainter(Element e, 167 ShapeNode node, 168 BridgeContext ctx) { 169 Shape shape = node.getShape(); 170 if (shape == null) return null; 171 172 Stroke stroke = convertStroke(e); 173 if (stroke == null) 174 return null; 175 176 Paint strokePaint = convertStrokePaint(e, node, ctx); 177 StrokeShapePainter sp = new StrokeShapePainter(shape); 178 sp.setStroke(stroke); 179 sp.setPaint(strokePaint); 180 return sp; 181 } 182 183 187 195 public static Paint convertStrokePaint(Element strokedElement, 196 GraphicsNode strokedNode, 197 BridgeContext ctx) { 198 Value v = CSSUtilities.getComputedStyle 199 (strokedElement, SVGCSSEngine.STROKE_OPACITY_INDEX); 200 float opacity = convertOpacity(v); 201 v = CSSUtilities.getComputedStyle 202 (strokedElement, SVGCSSEngine.STROKE_INDEX); 203 204 return convertPaint(strokedElement, 205 strokedNode, 206 v, 207 opacity, 208 ctx); 209 } 210 211 219 public static Paint convertFillPaint(Element filledElement, 220 GraphicsNode filledNode, 221 BridgeContext ctx) { 222 Value v = CSSUtilities.getComputedStyle 223 (filledElement, SVGCSSEngine.FILL_OPACITY_INDEX); 224 float opacity = convertOpacity(v); 225 v = CSSUtilities.getComputedStyle 226 (filledElement, SVGCSSEngine.FILL_INDEX); 227 228 return convertPaint(filledElement, 229 filledNode, 230 v, 231 opacity, 232 ctx); 233 } 234 235 245 public static Paint convertPaint(Element paintedElement, 246 GraphicsNode paintedNode, 247 Value paintDef, 248 float opacity, 249 BridgeContext ctx) { 250 if (paintDef.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { 251 switch (paintDef.getPrimitiveType()) { 252 case CSSPrimitiveValue.CSS_IDENT: 253 return null; 255 case CSSPrimitiveValue.CSS_RGBCOLOR: 256 return convertColor(paintDef, opacity); 257 258 case CSSPrimitiveValue.CSS_URI: 259 return convertURIPaint(paintedElement, 260 paintedNode, 261 paintDef, 262 opacity, 263 ctx); 264 265 default: 266 throw new Error (); } 268 } else { Value v = paintDef.item(0); 270 switch (v.getPrimitiveType()) { 271 case CSSPrimitiveValue.CSS_RGBCOLOR: 272 return convertRGBICCColor(paintedElement, v, 273 (ICCColor)paintDef.item(1), 274 opacity, ctx); 275 276 case CSSPrimitiveValue.CSS_URI: { 277 Paint result = silentConvertURIPaint(paintedElement, 278 paintedNode, 279 v, opacity, ctx); 280 if (result != null) return result; 281 282 v = paintDef.item(1); 283 switch (v.getPrimitiveType()) { 284 case CSSPrimitiveValue.CSS_IDENT: 285 return null; 287 case CSSPrimitiveValue.CSS_RGBCOLOR: 288 if (paintDef.getLength() == 2) { 289 return convertColor(v, opacity); 290 } else { 291 return convertRGBICCColor(paintedElement, v, 292 (ICCColor)paintDef.item(2), 293 opacity, ctx); 294 } 295 default: 296 throw new Error (); } 298 } 299 default: 300 throw new Error ("Unallowed Value: " + v.getPrimitiveType()); 302 } 303 } 304 } 305 306 318 public static Paint silentConvertURIPaint(Element paintedElement, 319 GraphicsNode paintedNode, 320 Value paintDef, 321 float opacity, 322 BridgeContext ctx) { 323 Paint paint = null; 324 try { 325 paint = convertURIPaint(paintedElement, paintedNode, 326 paintDef, opacity, ctx); 327 } catch (BridgeException ex) { 328 } 329 return paint; 330 } 331 332 341 public static Paint convertURIPaint(Element paintedElement, 342 GraphicsNode paintedNode, 343 Value paintDef, 344 float opacity, 345 BridgeContext ctx) { 346 347 String uri = paintDef.getStringValue(); 348 Element paintElement = ctx.getReferencedElement(paintedElement, uri); 349 350 Bridge bridge = ctx.getBridge(paintElement); 351 if (bridge == null || !(bridge instanceof PaintBridge)) { 352 throw new BridgeException(paintedElement, ERR_CSS_URI_BAD_TARGET, 353 new Object [] {uri}); 354 } 355 return ((PaintBridge)bridge).createPaint(ctx, 356 paintElement, 357 paintedElement, 358 paintedNode, 359 opacity); 360 } 361 362 373 public static Color convertRGBICCColor(Element paintedElement, 374 Value colorDef, 375 ICCColor iccColor, 376 float opacity, 377 BridgeContext ctx) { 378 Color color = null; 379 if (iccColor != null){ 380 color = convertICCColor(paintedElement, iccColor, opacity, ctx); 381 } 382 if (color == null){ 383 color = convertColor(colorDef, opacity); 384 } 385 return color; 386 } 387 388 398 public static Color convertICCColor(Element e, 399 ICCColor c, 400 float opacity, 401 BridgeContext ctx){ 402 String iccProfileName = c.getColorProfile(); 404 if (iccProfileName == null){ 405 return null; 406 } 407 SVGColorProfileElementBridge profileBridge 409 = (SVGColorProfileElementBridge) 410 ctx.getBridge(SVG_NAMESPACE_URI, SVG_COLOR_PROFILE_TAG); 411 if (profileBridge == null){ 412 return null; } 414 415 ICCColorSpaceExt profileCS 416 = profileBridge.createICCColorSpaceExt(ctx, e, iccProfileName); 417 if (profileCS == null){ 418 return null; } 420 421 int n = c.getNumberOfColors(); 423 float[] colorValue = new float[n]; 424 if (n == 0) { 425 return null; 426 } 427 for (int i = 0; i < n; i++) { 428 colorValue[i] = c.getColor(i); 429 } 430 431 float[] rgb = profileCS.intendedToRGB(colorValue); 433 return new Color (rgb[0], rgb[1], rgb[2], opacity); 434 } 435 436 441 public static Color convertColor(Value c, float opacity) { 442 int r = resolveColorComponent(c.getRed()); 443 int g = resolveColorComponent(c.getGreen()); 444 int b = resolveColorComponent(c.getBlue()); 445 return new Color (r, g, b, Math.round(opacity * 255f)); 446 } 447 448 452 457 public static Stroke convertStroke(Element e) { 458 Value v; 459 v = CSSUtilities.getComputedStyle 460 (e, SVGCSSEngine.STROKE_WIDTH_INDEX); 461 float width = v.getFloatValue(); 462 if (width == 0.0f) 463 return null; 465 v = CSSUtilities.getComputedStyle 466 (e, SVGCSSEngine.STROKE_LINECAP_INDEX); 467 int linecap = convertStrokeLinecap(v); 468 v = CSSUtilities.getComputedStyle 469 (e, SVGCSSEngine.STROKE_LINEJOIN_INDEX); 470 int linejoin = convertStrokeLinejoin(v); 471 v = CSSUtilities.getComputedStyle 472 (e, SVGCSSEngine.STROKE_MITERLIMIT_INDEX); 473 float miterlimit = convertStrokeMiterlimit(v); 474 v = CSSUtilities.getComputedStyle 475 (e, SVGCSSEngine.STROKE_DASHARRAY_INDEX); 476 float[] dasharray = convertStrokeDasharray(v); 477 478 float dashoffset = 0; 479 if (dasharray != null) { 480 v = CSSUtilities.getComputedStyle 481 (e, SVGCSSEngine.STROKE_DASHOFFSET_INDEX); 482 dashoffset = v.getFloatValue(); 483 484 if ( dashoffset < 0 ) { 487 float dashpatternlength = 0; 488 for ( int i=0; i<dasharray.length; i++ ) { 489 dashpatternlength += dasharray[i]; 490 } 491 if ( (dasharray.length % 2) != 0 ) 494 dashpatternlength *= 2; 495 496 if (dashpatternlength ==0) { 497 dashoffset=0; 498 } else { 499 while (dashoffset < 0) 500 dashoffset += dashpatternlength; 501 } 502 } 503 } 504 return new BasicStroke (width, 505 linecap, 506 linejoin, 507 miterlimit, 508 dasharray, 509 dashoffset); 510 } 511 512 516 522 public static float [] convertStrokeDasharray(Value v) { 523 float [] dasharray = null; 524 if (v.getCssValueType() == CSSValue.CSS_VALUE_LIST) { 525 int length = v.getLength(); 526 dasharray = new float[length]; 527 float sum = 0; 528 for (int i = 0; i < dasharray.length; ++i) { 529 dasharray[i] = v.item(i).getFloatValue(); 530 sum += dasharray[i]; 531 } 532 if (sum == 0) { 533 536 dasharray = null; 537 } 538 } 539 return dasharray; 540 } 541 542 546 public static float convertStrokeMiterlimit(Value v) { 547 float miterlimit = v.getFloatValue(); 548 return (miterlimit < 1f) ? 1f : miterlimit; 549 } 550 551 555 public static int convertStrokeLinecap(Value v) { 556 String s = v.getStringValue(); 557 switch (s.charAt(0)) { 558 case 'b': 559 return BasicStroke.CAP_BUTT; 560 case 'r': 561 return BasicStroke.CAP_ROUND; 562 case 's': 563 return BasicStroke.CAP_SQUARE; 564 default: 565 throw new Error (); } 567 } 568 569 574 public static int convertStrokeLinejoin(Value v) { 575 String s = v.getStringValue(); 576 switch (s.charAt(0)) { 577 case 'm': 578 return BasicStroke.JOIN_MITER; 579 case 'r': 580 return BasicStroke.JOIN_ROUND; 581 case 'b': 582 return BasicStroke.JOIN_BEVEL; 583 default: 584 throw new Error (); } 586 } 587 588 592 596 public static int resolveColorComponent(Value v) { 597 float f; 598 switch(v.getPrimitiveType()) { 599 case CSSPrimitiveValue.CSS_PERCENTAGE: 600 f = v.getFloatValue(); 601 f = (f > 100f) ? 100f : (f < 0f) ? 0f : f; 602 return Math.round(255f * f / 100f); 603 case CSSPrimitiveValue.CSS_NUMBER: 604 f = v.getFloatValue(); 605 f = (f > 255f) ? 255f : (f < 0f) ? 0f : f; 606 return Math.round(f); 607 default: 608 throw new Error (); } 610 } 611 612 617 public static float convertOpacity(Value v) { 618 float r = v.getFloatValue(); 619 return (r < 0f) ? 0f : (r > 1f) ? 1f : r; 620 } 621 } 622 | Popular Tags |