Logo Search packages:      
Sourcecode: latexdraw version File versions  Download package

LaTeXDrawRectangle.java

package latexDraw.figures;


import static java.lang.Math.*;

import java.awt.*;
import java.awt.geom.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;

import latexDraw.figures.properties.BordersMovable;
import latexDraw.psTricks.DviPsColors;
import latexDraw.psTricks.PSTricksConstants;
import latexDraw.ui.LaTeXDrawFrame;
import latexDraw.ui.components.Delimitor;
import latexDraw.ui.components.MagneticGrid;
import latexDraw.util.LaTeXDrawNumber;
import latexDraw.util.LaTeXDrawPoint2D;


/**
 * This class defines a Rectangle.<br>
 * <br>
 * This file is part of LaTeXDraw.<br>
 * Copyright (c) 2005-2008 Arnaud BLOUIN<br>
 * <br>
 * LaTeXDraw is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or any later version.<br>
 * <br>
 * LaTeXDraw is distributed without any warranty; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.<br>
 * <br>
 * 
 * 01/16/06<br>
 * @author Arnaud BLOUIN<br>
 * @version 2.0.0<br>
 */
00042 public class LaTeXDrawRectangle extends LaTeXDrawPolygon implements BordersMovable
{
      private static final long serialVersionUID = 1L;

      /** The North-West delimiter (therefore it's possible that the delimiter not be a this position it's just a indication). */
00047       protected Delimitor dNW;

      /** The South-East delimiter (therefore it's possible that the delimiter not be a this position it's just a indication). */
00050       protected Delimitor dSE;

      /** The South-West delimiter (therefore it's possible that the delimiter not be a this position it's just a indication). */
00053       protected Delimitor dSW;

      /** The North East delimiter (therefore it's possible that the delimiter not be a this position it's just a indication). */
00056       protected Delimitor dNE;

      /** The West delimiter (therefore it's possible that the delimiter not be a this position it's just a indication) */
00059       protected Delimitor dW;

      /** The South delimiter (therefore it's possible that the delimiter not be a this position it's just a indication) */
00062       protected Delimitor dS;

      /** The East delimiter (therefore it's possible that the delimiter not be a this position it's just a indication) */
00065       protected Delimitor dE;

      /** The North delimiter (therefore it's possible that the delimiter not be a this position it's just a indication) */
00068       protected Delimitor dN;

      /** Allows to know if the rectangle has round corner or not */
00071       protected boolean isRound;

      /** The level of roundness of the rectangle */
00074       protected double frameArc;

      /** The value by default of the roundness of the rectangle */
00077       public static final double DEFAULT_FRAME_ARC = 0.5;

      /** The number of points which contains a rectangle */
00080       public static final short NB_POINTS_FRAME = 4;

      public static final boolean DEFAULT_ISROUND = false;




      /**
       * The basic constructor.
       * @param increaseMeter True if the meter of figures must be increased.
       */
00091       public LaTeXDrawRectangle(boolean increaseMeter)
      {
            this(new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(),
                        new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), increaseMeter);
      }


      
      
      /**
       * Creates a figure from one another.
       * @param f The figure to copy.
       * @param sameNumber True is the new figure must have the same number as the other.
       * @throws IllegalArgumentException If f is null or if f has no border.
       */
00106       public LaTeXDrawRectangle(Figure f, boolean sameNumber)
      {
            super(f, sameNumber);
            
            borders = null;
            isBordersMovable = true;
            LaTeXDrawRectangle bord = f.getBorders();
            
            if(bord==null)
                  throw new IllegalArgumentException();
            
            pts = new Vector<LaTeXDrawPoint2D>();
            
            pts.add((LaTeXDrawPoint2D)bord.getPoint(0).clone());
            pts.add((LaTeXDrawPoint2D)bord.getPoint(1).clone());
            pts.add((LaTeXDrawPoint2D)bord.getPoint(2).clone());
            pts.add((LaTeXDrawPoint2D)bord.getPoint(3).clone());
            
            initializeDelimitors();
            updateShape();
            setThickness(thickness);
            
            if(f instanceof LaTeXDrawRectangle)
            {
                  frameArc = ((LaTeXDrawRectangle)f).frameArc;
                  isRound  = ((LaTeXDrawRectangle)f).isRound;
            }
      }
      


      /**
       * Allows to create a rectangle with the north-west point and the south-east point
       * @param NW The north-west point
       * @param SE The south-east point
       */
00142       public LaTeXDrawRectangle(LaTeXDrawPoint2D NW, LaTeXDrawPoint2D SE, boolean increaseMeter)
      {
            this(NW, new LaTeXDrawPoint2D(SE.x, NW.y), new LaTeXDrawPoint2D(NW.x, SE.y), SE, increaseMeter);
      }





      /**
       * The constructor taking four points.
       * @param first The first point of the rectangle (the highest and the westiest point)
       * @param second The second point of the rectangle (the lowest and the eastiest point)
       * @param third The third point of the rectangle (the lowest and the eastiest point)
       * @param fourth The fourth point of the rectangle (the lowest and the eastiest point)
       */
00158       public LaTeXDrawRectangle(LaTeXDrawPoint2D first, LaTeXDrawPoint2D second,
                  LaTeXDrawPoint2D third, LaTeXDrawPoint2D fourth , boolean increaseMeter)
      {
            super(increaseMeter);
            isBordersMovable = true;
            borders = null;
            pts.add(first);
            pts.add(second);
            pts.add(third);
            pts.add(fourth);

            frameArc = DEFAULT_FRAME_ARC;
            isRound = DEFAULT_ISROUND;

            initializeDelimitors();
            updateShape();
      }

      
      
      
      /**
       * Initialises the delimiters of the rectangle.
       */
00182       protected void initializeDelimitors()
      {
            if(getNbPoints()<4)
                  throw new IllegalArgumentException("Invalid number of points");//$NON-NLS-1$
            
            dNW = new Delimitor(getPoint(0));
            dNE = new Delimitor(getPoint(1));
            dSW = new Delimitor(getPoint(2));
            dSE = new Delimitor(getPoint(3));

            dN = new Delimitor(new LaTeXDrawPoint2D((dNW.getCenter().x + dNE.getCenter().x) / 2, dNW.getCenter().y));
            dS = new Delimitor(new LaTeXDrawPoint2D((dSW.getCenter().x + dSE.getCenter().x) / 2, dSW.getCenter().y));
            dE = new Delimitor(new LaTeXDrawPoint2D(dSE.getCenter().x, (dSE.getCenter().y + dNE.getCenter().y) / 2));
            dW = new Delimitor(new LaTeXDrawPoint2D(dNW.getCenter().x, (dSW.getCenter().y + dNW.getCenter().y) / 2));

            dN.setColorSet2();
            dS.setColorSet2();
            dE.setColorSet2();
            dW.setColorSet2();
      }




      /**
       * Sets id the rectangle must be round or not.
       * @param round Its new value : if true, the rectangle will be round.
       */
00210       public synchronized void setIsRound(boolean round)
      {
            if(round!=isRound)
            {
                  isRound = round;
                  shape = getInsideOutsideOrMiddleBorders();
            }
      }





      @Override
00224       public synchronized void setOnRotation(boolean on)
      {
            isOnRotation = on;
            updateStyleOfDelimitors();
      }




      /**
       * @return True if the rectangle is round.
       */
00236       public synchronized boolean isRound()
      {
            return isRound;
      }




      /**
       * @return The value of the attribute.
       */
00247       public synchronized double getFrameArc()
      {
            return frameArc;
      }




      /**
       * @return The width of the non-rotated rectangle.
       */
00258       public synchronized double getWidth()
      {
            return Math.abs(getTheNWPoint().x - getTheSEPoint().x);
      }




      /**
       * @return The height of the non-rotated rectangle.
       */
00269       public synchronized double getHeight()
      {
            return Math.abs(getTheNWPoint().y - getTheSEPoint().y);
      }




      @Override
00278       public synchronized LaTeXDrawRectangle getBorders()
      {
            return this;
      }




      @Override
00287       public LaTeXDrawPoint2D getBordersPoint(int id)
      {
            if(id == -1)
                  return getPoint(getNbPoints()-1);
            
            if(id < 0 || id > LaTeXDrawRectangle.NB_POINTS_FRAME - 1)
                  throw new IllegalArgumentException();

            return getPoint(id);
      }





      @Override
00303       public void shift(double shiftX, double shiftY)
      {
            if(shiftX==0 && shiftY==0) return ;
            
            if(pts == null)
                  pts = new Vector<LaTeXDrawPoint2D>();

            int i, size = pts.size();
            for(i = 0; i < size; i++)
            {
                  LaTeXDrawPoint2D p = pts.elementAt(i);
                  p.x += shiftX;
                  p.y += shiftY;
            }

            updateNSEWDelimitors();
            updateGravityCenter();
            shape = getInsideOutsideOrMiddleBorders();
      }





      /**
       * Sets the attribute frameArc.
       * @param value Its new value.
       */
00331       public synchronized void setFrameArc(double value)
      {
            if(value != frameArc && value>0)
            {
                  frameArc = min(value,1); // The frame arc must at max at 1
                  shape = getInsideOutsideOrMiddleBorders();
            }
      }





      @Override
00345       public void rescaleX(double formerX, double newX, double percent,
                  LaTeXDrawRectangle bound)
      {
            if(percent==1.) return ;
            
            int i, size = getNbPoints();

            if(size > 0)
            {
                  LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(), farest, p;

                  if(formerX == SE.x)
                        farest = NW;
                  else
                        if(formerX == NW.x)
                              farest = SE;
                        else
                              throw new IllegalArgumentException();

                  for(i = 0; i < size; i++)
                  {// We rescale each point
                        p = getPoint(i);
                        p.x = farest.x + (p.x - farest.x) * percent;
                  }
                  updateNSEWDelimitors();
            }
            
            shape = getInsideOutsideOrMiddleBorders();
      }





      @Override
00380       public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound)
      {
            if(percent==1.) return ;
            
            int i, size = getNbPoints();

            if(size > 0)
            {
                  LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(), farest, p;

                  if(formerY == SE.y)
                        farest = NW;
                  else
                        if(formerY == NW.y)
                              farest = SE;
                        else
                              throw new IllegalArgumentException();

                  for(i = 0; i < size; i++)
                  {// We rescale each point
                        p = getPoint(i);
                        p.y = farest.y + (p.y - farest.y) * percent;
                  }
                  updateNSEWDelimitors();
            }

            shape = getInsideOutsideOrMiddleBorders();
      }





      
      @Override
00415       public synchronized void setFirstPoint(double x, double y)
      {
            LaTeXDrawPoint2D first = getPoint(0), second = getPoint(1);
            LaTeXDrawPoint2D third = getPoint(2);

            first.setLocation(x, y);
            second.y = y;
            third.x = x;

            updateNSEWDelimitors();
            updateGravityCenter();
            shape = getInsideOutsideOrMiddleBorders();
      }


      
      
      @Override
00433       public synchronized void setBordersPosition(String doubleLinePosition)
      {
            super.setBordersPosition(doubleLinePosition);
            shape = getInsideOutsideOrMiddleBorders();
      }

      
      


      @Override
00444       public synchronized void setThickness(float val)
      {
            if(!Double.isInfinite(val) && !Double.isNaN(val) && val>0)
            {
                  thickness = val;
                  double dim = 1.33 * val + 3.33 + 1.;
                  
                  if(dim < 6.)
                        dim = 6;
      
                  if(dNW!=null)
                  {
                        dNW.setDim(dim);
                        dSE.setDim(dim);
                        dSW.setDim(dim);
                        dNE.setDim(dim);
                        dN.setDim(dim);
                        dS.setDim(dim);
                        dE.setDim(dim);
                        dW.setDim(dim);
                  }
                  
                  shape = getInsideOutsideOrMiddleBorders();
            }
      }





      @Override
00475       public synchronized void setRotationAngle(double theta)
      {
            theta%=(Math.PI*2);
            rotationAngle = theta;
      }





      @Override
00486       public synchronized void setSelected(boolean state)
      {
            isSelected = state;
      }





      /**
       * Updates the position of some delimiters.
       */
00498       public synchronized void updateNSEWDelimitors()
      {
            dN.setCoordinates((dNW.getCenter().x + dNE.getCenter().x)/2, dNW.getCenter().y);
            dS.setCoordinates((dSW.getCenter().x + dSE.getCenter().x)/2, dSW.getCenter().y);
            dE.setCoordinates(dSE.getCenter().x, (dSE.getCenter().y + dNE.getCenter().y) / 2);
            dW.setCoordinates(dNW.getCenter().x, (dSW.getCenter().y + dNW.getCenter().y) / 2);
      }





      @Override
00511       public synchronized void updateGravityCenter()
      {
            if(pts.size() == NB_POINTS_FRAME)
            {
                  LaTeXDrawPoint2D NW = getTheNWPoint();
                  LaTeXDrawPoint2D SE = getTheSEPoint();
                  
                  if(gravityCenter==null)
                        gravityCenter = new LaTeXDrawPoint2D((NW.x + SE.x) / 2., (NW.y + SE.y) / 2.);
                  else
                        gravityCenter.setLocation((NW.x + SE.x) / 2., (NW.y + SE.y) / 2.);
            }
      }





      /**
       * Changes the last point of the rectangle.
       * @param pt The new last point (in fact the south-east point).
       */
      @Override
00534       public synchronized void setLastPoint(LaTeXDrawPoint2D pt)
      {
            if(!pt.equals(getPoint(-1)))
            {
                  LaTeXDrawPoint2D third = getPoint(2), fourth = getPoint(3);
                  LaTeXDrawPoint2D second = getPoint(1);
      
                  fourth.setLocation(pt.x, pt.y);
                  third.y = pt.y;
                  second.x = pt.x;
      
                  updateNSEWDelimitors();
                  updateGravityCenter();
                  shape = getInsideOutsideOrMiddleBorders();
            }
      }





      @Override
00556       public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      {
            draw(g, true, antiAlias, rendering, alphaInter, colorRendering);
      }





      /**
       * This method draws the rectangle.
       * @param drawRectangle  if true, the rectangle is drawn ; else, only the delimiters may be drawn (Useful for Rhombus, ...).
       */
00569       public void draw(Graphics2D g, boolean drawRectangle, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      {
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            double cx = (NW.x + SE.x) / 2., cy = (NW.y + SE.y) / 2.;
            double c2x = Math.cos(rotationAngle) * cx - Math.sin(rotationAngle)* cy;
            double c2y = Math.sin(rotationAngle) * cx + Math.cos(rotationAngle)* cy;
            double c3x = Math.cos(-rotationAngle) * (cx - c2x)- Math.sin(-rotationAngle) * (cy - c2y);
            double c3y = Math.sin(-rotationAngle) * (cx - c2x)+ Math.cos(-rotationAngle) * (cy - c2y);
            double dx=0, dy=0;
            boolean changeFillStyle = false;
            
            if(rotationAngle % (Math.PI*2) != 0)
            {
                  g.rotate(rotationAngle);
                  g.translate(c3x, c3y);
            }

            if(hasShadow)
            {
                  LaTeXDrawPoint2D cg = getGravityCenter();
                  LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
                  shadowCg.setLocation(cg.x+shadowSize, cg.y);
                  shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
                  dx = shadowCg.x-cg.x;
                  dy = cg.y-shadowCg.y;
            }
            
            if(drawRectangle)
            {
                  Color formerCol = g.getColor();

                  if(hasDoubleBoundary)
                  {
                        Shape s0 = shape;
                        Shape s[] = getDbleBoundariesOutInOrMiddle(s0);
                        Shape s1, s2, s3;

                        if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
                        {
                              s1 = s0;
                              s2 = s[0];
                              s3 = s[1];
                        }
                        else
                              if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
                              {
                                    s1 = s[0];
                                    s2 = s0;
                                    s3 = s[1];
                              }
                              else
                              {
                                    s1 = s[0];
                                    s2 = s[1];
                                    s3 = s0;
                              }

                        Shape sTooSmall = getTooSmallShape(s1);
                        
                        if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
                        {
                              Area area = new Area(s1);
                              area.subtract(new Area(s3));
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                              
                              if(hasShadow)
                              {
                                    g.translate(dx, dy);
                                    g.setColor(shadowColor);
                                    g.fill(s1);
                                    
                                    if(sTooSmall==null)
                                          g.draw(s1);
                                    else
                                          g.draw(sTooSmall);
                              
                                    g.translate(-dx, -dy);
                                    
                                    if(!isFilled)
                                    {
                                          changeFillStyle = true;
                                          isFilled = true;
                                    }
                              }
                              
                              g.setColor(doubleColor);
                              g.fill(area);
                              fillFigure(g,antiAlias,rendering,alphaInter,colorRendering,s3);
                              g.setColor(linesColor);
                              
                              if(sTooSmall==null)
                                    g.draw(s1);
                              else
                                    g.draw(sTooSmall);
                              g.draw(s3);
                        }
                        else
                        {
                              if(hasShadow)
                              {
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    g.translate(dx, dy);
                                    g.setColor(shadowColor);
                                    g.fill(s1);
                                    
                                    if(sTooSmall==null)
                                          g.draw(s1);
                                    else
                                          g.draw(sTooSmall);
                                    
                                    g.translate(-dx, -dy);
                                    g.setColor(interiorColor);
                                    g.setStroke(new BasicStroke((float)(thickness*2+doubleSep), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    g.draw(s2);
                                    
                                    if(!isFilled)
                                    {
                                          changeFillStyle = true;
                                          isFilled = true;
                                    }
                              }
                              
                              if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                                    g.setStroke(new BasicStroke((float)(thickness*2+doubleSep), BasicStroke.CAP_ROUND,
                                                BasicStroke.JOIN_MITER, 1.f, new float[]
                                                { 0, (float)(thickness*2+doubleSep + dotSep) }, 0));
                              else
                                    g.setStroke(new BasicStroke((float)(thickness*2+doubleSep),
                                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
                                                new float[] { blackDashLength, whiteDashLength }, 0));
                              
                              fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, s2);
                              g.setColor(linesColor);
                              
                              Shape sTooSmall2 = getTooSmallShape(s2);
                              if(sTooSmall2==null)
                                    g.draw(s2);
                              else
                                    g.draw(sTooSmall2);
                              
                              g.setStroke(new BasicStroke((float)doubleSep, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                              g.setColor(doubleColor);
                              
                              if(sTooSmall2==null)
                                    g.draw(s2);
                              else
                                    g.draw(sTooSmall2);
                        }                       
                  }
                  else
                  {
                        Shape sTooSmall = getTooSmallShape(shape);
                        
                        if(hasShadow)
                        {
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                              g.translate(dx, dy);
                              g.setColor(shadowColor);
                              g.fill(shape);
                              
                              if(sTooSmall==null)
                                    g.draw(shape);
                              else
                                    g.draw(sTooSmall);
                              
                              g.translate(-dx, -dy);
                              if(!isFilled)
                              {
                                    changeFillStyle = true;
                                    isFilled = true;
                              }
                              g.setColor(interiorColor);
                              g.draw(shape);
                        }
                        
                        if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        else
                              if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND,
                                                BasicStroke.JOIN_MITER, 1.f, new float[] { 0, thickness + dotSep }, 0));
                              else
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
                                                      new float[] { blackDashLength, whiteDashLength }, 0));

                        fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, shape);
                        g.setColor(linesColor);
                        
                        if(sTooSmall==null)
                              g.draw(shape);
                        else
                              g.draw(sTooSmall);
                  }

                  if(changeFillStyle) isFilled = false;
                  g.setColor(formerCol);
            }

            if(isSelected())
            {
                  dN.draw(g);
                  dE.draw(g);
                  dW.draw(g);
                  dS.draw(g);
                  dNW.draw(g);
                  dSE.draw(g);
                  dNE.draw(g);
                  dSW.draw(g);
            }

            if((rotationAngle%(Math.PI*2))!=0)
            {
                  g.translate(-c3x, -c3y);
                  g.rotate(-rotationAngle);
            }
      }


      

      @Override
00790       public LaTeXDrawPoint2D getTheNWPoint()
      {
            LaTeXDrawPoint2D first = getPoint(0), second = getPoint(1), third = getPoint(2);
            LaTeXDrawPoint2D fourth = getPoint(3);

            if (first.x < second.x)
            {
                  if (first.y < third.y)
                        return first;
                  return third;
            }
            else
                  if (second.y < fourth.y)
                        return second;
                  else
                        return fourth;
      }




      @Override
00812       public LaTeXDrawPoint2D getTheSERotatedPoint()
      {
            if (!pts.isEmpty())
            {
                  LaTeXDrawPoint2D pt = rotatePoint(getPoint(0));
                  double SEx = pt.x, SEy = pt.y;
                  int i, size = pts.size();

                  for (i = 1; i < size; i++)
                  {
                        pt = rotatePoint(getPoint(i));
                        if (pt.x > SEx)
                              SEx = pt.x;
                        if (pt.y > SEy)
                              SEy = pt.y;
                  }

                  return new LaTeXDrawPoint2D(SEx, SEy);
            }
            return null;
      }




      @Override
00838       public LaTeXDrawPoint2D getTheNWRotatedPoint()
      {
            if(!pts.isEmpty())
            {
                  LaTeXDrawPoint2D pt = rotatePoint(getPoint(0));
                  double NWx = pt.x, NWy = pt.y;
                  int i, size = pts.size();

                  for(i=1; i<size; i++)
                  {
                        pt = rotatePoint(getPoint(i));
                        if(pt.x < NWx)
                              NWx = pt.x;
                        if(pt.y < NWy)
                              NWy = pt.y;
                  }

                  return new LaTeXDrawPoint2D(NWx, NWy);
            }
            return null;
      }




      @Override
00864       public LaTeXDrawPoint2D getTheSEPoint()
      {
            LaTeXDrawPoint2D first = getPoint(0);
            LaTeXDrawPoint2D second = getPoint(1);
            LaTeXDrawPoint2D third = getPoint(2);
            LaTeXDrawPoint2D fourth = getPoint(3);

            if(first.x > second.x)
            {
                  if (first.y > third.y)
                        return first;
                  return third;
            }

            if(second.y > fourth.y)
                  return second;
            return fourth;
      }




      @Override
00887       public boolean intersected(Rectangle2D.Double r)
      {
            if(r==null)
                  return false;
            
            Shape s                 = createShape2D();
            Rectangle2D bounds      = s.getBounds2D();

            if(bounds.getHeight()<=0)////fix #1591312
                  s = new Line2D.Double(bounds.getMinX(), bounds.getMaxY(), bounds.getMaxX(), bounds.getMaxY());
            else
                  if(bounds.getWidth()<=0)
                        s = new Line2D.Double(bounds.getMaxX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY());
            
            BasicStroke wideline = new BasicStroke(thickness);
        Shape outline = wideline.createStrokedShape(s);           
            
            return outline.intersects(r) && !outline.contains(r);
      }




      @Override
00911       public boolean isIn(LaTeXDrawPoint2D p)
      {
            if(p == null)
                  throw new IllegalArgumentException();
            
            LaTeXDrawPoint2D pt = rotateInvertPoint(p);

            if(isSelected() && (dNW.isIn(pt) || dSE.isIn(pt) || dSW.isIn(pt) || dNE.isIn(pt) || dS.isIn(pt) || 
                  dW.isIn(pt) || dN.isIn(pt) || dE.isIn(pt)))
                  return true;

            LaTeXDrawPoint2D NW = getTheNWNonRotatedBoundPoint();
            LaTeXDrawPoint2D SE = getTheSENonRotatedBoundPoint();
            Rectangle2D.Double s = new Rectangle2D.Double(NW.x, NW.y, 
                                    Math.abs(NW.x - SE.x), Math.abs(NW.y - SE.y));

            if(!s.contains(pt))
                  return false;

            if(isFilled || hasShadow || hasGradient())
                  return true;

            Shape s2;

            if(hasDoubleBoundary)
                  s2 = new Rectangle2D.Double(NW.x + thickness * 2 + doubleSep,
                                    NW.y + thickness * 2 + doubleSep, 
                                    Math.abs(NW.x - SE.x)- 4 * thickness - 2 * doubleSep, 
                                    Math.abs(NW.y- SE.y) - 4 * thickness - 2 * doubleSep);
            else
                  s2 = new Rectangle2D.Double(NW.x + thickness, NW.y + thickness,
                                    Math.abs(NW.x - SE.x) - 2 * thickness, 
                                    Math.abs(NW.y- SE.y)- 2 * thickness);

            return !s2.contains(pt);
      }





      @Override
00953       public synchronized String getCodePSTricks(DrawBorders drawBorders, float ppc)
      {
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            LaTeXDrawPoint2D d = drawBorders.getOriginPoint();
            double x1 = NW.x - d.x, x2 = SE.x - d.x;
            double y1 = d.y - NW.y, y2 = d.y - SE.y;
            String add = "", addBegin = "", addEnd = "", fillType = ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
            boolean isFilledWasChanged = false;
            double threshold = 0.001;
            
            if(hasShadow)
            {
                  fillType+=",shadow=true";//$NON-NLS-1$
                  if(Math.toDegrees(shadowAngle)!=PSTricksConstants.DEFAULT_SHADOW_ANGLE)
                        fillType+=",shadowangle="+(float)Math.toDegrees(shadowAngle);//$NON-NLS-1$
                  
                  if(((float)shadowSize)!=((float)DEFAULT_SHADOW_SIZE))
                        fillType+=",shadowsize="+(float)(shadowSize/PPC);//$NON-NLS-1$
                  
                  if(!shadowColor.equals(PSTricksConstants.DEFAULT_SHADOW_COLOR))
                  {
                        String name = DviPsColors.getColourName(shadowColor);
                        if(name==null)
                        {
                              name = "color"+number+'e';//$NON-NLS-1$
                              DviPsColors.addUserColour(shadowColor, name); 
                        }
                        fillType += ",shadowcolor=" + name; //$NON-NLS-1$
                  }
                  if(!isFilled)
                  {
                        isFilled = true;
                        isFilledWasChanged = true;
                  }
            }
            
            String str = getPSTricksCodeFilling(ppc);
            if(str.length()>0) fillType=fillType+','+str;
            
            str = getPSTricksCodeLine(ppc);
            if(str.length()>0) add=add+','+str;
            
            if(isRound)
                  add += ",framearc=" + (float)frameArc; //$NON-NLS-1$

            if(rotationAngle%(Math.PI*2)!=0.)
            {
                  double angle = -Math.toDegrees(rotationAngle);
                  double cx = (gravityCenter.x - d.x) / ppc;
                  double cy = (d.y - gravityCenter.y) / ppc;
                  double x = -Math.cos(-rotationAngle) * cx + Math.sin(-rotationAngle) * cy + cx;
                  double y = -Math.sin(-rotationAngle) * cx - Math.cos(-rotationAngle) * cy + cy;

                  x = LaTeXDrawNumber.getCutNumber(x, threshold);
                  y = LaTeXDrawNumber.getCutNumber(y, threshold);
                  
                  addBegin += "\\rput{" + (float)angle + "}(" + (float)x + ',' + (float)y + "){"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                  addEnd = "}"; //$NON-NLS-1$
            }

            add += ",dimen=" + bordersPosition; //$NON-NLS-1$
            
            if(hasDoubleBoundary)
            {
                  add += ",doubleline=true,doublesep=" + (float)(doubleSep / ppc); //$NON-NLS-1$

                  if(doubleColor != PSTricksConstants.DEFAULT_DOUBLE_COLOR)
                  {
                        String name = DviPsColors.getColourName(doubleColor);
                        if(name==null)
                        {
                              name = "color"+number+'d';//$NON-NLS-1$
                              DviPsColors.addUserColour(doubleColor, name); 
                        }
                        add += ",doublecolor=" + name; //$NON-NLS-1$
                  }
            }

            x2 = LaTeXDrawNumber.getCutNumber(x2, threshold);
            y2 = LaTeXDrawNumber.getCutNumber(y2, threshold);
            x1 = LaTeXDrawNumber.getCutNumber(x1, threshold);
            y1 = LaTeXDrawNumber.getCutNumber(y1, threshold);

            if(isFilledWasChanged) isFilled = false;
            
            return addBegin
                        + "\\psframe[linewidth=" + (thickness / ppc) + //$NON-NLS-1$
                        add + fillType+"](" + (float)(x2 / ppc) + ',' + //$NON-NLS-1$
                        (float)(y1 / ppc) + ")(" //$NON-NLS-1$
                        + (float)(x1 / ppc) + ',' + (float)(y2 / ppc) + ')' + addEnd;
      }





      
      /**
       * Recentres the figure after a drag with a rotated figure.
       * @param oldGravityCenter The former gravity centre
       */
01054       protected void recenterDraggedOnRotation(LaTeXDrawPoint2D oldGravityCenter)
      {
            if(oldGravityCenter==null)
                  throw new IllegalArgumentException();
            
            updateGravityCenter();
            LaTeXDrawPoint2D rotGc = rotatePoint(getGravityCenter(), oldGravityCenter, rotationAngle);
            shift(getGravityCenter(), rotGc);
      }
      
      
      
      
      @Override
01068       public void onDragged(Point formerPt, Point newPt)
      {
            if(formerPt.equals(newPt)) return;
            
            if(dSelected != null)
            {
                  if(isOnRotation())
                        rotate(formerPt, newPt);
                  else
                  {
                        LaTeXDrawPoint2D newPt2 = rotateInvertPoint(newPt);
                        LaTeXDrawPoint2D oldGc = (LaTeXDrawPoint2D)getGravityCenter().clone();
                  
                        if(dSelected == dE)
                              dNE.getCenter().x = dSE.getCenter().x = newPt2.x;
                        else
                        if(dSelected == dW)
                              dNW.getCenter().x = dSW.getCenter().x = newPt2.x;
                        else
                        if(dSelected == dN)
                              dNE.getCenter().y = dNW.getCenter().y = newPt2.y;
                        else
                        if(dSelected == dS)
                              dSE.getCenter().y = dSW.getCenter().y = newPt2.y;
                        else
                        if(dSelected == dNE)
                        {
                              dNW.getCenter().y = newPt2.y;
                              dSE.getCenter().x = newPt2.x;
                        }else
                        if(dSelected == dNW)
                        {
                              dNE.getCenter().y = newPt2.y;
                              dSW.getCenter().x = newPt2.x;
                        }else
                        if(dSelected == dSW)
                        {
                              dSE.getCenter().y = newPt2.y;
                              dNW.getCenter().x = newPt2.x;
                        }else
                        if(dSelected == dSE)
                        {
                              dSW.getCenter().y = newPt2.y;
                              dNE.getCenter().x = newPt2.x;
                        }
                        
                        dSelected.setCoordinates(newPt2);
                        
                        if(rotationAngle!=0)
                              recenterDraggedOnRotation(oldGc);
                  }
                  updateGravityCenter();
                  shape = getInsideOutsideOrMiddleBorders();
            }
            else
                  // If the user has clicked on the line
                  shift(formerPt, newPt);

            updateNSEWDelimitors();
      }





      @Override
01134       public synchronized void onClick(Point p)
      {
            updateNSEWDelimitors();

            LaTeXDrawPoint2D pt = rotateInvertPoint(p);

            if(dSE.isIn(pt))
                  dSelected = dSE;
            else
                  if(dNW.isIn(pt))
                        dSelected = dNW;
                  else
                        if(dNE.isIn(pt))
                              dSelected = dNE;
                        else
                              if(dSW.isIn(pt))
                                    dSelected = dSW;
                              else
                                    if(dN.isIn(pt))
                                          dSelected = dN;
                                    else
                                          if(dS.isIn(pt))
                                                dSelected = dS;
                                          else
                                                if(dE.isIn(pt))
                                                      dSelected = dE;
                                                else
                                                      if(dW.isIn(pt))
                                                            dSelected = dW;
            isSelected = true;
      }




      @Override
01170       public synchronized void onDelimitorRelease()
      {
            updateStyleOfDelimitors();
            dSelected = null;
      }




      @Override
01180       public synchronized void onRelease()
      {
            setOnRotation(false);
            isSelected = false;
            dSelected = null;
      }





      @Override
01192       public synchronized Shape createShape2D()
      {
            Shape area = createNonRotatedShape2D();

            if((rotationAngle % (2*PI)) != 0)
            {
                  LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
                  double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
                  double c2x = cos(rotationAngle)*cx - sin(rotationAngle)*cy;
                  double c2y = sin(rotationAngle)*cx + cos(rotationAngle)*cy;
                  Rectangle2D bounds = area.getBounds2D();
                  
                  if(bounds.getHeight()<=0)//AffineTransform has problem when the shape is very small.
                        if(bounds.getWidth()<=0)
                              area = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), 1, 1);
                        else
                              area = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), 1);
                  else
                        if(bounds.getWidth()<=0)
                              area = new Rectangle2D.Double(bounds.getMinX(), bounds.getMinY(), 1, bounds.getHeight());
                  
                  AffineTransform at = AffineTransform.getTranslateInstance(cx - c2x, cy - c2y);
                  at.rotate(rotationAngle);
                  area = at.createTransformedShape(area);
            }

            return area;
      }


      
      
      
      @Override
01226       public synchronized Shape createNonRotatedShape2D()
      {
            Shape area;
            Shape s = getInsideOutsideOrMiddleBorders();

            if(hasDoubleBoundary)
            {
                  Shape[] s2 = getDbleBoundariesOutInOrMiddle(s);
                  Shape min;
                  Shape max;

                  if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
                  {
                        max = s;
                        min = s2[1];
                  }
                  else
                        if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
                        {
                              max = s2[0];
                              min = s2[1];
                        }
                        else
                        {
                              max = s2[0];
                              min = s;
                        }
            
                  area = new Area(max);
                  ((Area)area).exclusiveOr(new Area(min));
                  
                  Shape tooSmallShape = getTooSmallShape(area);
            
                  if(tooSmallShape!=null)
                  {
                        Rectangle2D bounds = max.getBounds2D();
                        area = new Line2D.Double(Math.max(1, bounds.getMinX()), Math.max(1, bounds.getMinY()),
                                    Math.max(1, bounds.getMaxX()), Math.max(1, bounds.getMaxY()));
                  }
            }
            else
                  area = s;

            return area;
      }
      



      
      
      @Override
      public Object clone() throws CloneNotSupportedException
      {
            LaTeXDrawRectangle r = (LaTeXDrawRectangle)super.clone();

            r.dNW = new Delimitor(r.getPoint(0));
            r.dNE = new Delimitor(r.getPoint(1));
            r.dSW = new Delimitor(r.getPoint(2));
            r.dSE = new Delimitor(r.getPoint(3));

            r.dE = (Delimitor)dE.clone();
            r.dS = (Delimitor)dS.clone();
            r.dW = (Delimitor)dW.clone();
            r.dN = (Delimitor)dN.clone();

            r.setThickness(thickness);
            r.updateNSEWDelimitors();
            r.updateStyleOfDelimitors();
            r.isRound   = isRound;
            r.frameArc  = frameArc;
            r.shape     = getInsideOutsideOrMiddleBorders();
            
            return r;
      }





      @Override
01307       public synchronized void updateStyleOfDelimitors()
      {
            if(isOnRotation)
            {
                  dN.setColorSet4();
                  dS.setColorSet4();
                  dE.setColorSet4();
                  dW.setColorSet4();
                  dSW.setColorSet4();
                  dSE.setColorSet4();
                  dNW.setColorSet4();
                  dNE.setColorSet4();
            }
            else
            {
                  dN.setColorSet2();
                  dS.setColorSet2();
                  dE.setColorSet2();
                  dW.setColorSet2();
                  dSW.setColorSet1();
                  dSE.setColorSet1();
                  dNW.setColorSet1();
                  dNE.setColorSet1();
            }
      }



      @SuppressWarnings("unchecked")
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            canHaveShadow = true;
            interiorColor = (Color)ois.readObject();
            lineStyle = (String)ois.readObject();
            rotationAngle = ois.readDouble();
            float thick = ois.readFloat();
            thickness = DEFAULT_THICKNESS;
            isFilled = ois.readBoolean();
            isSelected = ois.readBoolean();
            isOnRotation = ois.readBoolean();
            linesColor = (Color)ois.readObject();
            blackDashLength = ois.readFloat();
            dotSep = ois.readFloat();
            whiteDashLength = ois.readFloat();
            pts = (Vector)ois.readObject();
            isRound = ois.readBoolean();
            frameArc = ois.readDouble();

            if(pts.size() != NB_POINTS_FRAME)
                  throw new ArrayIndexOutOfBoundsException();

            dNW = new Delimitor(pts.firstElement());
            dNE = new Delimitor(pts.elementAt(1));
            dSW = new Delimitor(pts.elementAt(2));
            dSE = new Delimitor(pts.elementAt(3));
      
            dN = new Delimitor(new LaTeXDrawPoint2D((dNW.getCenter().x+dNE.getCenter().x)/2, dNW.getCenter().y));
            dS = new Delimitor(new LaTeXDrawPoint2D((dSW.getCenter().x+dSE.getCenter().x)/2, dSW.getCenter().y));
            dE = new Delimitor(new LaTeXDrawPoint2D(dSE.getCenter().x,(dSE.getCenter().y+dNE.getCenter().y)/2));
            dW = new Delimitor(new LaTeXDrawPoint2D(dNW.getCenter().x,(dSW.getCenter().y+dNW.getCenter().y)/2));

            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5") >= 0)//$NON-NLS-1$
            {
                  hasDoubleBoundary = ois.readBoolean();
                  doubleColor = (Color)ois.readObject();
                  doubleSep = ois.readDouble();
                  bordersPosition = (String)ois.readObject();
                  if(!(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6")>=0)) //$NON-NLS-1$
                        ois.readBoolean();
                  hatchingAngle = ois.readDouble();
                  hatchingColor = (Color)ois.readObject();
                  hatchingStyle = (String)ois.readObject();
                  hatchingWidth = ois.readFloat();
                  
                  if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6") < 0)//$NON-NLS-1$
                  {
                        if(hatchingStyle.equals(DECREPETED_FILL_CROSS))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_CROSSHATCH;
                        else if(hatchingStyle.equals(DECREPETED_FILL_HORIZ))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_HLINES;
                        else if(hatchingStyle.equals(DECREPETED_FILL_VERT))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_VLINES;
                        else if(hatchingStyle.equals(DECREPETED_FILL_NO))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_NONE;
                  }
            }
            else
            {
                  hasDoubleBoundary = DEFAULT_HAS_DOUBLE_BOUNDARY;
                  doubleColor = DEFAULT_DOUBLE_COLOR;
                  doubleSep = DEFAULT_DOUBLESEP;
                  bordersPosition = DEFAULT_BORDERS_POSITION;
                  hatchingAngle = DEFAULT_HATCH_ANGLE;
                  hatchingColor = DEFAULT_HATCH_COL;
                  hatchingStyle = DEFAULT_HATCH_STYLE;
                  hatchingWidth = DEFAULT_HATCH_WIDTH;
            }
      
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0) //$NON-NLS-1$
            {
                  hasShadow   = ois.readBoolean();
                  shadowAngle = ois.readDouble();
                  shadowSize  = ois.readDouble();
                  shadowColor = (Color)ois.readObject();
                  gradientEndColor = (Color)ois.readObject();
                  gradientStartColor = (Color)ois.readObject();
                  gradientAngle = ois.readDouble();
                  gradientMidPoint = ois.readDouble();
            }
            else
            {
                  hasShadow   = DEFAULT_SHADOW_HAS;
                  shadowAngle = DEFAULT_SHADOW_ANGLE;
                  shadowSize  = DEFAULT_SHADOW_SIZE;
                  shadowColor = DEFAULT_SHADOW_COLOR;
                  gradientEndColor = PSTricksConstants.DEFAULT_GRADIENT_END_COLOR;
                  gradientStartColor = PSTricksConstants.DEFAULT_GRADIENT_START_COLOR;
                  gradientAngle = DEFAULT_GRADIENT_ANGLE;
                  gradientMidPoint = DEFAULT_GRADIENT_MID_POINT;
            }
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.8")>=0) //$NON-NLS-1$
                  hatchingSep = ois.readDouble();
            else
                  hatchingSep = DEFAULT_HATCH_SEP;
            
            setThickness(thick);
            updateStyleOfDelimitors();
            shape = getInsideOutsideOrMiddleBorders();
      }





      /**
       * Creates the borders of the rectangle in the position "inside".
       * @return The borders.
       */
01446       public Shape getInsideBorders()
      {
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            double width = abs(NW.x - SE.x), height = abs(NW.y - SE.y);
            double min = min(width, height);
            Shape s;
            
            if(isRound)//Fixes #1554750
                  s = new RoundRectangle2D.Double(NW.x+thickness/2., NW.y+thickness/2., 
                              max(width-thickness,1), max(height-thickness,1), 
                              (min-thickness)*frameArc, (min-thickness)*frameArc);
            else
                  s = new Rectangle2D.Double(NW.x+thickness/2., NW.y+thickness/2., 
                              max(width-thickness,1), max(height-thickness,1));

            return s;
      }





      /**
       * Creates the borders of the rectangle in the position "outside".
       * @return The borders.
       */
01472       public Shape getOutsideBorders()
      {
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            double width = abs(NW.x - SE.x), height = abs(NW.y - SE.y);
            double min = min(width, height);
            Shape s;

            if(isRound)//Fixes #1554750
                  s = new RoundRectangle2D.Double(NW.x-thickness/2., NW.y-thickness/2., 
                              max(width+thickness, 1), max(height+thickness, 1), 
                              (min+thickness)*frameArc, (min+thickness)*frameArc);
            else
                  s = new Rectangle2D.Double(NW.x-thickness/2., NW.y-thickness/2., 
                              max(width+thickness, 1), max(height+thickness, 1));

            return s;
      }





      /**
       * Creates the borders of the rectangle in the position "middle".
       * @return The borders.
       */
01498       public Shape getMiddleBorders()
      {
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            double width = abs(NW.x - SE.x), height = abs(NW.y - SE.y);
            double min = min(width, height);
            Shape s;

            if(isRound)
                  s = new RoundRectangle2D.Double(NW.x, NW.y, max(width,1), max(height,1), min*frameArc, min*frameArc);
            else
                  s = new Rectangle2D.Double(NW.x, NW.y, max(width, 1), max(height, 1));
            
            return s;
      }





      @Override
      public Shape getInsideOutsideOrMiddleBorders()
      {
            Shape s;

            if (bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
                  s = getInsideBorders();
            else
                  if (bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
                        s = getOutsideBorders();
                  else
                        s = getMiddleBorders();

            return s;
      }





      @Override
01538       public Shape[] getDbleBoundariesOutside(Shape classicBord)
      {
            if(classicBord == null)
                  return null;

            RectangularShape r = (RectangularShape)classicBord;
            Shape[] s = new Shape[2];
            double min = min(r.getWidth(), r.getHeight());
            double add = doubleSep+thickness;
            
            if(isRound)
            {//Fixes #1554750
                  s[0] = new RoundRectangle2D.Double(r.getX()-add, r.getY()-add, r.getWidth()+2*add, 
                                                                  r.getHeight()+2*add, (min+2*add)*frameArc, (min+2*add)*frameArc);
                  s[1] = new RoundRectangle2D.Double(r.getX()-add/2., 
                                                r.getY()-add/2., r.getWidth()+add, r.getHeight()+add, (min+add)*frameArc, (min+add)*frameArc);
            }
            else
            {
                  s[0] = new Rectangle2D.Double(r.getX()-add, r.getY()-add, r.getWidth()+2*add, r.getHeight()+2*add);
                  s[1] = new Rectangle2D.Double(r.getX()-add/2., r.getY()-add/2., r.getWidth()+add, r.getHeight()+add);
            }

            return s;
      }





      @Override
01569       public Shape[] getDbleBoundariesMiddle(Shape classicBord)
      {
            if(classicBord == null)
                  return null;

            RectangularShape r = (RectangularShape)classicBord;
            Shape[] s = new Shape[2];
            double min = min(r.getWidth(), r.getHeight());
            double add = doubleSep+thickness;

            if(isRound)
            {//Fixes #1554750
                  s[0] = new RoundRectangle2D.Double(r.getX()-add/2., r.getY()-add/2., 
                              r.getWidth()+add, r.getHeight()+add,
                              (min+add)*frameArc, (min+add)*frameArc);
                  s[1] = new RoundRectangle2D.Double(r.getX()+add/2., r.getY()+add/2., 
                              r.getWidth()-add, r.getHeight()-add,
                              (min-add)*frameArc, (min-add)*frameArc);
            }
            else
            {
                  s[0] = new Rectangle2D.Double(r.getX()-add/2., r.getY()-add/2., 
                              r.getWidth()+add, r.getHeight()+add);
                  s[1] = new Rectangle2D.Double(r.getX()+add/2., r.getY()+add/2., 
                              r.getWidth()-add, r.getHeight()-add);
            }
            
            return s;
      }





      @Override
01604       public Shape[] getDbleBoundariesInside(Shape classicBord)
      {
            if(classicBord == null)
                  return null;

            RectangularShape r = (RectangularShape)classicBord;
            Shape[] s = new Shape[2];
            double min = min(r.getWidth(), r.getHeight());
            double add = doubleSep+thickness;

            if(isRound)
            {//Fixes #1554750
                  s[0] = new RoundRectangle2D.Double( r.getX()+add/2., r.getY() + add/2., 
                                                r.getWidth()-add, r.getHeight()-add, (min-add)*frameArc, (min-add)*frameArc);
                  s[1] = new RoundRectangle2D.Double(r.getX()+add, 
                                          r.getY()+add, r.getWidth()-2*add, r.getHeight()-2*add, (min-add*2)*frameArc, (min-add*2)*frameArc);
            }
            else
            {
                  s[0] = new Rectangle2D.Double(r.getX() + add/2., r.getY()+add/2., r.getWidth()-add, r.getHeight()-add);
                  s[1] = new Rectangle2D.Double(r.getX()+add, r.getY()+add, r.getWidth()-2*add, r.getHeight()-2*add);
            }

            return s;
      }
      
      
      
      
      @Override
01634       public Shape[] getDbleBoundariesOutInOrMiddle(Shape classicBord)
      {
            Shape[] s;

            if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
                  s = getDbleBoundariesInside(classicBord);
            else
                  if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
                        s = getDbleBoundariesOutside(classicBord);
                  else
                        s = getDbleBoundariesMiddle(classicBord);

            return s;
      }

      
      
      
      @Override
01653       public boolean isTooSmallToBeRescaled()
      {
            if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
                  return (getTheSEPoint().x-getTheNWPoint().x-2*thickness)<1 ||
                              (getTheSEPoint().y-getTheNWPoint().y-2*thickness)<1;
            else if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
                   return (getTheSEPoint().x-getTheNWPoint().x)<1 ||
                              (getTheSEPoint().y-getTheNWPoint().y)<1;
            else return (getTheSEPoint().x-getTheNWPoint().x-thickness)<1 ||
                              (getTheSEPoint().y-getTheNWPoint().y-thickness)<1;
      }



      @Override
01668       public Shape createShadowShape()
      {
            if(!canHaveShadow || !hasShadow) return shape;
            
            Rectangle2D b = createShape2D().getBounds2D();
            double dx=0, dy=0;
            LaTeXDrawPoint2D cg = getGravityCenter();
            LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
            shadowCg.setLocation(cg.x+shadowSize, cg.y);
            shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
            dx = shadowCg.x-cg.x;
            dy = cg.y-shadowCg.y;
            Rectangle2D.Double shadowS = new Rectangle2D.Double(b.getX()+dx-thickness/2.,b.getY()+dy-thickness/2.,
                                                                              b.getWidth()+thickness, b.getHeight()+thickness);
            return shadowS;
      }
      
      
      
      @Override
01688       public void mirrorHorizontal(LaTeXDrawPoint2D origin)
      {
            super.mirrorHorizontal(origin);
            updateNSEWDelimitors();
      }



      @Override
01697       public void mirrorVertical(LaTeXDrawPoint2D origin)
      {
            super.mirrorVertical(origin);
            updateNSEWDelimitors();
      }




      @Override
01707       public void updateToGrid(MagneticGrid grid)
      {
            super.updateToGrid(grid);
            updateNSEWDelimitors();
      }




      @Override
01717       public int getSelectedDelimitorOrientation()
      {
            int del = super.getSelectedDelimitorOrientation();
            
            if(del!=DELIMITOR_ORIENTATION_NONE)
                  return del;
            
            if(dSelected==dN) return DELIMITOR_ORIENTATION_NORTH;
            if(dSelected==dS) return DELIMITOR_ORIENTATION_SOUTH;
            if(dSelected==dE) return DELIMITOR_ORIENTATION_EAST;
            if(dSelected==dW) return DELIMITOR_ORIENTATION_WEST;
            if(dSelected==dNE) return DELIMITOR_ORIENTATION_NE;
            if(dSelected==dNW) return DELIMITOR_ORIENTATION_NW;
            if(dSelected==dSE) return DELIMITOR_ORIENTATION_SE;
            if(dSelected==dSW) return DELIMITOR_ORIENTATION_SW;
            return DELIMITOR_ORIENTATION_NONE;
      }

      
      
      @Override
      public int hashCode()
      {
            return super.hashCode()*8;
      }
      
      
      
      /**
       * Creates a Rectangle2D from the LaTeXDrawRectangle.
       * @return A Rectangle2D
       * @since 1.9.2
       */
01750       public Rectangle2D toRectangle2D() 
      {
            LaTeXDrawPoint2D nw = getTheNWPoint(), se = getTheSEPoint();
            
            return  new Rectangle2D.Double(nw.x, nw.y, se.x-nw.x, se.y-nw.y);
      }
      
      
      /**
       * Creates a Rectangle from the LaTeXDrawRectangle.
       * @return A Rectangle
       * @since 1.9.2
       */
01763       public Rectangle toRectangle() 
      {
            LaTeXDrawPoint2D nw = getTheNWPoint(), se = getTheSEPoint();
            
            return  new Rectangle((int)nw.x, (int)nw.y, (int)(se.x-nw.x), (int)(se.y-nw.y));
      }
}

Generated by  Doxygen 1.6.0   Back to index