1 27 28 package org.nightlabs.editor2d.figures; 29 30 import java.awt.Color ; 31 import java.awt.Graphics2D ; 32 import java.awt.image.BufferedImage ; 33 import java.util.Iterator ; 34 import java.util.LinkedList ; 35 import java.util.List ; 36 37 import org.apache.log4j.Logger; 38 import org.eclipse.draw2d.Figure; 39 import org.eclipse.draw2d.FreeformFigure; 40 import org.eclipse.draw2d.FreeformListener; 41 import org.eclipse.draw2d.Graphics; 42 import org.eclipse.draw2d.IFigure; 43 import org.eclipse.draw2d.J2DGraphics; 44 import org.eclipse.draw2d.Layer; 45 import org.eclipse.draw2d.geometry.Point; 46 import org.eclipse.draw2d.geometry.Rectangle; 47 import org.eclipse.gef.EditPart; 48 import org.eclipse.gef.EditPartViewer; 49 import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; 50 import org.eclipse.swt.widgets.Control; 51 import org.holongate.j2d.J2DRegistry; 52 53 import org.nightlabs.editor2d.util.EditorUtil; 54 55 61 public class OversizedBufferFreeformLayer 62 extends Layer 63 implements FreeformFigure, BufferedFreeformLayer 64 { 65 public static final Logger LOGGER = Logger.getLogger(OversizedBufferFreeformLayer.class); 66 67 private LayerFreeformHelper helper = new LayerFreeformHelper(this); 69 70 73 private BufferedImage bufferedImage; 74 77 private Control viewerControl; 78 82 private EditPart editPart; 83 87 private double currentZoom = 1.0; 88 91 private Point bufferedScrollOffset; 92 95 private Point currentSize = new Point(0,0); 96 99 private Point bufferSize = new Point(0,0); 100 105 private Point bufferTranslation = new Point(0,0); 106 109 private Point bufferOrigin = new Point(0,0); 110 113 private List nonDCFChildren = new LinkedList (); 114 115 116 protected Point calculateBufferFactors() { 117 Point result = new Point(1,1); 118 Point realSizeBounds = EditorUtil.toAbsolute(editPart, currentSize.x, currentSize.y); 119 Point so = EditorUtil.getScrollOffset(editPart); 120 Rectangle childBound = getChildBounds(); 122 if (childBounds == null) 123 return result; 124 if (realSizeBounds.x >= childBound.width && realSizeBounds.y >= childBound.height) { 125 return result; 128 } 129 else { 130 int addX = 1; 131 int addY = 1; 132 if (so.x > 0) 133 addX = 2; 134 if (so.y > 0) 135 addY = 2; 136 result.setLocation( 137 Math.min(4, (childBound.width / realSizeBounds.x)+addX), 138 Math.min(4, (childBound.height / realSizeBounds.y)+addY) 139 ); 140 } 141 return result; 143 } 144 145 152 protected BufferedImage getBufferedImage() 153 { 154 double tmpZoom = EditorUtil.getZoom(editPart); 155 if (tmpZoom != currentZoom) { 156 currentZoom = EditorUtil.getZoom(editPart); 158 clearBuffer(); 159 } 160 if (bufferedScrollOffset == null) { 161 clearBuffer(); 162 } 163 if (bufferedImage == null) { 164 long time = System.currentTimeMillis(); 165 currentSize.setLocation(viewerControl.getSize().x, viewerControl.getSize().x); 166 Point factors = calculateBufferFactors(); 167 bufferSize.setLocation(currentSize.x * factors.x, currentSize.y*factors.y); 168 if (bufferedImage == null) { 169 bufferedImage = new BufferedImage (bufferSize.x, bufferSize.y, BufferedImage.TYPE_INT_ARGB); 170 } 171 Graphics2D bufferedGraphics = bufferedImage.createGraphics(); 172 try { 174 bufferedGraphics.setClip(null); 175 bufferedGraphics.scale(currentZoom, currentZoom); 176 bufferedScrollOffset = EditorUtil.getScrollOffset(editPart); 177 Point offsetTranslation = EditorUtil.toAbsolute( 178 editPart, 179 bufferedScrollOffset.x, 180 bufferedScrollOffset.y 181 ); 182 bufferTranslation.setLocation((bufferSize.x - currentSize.x) / 2, (bufferSize.y - currentSize.y) / 2); 183 Point absoluteBufferTranslation = EditorUtil.toAbsolute( 184 editPart, 185 bufferTranslation.x, 186 bufferTranslation.y 187 188 ); 189 bufferedGraphics.translate( 190 absoluteBufferTranslation.x-offsetTranslation.x, 191 absoluteBufferTranslation.y-offsetTranslation.y 192 ); 193 J2DRegistry.initGraphics(bufferedGraphics); 194 nonDCFChildren.clear(); 195 for (Iterator iter = getChildren().iterator(); iter.hasNext();) 196 { 197 Figure figure = (Figure) iter.next(); 198 if (figure instanceof RendererFigure) { 199 ((RendererFigure)figure).paint(bufferedGraphics); 201 } 202 else { 203 nonDCFChildren.add(figure); 206 } 207 } 208 LOGGER.debug("buffer created in "+(System.currentTimeMillis()-time)+" ms"); 209 } 210 finally { 211 if (bufferedGraphics != null) 212 bufferedGraphics.dispose(); 213 } 214 215 } 216 Point scrollOffset = EditorUtil.getScrollOffset(editPart); 217 bufferOrigin.setLocation(0,0); 218 bufferOrigin.translate( 219 (scrollOffset.x-bufferedScrollOffset.x)+bufferTranslation.x, 220 (scrollOffset.y-bufferedScrollOffset.y)+bufferTranslation.y 221 ); 222 if ( 223 (bufferOrigin.x < 0 || bufferOrigin.y < 0) || 224 (bufferOrigin.x > (bufferSize.x - currentSize.x) || bufferOrigin.y > (bufferSize.y - currentSize.y)) 225 ) { 226 clearBuffer(); 229 return getBufferedImage(); 230 } 231 return bufferedImage; 232 } 233 234 public void paint(Graphics graphics) 235 { 236 long time = System.currentTimeMillis(); 238 if (graphics instanceof J2DGraphics) 239 { 240 J2DGraphics j2dGraphics = (J2DGraphics)graphics; 241 243 BufferedImage buffer = getBufferedImage(); 245 246 Graphics2D g2d = j2dGraphics.createGraphics2D(); 248 g2d.scale(1/currentZoom, 1/currentZoom); 250 Point scrollOffset = EditorUtil.getScrollOffset(editPart); 253 g2d.translate(scrollOffset.x, scrollOffset.y); 254 255 g2d.setPaint(Color.WHITE); 257 g2d.fillRect(-2, -2, currentSize.x+2, currentSize.y+2); 258 g2d.drawImage( 259 buffer, 260 0, 0, currentSize.x, currentSize.y, 261 bufferOrigin.x, bufferOrigin.y, bufferOrigin.x+currentSize.x, bufferOrigin.y+currentSize.y, 262 null 263 ); 264 g2d.dispose(); 265 for (Iterator iter = nonDCFChildren.iterator(); iter.hasNext();) { 267 Figure figure = (Figure) iter.next(); 268 figure.paint(graphics); 269 } 270 } 271 else { 272 super.paint(graphics); 273 } 274 } 276 277 protected void clearBuffer() { 278 if (bufferedImage != null) { 280 bufferedImage.flush(); 281 } 285 bufferedImage = null; 286 childBounds = null; 287 LOGGER.debug("buffer cleared()"); 288 } 289 290 291 294 public void refresh() { 295 clearBuffer(); 296 } 297 298 301 public void refresh(IFigure figure) { 302 clearBuffer(); 303 } 304 305 309 private Rectangle childBounds; 310 311 protected Rectangle getChildBounds() 312 { 313 if (childBounds == null) { 314 for (Iterator iter = getChildren().iterator(); iter.hasNext();) { 315 Figure figure = (Figure) iter.next(); 316 Rectangle figureBounds = figure.getBounds(); 317 if (childBounds == null) 318 childBounds = new Rectangle(figureBounds); 319 else 320 childBounds.union(figureBounds); 321 } 322 } 323 return childBounds; 324 } 325 326 334 public OversizedBufferFreeformLayer() 335 { 336 super.setBounds(new Rectangle(-Integer.MAX_VALUE / 2, -Integer.MAX_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE)); 339 } 340 341 public void init(EditPart editPart) { 342 this.editPart = editPart; 343 EditPartViewer viewer = editPart.getRoot().getViewer(); 344 if (viewer instanceof ScrollingGraphicalViewer) { 345 ScrollingGraphicalViewer graphicalViewer = (ScrollingGraphicalViewer) viewer; 346 Control control = graphicalViewer.getControl(); 347 this.viewerControl = control; 348 } 349 } 350 351 354 public void add(IFigure child, Object constraint, int index) { 355 super.add(child, constraint, index); 356 helper.hookChild(child); 357 clearBuffer(); 358 } 359 360 363 public void addFreeformListener(FreeformListener listener) { 364 addListener(FreeformListener.class, listener); 365 } 366 367 370 public void fireExtentChanged() { 371 Iterator iter = getListeners(FreeformListener.class); 372 while (iter.hasNext()) 373 ((FreeformListener)iter.next()) 374 .notifyFreeformExtentChanged(); 375 } 376 377 383 386 public Rectangle getFreeformExtent() { 387 return helper.getFreeformExtent(); 388 } 389 390 393 public void primTranslate(int dx, int dy) { 394 bounds.x += dx; 395 bounds.y += dy; 396 } 397 398 401 public void remove(IFigure child) { 402 helper.unhookChild(child); 403 super.remove(child); 404 clearBuffer(); 405 } 406 407 410 public void removeFreeformListener(FreeformListener listener) { 411 removeListener(FreeformListener.class, listener); 412 } 413 414 417 public void setFreeformBounds(Rectangle bounds) 418 { 419 } 423 424 public void setBounds(Rectangle rect) 425 { 426 } 430 431 } 432 | Popular Tags |