svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / core / symbols / SimpleTextSymbol.java @ 28367
History | View | Annotate | Download (10.8 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 | 20700 | vcaballero | g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
94 | 10812 | jaume | g.setColor(textColor); |
95 | 28367 | vcaballero | float size=font.getSize2D();
|
96 | if (properties!=null){ |
||
97 | PrintQuality pq = (PrintQuality) properties.get(PrintQuality.class); |
||
98 | if (pq.equals(PrintQuality.NORMAL)){ |
||
99 | size *= (float) 300/72; |
||
100 | }else if (pq.equals(PrintQuality.HIGH)){ |
||
101 | size *= (float) 600/72; |
||
102 | }else if (pq.equals(PrintQuality.DRAFT)){ |
||
103 | // unitFactor *= 72; (which is the same than doing nothing)
|
||
104 | } |
||
105 | font=font.deriveFont(size); |
||
106 | } |
||
107 | 10812 | jaume | g.setFont(font); |
108 | 20700 | vcaballero | g.translate(((FPoint2D) shp).getX(), ((FPoint2D) shp).getY()); |
109 | 10812 | jaume | |
110 | 20700 | vcaballero | g.rotate(rotation); |
111 | 26986 | vcaballero | Rectangle2D bounds = getHorizontalTextWrappingShape(new FPoint2D(0,0)).getBounds(); |
112 | // Antes tomabamos el resultado de getBounds pero ya se le hab?a aplicado
|
||
113 | // la rotaci?n, con lo que no obten?amos el la altura correcta de la fuente.
|
||
114 | |||
115 | // Alineamos el texto de manera que la parte superior
|
||
116 | // izquierda de la primera letra est? en (0,0).
|
||
117 | g.drawString(getText(), 0, (int)-bounds.getY()); |
||
118 | 28367 | vcaballero | if (properties!=null){ |
119 | font=font.deriveFont(size); |
||
120 | g.setFont(font); |
||
121 | } |
||
122 | 20700 | vcaballero | g.rotate(-rotation); |
123 | g.translate(-((FPoint2D) shp).getX(), -((FPoint2D) shp).getY()); |
||
124 | 10679 | jaume | } |
125 | |||
126 | public void drawInsideRectangle(Graphics2D g, |
||
127 | 28367 | vcaballero | AffineTransform scaleInstance, Rectangle r, PrintRequestAttributeSet properties) throws SymbolDrawingException { |
128 | 20700 | vcaballero | int s = getFont().getSize();
|
129 | 24373 | vcaballero | |
130 | 21535 | vcaballero | if (autoresize) {
|
131 | if (s==0) { |
||
132 | s =1;
|
||
133 | setFontSize(s); |
||
134 | } |
||
135 | g.setFont(getFont()); |
||
136 | FontMetrics fm = g.getFontMetrics();
|
||
137 | Rectangle2D rect = fm.getStringBounds(text, g);
|
||
138 | double width = rect.getWidth();
|
||
139 | double height = rect.getHeight();
|
||
140 | double rWidth = r.getWidth();
|
||
141 | double rHeight = r.getHeight();
|
||
142 | double ratioText = width/height;
|
||
143 | double ratioRect = rWidth/rHeight;
|
||
144 | 23073 | vcaballero | |
145 | 21535 | vcaballero | if (ratioText>ratioRect) {
|
146 | s = (int) (s*(rWidth/width));
|
||
147 | } else {
|
||
148 | s = (int) (s*(rHeight/height));
|
||
149 | } |
||
150 | 24373 | vcaballero | setFontSize(s); |
151 | 21535 | vcaballero | } |
152 | 24373 | vcaballero | |
153 | 25764 | vcaballero | //Only for debugging purpose
|
154 | // g.drawRect((int)r.getX(), (int)r.getY(), (int)r.getWidth(), (int)r.getHeight());
|
||
155 | 28367 | vcaballero | if (properties==null) |
156 | draw(g, null, new FPoint2D(r.getX(), r.getY()), null); |
||
157 | else
|
||
158 | print(g, new AffineTransform(), new FPoint2D(r.getX(), r.getY()), properties); |
||
159 | 24373 | vcaballero | |
160 | 10679 | jaume | } |
161 | |||
162 | public int getOnePointRgb() { |
||
163 | 10812 | jaume | return textColor.getRGB();
|
164 | 10679 | jaume | } |
165 | |||
166 | 18621 | jdominguez | public void getPixExtentPlus(FShape shp, float[] distances, |
167 | ViewPort viewPort, int dpi) {
|
||
168 | 10679 | jaume | throw new Error("Not yet implemented!"); |
169 | |||
170 | } |
||
171 | |||
172 | public ISymbol getSymbolForSelection() {
|
||
173 | return this; // a text is not selectable |
||
174 | } |
||
175 | |||
176 | public int getSymbolType() { |
||
177 | return FShape.TEXT;
|
||
178 | } |
||
179 | |||
180 | public XMLEntity getXMLEntity() {
|
||
181 | XMLEntity xml = new XMLEntity();
|
||
182 | xml.putProperty("className", getClassName());
|
||
183 | xml.putProperty("desc", getDescription());
|
||
184 | 10844 | jaume | xml.putProperty("isShapeVisible", isShapeVisible());
|
185 | 10679 | jaume | xml.putProperty("font", font.getName());
|
186 | xml.putProperty("fontStyle", font.getStyle());
|
||
187 | 10812 | jaume | xml.putProperty("size", font.getSize());
|
188 | 10679 | jaume | xml.putProperty("text", text);
|
189 | xml.putProperty("textColor", StringUtilities.color2String(textColor));
|
||
190 | 18621 | jdominguez | xml.putProperty("unit", getUnit());
|
191 | xml.putProperty("referenceSystem", getReferenceSystem());
|
||
192 | 21535 | vcaballero | xml.putProperty("autoresizeFlag", isAutoresizeEnabled());
|
193 | 10679 | jaume | return xml;
|
194 | } |
||
195 | |||
196 | public boolean isSuitableFor(IGeometry geom) { |
||
197 | return true; |
||
198 | } |
||
199 | |||
200 | public void setXMLEntity(XMLEntity xml) { |
||
201 | font = new Font(xml.getStringProperty("font"), |
||
202 | xml.getIntProperty("fontStyle"),
|
||
203 | xml.getIntProperty("size"));
|
||
204 | 10844 | jaume | setDescription(xml.getStringProperty("desc"));
|
205 | setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
|
||
206 | 10679 | jaume | text = xml.getStringProperty("text");
|
207 | textColor = StringUtilities.string2Color(xml.getStringProperty("textColor"));
|
||
208 | 18621 | jdominguez | setUnit(xml.getIntProperty("unit"));
|
209 | setReferenceSystem(xml.getIntProperty("referenceSystem"));
|
||
210 | 21535 | vcaballero | setAutoresizeEnabled(xml.getBooleanProperty("autoresizeFlag"));
|
211 | 25877 | vcaballero | this.bounds = null; |
212 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
213 | 10679 | jaume | } |
214 | |||
215 | public String getClassName() { |
||
216 | return getClass().getName();
|
||
217 | } |
||
218 | |||
219 | 28367 | vcaballero | public void print(Graphics2D g, AffineTransform at, FShape shape, PrintRequestAttributeSet properties) { |
220 | this.properties=properties;
|
||
221 | draw(g, at, shape, null);
|
||
222 | this.properties=null; |
||
223 | 23499 | vcaballero | |
224 | 10679 | jaume | } |
225 | |||
226 | public String getText() { |
||
227 | return text;
|
||
228 | } |
||
229 | |||
230 | public Font getFont() { |
||
231 | return font;
|
||
232 | } |
||
233 | |||
234 | public Color getTextColor() { |
||
235 | return textColor;
|
||
236 | } |
||
237 | |||
238 | public void setText(String text) { |
||
239 | 25877 | vcaballero | if(text != null && !text.equals(this.text)){ |
240 | this.text = text;
|
||
241 | this.bounds = null; |
||
242 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
243 | 25877 | vcaballero | } |
244 | 10679 | jaume | } |
245 | |||
246 | public void setFont(Font font) { |
||
247 | 25877 | vcaballero | if (font != null && !font.equals(this.font)){ |
248 | this.font = font;
|
||
249 | this.bounds = null; |
||
250 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
251 | 25877 | vcaballero | } |
252 | 10679 | jaume | } |
253 | |||
254 | public void setTextColor(Color color) { |
||
255 | this.textColor = color;
|
||
256 | } |
||
257 | |||
258 | 10812 | jaume | public void setFontSize(double size) { |
259 | 25877 | vcaballero | if (size != this.font.getSize2D()){ |
260 | this.font = this.font.deriveFont((float) size); |
||
261 | this.bounds = null; |
||
262 | 26986 | vcaballero | this.horizontalTextWrappingShape = null; |
263 | 25877 | vcaballero | } |
264 | 24373 | vcaballero | // this.font = new Font(this.font.getName(),this.font.getStyle(),(int)size);
|
265 | 10812 | jaume | } |
266 | |||
267 | 12999 | jvidal | /**
|
268 | * Defines the angle of rotation for the text that composes the symbol
|
||
269 | *
|
||
270 | * @param rotation
|
||
271 | */
|
||
272 | 10812 | jaume | public void setRotation(double rotation) { |
273 | 25877 | vcaballero | if(rotation != this.rotation){ |
274 | this.rotation = rotation;
|
||
275 | this.bounds = null; |
||
276 | } |
||
277 | 10812 | jaume | } |
278 | |||
279 | 23499 | vcaballero | public double getRotation() { |
280 | return rotation;
|
||
281 | } |
||
282 | |||
283 | 11509 | jaume | /**
|
284 | * Returns an FShape which represents a rectangle containing the text in
|
||
285 | * <b>screen</b> units.
|
||
286 | */
|
||
287 | 26986 | vcaballero | private FShape getHorizontalTextWrappingShape(FPoint2D p) {
|
288 | if (this.horizontalTextWrappingShape == null){ |
||
289 | Font font = getFont();
|
||
290 | /* Para tama?os de fuente de letras excesivamente grandes obtenemos
|
||
291 | * shapes con todas las coordenadas a 0, por eso limitamos el tama?o
|
||
292 | * a 1000 y despu?s reescalamos el bounds.
|
||
293 | */
|
||
294 | double scale = 1; |
||
295 | float fontSize = font.getSize2D();
|
||
296 | if (fontSize > 1000){ |
||
297 | scale = fontSize/1000;
|
||
298 | fontSize = 1000;
|
||
299 | } |
||
300 | font = font.deriveFont(fontSize); |
||
301 | GlyphVector gv = font.createGlyphVector(frc, text);
|
||
302 | Shape shape = gv.getOutline((float) p.getX(), (float) p.getY()); |
||
303 | FShape myFShape = new FPolygon2D(new GeneralPathX(shape.getBounds2D())); |
||
304 | |||
305 | if(scale != 1){ |
||
306 | myFShape.transform(AffineTransform.getScaleInstance(scale, scale));
|
||
307 | } |
||
308 | |||
309 | this.horizontalTextWrappingShape = myFShape;
|
||
310 | 25877 | vcaballero | } |
311 | 26986 | vcaballero | return this.horizontalTextWrappingShape; |
312 | } |
||
313 | 23073 | vcaballero | |
314 | 26986 | vcaballero | /**
|
315 | * Returns an FShape which represents a rectangle containing the text in
|
||
316 | * <b>screen</b> units.
|
||
317 | */
|
||
318 | public FShape getTextWrappingShape(FPoint2D p) {
|
||
319 | |||
320 | FShape myFShape = getHorizontalTextWrappingShape(p); |
||
321 | 18621 | jdominguez | myFShape.transform(AffineTransform.getTranslateInstance(p.getX(), p.getY()));
|
322 | 23073 | vcaballero | |
323 | 11509 | jaume | if (rotation != 0) { |
324 | 18621 | jdominguez | myFShape.transform(AffineTransform.getRotateInstance(rotation));
|
325 | 11509 | jaume | } |
326 | return myFShape;
|
||
327 | } |
||
328 | 23073 | vcaballero | |
329 | 18621 | jdominguez | public Rectangle getBounds() { |
330 | 20700 | vcaballero | // FontMetrics fm = g.getFontMetrics();
|
331 | // Rectangle2D rect = fm.getStringBounds("graphics", g);
|
||
332 | 23073 | vcaballero | |
333 | 25877 | vcaballero | if(this.bounds == null){ |
334 | this.bounds = getTextWrappingShape(new FPoint2D(0,0)).getBounds(); |
||
335 | } |
||
336 | return this.bounds; |
||
337 | 18621 | jdominguez | } |
338 | 11509 | jaume | |
339 | 18621 | jdominguez | public void setCartographicSize(double cartographicSize, FShape shp) { |
340 | setFontSize(cartographicSize); |
||
341 | } |
||
342 | |||
343 | public double toCartographicSize(ViewPort viewPort, double dpi, FShape shp) { |
||
344 | double oldSize = getFont().getSize();
|
||
345 | setCartographicSize(getCartographicSize( |
||
346 | viewPort, |
||
347 | dpi, |
||
348 | shp), |
||
349 | shp); |
||
350 | return oldSize;
|
||
351 | } |
||
352 | |||
353 | public double getCartographicSize(ViewPort viewPort, double dpi, FShape shp) { |
||
354 | return CartographicSupportToolkit.
|
||
355 | getCartographicLength(this,
|
||
356 | getFont().getSize(), |
||
357 | viewPort, |
||
358 | dpi); |
||
359 | } |
||
360 | 23073 | vcaballero | |
361 | 21535 | vcaballero | public boolean isAutoresizeEnabled() { |
362 | return autoresize;
|
||
363 | } |
||
364 | 23073 | vcaballero | |
365 | 21535 | vcaballero | public void setAutoresizeEnabled(boolean autoresizeFlag) { |
366 | this.autoresize = autoresizeFlag;
|
||
367 | } |
||
368 | 10679 | jaume | } |