/** * returns the skew transform * * @param svgHandle a svg handle * @param bounds the bounds of the area to transform * @param firstPoint the first clicked point by the user * @param currentPoint the current point of the drag action by the user * @param item the selection item * @return the skew transform */ protected AffineTransform getSkewTransform( SVGHandle svgHandle, Rectangle2D bounds, Point2D firstPoint, Point2D currentPoint, SelectionItem item) { // getting the skew factor double skewX = 0, skewY = 0; boolean isHorizontal = (item.getType() == SelectionItem.NORTH || item.getType() == SelectionItem.SOUTH); if (bounds.getWidth() > 0 && bounds.getHeight() > 0) { if (isHorizontal) { skewX = (currentPoint.getX() - firstPoint.getX()) / bounds.getHeight(); } else { skewY = (currentPoint.getY() - firstPoint.getY()) / bounds.getWidth(); } } // getting the center point Point2D centerPoint = getRotationSkewCenterPoint(svgHandle, bounds); // creating the affine transform AffineTransform af = AffineTransform.getTranslateInstance(-centerPoint.getX(), -centerPoint.getY()); af.preConcatenate(AffineTransform.getShearInstance(skewX, skewY)); af.preConcatenate(AffineTransform.getTranslateInstance(centerPoint.getX(), centerPoint.getY())); return af; }
@Override public UndoRedoAction validateAction( SVGHandle handle, int level, Set<Element> elementSet, SelectionItem item, Point2D firstPoint, Point2D lastPoint) { // the undo/redo action that will be returned UndoRedoAction undoRedoAction = null; // getting the element that will undergo the action Element element = elementSet.iterator().next(); // executing the accurate action switch (level) { case 0: // getting the resize transform AffineTransform resizeTransform = getResizeTransform(handle, element, item, firstPoint, lastPoint); // executing the resize action undoRedoAction = resize(handle, elementSet, resizeTransform); break; case 1: if (item.getType() != SelectionItem.CENTER) { // getting the center point Point2D centerPoint = getRotationSkewCenterPoint(handle, element); if (item.getType() == SelectionItem.NORTH_WEST || item.getType() == SelectionItem.NORTH_EAST || item.getType() == SelectionItem.SOUTH_EAST || item.getType() == SelectionItem.SOUTH_WEST) { // getting the angle for the rotation double angle = ShapeToolkit.getRotationAngle(centerPoint, firstPoint, lastPoint); // executing the rotation action undoRedoAction = rotate(handle, elementSet, centerPoint, angle); } else { // getting the skew factor and whether it's horizontal // or not boolean isHorizontal = (item.getType() == SelectionItem.NORTH || item.getType() == SelectionItem.SOUTH); double skewFactor = 0; if (isHorizontal) { skewFactor = lastPoint.getX() - firstPoint.getX(); } else { skewFactor = lastPoint.getY() - firstPoint.getY(); } // executing the skew action undoRedoAction = skew(handle, elementSet, centerPoint, skewFactor, isHorizontal); } rotationSkewSelectionItemCenterPoint = null; } else { rotationSkewCenterPoint = rotationSkewSelectionItemCenterPoint; rotationSkewSelectionItemCenterPoint = null; } break; } return undoRedoAction; }
@Override public CanvasPainter showAction( SVGHandle handle, int level, Set<Element> elementSet, SelectionItem item, Point2D firstPoint, Point2D currentPoint) { // getting the element that will undergo the action Element element = elementSet.iterator().next(); // the canvas painter that should be returned CanvasPainter painter = null; // whether the shape should be painted boolean canPaintShape = true; // the shape that will be painted Shape shape = null; // getting the action transform AffineTransform actionTransform = null; switch (level) { case 0: // getting the resize transform actionTransform = getResizeTransform(handle, element, item, firstPoint, currentPoint); break; case 1: if (item.getType() == SelectionItem.CENTER) { // storing the center point for the rotate action rotationSkewSelectionItemCenterPoint = currentPoint; item.setPoint(currentPoint); canPaintShape = false; } else if (item.getType() == SelectionItem.NORTH_WEST || item.getType() == SelectionItem.NORTH_EAST || item.getType() == SelectionItem.SOUTH_EAST || item.getType() == SelectionItem.SOUTH_WEST) { // getting the rotation transform actionTransform = getRotationTransform(handle, element, firstPoint, currentPoint); } else { // getting the skew transform actionTransform = getSkewTransform(handle, element, firstPoint, currentPoint, item); } break; } if (actionTransform != null) { // getting the initial shape shape = getShape(handle, element, true); // getting the element's transform AffineTransform transform = handle.getSvgElementsManager().getTransform(element); // concatenating the action transform to the element's transform transform.preConcatenate(actionTransform); // computing the screen scaled shape shape = handle.getTransformsManager().getScaledShape(shape, false, transform); } if (canPaintShape && shape != null) { final Shape fshape = shape; // creating the set of the clips final HashSet<Rectangle2D> fclips = new HashSet<Rectangle2D>(); fclips.add(fshape.getBounds2D()); painter = new CanvasPainter() { @Override public void paintToBeDone(Graphics2D g) { g = (Graphics2D) g.create(); g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(strokeColor); g.draw(fshape); g.dispose(); } @Override public Set<Rectangle2D> getClip() { return fclips; } }; } return painter; }
/** * returns the resize transform corresponding to the parameters * * @param handle a svg handle * @param bounds the bounds of the area to be resized * @param item the selection item * @param firstPoint the first point * @param secondPoint the second point * @return the resize transform corresponding to the parameters */ protected AffineTransform getResizeTransform( SVGHandle handle, Rectangle2D bounds, SelectionItem item, Point2D firstPoint, Point2D secondPoint) { // getting the diff point Point2D diff = new Point2D.Double( secondPoint.getX() - firstPoint.getX(), secondPoint.getY() - firstPoint.getY()); // getting the scale and the translation factors double sx = 1.0, sy = 1.0, tx = 0, ty = 0; int type = item.getType(); if (Editor.getEditor().getSquareModeManager().isSquareMode()) { switch (type) { case SelectionItem.NORTH: diff = new Point2D.Double(diff.getY(), diff.getY()); sy = 1 - diff.getY() / bounds.getHeight(); sx = sy; tx = (bounds.getX() + bounds.getWidth() / 2) * (1 - sx); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.SOUTH: diff = new Point2D.Double(diff.getY(), diff.getY()); sy = 1 + diff.getY() / bounds.getHeight(); sx = sy; tx = (bounds.getX() + bounds.getWidth() / 2) * (1 - sx); ty = bounds.getY() * (1 - sy); break; case SelectionItem.EAST: diff = new Point2D.Double(diff.getX(), diff.getX()); sx = 1 + diff.getX() / bounds.getWidth(); sy = sx; tx = bounds.getX() * (1 - sx); ty = (bounds.getY() + bounds.getHeight() / 2) * (1 - sy); break; case SelectionItem.WEST: diff = new Point2D.Double(diff.getX(), -diff.getX()); sx = 1 - diff.getX() / bounds.getWidth(); sy = sx; tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); ty = (bounds.getY() + bounds.getHeight() / 2) * (1 - sy); break; case SelectionItem.NORTH_EAST: diff = new Point2D.Double(diff.getX(), -diff.getX()); sx = 1 + diff.getX() / bounds.getWidth(); sy = sx; tx = (bounds.getX()) * (1 - sx); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.NORTH_WEST: diff = new Point2D.Double(diff.getY(), diff.getY()); sy = 1 - diff.getY() / bounds.getHeight(); sx = sy; tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.SOUTH_EAST: diff = new Point2D.Double(diff.getY(), diff.getY()); sy = 1 + diff.getY() / bounds.getHeight(); sx = sy; tx = bounds.getX() * (1 - sx); ty = bounds.getY() * (1 - sy); break; case SelectionItem.SOUTH_WEST: diff = new Point2D.Double(diff.getX(), -diff.getX()); sx = 1 - diff.getX() / bounds.getWidth(); sy = sx; tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); ty = (bounds.getY()) * (1 - sy); break; } } else { switch (type) { case SelectionItem.NORTH: sy = 1 - diff.getY() / bounds.getHeight(); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.SOUTH: sy = 1 + diff.getY() / bounds.getHeight(); ty = bounds.getY() * (1 - sy); break; case SelectionItem.EAST: sx = 1 + diff.getX() / bounds.getWidth(); tx = bounds.getX() * (1 - sx); break; case SelectionItem.WEST: sx = 1 - diff.getX() / bounds.getWidth(); tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); break; case SelectionItem.NORTH_EAST: sx = 1 + diff.getX() / bounds.getWidth(); sy = 1 - diff.getY() / bounds.getHeight(); tx = (bounds.getX()) * (1 - sx); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.NORTH_WEST: sx = 1 - diff.getX() / bounds.getWidth(); sy = 1 - diff.getY() / bounds.getHeight(); tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); ty = (bounds.getY() + bounds.getHeight()) * (1 - sy); break; case SelectionItem.SOUTH_EAST: sx = 1 + diff.getX() / bounds.getWidth(); sy = 1 + diff.getY() / bounds.getHeight(); tx = bounds.getX() * (1 - sx); ty = bounds.getY() * (1 - sy); break; case SelectionItem.SOUTH_WEST: sx = 1 - diff.getX() / bounds.getWidth(); sy = 1 + diff.getY() / bounds.getHeight(); tx = (bounds.getX() + bounds.getWidth()) * (1 - sx); ty = (bounds.getY()) * (1 - sy); break; } } // creating the transform AffineTransform af = new AffineTransform(); af.preConcatenate(AffineTransform.getScaleInstance(sx, sy)); af.preConcatenate(AffineTransform.getTranslateInstance(tx, ty)); return af; }