| 1 9 package com.nightlabs.editor2d.figures; 10 11 import java.awt.Color ; 12 import java.awt.Graphics2D ; 13 import java.awt.image.BufferedImage ; 14 import java.util.Iterator ; 15 import java.util.LinkedList ; 16 import java.util.List ; 17 18 import org.apache.log4j.Logger; 19 import org.eclipse.draw2d.Figure; 20 import org.eclipse.draw2d.FreeformFigure; 21 import org.eclipse.draw2d.FreeformListener; 22 import org.eclipse.draw2d.Graphics; 23 import org.eclipse.draw2d.IFigure; 24 import org.eclipse.draw2d.J2DGraphics; 25 import org.eclipse.draw2d.Layer; 26 import org.eclipse.draw2d.geometry.Point; 27 import org.eclipse.draw2d.geometry.Rectangle; 28 import org.eclipse.gef.EditPart; 29 import org.eclipse.gef.EditPartViewer; 30 import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; 31 import org.eclipse.swt.widgets.Control; 32 import org.holongate.j2d.J2DRegistry; 33 34 import com.nightlabs.editor2d.util.EditorUtil; 35 36 42 public class OversizedBufferFreeformLayer 43 extends Layer 44 implements FreeformFigure, BufferedFreeformLayer 45 { 46 public static final Logger LOGGER = Logger.getLogger(OversizedBufferFreeformLayer.class); 47 48 private LayerFreeformHelper helper = new LayerFreeformHelper(this); 50 51 54 private BufferedImage bufferedImage; 55 58 private Control viewerControl; 59 63 private EditPart editPart; 64 68 private double currentZoom = 1.0; 69 72 private Point bufferedScrollOffset; 73 76 private Point currentSize = new Point(0,0); 77 80 private Point bufferSize = new Point(0,0); 81 86 private Point bufferTranslation = new Point(0,0); 87 90 private Point bufferOrigin = new Point(0,0); 91 94 private List nonDCFChildren = new LinkedList (); 95 96 97 protected Point calculateBufferFactors() { 98 Point result = new Point(1,1); 99 Point realSizeBounds = EditorUtil.toAbsolute(editPart, currentSize.x, currentSize.y); 100 Point so = EditorUtil.getScrollOffset(editPart); 101 Rectangle childBound = getChildBounds(); 103 if (childBounds == null) 104 return result; 105 if (realSizeBounds.x >= childBound.width && realSizeBounds.y >= childBound.height) { 106 return result; 109 } 110 else { 111 int addX = 1; 112 int addY = 1; 113 if (so.x > 0) 114 addX = 2; 115 if (so.y > 0) 116 addY = 2; 117 result.setLocation( 118 Math.min(4, (childBound.width / realSizeBounds.x)+addX), 119 Math.min(4, (childBound.height / realSizeBounds.y)+addY) 120 ); 121 } 122 LOGGER.debug("Calculated buffer factors: "+result); 123 return result; 124 } 125 126 133 protected BufferedImage getBufferedImage() { 134 135 double tmpZoom = EditorUtil.getZoom(editPart); 136 if (tmpZoom != currentZoom) { 137 currentZoom = EditorUtil.getZoom(editPart); 139 clearBuffer(); 140 } 141 if (bufferedScrollOffset == null) { 142 clearBuffer(); 143 } 144 if (bufferedImage == null) { 145 long time = System.currentTimeMillis(); 146 currentSize.setLocation(viewerControl.getSize().x, viewerControl.getSize().x); 147 Point factors = calculateBufferFactors(); 148 bufferSize.setLocation(currentSize.x * factors.x, currentSize.y*factors.y); 149 if (bufferedImage == null) { 150 bufferedImage = new BufferedImage (bufferSize.x, bufferSize.y, BufferedImage.TYPE_INT_ARGB); 151 } 152 Graphics2D bufferedGraphics = bufferedImage.createGraphics(); 153 try { 155 bufferedGraphics.setClip(null); 156 bufferedGraphics.scale(currentZoom, currentZoom); 157 bufferedScrollOffset = EditorUtil.getScrollOffset(editPart); 158 Point offsetTranslation = EditorUtil.toAbsolute( 159 editPart, 160 bufferedScrollOffset.x, 161 bufferedScrollOffset.y 162 ); 163 bufferTranslation.setLocation((bufferSize.x - currentSize.x) / 2, (bufferSize.y - currentSize.y) / 2); 164 Point absoluteBufferTranslation = EditorUtil.toAbsolute( 165 editPart, 166 bufferTranslation.x, 167 bufferTranslation.y 168 169 ); 170 bufferedGraphics.translate( 171 absoluteBufferTranslation.x-offsetTranslation.x, 172 absoluteBufferTranslation.y-offsetTranslation.y 173 ); 174 J2DRegistry.initGraphics(bufferedGraphics); 175 nonDCFChildren.clear(); 176 for (Iterator iter = getChildren().iterator(); iter.hasNext();) { 177 Figure figure = (Figure) iter.next(); 178 if (figure instanceof DrawComponentFigure) { 179 ((DrawComponentFigure)figure).paint(bufferedGraphics); 181 } 182 else { 183 nonDCFChildren.add(figure); 186 } 187 } 188 LOGGER.debug("buffer created in "+(System.currentTimeMillis()-time)+" ms"); 189 } 190 finally { 191 if (bufferedGraphics != null) 192 bufferedGraphics.dispose(); 193 } 194 195 } 196 Point scrollOffset = EditorUtil.getScrollOffset(editPart); 197 bufferOrigin.setLocation(0,0); 198 bufferOrigin.translate( 199 (scrollOffset.x-bufferedScrollOffset.x)+bufferTranslation.x, 200 (scrollOffset.y-bufferedScrollOffset.y)+bufferTranslation.y 201 ); 202 if ( 203 (bufferOrigin.x < 0 || bufferOrigin.y < 0) || 204 (bufferOrigin.x > (bufferSize.x - currentSize.x) || bufferOrigin.y > (bufferSize.y - currentSize.y)) 205 ) { 206 clearBuffer(); 209 return getBufferedImage(); 210 } 211 return bufferedImage; 212 } 213 214 public void paint(Graphics graphics) { 215 long time = System.currentTimeMillis(); 219 if (graphics instanceof J2DGraphics) { 220 J2DGraphics j2dGraphics = (J2DGraphics)graphics; 221 j2dGraphics.clipRect(null); 223 224 BufferedImage buffer = getBufferedImage(); 226 227 Graphics2D g2d = j2dGraphics.createGraphics2D(); 229 g2d.scale(1/currentZoom, 1/currentZoom); 231 Point scrollOffset = EditorUtil.getScrollOffset(editPart); 234 g2d.translate(scrollOffset.x, scrollOffset.y); 235 236 g2d.setPaint(Color.WHITE); 240 g2d.fillRect(-2, -2, currentSize.x+2, currentSize.y+2); 241 g2d.drawImage( 242 buffer, 243 0, 0, currentSize.x, currentSize.y, 244 bufferOrigin.x, bufferOrigin.y, bufferOrigin.x+currentSize.x, bufferOrigin.y+currentSize.y, 245 null 246 ); 247 g2d.dispose(); 248 for (Iterator iter = nonDCFChildren.iterator(); iter.hasNext();) { 250 Figure figure = (Figure) iter.next(); 251 figure.paint(graphics); 252 } 253 } 254 else { 255 super.paint(graphics); 256 } 257 } 259 260 261 protected void clearBuffer() { 262 if (bufferedImage != null) { 264 bufferedImage.flush(); 265 long time = System.currentTimeMillis(); 266 System.gc(); 267 LOGGER.debug("gc() took "+(System.currentTimeMillis()-time)+" ms"); 268 } 269 bufferedImage = null; 270 childBounds = null; 271 } 273 274 275 278 public void refresh() { 279 clearBuffer(); 280 } 281 282 285 public void refresh(Figure figure) { 286 clearBuffer(); 287 } 288 289 293 private Rectangle childBounds; 294 295 protected Rectangle getChildBounds() { 296 if (childBounds == null) { 297 for (Iterator iter = getChildren().iterator(); iter.hasNext();) { 298 Figure figure = (Figure) iter.next(); 299 Rectangle figureBounds = figure.getBounds(); 300 if (childBounds == null) 301 childBounds = new Rectangle(figureBounds); 302 else 303 childBounds.union(figureBounds); 304 } 305 } 306 return childBounds; 307 } 308 309 317 public OversizedBufferFreeformLayer() 318 { 319 super.setBounds(new Rectangle(-Integer.MAX_VALUE / 2, -Integer.MAX_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE)); 322 } 323 324 public void init(EditPart editPart) { 325 this.editPart = editPart; 326 EditPartViewer viewer = editPart.getRoot().getViewer(); 327 if (viewer instanceof ScrollingGraphicalViewer) { 328 ScrollingGraphicalViewer graphicalViewer = (ScrollingGraphicalViewer) viewer; 329 Control control = graphicalViewer.getControl(); 330 this.viewerControl = control; 331 } 332 } 333 334 337 public void add(IFigure child, Object constraint, int index) { 338 super.add(child, constraint, index); 339 helper.hookChild(child); 340 clearBuffer(); 341 } 342 343 346 public void addFreeformListener(FreeformListener listener) { 347 addListener(FreeformListener.class, listener); 348 } 349 350 353 public void fireExtentChanged() { 354 Iterator iter = getListeners(FreeformListener.class); 355 while (iter.hasNext()) 356 ((FreeformListener)iter.next()) 357 .notifyFreeformExtentChanged(); 358 } 359 360 364 protected void fireMoved() { } 365 366 369 public Rectangle getFreeformExtent() { 370 return helper.getFreeformExtent(); 371 } 372 373 376 public void primTranslate(int dx, int dy) { 377 bounds.x += dx; 378 bounds.y += dy; 379 } 380 381 384 public void remove(IFigure child) { 385 helper.unhookChild(child); 386 super.remove(child); 387 clearBuffer(); 388 } 389 390 393 public void removeFreeformListener(FreeformListener listener) { 394 removeListener(FreeformListener.class, listener); 395 } 396 397 400 public void setFreeformBounds(Rectangle bounds) { 401 } 405 406 public void setBounds(Rectangle rect) { 407 } 411 412 413 } 414 | Popular Tags |