1 18 package org.apache.batik.ext.awt.image.renderable; 19 20 import java.awt.Composite ; 21 import java.awt.Graphics2D ; 22 import java.awt.Rectangle ; 23 import java.awt.RenderingHints ; 24 import java.awt.Shape ; 25 import java.awt.color.ColorSpace ; 26 import java.awt.geom.AffineTransform ; 27 import java.awt.geom.Rectangle2D ; 28 import java.awt.image.RenderedImage ; 29 import java.awt.image.renderable.RenderContext ; 30 import java.awt.image.renderable.RenderableImage ; 31 import java.lang.ref.Reference ; 32 import java.lang.ref.SoftReference ; 33 import java.util.Iterator ; 34 import java.util.ListIterator ; 35 import java.util.Vector ; 36 37 import org.apache.batik.ext.awt.image.CompositeRule; 38 import org.apache.batik.ext.awt.image.GraphicsUtil; 39 import org.apache.batik.ext.awt.image.SVGComposite; 40 import org.apache.batik.ext.awt.image.rendered.AffineRed; 41 import org.apache.batik.ext.awt.image.rendered.TileCacheRed; 42 43 49 public class FilterResRable8Bit extends AbstractRable 50 implements FilterResRable, PaintRable { 51 52 55 private int filterResolutionX = -1; 56 57 60 private int filterResolutionY = -1; 61 62 public FilterResRable8Bit() { 63 } 65 66 67 public FilterResRable8Bit(Filter src, int filterResX, int filterResY) { 68 init(src, null); 69 setFilterResolutionX(filterResX); 70 setFilterResolutionY(filterResY); 71 } 72 73 76 public Filter getSource() { 77 return (Filter)srcs.get(0); 78 } 79 80 84 public void setSource(Filter src){ 85 init(src, null); 86 } 87 88 91 public int getFilterResolutionX(){ 92 return filterResolutionX; 93 } 94 95 101 public void setFilterResolutionX(int filterResolutionX){ 102 if(filterResolutionX < 0){ 103 throw new IllegalArgumentException (); 104 } 105 touch(); 106 this.filterResolutionX = filterResolutionX; 107 } 108 109 112 public int getFilterResolutionY(){ 113 return filterResolutionY; 114 } 115 116 122 public void setFilterResolutionY(int filterResolutionY){ 123 touch(); 124 this.filterResolutionY = filterResolutionY; 125 } 126 127 128 140 public boolean allPaintRable(RenderableImage ri) { 141 if (!(ri instanceof PaintRable)) 142 return false; 143 144 Vector v = ri.getSources(); 145 if (v == null) return true; 147 148 Iterator i = v.iterator(); 149 while (i.hasNext()) { 150 RenderableImage nri = (RenderableImage )i.next(); 151 if (!allPaintRable(nri)) return false; 153 } 154 155 return true; 156 } 157 158 170 public boolean distributeAcross(RenderableImage src, Graphics2D g2d) { 171 boolean ret; 172 if (src instanceof PadRable) { 173 PadRable pad = (PadRable)src; 174 Shape clip = g2d.getClip(); 175 g2d.clip(pad.getPadRect()); 176 ret = distributeAcross(pad.getSource(), g2d); 177 g2d.setClip(clip); 178 return ret; 179 } 180 181 if (src instanceof CompositeRable) { 182 CompositeRable comp = (CompositeRable)src; 183 if (comp.getCompositeRule() != CompositeRule.OVER) 184 return false; 185 186 if (false) { 187 ColorSpace crCS = comp.getOperationColorSpace(); 190 ColorSpace g2dCS = GraphicsUtil.getDestinationColorSpace(g2d); 191 if ((g2dCS == null) || (g2dCS != crCS)) 192 return false; 193 } 194 195 Vector v = comp.getSources(); 196 if (v == null) return true; 197 ListIterator li = v.listIterator(v.size()); 198 while (li.hasPrevious()) { 199 RenderableImage csrc = (RenderableImage )li.previous(); 200 if (!allPaintRable(csrc)) { 201 li.next(); 202 break; 203 } 204 } 205 206 if (!li.hasPrevious()) { 207 GraphicsUtil.drawImage(g2d, comp); 210 return true; 211 } 212 213 if (!li.hasNext()) 214 return false; 217 218 int idx = li.nextIndex(); Filter f = new CompositeRable8Bit(v.subList(0, idx), 225 comp.getCompositeRule(), 226 comp.isColorSpaceLinear()); 227 f = new FilterResRable8Bit(f, getFilterResolutionX(), 228 getFilterResolutionY()); 229 GraphicsUtil.drawImage(g2d, f); 230 while (li.hasNext()) { 231 PaintRable pr = (PaintRable)li.next(); 232 if (!pr.paintRable(g2d)) { 233 Filter prf = (Filter)pr; 235 prf = new FilterResRable8Bit(prf, getFilterResolutionX(), 236 getFilterResolutionY()); 237 GraphicsUtil.drawImage(g2d, prf); 238 } 239 } 240 return true; 241 } 242 return false; 243 } 244 245 254 public boolean paintRable(Graphics2D g2d) { 255 264 266 Composite c = g2d.getComposite(); 269 if (!SVGComposite.OVER.equals(c)) 270 return false; 271 272 Filter src = getSource(); 273 return distributeAcross(src, g2d); 274 } 275 276 279 Reference resRed = null; 280 float resScale = 0; 281 282 private float getResScale() { 283 return resScale; 284 } 285 286 private RenderedImage getResRed(RenderingHints hints) { 287 Rectangle2D imageRect = getBounds2D(); 288 double resScaleX = getFilterResolutionX()/imageRect.getWidth(); 289 double resScaleY = getFilterResolutionY()/imageRect.getHeight(); 290 291 292 295 float resScale = (float)Math.min(resScaleX, resScaleY); 296 297 RenderedImage ret; 298 if (resScale == this.resScale) { 299 ret = (RenderedImage )resRed.get(); 301 if (ret != null) 302 return ret; 303 } 304 305 AffineTransform resUsr2Dev; 306 resUsr2Dev = AffineTransform.getScaleInstance(resScale, resScale); 307 308 RenderContext newRC = new RenderContext (resUsr2Dev, null, hints); 312 313 ret = getSource().createRendering(newRC); 314 315 ret = new TileCacheRed(GraphicsUtil.wrap(ret)); 320 this.resScale = resScale; 321 this.resRed = new SoftReference (ret); 322 323 return ret; 324 } 325 326 327 328 331 public RenderedImage createRendering(RenderContext renderContext) { 332 AffineTransform usr2dev = renderContext.getTransform(); 334 if(usr2dev == null){ 335 usr2dev = new AffineTransform (); 336 } 337 338 RenderingHints hints = renderContext.getRenderingHints(); 339 340 int filterResolutionX = getFilterResolutionX(); 353 int filterResolutionY = getFilterResolutionY(); 354 357 if ((filterResolutionX <= 0) || (filterResolutionY == 0)) 358 return null; 359 360 Rectangle2D imageRect = getBounds2D(); 362 Rectangle devRect; 363 devRect = usr2dev.createTransformedShape(imageRect).getBounds(); 364 365 float scaleX = 1; 368 if(filterResolutionX < devRect.width) 369 scaleX = filterResolutionX / (float)devRect.width; 370 371 float scaleY = 1; 372 if(filterResolutionY < 0) 373 scaleY = scaleX; 374 else if(filterResolutionY < devRect.height) 375 scaleY = filterResolutionY / (float)devRect.height; 376 377 if ((scaleX >= 1) && (scaleY >= 1)) 380 return getSource().createRendering(renderContext); 381 382 384 RenderedImage resRed = getResRed(hints); 387 float resScale = getResScale(); 388 389 AffineTransform residualAT; 390 residualAT = new AffineTransform (usr2dev.getScaleX()/resScale, 391 usr2dev.getShearY()/resScale, 392 usr2dev.getShearX()/resScale, 393 usr2dev.getScaleY()/resScale, 394 usr2dev.getTranslateX(), 395 usr2dev.getTranslateY()); 396 397 399 return new AffineRed(GraphicsUtil.wrap(resRed), residualAT, hints); 400 } 401 } 402 403 | Popular Tags |