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

Text.java

package latexDraw.figures;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.JComboBox;

import latexDraw.psTricks.DviPsColors;
import latexDraw.psTricks.PSTricksConstants;
import latexDraw.ui.DrawContainer;
import latexDraw.ui.LaTeXDrawFrame;
import latexDraw.ui.components.MagneticGrid;
import latexDraw.util.LaTeXDrawPoint2D;


/** 
 * This class defines a text.
 *<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
 *  (at your option) 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/20/06<br>
 * @author Arnaud BLOUIN<br>
 * @version 2.0.0<br>
 */
00043 public class Text extends Figure
{
      private static final long serialVersionUID = 1L;
      
      public class TextPosition
      {
            protected int start;
            
            protected int end;
            
            protected LaTeXDrawPoint2D pos;
            
            public TextPosition(int s, int e, LaTeXDrawPoint2D p)
            {
                  start       = s;
                  end         = e;
                  pos         = p;
            }
            
            
            public TextPosition(int s, int e, double x, double y)
            {
                  start       = s;
                  end         = e;
                  pos         = new LaTeXDrawPoint2D(x, y);
            }


            /**
             * @return the start.
             * @since 2.0.0
             */
            public synchronized int getStart()
            {
                  return start;
            }


            /**
             * @return the end.
             * @since 2.0.0
             */
            public synchronized int getEnd()
            {
                  return end;
            }


            /**
             * @return the pos.
             * @since 2.0.0
             */
            public synchronized LaTeXDrawPoint2D getPos()
            {
                  return pos;
            }
      }

      
      
      /** The text which must be displayed */
00104       protected String text;
      
      /** The position of the first character of the text */
00107       protected LaTeXDrawPoint2D position;

      /** The current font*/
00110       protected Font currentFont;
      
      /** The current size of the text */
00113       protected TextSize currentSize;

      /** Allows to know if the text is bold */
00116       protected boolean isBold;
      
      /** Allows to know if the text is italic */
00119       protected boolean isItalic;
      
      /** The text is in italic or not by default */
00122       public static final boolean DEFAULT_ISITALIC = false;
      
      /** The text is bold or not by default */
00125       public static final boolean DEFAULT_ISBOLD = false;
      
      /** The text is or not framed by default. */
00128       public static final boolean DEFAULT_HAS_BOX = false;
      
      /** Define if the text is opaque by default. */
00131       public static final boolean DEFAULT_IS_OPAQUE = false;
      
      /** The text has a simple box or not by default */
00134       public static final boolean DEFAULT_HAS_SIMPLE_BOX = true;
      
      /** The colour of the opacity by default. */
00137       public static final Color DEFAULT_OPACITY_COLOR = Color.WHITE;
      
      /** The current font metrics of the text */
00140       protected FontMetrics fontMetrics;
      
      /** The current FontRenderContext of the text. */
00143       protected transient FontRenderContext fontRenderContext;
      
      /** The simple framed box of the text. */
00146       protected FramedBox simpleBox;
      
      /** Define if the text has a framed box. */
00149       protected boolean hasFramedBox;
      
      /** Define if the text has a simple or a complex framed box. */
00152       protected boolean hasSimpleFramedBox;
      
      /** The size of the labels which is used when the grid is drawn (takes account the PPC).*/
00155       protected double textSizeDrawn;
      
      /** Define if the background of the text is opaque. */
00158       protected boolean isOpaque;
      
      /** Contains all the boxes define by the user when she has selected multiple boxes. */
00161       protected Vector<FramedBox> multipleBox;
      
      /** 
       * Contains the boxes of the vector multipleBox and some textPostions but in the order to by displayed. 
       * The parts of the non-boxed text are contained in this vector as TextPosition. In order to display
       * the words of the text in the order.
       */
00168       protected transient Vector<FramedBox> multipleBoxDisplay;
      
      protected transient Vector<TextPosition> textPos;
      
      /** Define if a text has been change and so, if several parameters (font, ...) must be
       * updated. */
00174       protected transient boolean hasChanged;
      
      /** The colour of the opacity */
00177       protected Color opacityColor;
      
      
      
      
      /**
       * Allows to define a font of text
       * 01/20/06<br>
       * @author Arnaud BLOUIN<br>
       * @version 0.5<br>
       */
00188       public static class TextFont implements Cloneable, Serializable
      {
            private static final long serialVersionUID = 1L;

            /** The name of the font */
00193             protected String name;
            
            /** The family of the font */
00196             protected String family;
            
            /** The encoding of the font */
00199             protected String encoding;
            
            
            /**
             * The constructor by default
             * @param name The name of the font
             * @param family The family of the font
             * @param encoding The encoding of the font (cf. LaTeX : T1, ...)
             */
00208             public TextFont(String name, String family, String encoding)
            {
                  this.name = name;
                  this.family = family;
                  this.encoding = encoding;
            }
            
            
            /**
             * Allows to get the name of the font
             * @return The name of the font
             */
00220             public String getName()
            {
                  return name;
            }
            
            
            
            /**
             * Allows to get the family of the font
             * @return The family of the font
             */
00231             public String getFamily()
            {
                  return family;
            }
            
            
            
            /**
             * Allows to get the encoding of the font
             * @return The encoding of the font
             */
00242             public String getEncoding()
            {
                  return encoding;
            }
            
            
            @Override
            public Object clone() throws CloneNotSupportedException
            {
                  return super.clone();
            }
      }
      
      
      
      
      /**
       * Allows to define a size of text
       * 01/20/06<br>
       * @author Arnaud BLOUIN<br>
       * @version 0.5<br>
       */
00264       public static class TextSize implements Cloneable, Serializable
      {
            private static final long serialVersionUID = 1L;

            /** The label of the size */
00269             protected String label;
            
            /** The (pstricks) keyword of the size */
00272             protected String keyword;
            
            /** The size */
00275             protected int size;
            
            
            
            /**
             * The constructor by default
             * @param label The label of the size
             * @param keyword The pstricks keyword of the size
             * @param size The size
             */
00285             public TextSize(String label, String keyword, int size)
            {
                  this.label = label;
                  this.keyword = keyword;
                  this.size = size;
            }
            
            
            
            /**
             * Allows to get the label of the size
             * @return The label of the size
             */
00298             public String getLabel()
            {
                  return label;
            }
            
            
            /**
             * Allows to get the pstricks keyword of the size 
             * @return The keyword
             */
00308             public String getKeyword()
            {
                  return keyword;
            }
            
            
            
            /**
             * Allows to get the size
             * @return The size
             */
00319             public int getSize()
            {
                  return size;
            }
            
            
            
            @Override
            public Object clone() throws CloneNotSupportedException
            {
                  return super.clone();
            }
      }
      
      
      /** The tiny size */
00335       public static final TextSize SIZE_TINY = new TextSize("Tiny", PSTricksConstants.COMMAND_TEXT_TINY, 11); //$NON-NLS-1$ 
      /** The script size */
00337       public static final TextSize SIZE_SCRIPT = new TextSize("Script size", PSTricksConstants.COMMAND_TEXT_SCRIPT, 14); //$NON-NLS-1$ 
      /** The footnote size */
00339       public static final TextSize SIZE_FOOTNOTE = new TextSize("Footnote size", PSTricksConstants.COMMAND_TEXT_FOOTNOTE, 16); //$NON-NLS-1$
      /** The small size */
00341       public static final TextSize SIZE_SMALL = new TextSize("Small", PSTricksConstants.COMMAND_TEXT_SMALL, 17); //$NON-NLS-1$ 
      /** The normal size */
00343       public static final TextSize SIZE_NORMAL = new TextSize("Normal", PSTricksConstants.COMMAND_TEXT_NORMAL, 18); //$NON-NLS-1$ 
      /** The large size */
00345       public static final TextSize SIZE_LARGE1 = new TextSize("Large", PSTricksConstants.COMMAND_TEXT_LARGE1, 22); //$NON-NLS-1$ 
      /** The very large size */
00347       public static final TextSize SIZE_LARGE2 = new TextSize("Very large", PSTricksConstants.COMMAND_TEXT_LARGE2, 24); //$NON-NLS-1$ 
      /** The very very large size */
00349       public static final TextSize SIZE_LARGE3 = new TextSize("Very very large", PSTricksConstants.COMMAND_TEXT_LARGE3, 30); //$NON-NLS-1$ 
      /** The huge size */
00351       public static final TextSize SIZE_HUGE1 = new TextSize("huge", PSTricksConstants.COMMAND_TEXT_HUGE1, 35); //$NON-NLS-1$ 
      /** The very huge size */
00353       public static final TextSize SIZE_HUGE2 = new TextSize("Very huge", PSTricksConstants.COMMAND_TEXT_HUGE2, 44); //$NON-NLS-1$ 
      
      /** The times new roman font */
00356       public static final TextFont TEXTFONT_TIMES = new TextFont("Times New Roman", "ptm", "T1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      
      /** The courier font */
00359       public static final TextFont TEXTFONT_COURIER = new TextFont("Courier New", "pcr", "T1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      
      /** The palatino font */
00362       public static final TextFont TEXTFONT_PALATINO = new TextFont("Palatino Linotype", "ppl", "T1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      
      /** The font used by default */
00365       public static final TextFont DEFAULT_TEXTFONT = TEXTFONT_TIMES;
      
      /** The size by default of the text */
00368       public static final TextSize DEFAULT_SIZE = SIZE_NORMAL;
      
      /** The style of the text by default */
00371       public static final int DEFAULT_STYLE = Font.PLAIN;
      
      /** The current textFont */
00374       protected TextFont currentTextFont;
      
      protected static final Graphics2D          INS_GRAPHICS;
      protected static final FontMetrics         INS_FONT_METRICS;
      protected static final FontRenderContext INS_FONT_RENDER_CONT;
      
      static
      {
            BufferedImage bufferImage = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB);
            INS_GRAPHICS = bufferImage.createGraphics();
            
            INS_GRAPHICS.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            INS_GRAPHICS.setFont(new Font(DEFAULT_TEXTFONT.getName(), DEFAULT_STYLE, DEFAULT_SIZE.getSize()));

            INS_FONT_METRICS   = INS_GRAPHICS.getFontMetrics();
            INS_FONT_RENDER_CONT = INS_GRAPHICS.getFontRenderContext();
            
            bufferImage.flush();
            bufferImage = null;
      }

      


      /**
       * The constructor by default
       */
00401       public Text(boolean increaseMeter)
      {
            this("", new LaTeXDrawPoint2D(), increaseMeter);//$NON-NLS-1$
      }
      
      
      
      
      /**
       * The constructor using two parameters
       * @param t The text
       * @param increaseMeter If true the meter of figures will be increased
       */
00414       public Text(String t, boolean increaseMeter)
      {
            this(t, new LaTeXDrawPoint2D(), increaseMeter);
      }
      
      
      
      
      /**
       * The constructor using three parameters
       * @param t The text.
       * @param increaseMeter If true the meter of figures will be increased.
       * @param pos The position of the text.
       */
00428       public Text(String t, LaTeXDrawPoint2D pos, boolean increaseMeter)
      {
            super(increaseMeter);
            
            opacityColor = DEFAULT_OPACITY_COLOR;
            hasChanged = true;
            textPos = new Vector<TextPosition>();
            multipleBox = new Vector<FramedBox>();
            multipleBoxDisplay = new Vector<FramedBox>();
            hasFramedBox            = false;
            hasSimpleFramedBox      = true;
            simpleBox               = null;
            canHaveShadow           = false;
            isBordersMovable  = false;
            isResizable             = false;
            isDashableOrDotable = false;
            isDoubleBoundaryable= false;
            isThicknessable = false;
            canBeFilled = false;
            currentFont = new Font(DEFAULT_TEXTFONT.getName(), DEFAULT_STYLE, DEFAULT_SIZE.getSize());
            currentSize = DEFAULT_SIZE;
            currentTextFont = DEFAULT_TEXTFONT;
            isItalic = DEFAULT_ISITALIC;
            isBold   = DEFAULT_ISBOLD;
            text = t==null ? "" : t; //$NON-NLS-1$
            position = pos;
            borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)pos.clone(), (LaTeXDrawPoint2D)pos.clone(),false);
            borders.setIsFilled(true);
            borders.setBordersPosition(PSTricksConstants.BORDERS_OUTSIDE);
            
            fontMetrics = INS_FONT_METRICS;
            fontRenderContext = INS_FONT_RENDER_CONT;
            
            updateBorders(fontMetrics);
            shape = createShape2D();
            textSizeDrawn = currentSize.getSize();
            currentFont = new Font(currentFont.getFontName(), currentFont.getStyle(), (int)textSizeDrawn);
            updateFontsBorders();
            hasChanged = true;
      }
      
      
      
      /**
       * Allows to know if the given label is a valid size of text
       * @param label The label to check
       * @return True if the label is valid
       */
00476       public static boolean isValidSize(String label)
      {
            return label.equals(SIZE_TINY.getLabel()) ||
                        label.equals(SIZE_SMALL.getLabel()) ||
                        label.equals(SIZE_SCRIPT.getLabel()) ||
                        label.equals(SIZE_FOOTNOTE.getLabel()) ||
                        label.equals(SIZE_NORMAL.getLabel()) ||
                        label.equals(SIZE_LARGE1.getLabel()) ||
                        label.equals(SIZE_LARGE2.getLabel()) ||
                        label.equals(SIZE_LARGE3.getLabel()) ||
                        label.equals(SIZE_HUGE1.getLabel()) ||
                        label.equals(SIZE_HUGE2.getLabel());
      }
      
      
      
      /**
       * Allows to create a list with the different size of text
       * @return The list
       */
00496       public static JComboBox getChoiceSize()
      {
            JComboBox c = new JComboBox();
            
            c.addItem(SIZE_TINY.getLabel());
            c.addItem(SIZE_SCRIPT.getLabel());
            c.addItem(SIZE_FOOTNOTE.getLabel());
            c.addItem(SIZE_SMALL.getLabel());
            c.addItem(SIZE_NORMAL.getLabel());
            c.addItem(SIZE_LARGE1.getLabel());
            c.addItem(SIZE_LARGE2.getLabel());
            c.addItem(SIZE_LARGE3.getLabel());
            c.addItem(SIZE_HUGE1.getLabel());
            c.addItem(SIZE_HUGE2.getLabel());
            
            return c;
      }
      
      
      
      /**
       * Allows to create a list of the different fonts.
       * @return The list
       */
00520       public static JComboBox getChoiceFont()
      {
            JComboBox c = new JComboBox();
            
            c.addItem(TEXTFONT_TIMES.getName());
            c.addItem(TEXTFONT_COURIER.getName());
            c.addItem(TEXTFONT_PALATINO.getName());
            
            return c;
      }
      
      
      
      
      /**
       * Allows to update the borders of the text
       */
00537       public synchronized void updateBorders()
      {
            updateBorders(fontMetrics);
      }
      
      
      
      
      /**
       * @since 1.7
       * Update the simple or the complexes boxes of the text.
       */
00549       public synchronized void updateFramedBoxes()
      {
            if(!hasFramedBox)
                  return ;
            
            if(hasSimpleFramedBox)
            {
                  if(simpleBox!=null)
                        simpleBox.updateBoxSize();
            }
            else 
            {
                  FramedBox.updateDimensions(multipleBox, this);
                  updateBoxesOrder();
            }
      }
      
      
      
      /**
       * Allows to update the borders of the text. It is possible that you need to
       * update the framed boxes before: updateFramedBoxes.
       */
00572       public synchronized void updateBorders(FontMetrics f)
      {
            fontMetrics = f;
            
            if(hasSeveralBoxes() && !multipleBox.isEmpty())
            {
                  FramedBox.updateDimensions(multipleBox, this);
                  return ;
            }
            
            if(text.length()!=0)
            {                 
                  if(hasFramedBox && hasSimpleFramedBox && simpleBox!=null)
                  {
                        borders.setFirstPoint((LaTeXDrawPoint2D)simpleBox.getBorders().getPoint(0).clone());
                        borders.setLastPoint((LaTeXDrawPoint2D)simpleBox.getBorders().getPoint(-1).clone());
                  }
                  else
                  {
                        TextLayout tl = new TextLayout(text, currentFont, fontRenderContext);
                        Rectangle2D bounds = tl.getBounds();
                        borders.setFirstPoint(position.x+bounds.getX(), bounds.getY()+position.y);
                        borders.setLastPoint(position.x+bounds.getWidth()+bounds.getX(), 
                                                       position.y+bounds.getHeight()+bounds.getY());
                  }
                  gravityCenter = borders.getGravityCenter();
                  shape = createShape2D();
            }
      }
      
      
      
      
      @Override
      public Object clone() throws CloneNotSupportedException
      {
            Text t = (Text) super.clone();
            
            t.isOpaque = isOpaque;
            t.opacityColor = opacityColor;
            t.textPos = new Vector<TextPosition>();
            t.text = text;
            t.textSizeDrawn = textSizeDrawn;
            t.borders = (LaTeXDrawRectangle) borders.clone();
            t.position = (LaTeXDrawPoint2D)t.position.clone();
            t.hasFramedBox = hasFramedBox;
            t.hasSimpleFramedBox = hasSimpleFramedBox;
            t.updateBorders(fontMetrics);
            t.shape = t.createShape2D();
            if(simpleBox!=null) 
            {
                  t.simpleBox = (FramedBox)simpleBox.clone();
                  t.simpleBox.setText(t);
            }
            t.multipleBox = new Vector<FramedBox>();
            t.multipleBoxDisplay = new Vector<FramedBox>(); 
            int i, size = multipleBox.size();
            for(i=0; i<size; i++)
            {
                  FramedBox fb = (FramedBox)multipleBox.elementAt(i).clone();
                  fb.setText(t);
                  t.multipleBox.add(fb);
            }
            
            t.updateFramedBoxes();
            t.updateFontsBorders();
            t.hasChanged = true;
            return t;
      }

      
      
      
      @Override
00646       public void onDragged(Point formerPt, Point newPt) throws Exception 
      {
            if(formerPt.equals(newPt)) return;
            
            if(isOnRotation && borders.dSelected!=null)
            {
                  borders.onDragged(formerPt, newPt);
                  rotationAngle = borders.getRotationAngle();
                  
                  if(hasFramedBox())
                        updateFramedBoxes();
            }
            else
                  shift(formerPt, newPt);
            
            hasChanged = true;
      }

      
      
      
      @Override
00668       public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      {
            g.setFont(currentFont);
            
            if(hasChanged)
            {
                  updateFramedBoxes();
                  updateFontsBorders();
                  hasChanged = false;
            }
            
            LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
            TextLayout layout;
            Color formerCol = g.getColor();
            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);

            if(rotationAngle%(Math.PI*2)!=0)
            {           
                  g.rotate(rotationAngle);
                  g.translate(c3x,c3y);
            }
      
            if(text.length()==0) return;
      
            if(simpleBox!=null && hasFramedBox() && hasSimpleFramedBox())
                  simpleBox.draw(g, antiAlias, rendering, alphaInter, colorRendering);
            else 
                  if(hasSeveralBoxes() && !multipleBox.isEmpty())
                  {
                        for(TextPosition tp : textPos)
                        {
                              for(FramedBox fb : multipleBoxDisplay)
                                    if(fb.start==tp.start)
                                          fb.draw(g, antiAlias, rendering, alphaInter, colorRendering);
                              
                              layout = new TextLayout(text.substring(tp.getStart(), tp.getEnd()+1), currentFont, fontRenderContext);
                              g.setColor(linesColor);
                              layout.draw(g, (float)tp.getPos().x, (float)tp.getPos().y);
                        }
                  }
                  else
                        if(isOpaque() && borders!=null)
                        {
                              Color formerC = borders.getLinesColor();
                              borders.setLinesColor(getOpacityColor());
                              borders.setInteriorColor(getOpacityColor());
                              borders.setIsFilled(true);
                              borders.draw(g, antiAlias, rendering, alphaInter, colorRendering);
                              borders.setLinesColor(formerC);
                        }
            
            if(!hasSeveralBoxes() || multipleBox.isEmpty())
            {
                  layout = new TextLayout(text, currentFont, fontRenderContext);
                  g.setColor(linesColor);
                  layout.draw(g, (float)position.x, (float)position.y);
            }

            g.setColor(formerCol);
            
            if(rotationAngle%(Math.PI*2)!=0)
            {
                  g.translate(-c3x, -c3y);
                  g.rotate(-rotationAngle);
            }
            
            if(isSelected && borders!=null)
                  borders.draw(g, false, antiAlias, rendering, alphaInter, colorRendering);
      }

      
      
      
      /**
       * @return A rectangle corresponding to the opaque background of the text or null is the background is not opaque.
       * @since 2.0.0
       * TODO 2.1: To put in the Java view
       */
00750       public LaTeXDrawRectangle getOpaqueBackGround()
      {
            LaTeXDrawRectangle f;
            
            if(isOpaque())
                  try
                  {
                        f = (LaTeXDrawRectangle)borders.clone();
                        f.setLinesColor(getOpacityColor());
                        f.setInteriorColor(getOpacityColor());
                        f.setIsFilled(true);
                  }
                  catch(CloneNotSupportedException e) { f = null; }
            else
                  f = null;
            
            return f;
      }
      
      
      
      
      /**
       * Update the font: takes the style, the size and creates a new font.
       */
00775       public void updateFont()
      {
            int currentStyle = Font.PLAIN;
            if(isItalic())
            {
                  currentStyle = Font.ITALIC;
                  if(isBold())
                        currentStyle+=Font.BOLD;
            }
            else 
                  if(isBold()) currentStyle = Font.BOLD;
      
            currentFont = new Font(getCurrentTextFont().getName(), currentStyle, (int)textSizeDrawn);
            updateFramedBoxes();
      }
      
      
      
      @Override
      @Deprecated
00795       public void setLastPoint(double x, double y) 
      {
            /*
             * This function is disable
             */
      }
      
      
      @Override
      @Deprecated
00805       public void setFirstPoint(double x, double y) 
      {
            /*
             * This function is disable
             */
      }

      
      
      
      @Override
00816       public void shift(double shiftX, double shiftY)
      {
            if(shiftX==0. && shiftY==0.) return ;
            
            position.x+=shiftX;
            position.y+=shiftY;
            updateFramedBoxes();
            updateFontsBorders();
            hasChanged = true;
      }

      
      
      
      @Override
00831       public boolean isIn(LaTeXDrawPoint2D pt) 
      {
            if(hasFramedBox() && hasSimpleFramedBox() && getSimpleBox()!=null)
            {
                  boolean formerF = simpleBox.box.isFilled();
                  simpleBox.box.setIsFilled(true);
                  boolean in = simpleBox.box.isIn(pt);
                  simpleBox.box.setIsFilled(formerF);
                  if(in) return true;
                  
                  formerF = borders.isFilled;
                  borders.setIsFilled(false);
                  in = borders.isIn(pt);
                  borders.setIsFilled(formerF);
                  return in;
            }
            return borders.isIn(pt);
      }

      
      
      
      /**
       * Allows to get the position of the text
       * @return The position of the text
       */
00857       public synchronized LaTeXDrawPoint2D getPosition()
      {
            return position;
      }
      
      
      
      /**
       * Allows to get the current font @see TextFont
       * @return The current TextFont
       */
00868       public synchronized TextFont getCurrentTextFont()
      {
            return currentTextFont;
      }
      
      
      
      
      /**
       * Allows to know if the text is bold
       * @return True if the text is bold
       */
00880       public synchronized boolean isBold()
      {
            return isBold;
      }
      
      
      
      /**
       * Allows to know if the text is italic or not
       * @return True if the text is italic
       */
00891       public synchronized boolean isItalic()
      {
            return isItalic;
      }
      
      
      
      /**
       * Allows to get the text
       * @return The text
       */
00902       public synchronized String getText()
      {
            return text;
      }
      
      
      
      /**
       * Allows to get the current size of the text
       * @return The current size of the text
       */
00913       public synchronized TextSize getTextSize()
      {
            return currentSize;
      }
      
      
      
      
      
      /**
       * Allows to set the position of the first character of the text
       * @param p The new position
       */
00926       public synchronized void setPosition(LaTeXDrawPoint2D p)
      {
            if(p==null)
                  return ;
            
            position = p;
            if(simpleBox!=null)
                  simpleBox.updateBoxSize();
            hasChanged = true;
      }
      
      
      
      /**
       * Allows to set the X-coordinate of the text
       * @param x The new X-coordinate of the text
       */
00943       public synchronized void setX(double x)
      {
            position.x = x;
            if(simpleBox!=null)
                  simpleBox.updateBoxSize();
            hasChanged = true;
      }
      
      
      
      /**
       * Allows to set the Y-coordinate of the text
       * @param y The new Y-coordinate of the text
       */
00957       public synchronized void setY(double y)
      {
            position.y = y;
            if(simpleBox!=null)
                  simpleBox.updateBoxSize();
            hasChanged = true;
      }
      
      
      
      
      /**
       * Allows to set if the text must be bold or not
       * @param is True : the text must be bold
       */
00972       public synchronized void setIsBold(boolean is)
      {
            isBold = is;
            updateFont();
            hasChanged = true;
      }
      
      
      
      
      /**
       * Allows to set if the text is italic or not
       * @param is True : the text is italic
       */
00986       public synchronized void setIsItalic(boolean is)
      {
            isItalic = is;
            updateFont();
            hasChanged = true;
      }
      
      
      
      
      /**
       * Allows to set the text
       * @param t The new text
       */
01000       public synchronized void setText(String t)
      {
            if(t==null)
                  return ;
            
            text = t;
            
            if(simpleBox!=null)
                  simpleBox.updateBoxSize();
            
            hasChanged = true;
      }
      
      
      
      /**
       * Allows to set the font of the text
       * @param name The name of the new font
       */
01019       public synchronized void setTextFont(String name)
      {
            if(name==null)
                  return ;
            
            if(name.equals(TEXTFONT_TIMES.getName()))
                  currentTextFont = TEXTFONT_TIMES;
            else
            if(name.equals(TEXTFONT_COURIER.getName()))
                  currentTextFont = TEXTFONT_COURIER;
            else
            if(name.equals(TEXTFONT_PALATINO.getName()))
                  currentTextFont = TEXTFONT_PALATINO;
            
            updateFont();
            updateFontsBorders();
            hasChanged = true;
      }
      
      
      
      /**
       * Allows to set the font of the text
       * @param fam The family of the new font
       */
01044       public synchronized void setTextFontByFamily(String fam)
      {
            if(fam==null)
                  return ;
            
            if(fam.equals(TEXTFONT_TIMES.getFamily()))
                  currentTextFont = TEXTFONT_TIMES;
            else
            if(fam.equals(TEXTFONT_COURIER.getFamily()))
                  currentTextFont = TEXTFONT_COURIER;
            else
            if(fam.equals(TEXTFONT_PALATINO.getFamily()))
                  currentTextFont = TEXTFONT_PALATINO;
            
            updateFont();
            hasChanged = true;
      }
      
      
      
      
      /**
       * Allows to set the current size of the text.
       * @param cmd The command of the size of the text (\large, ...).
       */
01069       public synchronized void setSizeByCommand(String cmd)
      {
            if(cmd==null)
                  return ;
            
            int formerSize=currentSize.getSize();
            
            if(cmd.equals(SIZE_TINY.getKeyword()))
                  currentSize = SIZE_TINY;
            else
            if(cmd.equals(SIZE_SCRIPT.getKeyword()))
                  currentSize = SIZE_SCRIPT;
            else 
            if(cmd.equals(SIZE_FOOTNOTE.getKeyword()))
                  currentSize = SIZE_FOOTNOTE;
            else
            if(cmd.equals(SIZE_SMALL.getKeyword()))
                  currentSize = SIZE_SMALL;
            else
            if(cmd.equals(SIZE_NORMAL.getKeyword()))
                  currentSize = SIZE_NORMAL;
            else
            if(cmd.equals(SIZE_LARGE1.getKeyword()))
                  currentSize = SIZE_LARGE1;
            else
            if(cmd.equals(SIZE_LARGE2.getKeyword()))
                  currentSize = SIZE_LARGE2;
            else
            if(cmd.equals(SIZE_LARGE3.getKeyword()))
                  currentSize = SIZE_LARGE3;
            else
            if(cmd.equals(SIZE_HUGE1.getKeyword()))
                  currentSize = SIZE_HUGE1;
            else
            if(cmd.equals(SIZE_HUGE2.getKeyword()))
                  currentSize = SIZE_HUGE2;
            
            if(formerSize!=currentSize.getSize())
                  textSizeDrawn = (textSizeDrawn*currentSize.getSize())/formerSize;
            
            updateFont();
            hasChanged = true;
      }
      
      

      /**
       * Sets the size of the text.
       * @param size The new size (must corresponds to the size of one of the SIZE_XXX constants.
       * @since 2.0.0
       */
01120       public synchronized void setSize(int size)
      {
            TextSize ts = null;
            
            if(size==SIZE_FOOTNOTE.getSize())
                  ts = SIZE_FOOTNOTE;
            else
            if(size==SIZE_HUGE1.getSize())
                  ts = SIZE_HUGE1;
            else
            if(size==SIZE_HUGE2.getSize())
                  ts = SIZE_HUGE2;
            else
            if(size==SIZE_LARGE1.getSize())
                  ts = SIZE_LARGE1;
            else
            if(size==SIZE_LARGE2.getSize())
                  ts = SIZE_LARGE2;
            else
            if(size==SIZE_LARGE3.getSize())
                  ts = SIZE_LARGE3;
            else
            if(size==SIZE_NORMAL.getSize())
                  ts = SIZE_NORMAL;
            else
            if(size==SIZE_SCRIPT.getSize())
                  ts = SIZE_SCRIPT;
            else
            if(size==SIZE_SMALL.getSize())
                  ts = SIZE_SMALL;
            else
            if(size==SIZE_TINY.getSize())
                  ts = SIZE_TINY;
            
            if(ts!=null)
                  setSize(ts.getLabel());
      }
      
      
      
      /**
       * Allows to set the current size of the text
       * @param label The label of the size of the text
       */
01164       public synchronized void setSize(String label)
      {
            if(label==null)
                  return ;
            
            int formerSize=currentSize.getSize();
            
            if(label.equals(SIZE_TINY.getLabel()))
                  currentSize = SIZE_TINY;
            else
            if(label.equals(SIZE_SCRIPT.getLabel()))
                  currentSize = SIZE_SCRIPT;
            else 
            if(label.equals(SIZE_FOOTNOTE.getLabel()))
                  currentSize = SIZE_FOOTNOTE;
            else
            if(label.equals(SIZE_SMALL.getLabel()))
                  currentSize = SIZE_SMALL;
            else
            if(label.equals(SIZE_NORMAL.getLabel()))
                  currentSize = SIZE_NORMAL;
            else
            if(label.equals(SIZE_LARGE1.getLabel()))
                  currentSize = SIZE_LARGE1;
            else
            if(label.equals(SIZE_LARGE2.getLabel()))
                  currentSize = SIZE_LARGE2;
            else
            if(label.equals(SIZE_LARGE3.getLabel()))
                  currentSize = SIZE_LARGE3;
            else
            if(label.equals(SIZE_HUGE1.getLabel()))
                  currentSize = SIZE_HUGE1;
            else
            if(label.equals(SIZE_HUGE2.getLabel()))
                  currentSize = SIZE_HUGE2;
            
            if(formerSize!=currentSize.getSize())
                  textSizeDrawn = (textSizeDrawn*currentSize.getSize())/formerSize;
            
            updateFont();
            updateFontsBorders();
            hasChanged = true;
      }
      
      

      
      public synchronized String getCodePSTricksBody(DrawBorders drawBorders, float ppc)
      {
            if(text==null || text.length()==0) return null;
            
            String add="";
            
            if(!linesColor.equals(PSTricksConstants.DEFAULT_LINE_COLOR))
            {
                  String name = DviPsColors.getColourName(linesColor);
                  if(name==null)
                  {
                        name = "color"+number;//$NON-NLS-1$
                        DviPsColors.addUserColour(linesColor, name); 
                  }
                  add += "\\color{"+name+"}"; //$NON-NLS-1$ //$NON-NLS-2$
            }
            
            String txt = text;
            
            if(hasFramedBox)
                  if(hasSimpleFramedBox)
                        txt = simpleBox.getCodePSTricks(drawBorders, ppc);
                  else
                        txt = FramedBox.getCode(multipleBox, drawBorders, ppc);
            else
                  if(isOpaque)
                  {
                        String name = DviPsColors.getColourName(opacityColor);
                        
                        if(name==null)
                        {
                              name = "color"+number+"z";//$NON-NLS-1$ //$NON-NLS-2$
                              DviPsColors.addUserColour(opacityColor, name); 
                        }
                              
                        txt = "\\psframebox*[framesep=0, boxsep=false,fillcolor="+name+ //$NON-NLS-1$
                        "] {"+txt+"}";//$NON-NLS-1$ //$NON-NLS-2$ 
                  }
            
            return add + txt;
      }

      
      
      @Override
01257       public synchronized String getCodePSTricks(DrawBorders drawBorders, float ppc)
      {
            if(text==null || text.length()==0) return null;
            
            String addBegin="", addEnd="", size="", font=""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
            LaTeXDrawPoint2D d = drawBorders.getOriginPoint();
            double yGap = 0;
            
            if(fontMetrics!=null)
                  yGap = fontMetrics.getHeight()/4.;
            
            TextLayout tl = new TextLayout(text, currentFont, fontRenderContext);
            Rectangle2D bounds = tl.getBounds();
            double xa = position.x+bounds.getX(), xb = position.x+bounds.getWidth()+bounds.getX();
            
            float x = (float)((position.x + (xb-xa)/2. - d.x)/ppc);
            float y = (float)(((d.y - position.y+yGap)/ppc));
            
            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 x2 = -Math.cos(-rotationAngle)*cx+
                                    Math.sin(-rotationAngle)*cy+cx;
                  double y2 =  -Math.sin(-rotationAngle)*cx-
                                    Math.cos(-rotationAngle)*cy+cy;
                  addBegin +="\\rput{"+(float)angle+ "}("+(float)x2+','+(float)y2+"){"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                  addEnd = "}"; //$NON-NLS-1$
            }
            
            
            if(!currentSize.getLabel().equals(SIZE_NORMAL.getLabel()))
                  size = currentSize.getKeyword();
            
            font = "\\usefont{"+currentTextFont.getEncoding()+"}{"+ //$NON-NLS-1$ //$NON-NLS-2$
                        currentTextFont.getFamily()+"}{"; //$NON-NLS-1$
            
            if(isBold)
                    font+="b}{"; //$NON-NLS-1$
            else  font+="m}{"; //$NON-NLS-1$
            
            if(isItalic)
                    font+="it}\n"; //$NON-NLS-1$
            else  font+="n}\n"; //$NON-NLS-1$

            if(hasFramedBox)
                  if(hasSimpleFramedBox)
                  {
                        if(simpleBox.getBoxType()==FramedBox.BOX_TRIANGLE)
                        {
                              double height = (simpleBox.box.getTheSEBoundPoint().y-simpleBox.box.getTheNWBoundPoint().y)/4.;
                              y+=(height/ppc);
                        }
                  }
                  else
                  {
                        FramedBox fb, max=null;
                        double xMin=Double.MAX_VALUE;
                        int i=0, size2 = getMultipleBox().size();
                        
                        while(i<size2)
                        {
                              fb = getMultipleBox().elementAt(i);
                              if(fb.isBoxSep() && fb.getBox().getTheNWBoundPoint().x<xMin && fb.getBoxType()==FramedBox.BOX_TRIANGLE)
                              {
                                    xMin = fb.getBox().getTheNWBoundPoint().x;
                                    max = fb;
                              }
                              else i++;
                        }
                        
                        if(max!=null)
                        {
                              double height = (max.getBox().getTheSEBoundPoint().y-max.getBox().getTheNWBoundPoint().y)/4.;
                              y+=(height/ppc);
                        }
                  }
            else
                  if(isOpaque)
                  {
                        String name = DviPsColors.getColourName(opacityColor);
                        
                        if(name==null)
                        {
                              name = "color"+number+"z";//$NON-NLS-1$ //$NON-NLS-2$
                              DviPsColors.addUserColour(opacityColor, name); 
                        }
                  }
            
            return font + addBegin+"\\rput(" + x + "," + y +"){"+ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                        size + getCodePSTricksBody(drawBorders, ppc) +"}"+addEnd; //$NON-NLS-1$ 
      }



      @Override
01354       public Shape createShape2D() 
      {
            Shape s = borders.shape;
            double ra = borders.getRotationAngle();
            
            if(ra%(Math.PI*2)!=0)
            {
                  LaTeXDrawPoint2D NW = borders.getTheNWPoint();
                  LaTeXDrawPoint2D SE = borders.getTheSEPoint();
                  double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;

                  double c2x = Math.cos(ra)*cx-Math.sin(ra)*cy;
                  double c2y = Math.sin(ra)*cx+Math.cos(ra)*cy;

                  AffineTransform at = AffineTransform.getTranslateInstance(cx-c2x, cy-c2y);
                  at.rotate(ra);
                  s = at.createTransformedShape(s);
            }
            
            return s;
      }


      

      @Override
      @Deprecated
01381       public void rescaleX(double formerX, double newX, double percent, LaTeXDrawRectangle bound) 
      {
            /*
             * We can't resize a text
             */
      }


      


      @Override
      @Deprecated
01394       public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound) 
      {
            /*
             * We can't resize a text
             */
      }
      
      
      
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            textPos = new Vector<TextPosition>();
            interiorColor     = (Color) ois.readObject();
            lineStyle         = (String) ois.readObject();
            rotationAngle     = ois.readDouble();
            thickness         = ois.readFloat();
            isFilled          = ois.readBoolean();
            isSelected        = ois.readBoolean();
            isOnRotation      = ois.readBoolean();
            linesColor        = (Color) ois.readObject();
            blackDashLength = ois.readFloat();
            dotSep                  = ois.readFloat();
            whiteDashLength = ois.readFloat();  
            borders           = (LaTeXDrawRectangle) ois.readObject();
            text              = (String) ois.readObject();
            position          = (LaTeXDrawPoint2D) ois.readObject();
            currentFont       = (Font)ois.readObject();
            currentSize       = (TextSize) ois.readObject();
            currentTextFont = (TextFont) ois.readObject();
            isItalic          = ois.readBoolean();
            isBold                  = ois.readBoolean();
            textSizeDrawn     = DrawContainer.DEFAULT_PIXPERCM;
            currentFont = new Font(currentTextFont.getName(), currentFont.getStyle(), currentSize.getSize());
            multipleBoxDisplay = new Vector<FramedBox>();
            textPos = new Vector<TextPosition>();
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0)//$NON-NLS-1$
            {
                  hasFramedBox = ois.readBoolean();
                  hasSimpleFramedBox = ois.readBoolean();
                  isOpaque = ois.readBoolean();
                  simpleBox = (FramedBox)ois.readObject();
                  multipleBox = new Vector<FramedBox>();
                  int size = ois.readInt();
                  for(int i=0; i<size; i++)
                  {
                        FramedBox fb = (FramedBox)ois.readObject();
                        fb.setText(this);
                        multipleBox.add(fb);
                  }
                  opacityColor = (Color)ois.readObject();
                  
                  if(simpleBox!=null)
                        simpleBox.setText(this);
            }
            else
            {
                  hasFramedBox = DEFAULT_HAS_BOX;
                  hasSimpleFramedBox = DEFAULT_HAS_SIMPLE_BOX;
                  isOpaque = DEFAULT_IS_OPAQUE;
                  simpleBox = new FramedBox(this);
                  multipleBox = new Vector<FramedBox>();
            }
            
            updateFontsBorders();
            updateFramedBoxes();
            shape = createShape2D();
            textSizeDrawn = currentSize.getSize();
            currentFont = new Font(currentFont.getFontName(), currentFont.getStyle(), (int)textSizeDrawn);
            updateFontsBorders();
            hasChanged = true;
      }


      
      
      
      /**
       * Allows to update the Font, the FontMetrics and
       * the borders of the text.
       */
01475       public void updateFontsBorders()
      {
            INS_GRAPHICS.setFont(getCurrentFont());
            fontRenderContext = INS_GRAPHICS.getFontRenderContext();
            updateBorders(INS_GRAPHICS.getFontMetrics());
      }
      

      
      
      @Override
01486       public Shape createNonRotatedShape2D()
      {
            return borders.createNonRotatedShape2D();
      }




      @Override
01495       public synchronized void updateShape()
      {
            shape = createShape2D();
      }
      
      
      
      
      /**
       * @return the currentFont
       */
01506       public synchronized Font getCurrentFont()
      {
            return currentFont;
      }


      
      /**
       * Allows to get the width of the text.
       * @return The width of the text.
       */
01517       public synchronized double getWidth()
      {
            return fontMetrics.stringWidth(getText());
      }

      
      /**
       * Allows to get the height of the text.
       * @return The height of the text.
       */
01527       public synchronized double getHeight()
      {
            return fontMetrics.getHeight();
      }



      /**
       * @return the fontMetrics
       */
01537       public synchronized FontMetrics getFontMetrics()
      {
            return fontMetrics;
      }




      @Override
01546       public synchronized boolean isTooSmallToBeRescaled()
      {
            return true;
      }




      /**
       * @since 1.7
       * @return the simpleBox
       */
01558       public synchronized FramedBox getSimpleBox()
      {
            return simpleBox;
      }




      /**
       * @return the hasFramedBox
       */
01569       public synchronized boolean hasFramedBox()
      {
            return hasFramedBox;
      }




      /**
       * @param hasFramedBox the hasFramedBox to set
       */
01580       public synchronized void setHasFramedBox(boolean hasFramedBox)
      {
            this.hasFramedBox = hasFramedBox;
            if(simpleBox==null)
                  simpleBox = new FramedBox(this);
            
            updateFramedBoxes();
            hasChanged = true;
      }




      /**
       * @return the hasSimpleFramedBox
       */
01596       public synchronized boolean hasSimpleFramedBox()
      {
            return hasSimpleFramedBox && hasFramedBox();
      }




      /**
       * Must be used with setHasFramedBox.
       * @param hasSimpleFramedBox the hasSimpleFramedBox to set.
       */
01608       public synchronized void setHasSimpleFramedBox(boolean hasSimpleFramedBox)
      {
            if(hasSimpleFramedBox)
                  isOpaque = false;
            
            this.hasSimpleFramedBox = hasSimpleFramedBox;
            
            if(simpleBox==null)
                  simpleBox = new FramedBox(this);
            
            updateBorders();
            hasChanged = true;
      }




      /**
       * @since 1.7
       * @param simpleBox the simpleBox to set.
       */
01629       public synchronized void setSimpleBox(FramedBox simpleBox)
      {
            if(simpleBox==null)
                  return ;
            
            Figure box = simpleBox.getBox();
            if(box!=null && (box instanceof LaTeXDrawRectangle || box instanceof Circle || 
                  box instanceof Ellipse || box instanceof Triangle || box instanceof Rhombus))
                  this.simpleBox = simpleBox;
            
            this.simpleBox.text = this;
            hasChanged = true;
      }




      /**
       * @return the fontRenderContext.
       */
01649       public synchronized FontRenderContext getFontRenderContext()
      {
            return fontRenderContext;
      }





      @Override
01659       public boolean intersected(Rectangle2D.Double r)
      {
            if(hasFramedBox() && hasSimpleFramedBox() && simpleBox!=null)
            {
                  Shape s = simpleBox.getBox().createShape2D();
                  return s.intersects(r) && !s.contains(r);
            }
            
            Shape s;
            
            if(shape==null)
                  s = createShape2D();
            else s = shape;
            
            return s.intersects(r) && !s.contains(r);
      }




      /**
       * @since 1.7
       * @return the isOpaque.
       */
01683       public synchronized boolean isOpaque()
      {
            return isOpaque;
      }




      /**
       * @since 1.7
       * @param isOpaque the isOpaque to set.
       */
01695       public synchronized void setOpaque(boolean isOpaque)
      {
            this.isOpaque = isOpaque;
            if(isOpaque)
                  hasSimpleFramedBox = false;
            updateBorders();
            hasChanged = true;
      }
      
      
      
      /**
       * @return True if the text has several framed boxes (not only or no one).
       */
01709       public synchronized boolean hasSeveralBoxes()
      {
            return hasFramedBox && !hasSimpleFramedBox;
      }
      
      
      
      
      
      /**
       * Allows to add a box to frame a part of the text.
       * @since 1.7
       * @param box The new box to add.
       * @return True if the box has been added and false of it is not possible.
       */
01724       public synchronized boolean addBox(FramedBox box)
      {
            if(multipleBox==null)
                  multipleBox = new Vector<FramedBox>();
            
            if(box==null)
                  return false;
            
            boolean valid = true;
            int i=0, size = multipleBox.size();
            
            while(valid && i<size)
                  if(multipleBox.elementAt(i).overlap(box))
                        valid = false;
                  else i++;
            
            if(!valid) return false;
            
            box.setText(this);
            multipleBox.add(box);
            updateBoxesOrder();
            updateFramedBoxes();
            updateBorders();
            
            return true;
      }
      
      
      
      
      /**
       * @since 1.7
       * Allows to remove a box.
       * @param b The box to remove.
       */
01759       public synchronized void removeBox(FramedBox b)
      {
            if(b==null) return ;
            multipleBox.remove(b);
            updateFramedBoxes();
            updateBorders();
            hasChanged = true;
      }




      /**
       * @since 1.7
       * @return the multipleBox.
       */
01775       public synchronized Vector<FramedBox> getMultipleBox()
      {
            return multipleBox;
      }
      
      
      
      
      /**
       * Update the position of the elements of the text by taking account of the
       * multiple boxes.
       */
01787       public void updateTextPosition()
      {
            if(!hasSeveralBoxes())
                  return ;
            
            textPos.removeAllElements();
            
            textPos.add(new TextPosition(0,text.length()-1, (LaTeXDrawPoint2D)position.clone()));
            boolean found, ok;
            int i, size, j;
            TextPosition tp, add;
            double x;
            
            for(FramedBox fb : multipleBox)
            {
                  i=0;
                  found = false;
                  size = textPos.size();
                  while(i<size && !found)
                        if(fb.start>=textPos.elementAt(i).start && fb.end<=(textPos.elementAt(i).end+1))
                              found = true;
                        else i++;
                  
                  if(found)
                  {
                        tp = textPos.elementAt(i);
                        
                        if(fb.start!=tp.start || (fb.end-1)!=tp.end)
                        {
                              textPos.remove(i);
                              
                              x = tp.pos.x + (tp.start==fb.start ? 0 : 
                                    fontMetrics.stringWidth(text.substring(tp.start, fb.start)));
                              
                              if(fb.start>tp.start)
                                    textPos.add(i++, new TextPosition(tp.start, fb.start-1, (LaTeXDrawPoint2D)tp.pos.clone()));
                              
                              add = new TextPosition(fb.start, fb.end-1, x, tp.pos.y);
                              textPos.add(i++, add);
                              
                              if((fb.end-1)<tp.end)
                                    textPos.add(i, new TextPosition(fb.end, tp.end, new LaTeXDrawPoint2D(
                                          x +fontMetrics.stringWidth(text.substring(fb.start, fb.end)), position.y)));
                        }
                  }
                  else
                  {
                        found = false;
                        i=0;
                        while(!found && i<size)
                              if(fb.start>textPos.elementAt(i).start && fb.start<(textPos.elementAt(i).end+1))
                                    found = true;
                              else i++;
                        
                        if(found)
                        {
                              tp = textPos.remove(i);
                              
                              if(fb.start>tp.start)
                                    textPos.add(i++, new TextPosition(tp.start, fb.start-1, (LaTeXDrawPoint2D)tp.pos.clone()));
                              
                              x = tp.pos.x + fontMetrics.stringWidth(text.substring(tp.start, fb.start));
                              add = new TextPosition(fb.start, tp.end, x, tp.pos.y);
                              textPos.add(i, add);
                        }
                        
                        found = false;
                        i=0;
                        size = textPos.size();
                        
                        while(!found && i<size)
                              if(fb.end>textPos.elementAt(i).start && fb.end<(textPos.elementAt(i).end+1))
                                    found = true;
                              else i++;
                        
                        if(found)
                        {
                              tp = textPos.remove(i);
                              
                              add = new TextPosition(tp.start, fb.end-1, (LaTeXDrawPoint2D)tp.pos.clone());
                              textPos.add(i, add);
                              
                              if(fb.end<(tp.end+1))
                              {
                                    x = tp.pos.x + fontMetrics.stringWidth(text.substring(tp.start, fb.end));
                                    textPos.add(i+1, new TextPosition(fb.end, tp.end, x, tp.pos.y));
                              }
                        }
                  }//else
            }//for
            
            // We update the TextPostion of the FramedBox
            Vector<FramedBox> boxes = new Vector<FramedBox>();
            Vector<TextPosition> tps = new Vector<TextPosition>();
            FramedBox fb;
            
            for(FramedBox fb2 : multipleBox)
            {
                  fb2.removeAllTextPosition();
                  boxes.add(fb2);
            }
            for(TextPosition tp2 : textPos)
                  tps.add(tp2);
            
            while(!boxes.isEmpty())
            {
                  found = false;
                  i=0;
                  size = boxes.size();
                  
                  while(!found && i<size)
                  {
                        fb = boxes.elementAt(i);
                        j = 0;
                        ok = true;
                        
                        while(j<i && ok)
                              if(fb.contains(boxes.elementAt(j))==1)
                                    ok = false;
                              else j++;
                        
                        j= i+1;
                        while(j<size && ok)
                              if(fb.contains(boxes.elementAt(j))==1)
                                    ok = false;
                              else j++;
                        
                        if(ok)
                              found = true;
                        else i++;
                  }//while
                  
                  fb = boxes.remove(i);
                  i=0;
                  while(i<tps.size())
                  {
                        TextPosition tp2 = tps.elementAt(i);
                        if(tp2.start>=fb.start && (tp2.end+1)<=fb.end)
                        {
                              tps.remove(tp2);
                              fb.addTextPosition(tp2);
                        }
                        else i++;
                  }
            }//while
      }




      /**
       * @since 1.7
       * @return the textPos.
       */
01941       public synchronized Vector<TextPosition> getTextPos()
      {
            return textPos;
      }
      
      
      
      
      
      /**
       * @since 1.7
       * @return The first textPosition (where start==0 and pos.x is min) of the vector.
       */
01954       public synchronized TextPosition getFirstTextPosition()
      {
            if(textPos==null || textPos.isEmpty())
                  return null;
            
            TextPosition tp = null;
            for(TextPosition tp2 : textPos)
                  if(tp2.start==0)
                        if(tp==null) tp = tp2;
                        else if(tp.pos.x>tp2.pos.x) tp = tp2;
            
            return tp;
      }
      
      
      
      /**
       * @since 1.7
       * @return The last textPosition (where end==text.length-1 and pos.x is max) of the vector.
       */
01974       public synchronized TextPosition getLastTextPosition()
      {
            if(textPos==null || textPos.isEmpty())
                  return null;
            
            TextPosition tp = null;
            int size = text.length()-1;
            
            for(TextPosition tp2 : textPos)
                  if(tp2.end==size)
                        if(tp==null) tp = tp2;
                        else if(tp.pos.x<tp2.pos.x) tp = tp2;
            
            return tp;
      }
      
      
      
      /**
       * @since 1.7
       * Remove all the boxes (from the vector multipleBox). Set hasFramedBox to false.
       */
01996       public void removeAllBoxes()
      {
            if(multipleBox!=null)
            {
                  multipleBox.removeAllElements();
                  hasFramedBox = false;
                  updateBorders();
            }
            hasChanged = true;
      }
      
      
      
      
      
      /**
       * @since 1.7
       * Allows to update the order of the boxes when they will be displayed.
       * Using the borders of the boxes and the textPositions, so they must be updated.
       */
02016       public synchronized void updateBoxesOrder()
      {
            if(multipleBox.isEmpty())
                  return ;
            
            Vector<FramedBox> boxes = new Vector<FramedBox>();

            for(FramedBox fb : multipleBox)
                  boxes.add(fb);
            
            multipleBoxDisplay.removeAllElements();
            
            while(!boxes.isEmpty())
            {
                  FramedBox first=null, fb;
                  int start=text.length()+1, i;
                  
                  for(i = boxes.size()-1; i>=0; i--)
                  {
                        fb = boxes.elementAt(i);
                        if(fb.start<start)
                        {
                              first = fb;
                              start = fb.start;
                        }
                        else
                              if(fb.start==start && first!=null && first.end<fb.end)
                              {
                                    first = fb;
                                    start = fb.start;
                              }
                  }
                  
                  multipleBoxDisplay.add(first);
                  boxes.remove(first);
            }
      }




      /**
       * @since 1.7
       * @return the opacityColor.
       */
02061       public synchronized Color getOpacityColor()
      {
            return opacityColor;
      }




      /**
       * @since 1.7
       * @param opacityColor the opacityColor to set.
       */
02073       public synchronized void setOpacityColor(Color opacityColor)
      {
            if(opacityColor!=null)
                  this.opacityColor = opacityColor;
      }




      @Override
02083       public void mirrorHorizontal(LaTeXDrawPoint2D origin)
      {
            if(simpleBox!=null)
                  simpleBox.mirrorHorizontal(origin);
            
            for(FramedBox f : multipleBox)
                  f.mirrorHorizontal(origin);
            
            LaTeXDrawPoint2D se = borders.getTheSEPoint(), nw = borders.getTheNWPoint();
            double distance = se.x-nw.x, distance2 = distance-se.x+position.x;
            se.x-=distance2;
            position.setLocation(se.horizontalSymmetry(origin).getX(), position.y);
            
            updateFramedBoxes();
            updateFontsBorders();
            hasChanged = true;
      }




      @Override
02105       public void mirrorVertical(LaTeXDrawPoint2D origin)
      {// Fixes #1564478
            if(getSimpleBox()!=null)
                  getSimpleBox().mirrorVertical(origin);
            
            for(FramedBox f : multipleBox)
                  f.mirrorVertical(origin);
            
            LaTeXDrawPoint2D se = borders.getTheSEPoint(), nw = borders.getTheNWPoint();
            double distance = se.y-nw.y, distance2 = distance-se.y+position.y;
            se.y-=distance2;
            position.setLocation(position.x, se.verticalSymmetry(origin).getY());
            
            updateFramedBoxes();
            updateFontsBorders();
            hasChanged = true;
      }




      @Override
      @Deprecated
02128       public LaTeXDrawPoint2D getLastPoint()
      {
            return null;
      }




      @Override
02137       public void updateToGrid(MagneticGrid grid)
      {
            position.setLocation(grid.getTransformedPointToGrid(position, false));
            updateFramedBoxes();
            updateBorders();
            updateShape();
      }
      
      
      
      @Override
      public int hashCode()
      {
            return super.hashCode()^9;
      }



      /**
       * @return the multipleBoxDisplay.
       * @since 2.0.0
       */
02159       public synchronized Vector<FramedBox> getMultipleBoxDisplay()
      {
            return multipleBoxDisplay;
      }
}

Generated by  Doxygen 1.6.0   Back to index