root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / symbols / SimpleTextSymbol.java @ 38563
History | View | Annotate | Download (10.7 KB)
1 | 11073 | jaume | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | 10679 | jaume | package com.iver.cit.gvsig.fmap.core.symbols; |
42 | |||
43 | import java.awt.Color; |
||
44 | import java.awt.Font; |
||
45 | 21535 | vcaballero | import java.awt.FontMetrics; |
46 | 10679 | jaume | import java.awt.Graphics2D; |
47 | import java.awt.Rectangle; |
||
48 | 20700 | vcaballero | import java.awt.RenderingHints; |
49 | 10679 | jaume | import java.awt.Shape; |
50 | 10994 | jaume | import java.awt.font.FontRenderContext; |
51 | import java.awt.font.GlyphVector; |
||
52 | 10679 | jaume | import java.awt.geom.AffineTransform; |
53 | 18621 | jdominguez | import java.awt.geom.Rectangle2D; |
54 | 10679 | jaume | |
55 | 10908 | jaume | import javax.print.attribute.PrintRequestAttributeSet; |
56 | 24373 | vcaballero | import javax.print.attribute.standard.PrintQuality; |
57 | 10908 | jaume | |
58 | 24373 | vcaballero | import com.iver.cit.gvsig.fmap.MapContext; |
59 | 18621 | jdominguez | import com.iver.cit.gvsig.fmap.ViewPort; |
60 | import com.iver.cit.gvsig.fmap.core.CartographicSupportToolkit; |
||
61 | 10679 | jaume | import com.iver.cit.gvsig.fmap.core.FPoint2D; |
62 | 10994 | jaume | import com.iver.cit.gvsig.fmap.core.FPolygon2D; |
63 | 10679 | jaume | import com.iver.cit.gvsig.fmap.core.FShape; |
64 | 10994 | jaume | import com.iver.cit.gvsig.fmap.core.GeneralPathX; |
65 | 10679 | jaume | import com.iver.cit.gvsig.fmap.core.IGeometry; |
66 | 23586 | vcaballero | import com.iver.cit.gvsig.fmap.core.SymbologyFactory; |
67 | 24373 | vcaballero | import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
68 | 10679 | jaume | import com.iver.utiles.StringUtilities; |
69 | import com.iver.utiles.XMLEntity; |
||
70 | 13953 | jaume | import com.iver.utiles.swing.threads.Cancellable; |
71 | 10679 | jaume | |
72 | 11073 | jaume | /**
|
73 | 12999 | jvidal | * SimpleTextSymbol is a class used to create symbols composed using a text defined by
|
74 | * the user.This text can be edited (changing the color, the font of the characters, and
|
||
75 | * the rotation of the text).
|
||
76 | 11073 | jaume | * @author jaume dominguez faus - jaume.dominguez@iver.es
|
77 | *
|
||
78 | */
|
||
79 | 23073 | vcaballero | public class SimpleTextSymbol extends AbstractSymbol implements ITextSymbol { |
80 | private String text = ""; |
||
81 | 23586 | vcaballero | private Font font = SymbologyFactory.DefaultTextFont; |
82 | 10679 | jaume | private Color textColor = Color.BLACK; |
83 | 10812 | jaume | private double rotation; |
84 | 11509 | jaume | private FontRenderContext frc = new FontRenderContext( |
85 | new AffineTransform(), false, true); |
||
86 | 23073 | vcaballero | private boolean autoresize; |
87 | 25877 | vcaballero | private Rectangle bounds = null; |
88 | 26986 | vcaballero | private FShape horizontalTextWrappingShape = null; |
89 | 28367 | vcaballero | private PrintRequestAttributeSet properties; |
90 | 23073 | vcaballero | |
91 | 13953 | jaume | public void draw(Graphics2D g, AffineTransform affineTransform, FShape shp, Cancellable cancel) { |
92 | 10959 | jaume | if (!isShapeVisible()) return; |
93 | 30002 | vcaballero | double shpX = ((FPoint2D) shp).getX();
|
94 | double shpY = ((FPoint2D) shp).getY();
|
||
95 | //Parche porque a veces llegan puntos cuyas coordenadas no han podido ser calculadas y vienen como NaN
|
||
96 | if( Double.isNaN(shpX) || Double.isNaN(shpY)){ |
||
97 | return;
|
||
98 | } |
||
99 | //Fin del parche
|
||
100 | 20700 | vcaballero | g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
101 | 10812 | jaume | g.setColor(textColor); |
102 | g.setFont(font); |
||
103 | 30002 | vcaballero | g.translate(shpX, shpY); |
104 | 10812 | jaume | |
105 | 20700 | vcaballero | g.rotate(rotation); |
106 | 26986 | vcaballero | Rectangle2D bounds = getHorizontalTextWrappingShape(new FPoint2D(0,0)).getBounds(); |
107 | // Antes tomabamos el resultado de getBounds pero ya se le hab?a aplicado
|
||
108 | // la rotaci?n, con lo que no obten?amos el la altura correcta de la fuente.
|
||
109 | |||
110 | 32881 | fpenarrubia | // Alineamos el texto de manera que la parte inferior
|
111 | 26986 | vcaballero | // izquierda de la primera letra est? en (0,0).
|
112 | 32111 | fpenarrubia | // Para chino hay que escoger una fuente como esta (SimSun)
|
113 | // g.setFont(new Font("SimSun",Font.PLAIN, 12));
|
||
114 | |||
115 | 38563 | fpuga | // g.drawString(getText(), -((int) bounds.getWidth()/2), 0); //(int)-bounds.getY());
|
116 | g.drawString(getText(), 0, 0); |
||
117 | 32881 | fpenarrubia | // g.drawRect(0, 0, 5, 5);
|
118 | 20700 | vcaballero | g.rotate(-rotation); |
119 | 30002 | vcaballero | g.translate(-shpX, -shpY); |
120 | 10679 | jaume | } |
121 | |||
122 | public void drawInsideRectangle(Graphics2D g, |
||
123 | 28367 | vcaballero | AffineTransform scaleInstance, Rectangle r, PrintRequestAttributeSet properties) throws SymbolDrawingException { |
124 | 20700 | vcaballero | int s = getFont().getSize();
|
125 | 24373 | vcaballero | |
126 | 21535 | vcaballero | if (autoresize) {
|
127 | if (s==0) { |
||
128 | s =1;
|
||
129 | setFontSize(s); |
||
130 | } |
||
131 | g.setFont(getFont()); |
||
132 | FontMetrics fm = g.getFontMetrics();
|
||
133 | Rectangle2D rect = fm.getStringBounds(text, g);
|
||
134 | double width = rect.getWidth();
|
||
135 | double height = rect.getHeight();
|
||
136 | double rWidth = r.getWidth();
|
||
137 | double rHeight = r.getHeight();
|
||
138 | double ratioText = width/height;
|
||
139 | double ratioRect = rWidth/rHeight;
|
||
140 | 23073 | vcaballero | |
141 | 21535 | vcaballero | if (ratioText>ratioRect) {
|
142 | s = (int) (s*(rWidth/width));
|
||
143 | } else {
|
||
144 | s = (int) (s*(rHeight/height));
|
||
145 | } |
||
146 | 24373 | vcaballero | setFontSize(s); |
147 | 21535 | vcaballero | } |
148 | 24373 | vcaballero | |
149 | 25764 | vcaballero | //Only for debugging purpose
|
150 | // g.drawRect((int)r.getX(), (int)r.getY(), (int)r.getWidth(), (int)r.getHeight());
|
||
151 | 28367 | vcaballero | if (properties==null) |
152 | 38563 | fpuga | draw(g, null, new FPoint2D(r.getX(), r.getY() + r.height), null); |
153 | 28367 | vcaballero | else
|
154 | 38563 | fpuga | print(g, new AffineTransform(), new FPoint2D(r.getX(), r.getY() + r.getHeight()), properties); |
155 | 24373 | vcaballero | |
156 | 10679 | jaume | } |
157 | |||
158 | public int getOnePointRgb() { |
||
159 | 10812 | jaume | return textColor.getRGB();
|
160 | 10679 | jaume | } |
161 | |||
162 | 18621 | jdominguez | public void getPixExtentPlus(FShape shp, float[] distances, |
163 | ViewPort viewPort, int dpi) {
|
||
164 | 10679 | jaume | throw new Error("Not yet implemented!"); |
165 | |||
166 | } |
||
167 | |||
168 | public ISymbol getSymbolForSelection() {
|
||
169 | return this; // a text is not selectable |
||
170 | } |
||
171 | |||
172 | public int getSymbolType() { |
||
173 | return FShape.TEXT;
|
||
174 | } |
||
175 | |||
176 | public XMLEntity getXMLEntity() {
|
||
177 | XMLEntity xml = new XMLEntity();
|
||
178 | xml.putProperty("className", getClassName());
|
||
179 | xml.putProperty("desc", getDescription());
|
||
180 | 10844 | jaume | xml.putProperty("isShapeVisible", isShapeVisible());
|
181 | 10679 | jaume | xml.putProperty("font", font.getName());
|
182 | xml.putProperty("fontStyle", font.getStyle());
|
||
183 | 10812 | jaume | xml.putProperty("size", font.getSize());
|
184 | 10679 | jaume | xml.putProperty("text", text);
|
185 | xml.putProperty("textColor", StringUtilities.color2String(textColor));
|
||
186 | 18621 | jdominguez | xml.putProperty("unit", getUnit());
|
187 | xml.putProperty("referenceSystem", getReferenceSystem());
|
||
188 | 21535 | vcaballero | xml.putProperty("autoresizeFlag", isAutoresizeEnabled());
|
189 | 10679 | jaume | return xml;
|
190 | } |
||
191 | |||
192 | public boolean isSuitableFor(IGeometry geom) { |
||
193 | return true; |
||
194 | } |
||
195 | |||
196 | public void setXMLEntity(XMLEntity xml) { |
||
197 | font = new Font(xml.getStringProperty("font"), |
||
198 | xml.getIntProperty("fontStyle"),
|
||
199 | xml.getIntProperty("size"));
|
||
200 | 10844 | jaume | setDescription(xml.getStringProperty("desc"));
|
201 | setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
|
||
202 | 10679 | jaume | text = xml.getStringProperty("text");
|
203 | textColor = StringUtilities.string2Color(xml.getStringProperty("textColor"));
|
||
204 | 18621 | jdominguez | setUnit(xml.getIntProperty("unit"));
|
205 | setReferenceSystem(xml.getIntProperty("referenceSystem"));
|
||
206 | 21535 | vcaballero | setAutoresizeEnabled(xml.getBooleanProperty("autoresizeFlag"));
|
207 | 25877 | vcaballero | this.bounds = null; |
208 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
209 | 10679 | jaume | } |
210 | |||
211 | public String getClassName() { |
||
212 | return getClass().getName();
|
||
213 | } |
||
214 | |||
215 | 28367 | vcaballero | public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties) { |
216 | this.properties=properties;
|
||
217 | draw(g, at, shape, null);
|
||
218 | this.properties=null; |
||
219 | 23499 | vcaballero | |
220 | 10679 | jaume | } |
221 | |||
222 | public String getText() { |
||
223 | return text;
|
||
224 | } |
||
225 | |||
226 | public Font getFont() { |
||
227 | return font;
|
||
228 | } |
||
229 | |||
230 | public Color getTextColor() { |
||
231 | return textColor;
|
||
232 | } |
||
233 | |||
234 | public void setText(String text) { |
||
235 | 25877 | vcaballero | if(text != null && !text.equals(this.text)){ |
236 | this.text = text;
|
||
237 | this.bounds = null; |
||
238 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
239 | 25877 | vcaballero | } |
240 | 10679 | jaume | } |
241 | |||
242 | public void setFont(Font font) { |
||
243 | 25877 | vcaballero | if (font != null && !font.equals(this.font)){ |
244 | this.font = font;
|
||
245 | this.bounds = null; |
||
246 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
247 | 25877 | vcaballero | } |
248 | 10679 | jaume | } |
249 | |||
250 | public void setTextColor(Color color) { |
||
251 | this.textColor = color;
|
||
252 | } |
||
253 | |||
254 | 10812 | jaume | public void setFontSize(double size) { |
255 | 25877 | vcaballero | if (size != this.font.getSize2D()){ |
256 | this.font = this.font.deriveFont((float) size); |
||
257 | this.bounds = null; |
||
258 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
259 | 25877 | vcaballero | } |
260 | 24373 | vcaballero | // this.font = new Font(this.font.getName(),this.font.getStyle(),(int)size);
|
261 | 10812 | jaume | } |
262 | |||
263 | 12999 | jvidal | /**
|
264 | * Defines the angle of rotation for the text that composes the symbol
|
||
265 | *
|
||
266 | * @param rotation
|
||
267 | */
|
||
268 | 10812 | jaume | public void setRotation(double rotation) { |
269 | 25877 | vcaballero | if(rotation != this.rotation){ |
270 | this.rotation = rotation;
|
||
271 | this.bounds = null; |
||
272 | } |
||
273 | 10812 | jaume | } |
274 | |||
275 | 23499 | vcaballero | public double getRotation() { |
276 | return rotation;
|
||
277 | } |
||
278 | |||
279 | 11509 | jaume | /**
|
280 | * Returns an FShape which represents a rectangle containing the text in
|
||
281 | * <b>screen</b> units.
|
||
282 | */
|
||
283 | 26986 | vcaballero | private FShape getHorizontalTextWrappingShape(FPoint2D p) {
|
284 | if (this.horizontalTextWrappingShape == null){ |
||
285 | Font font = getFont();
|
||
286 | /* Para tama?os de fuente de letras excesivamente grandes obtenemos
|
||
287 | * shapes con todas las coordenadas a 0, por eso limitamos el tama?o
|
||
288 | * a 1000 y despu?s reescalamos el bounds.
|
||
289 | */
|
||
290 | double scale = 1; |
||
291 | float fontSize = font.getSize2D();
|
||
292 | if (fontSize > 1000){ |
||
293 | scale = fontSize/1000;
|
||
294 | fontSize = 1000;
|
||
295 | } |
||
296 | font = font.deriveFont(fontSize); |
||
297 | GlyphVector gv = font.createGlyphVector(frc, text);
|
||
298 | Shape shape = gv.getOutline((float) p.getX(), (float) p.getY()); |
||
299 | FShape myFShape = new FPolygon2D(new GeneralPathX(shape.getBounds2D())); |
||
300 | |||
301 | if(scale != 1){ |
||
302 | myFShape.transform(AffineTransform.getScaleInstance(scale, scale));
|
||
303 | } |
||
304 | |||
305 | this.horizontalTextWrappingShape = myFShape;
|
||
306 | 25877 | vcaballero | } |
307 | 26986 | vcaballero | return this.horizontalTextWrappingShape; |
308 | } |
||
309 | 23073 | vcaballero | |
310 | 26986 | vcaballero | /**
|
311 | * Returns an FShape which represents a rectangle containing the text in
|
||
312 | * <b>screen</b> units.
|
||
313 | */
|
||
314 | public FShape getTextWrappingShape(FPoint2D p) {
|
||
315 | |||
316 | FShape myFShape = getHorizontalTextWrappingShape(p); |
||
317 | 18621 | jdominguez | myFShape.transform(AffineTransform.getTranslateInstance(p.getX(), p.getY()));
|
318 | 23073 | vcaballero | |
319 | 11509 | jaume | if (rotation != 0) { |
320 | 18621 | jdominguez | myFShape.transform(AffineTransform.getRotateInstance(rotation));
|
321 | 11509 | jaume | } |
322 | return myFShape;
|
||
323 | } |
||
324 | 23073 | vcaballero | |
325 | 18621 | jdominguez | public Rectangle getBounds() { |
326 | 20700 | vcaballero | // FontMetrics fm = g.getFontMetrics();
|
327 | // Rectangle2D rect = fm.getStringBounds("graphics", g);
|
||
328 | 23073 | vcaballero | |
329 | 25877 | vcaballero | if(this.bounds == null){ |
330 | this.bounds = getTextWrappingShape(new FPoint2D(0,0)).getBounds(); |
||
331 | } |
||
332 | return this.bounds; |
||
333 | 18621 | jdominguez | } |
334 | 11509 | jaume | |
335 | 18621 | jdominguez | public void setCartographicSize(double cartographicSize, FShape shp) { |
336 | setFontSize(cartographicSize); |
||
337 | } |
||
338 | |||
339 | public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) { |
||
340 | double oldSize = getFont().getSize();
|
||
341 | setCartographicSize(getCartographicSize( |
||
342 | viewPort, |
||
343 | dpi, |
||
344 | shp), |
||
345 | shp); |
||
346 | return oldSize;
|
||
347 | } |
||
348 | |||
349 | public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) { |
||
350 | return CartographicSupportToolkit.
|
||
351 | getCartographicLength(this,
|
||
352 | getFont().getSize(), |
||
353 | viewPort, |
||
354 | dpi); |
||
355 | } |
||
356 | 23073 | vcaballero | |
357 | 21535 | vcaballero | public boolean isAutoresizeEnabled() { |
358 | return autoresize;
|
||
359 | } |
||
360 | 23073 | vcaballero | |
361 | 21535 | vcaballero | public void setAutoresizeEnabled(boolean autoresizeFlag) { |
362 | this.autoresize = autoresizeFlag;
|
||
363 | } |
||
364 | 10679 | jaume | } |