protected void updateHoverHandles(@Nullable DrawingView view, @Nullable Figure f) {
   if (f != hoverFigure) {
     Rectangle r = null;
     if (hoverFigure != null && hoverFigure.isSelectable()) {
       for (Handle h : hoverHandles) {
         if (r == null) {
           r = h.getDrawingArea();
         } else {
           r.add(h.getDrawingArea());
         }
         h.setView(null);
         h.dispose();
       }
       hoverHandles.clear();
     }
     hoverFigure = f;
     if (hoverFigure != null) {
       hoverHandles.addAll(hoverFigure.createHandles(-1));
       for (Handle h : hoverHandles) {
         h.setView(view);
         if (r == null) {
           r = h.getDrawingArea();
         } else {
           r.add(h.getDrawingArea());
         }
       }
     }
     if (r != null) {
       r.grow(1, 1);
       fireAreaInvalidated(r);
     }
   }
 }
  @Override
  public void mouseReleased(MouseEvent evt) {
    dragLocation = new Point(evt.getX(), evt.getY());
    multicaster.trackEnd(anchor, dragLocation, evt.getModifiersEx(), getView());

    // Note: we must not fire "Tool Done" in this method, because then we can not
    // listen to keyboard events for the handle.

    Rectangle r = new Rectangle(anchor.x, anchor.y, 0, 0);
    r.add(evt.getX(), evt.getY());
    maybeFireBoundsInvalidated(r);
    dragLocation = null;
  }
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and ellipse.
  *
  * @return Returns true, if the circle is inside of the image bounds.
  */
 private boolean writeCircleAttributes(IXMLElement elem, SVGFigure f, Ellipse2D.Double ellipse) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType() &&
             ellipse.width == ellipse.height
             ) {
         
         Point2D.Double start = new Point2D.Double(ellipse.x, ellipse.y);
         Point2D.Double end = new Point2D.Double(ellipse.x + ellipse.width, ellipse.y + ellipse.height);
         t.transform(start, start);
         t.transform(end, end);
         ellipse.x = Math.min(start.x, end.x);
         ellipse.y = Math.min(start.y, end.y);
         ellipse.width = Math.abs(start.x - end.x);
         ellipse.height = Math.abs(start.y - end.y);
         
         elem.setAttribute("shape", "circle");
         elem.setAttribute("coords",
                 (int) (ellipse.x + ellipse.width / 2d)+","+
                 (int) (ellipse.y + ellipse.height / 2d)+","+
                 (int) (ellipse.width / 2d)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(ellipse.getBounds());
     } else {
         return writePolyAttributes(elem, f, (Shape) ellipse);
     }
 }
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and rectangle.
  *
  * @return Returns true, if the rect is inside of the image bounds.
  */
 private boolean writeRectAttributes(IXMLElement elem, SVGFigure f, Rectangle2D.Double rect) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType()
             ) {
         
         Point2D.Double start = new Point2D.Double(rect.x, rect.y);
         Point2D.Double end = new Point2D.Double(rect.x + rect.width, rect.y + rect.height);
         t.transform(start, start);
         t.transform(end, end);
         Rectangle r = new Rectangle(
                 (int) Math.min(start.x, end.x),
                 (int) Math.min(start.y, end.y),
                 (int) Math.abs(start.x - end.x),
                 (int) Math.abs(start.y - end.y)
                 );
         
         elem.setAttribute("shape", "rect");
         elem.setAttribute("coords",
                 r.x + ","+
                 r.y + ","+
                 (r.x + r.width) + ","+
                 (r.y + r.height)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(r);
     } else {
         return writePolyAttributes(elem, f, (Shape) rect);
     }
 }