1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai; 4 5 import com.lightcrafts.model.Region; 6 import com.lightcrafts.model.Contour; 7 import com.lightcrafts.jai.opimage.ShapedMask; 8 9 import com.lightcrafts.mediax.jai.*; 10 import java.util.Iterator; 11 import java.util.LinkedList; 12 import java.util.List; 13 import java.awt.*; 14 import java.awt.image.Raster; 15 import java.awt.geom.AffineTransform; 16 import java.awt.geom.Rectangle2D; 17 import java.awt.geom.NoninvertibleTransformException; 18 19 /** 20 * Created by IntelliJ IDEA. 21 * User: fabio 22 * Date: Apr 5, 2005 23 * Time: 5:21:51 PM 24 * To change this template use File | Settings | File Templates. 25 */ 26 public class LCROIShape extends ROIShape { LCROIShape(Region r, AffineTransform transform)27 public LCROIShape(Region r, AffineTransform transform) { 28 super(r.getOuterShape()); 29 this.transform = transform; 30 this.region = r; 31 } 32 33 private Region region; 34 private AffineTransform transform; 35 getTransform()36 public AffineTransform getTransform() { 37 return transform; 38 } 39 getRegion()40 public Region getRegion() { 41 return region; 42 } 43 intersects(Rectangle rect)44 public boolean intersects(Rectangle rect) { 45 return intersects(new Rectangle2D.Double(rect.x, rect.y, rect.width, rect.height)); 46 } 47 intersects(Rectangle2D rect)48 public boolean intersects(Rectangle2D rect) { 49 for (final Contour c : region.getContours()) { 50 AffineTransform combined = transform; 51 if (c.getTranslation() != null) { 52 combined = AffineTransform.getTranslateInstance(c.getTranslation().getX(), c.getTranslation().getY()); 53 combined.preConcatenate(transform); 54 } 55 Rectangle2D translatedRect = rect; 56 if (!combined.isIdentity()) { 57 try { 58 AffineTransform inverse = combined.createInverse(); 59 translatedRect = inverse.createTransformedShape(rect).getBounds2D(); 60 } catch (NoninvertibleTransformException e) { 61 e.printStackTrace(); 62 } 63 } 64 65 // Take the blur tapering into account 66 Rectangle bounds = c.getOuterShape().getBounds(); 67 bounds.grow((int) (c.getWidth()), (int) (c.getWidth())); 68 69 if (bounds.intersects(translatedRect)) 70 return true; 71 } 72 return false; 73 } 74 getOuterBounds()75 public Rectangle getOuterBounds() { 76 return ShapedMask.getOuterBounds(region, transform); 77 } 78 79 private List<Object> contours = new LinkedList<Object>(); 80 somethingChanged()81 private synchronized boolean somethingChanged() { 82 int i = 0; 83 for (final Contour c : region.getContours()) { 84 if (c != contours.get(i)) 85 return true; 86 87 if (c.getTranslation() != null) { 88 if (contours.size() > (i+1) && c.getTranslation() != contours.get(i+1)) 89 return true; 90 i+=2; 91 } else { 92 i++; 93 } 94 } 95 96 return contours.size() != i; 97 } 98 99 private ShapedMask theMask = null; 100 getData(Rectangle rect)101 public synchronized Raster getData(Rectangle rect) { 102 if (theMask == null || somethingChanged()) { 103 /* 104 We keep the current configuration around 105 to check if something changes in this region. 106 */ 107 for (final Contour c : region.getContours()) { 108 contours.add(c); 109 110 // if a contour has a translation 111 // put that in the next list slot 112 if (c.getTranslation() != null) 113 contours.add(c.getTranslation()); 114 } 115 116 theMask = new ShapedMask(region, this); 117 } 118 119 return theMask.getData(rect); 120 } 121 } 122