OSDN Git Service

Initial revision
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / text / PlainView.java
1 /* PlainView.java -- 
2    Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing.text;
40
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Font;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.Rectangle;
47 import java.awt.Shape;
48
49 public class PlainView extends View
50   implements TabExpander
51 {
52   Color selectedColor;
53   Color unselectedColor;
54   Font font;
55   
56   protected FontMetrics metrics;
57
58   public PlainView(Element elem)
59   {
60     super(elem);
61   }
62
63   /**
64    * @since 1.4
65    */
66   protected void updateMetrics()
67   {
68     Component component = getContainer();
69     Font font = component.getFont();
70
71     if (this.font != font)
72       {
73         this.font = font;
74         metrics = component.getFontMetrics(font);
75       }
76   }
77   
78   /**
79    * @since 1.4
80    */
81   protected Rectangle lineToRect(Shape a, int line)
82   {
83     // Ensure metrics are up-to-date.
84     updateMetrics();
85     
86     Rectangle rect = a.getBounds();
87     int fontHeight = metrics.getHeight();
88     return new Rectangle(rect.x, rect.y + (line * fontHeight),
89                          rect.width, fontHeight);
90   }
91
92   public Shape modelToView(int position, Shape a, Position.Bias b)
93     throws BadLocationException
94   {
95     // Ensure metrics are up-to-date.
96     updateMetrics();
97     
98     Document document = getDocument();
99
100     // Get rectangle of the line containing position.
101     int lineIndex = getElement().getElementIndex(position);
102     Rectangle rect = lineToRect(a, lineIndex);
103
104     // Get the rectangle for position.
105     Element line = getElement().getElement(lineIndex);
106     int lineStart = line.getStartOffset();
107     Segment segment = new Segment();
108     document.getText(lineStart, position - lineStart, segment);
109     int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
110                                                this, lineStart);
111
112     // Calc the real rectangle.
113     rect.x += xoffset;
114     rect.width = 1;
115     rect.height = metrics.getHeight();
116
117     return rect;
118   }
119   
120   protected void drawLine(int lineIndex, Graphics g, int x, int y)
121   {
122     try
123       {
124         metrics = g.getFontMetrics();
125         // FIXME: Selected text are not drawn yet.
126         Element line = getElement().getElement(lineIndex);
127         drawUnselectedText(g, x, y, line.getStartOffset(), line.getEndOffset());
128         //drawSelectedText(g, , , , );
129       }
130     catch (BadLocationException e)
131       {
132         // This should never happen.
133       }
134   }
135
136   protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
137     throws BadLocationException
138   {
139     g.setColor(selectedColor);
140     Segment segment = new Segment();
141     getDocument().getText(p0, p1 - p0, segment);
142     return Utilities.drawTabbedText(segment, x, y, g, this, 0);
143   }
144
145   protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
146     throws BadLocationException
147   {
148     g.setColor(unselectedColor);
149     Segment segment = new Segment();
150     getDocument().getText(p0, p1 - p0, segment);
151     return Utilities.drawTabbedText(segment, x, y, g, this, segment.offset);
152   }
153
154   public void paint(Graphics g, Shape s)
155   {
156     // Ensure metrics are up-to-date.
157     updateMetrics();
158     
159     JTextComponent textComponent = (JTextComponent) getContainer();
160
161     g.setFont(textComponent.getFont());
162     selectedColor = textComponent.getSelectedTextColor();
163     unselectedColor = textComponent.getForeground();
164     
165     Rectangle rect = s.getBounds();
166
167     // FIXME: Text may be scrolled.
168     Document document = textComponent.getDocument();
169     Element root = document.getDefaultRootElement();
170     int y = rect.y;
171     
172     for (int i = 0; i < root.getElementCount(); i++)
173       {
174         drawLine(i, g, rect.x, y);
175         y += metrics.getHeight();
176       }
177   }
178
179   protected int getTabSize()
180   {
181     return 8;
182   }
183
184   /**
185    * Returns the next tab stop position after a given reference position.
186    *
187    * This implementation ignores the <code>tabStop</code> argument.
188    * 
189    * @param x the current x position in pixels
190    * @param tabStop the position within the text stream that the tab occured at
191    */
192   public float nextTabStop(float x, int tabStop)
193   {
194     float tabSizePixels = getTabSize() + metrics.charWidth('m');
195     return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
196   }
197
198   public float getPreferredSpan(int axis)
199   {
200     if (axis != X_AXIS && axis != Y_AXIS)
201       throw new IllegalArgumentException();
202
203     // make sure we have the metrics
204     updateMetrics();
205
206     float span = 0;
207     Element el = getElement();
208     Document doc = el.getDocument();
209     Segment seg = new Segment();
210
211     switch (axis)
212       {
213       case X_AXIS:
214         // calculate the maximum of the line's widths
215         for (int i = 0; i < el.getElementCount(); i++)
216           {
217             Element child = el.getElement(i);
218             int start = child.getStartOffset();
219             int end = child.getEndOffset();
220             try {
221               doc.getText(start, start + end, seg);
222             }
223             catch (BadLocationException ex)
224               {
225                 // throw new ClasspathAssertionError
226                 // ("no BadLocationException should be thrown here");
227               }
228             int width = metrics.charsWidth(seg.array, seg.offset, seg.count);
229             span = Math.max(span, width);
230           }
231         break;
232       case Y_AXIS:
233       default:
234         span = metrics.getHeight() * el.getElementCount();
235         break;
236       }
237
238     return span;
239   }
240 }
241