/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.ui.vector.awt; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.arakhne.afc.math.continous.object2d.Path2f; import org.arakhne.afc.math.continous.object2d.Rectangle2f; import org.arakhne.afc.math.matrix.Transform2D; import org.arakhne.afc.ui.CenteringTransform; import org.arakhne.afc.ui.ZoomableContextUtil; import org.arakhne.afc.ui.awt.VirtualizableShape; import org.arakhne.afc.ui.awt.ZoomableAwtContextUtil; /** Public implementation of a Path2D. * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @deprecated see JavaFX API */ @Deprecated class AwtPath implements VirtualizableShape, NativeWrapper { private final Path2f path; /** * @param path */ public AwtPath(Path2f path) { super(); this.path = path; } @Override public <T> T getNativeObject(Class<T> type) { return type.cast(this); } @Override public Rectangle getBounds() { Rectangle2f bb = this.path.toBoundingBox(); int ix = (int)bb.getMinX(); int iy = (int)bb.getMinY(); int mx = (int)Math.ceil(bb.getMaxX()); int my = (int)Math.ceil(bb.getMaxY()); return new Rectangle(ix, iy, mx-ix, my-iy); } @Override public Rectangle2D getBounds2D() { Rectangle2f bb = this.path.toBoundingBox(); return new Rectangle2D.Float( bb.getMinX(), bb.getMinY(), bb.getWidth(), bb.getHeight()); } @Override public boolean contains(double x, double y) { return this.path.contains((float)x, (float)y); } @Override public boolean contains(Point2D p) { return this.path.contains((float)p.getX(), (float)p.getY()); } @Override public boolean intersects(double x, double y, double w, double h) { return Path2f.intersects(this.path.getPathIterator(), (float)x, (float)y, (float)w, (float)h); } @Override public boolean intersects(Rectangle2D r) { return Path2f.intersects(this.path.getPathIterator(), (float)r.getMinX(), (float)r.getMinY(), (float)r.getWidth(), (float)r.getHeight()); } @Override public boolean contains(double x, double y, double w, double h) { return Path2f.contains(this.path.getPathIterator(), (float)x, (float)y, (float)w, (float)h); } @Override public boolean contains(Rectangle2D r) { return Path2f.contains(this.path.getPathIterator(), (float)r.getMinX(), (float)r.getMinY(), (float)r.getWidth(), (float)r.getHeight()); } @Override public PathIterator getPathIterator(AffineTransform at) { if (at==null || at.isIdentity()) return new AwtPathIterator(this.path.getPathIterator()); Transform2D tr = new Transform2D( (float)at.getScaleX(), (float)at.getShearX(), (float)at.getTranslateX(), (float)at.getShearY(), (float)at.getScaleY(), (float)at.getTranslateY()); return new AwtPathIterator(this.path.getPathIterator(tr)); } @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { if (at==null || at.isIdentity()) return new AwtPathIterator(this.path.getPathIterator((float)flatness)); Transform2D tr = new Transform2D( (float)at.getScaleX(), (float)at.getShearX(), (float)at.getTranslateX(), (float)at.getShearY(), (float)at.getScaleY(), (float)at.getTranslateY()); return new AwtPathIterator(this.path.getPathIterator(tr, (float)flatness)); } @Override public VirtualizableShape toScreen(CenteringTransform centeringTransform, float zoom) { return new ScreenPath(centeringTransform, zoom); } @Override public VirtualizableShape fromScreen(CenteringTransform centeringTransform, float zoom) { return this; } /** * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ private class ScreenPath implements VirtualizableShape, NativeWrapper { final CenteringTransform centeringTransform; float zoom; /** * @param centeringTransform is the transformation that permits to * center the objects on the view. * @param zoom is the current zooming factor of the view. */ public ScreenPath( CenteringTransform centeringTransform, float zoom) { this.centeringTransform = centeringTransform; this.zoom = zoom; } @Override public Rectangle getBounds() { Rectangle r = (Rectangle)AwtPath.this.getBounds().clone(); ZoomableAwtContextUtil.logical2pixel( r, this.centeringTransform, this.zoom); return r; } @Override public Rectangle2D getBounds2D() { Rectangle2D r = (Rectangle2D)AwtPath.this.getBounds2D().clone(); ZoomableAwtContextUtil.logical2pixel( r, this.centeringTransform, this.zoom); return r; } @Override public boolean contains(double x, double y) { float sx = ZoomableContextUtil.pixel2logical_x( (float)x, this.centeringTransform, this.zoom); float sy = ZoomableContextUtil.pixel2logical_y( (float)y, this.centeringTransform, this.zoom); return AwtPath.this.contains(sx, sy); } @Override public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } @Override public boolean intersects(double x, double y, double w, double h) { Rectangle2D r = new Rectangle2D.Float((float)x, (float)y, (float)w, (float)h); ZoomableAwtContextUtil.pixel2logical( r, this.centeringTransform, this.zoom); return AwtPath.this.intersects(r); } @Override public boolean intersects(Rectangle2D r) { Rectangle2D rr = (Rectangle2D)r.clone(); ZoomableAwtContextUtil.pixel2logical( rr, this.centeringTransform, this.zoom); return AwtPath.this.intersects(rr); } @Override public boolean contains(double x, double y, double w, double h) { Rectangle2D r = new Rectangle2D.Float((float)x, (float)y, (float)w, (float)h); ZoomableAwtContextUtil.pixel2logical( r, this.centeringTransform, this.zoom); return AwtPath.this.contains(r); } @Override public boolean contains(Rectangle2D r) { Rectangle2D rr = (Rectangle2D)r.clone(); ZoomableAwtContextUtil.pixel2logical( rr, this.centeringTransform, this.zoom); return AwtPath.this.contains(rr); } @Override public PathIterator getPathIterator(AffineTransform at) { return new ScreenPathIterator(at, AwtPath.this.getPathIterator(null)); } @Override public PathIterator getPathIterator(AffineTransform at, double flatness) { float vFlatness = ZoomableContextUtil.pixel2logical_size((float)flatness, this.zoom); return new ScreenPathIterator(at, AwtPath.this.getPathIterator(null,vFlatness)); } @Override public <T> T getNativeObject(Class<T> type) { return type.cast(this); } @Override public VirtualizableShape toScreen(CenteringTransform centeringTransform, float zoom) { return this; } @Override public VirtualizableShape fromScreen(CenteringTransform centeringTransform, float zoom) { return AwtPath.this; } /** * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ private class ScreenPathIterator implements PathIterator { private final AffineTransform tr; private final PathIterator pi; public ScreenPathIterator(AffineTransform tr, PathIterator pi) { this.pi = pi; this.tr = tr; } @Override public int getWindingRule() { return this.pi.getWindingRule(); } @Override public boolean isDone() { return this.pi.isDone(); } @Override public void next() { this.pi.next(); } @Override public int currentSegment(float[] coords) { int t = this.pi.currentSegment(coords); int numPts = 0; switch(t) { case PathIterator.SEG_CUBICTO: ++numPts; coords[4] = ZoomableContextUtil.logical2pixel_x( coords[4], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[5] = ZoomableContextUtil.logical2pixel_y( coords[5], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); //$FALL-THROUGH$ case PathIterator.SEG_QUADTO: ++numPts; coords[2] = ZoomableContextUtil.logical2pixel_x( coords[2], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[3] = ZoomableContextUtil.logical2pixel_y( coords[3], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); //$FALL-THROUGH$ case PathIterator.SEG_MOVETO: case PathIterator.SEG_LINETO: ++numPts; coords[0] = ZoomableContextUtil.logical2pixel_x( coords[0], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[1] = ZoomableContextUtil.logical2pixel_y( coords[1], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); if (this.tr!=null) { this.tr.transform(coords, 0, coords, 0, numPts); } break; case SEG_CLOSE: default: break; } return t; } @Override public int currentSegment(double[] coords) { int t = this.pi.currentSegment(coords); int numPts = 0; switch(t) { case PathIterator.SEG_CUBICTO: ++numPts; coords[4] = ZoomableContextUtil.logical2pixel_x( (float)coords[4], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[5] = ZoomableContextUtil.logical2pixel_y( (float)coords[5], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); //$FALL-THROUGH$ case PathIterator.SEG_QUADTO: ++numPts; coords[2] = ZoomableContextUtil.logical2pixel_x( (float)coords[2], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[3] = ZoomableContextUtil.logical2pixel_y( (float)coords[3], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); //$FALL-THROUGH$ case PathIterator.SEG_MOVETO: case PathIterator.SEG_LINETO: ++numPts; coords[0] = ZoomableContextUtil.logical2pixel_x( (float)coords[0], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); coords[1] = ZoomableContextUtil.logical2pixel_y( (float)coords[1], ScreenPath.this.centeringTransform, ScreenPath.this.zoom); if (this.tr!=null) { this.tr.transform(coords, 0, coords, 0, numPts); } break; case SEG_CLOSE: default: break; } return t; } } } }