Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.labeling.app / org.gvsig.labeling.app.mainplugin / src / main / java / org / gvsig / labeling / symbol / SmartTextSymbol.java @ 40911

History | View | Annotate | Download (19.8 KB)

1
package org.gvsig.labeling.symbol;
2

    
3
import java.awt.BasicStroke;
4
import java.awt.Color;
5
import java.awt.Font;
6
import java.awt.Graphics2D;
7
import java.awt.Rectangle;
8
import java.awt.RenderingHints;
9
import java.awt.Shape;
10
import java.awt.font.FontRenderContext;
11
import java.awt.font.GlyphVector;
12
import java.awt.font.LineMetrics;
13
import java.awt.geom.AffineTransform;
14

    
15
import org.gvsig.compat.print.PrintAttributes;
16
import org.gvsig.fmap.dal.feature.Feature;
17
import org.gvsig.fmap.geom.Geometry;
18
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
19
import org.gvsig.fmap.geom.Geometry.TYPES;
20
import org.gvsig.fmap.geom.GeometryLocator;
21
import org.gvsig.fmap.geom.GeometryManager;
22
import org.gvsig.fmap.geom.exception.CreateGeometryException;
23
import org.gvsig.fmap.geom.primitive.Envelope;
24
import org.gvsig.fmap.geom.primitive.GeneralPathX;
25
import org.gvsig.fmap.geom.primitive.Point;
26
import org.gvsig.fmap.geom.primitive.Surface;
27
import org.gvsig.fmap.mapcontext.MapContextLocator;
28
import org.gvsig.fmap.mapcontext.ViewPort;
29
import org.gvsig.fmap.mapcontext.rendering.legend.styling.IPlacementConstraints;
30
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
31
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
32
import org.gvsig.fmap.mapcontext.rendering.symbols.ITextSymbol;
33
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
34
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolPreferences;
35
import org.gvsig.labeling.placements.PointPlacementConstraints;
36
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.styling.TextPath;
37
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
38
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.dynobject.DynStruct;
41
import org.gvsig.tools.persistence.PersistenceManager;
42
import org.gvsig.tools.persistence.PersistentState;
43
import org.gvsig.tools.persistence.exception.PersistenceException;
44
import org.gvsig.tools.task.Cancellable;
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48

    
49
/**
50
 * Class used to create symbols composed using a text defined by
51
 * the user.This text can be edited (changing the color, the font of the characters, and
52
 * the rotation of the text)and has the property that can follow a path.If this path
53
 * does not exist, the text is treated as a simpletextsymbol (when is drawn).
54
 * @author   jaume dominguez faus - jaume.dominguez@iver.es
55
 */
56
public class SmartTextSymbol implements ISimpleTextSymbol, CartographicSupport {
57
        
58
        private static final Logger logger = LoggerFactory.getLogger(
59
                        SmartTextSymbol.class);
60
        // ===========================
61
        public static final String SMART_TEXT_SYMBOL_PERSISTENCE_DEFINITION_NAME =
62
                        "SMART_TEXT_SYMBOL_PERSISTENCE_DEFINITION_NAME";
63
        
64
        private static final String FIELD_UNIT = "unit";
65
        private static final String FIELD_REFERENCE_SYSTEM = "referenceSystem";
66
        private static final String FIELD_IS_SHAPE_VISIBLE = "isShapeVisible";
67
        private static final String FIELD_DESCRIPTION = "description";
68
        private static final String FIELD_TEXT = "text";
69
        private static final String FIELD_FONT = "font";
70
        private static final String FIELD_TEXT_COLOR = "textColor";
71
        private static final String FIELD_ROTATION = "rotation";
72
        private static final String FIELD_AUTO_RESIZE = "autoResize";
73
        // ====================================
74
        private static final String FIELD_HAS_HALO = "hasHalo";
75
        private static final String FIELD_HALO_COLOR = "haloColor";
76
        private static final String FIELD_HALO_WIDTH = "haloWidth";
77
        // ====================================
78
        public static final int SYMBOL_STYLE_TEXTALIGNMENT_LEFT = 0;
79
        public static final int SYMBOL_STYLE_TEXTALIGNMENT_RIGHT = 1;
80
        public static final int SYMBOL_STYLE_TEXTALIGNMENT_CENTERED = 2;
81

    
82
        // ===========================
83
        private static GeometryManager geoman = GeometryLocator.getGeometryManager();
84
        
85
        private String text;
86
        private FontRenderContext frc = new FontRenderContext(
87
                        new AffineTransform(), false, true);
88
        
89
        // Background: ITextBackground
90
//        Case
91
        private double characterSpacing;
92
        private double characterWidth;
93
//        Direction
94
        private IFillSymbol fillSymbol;
95
        private double flipAngle;
96
//        boolean kerning;
97
        private double leading;
98
//        Position: textPosition
99
        private Color ShadowColor;
100
        private double ShadowXOffset;
101
        private double ShadowYOffset;
102
//        TypeSetting: Boolean
103
        private double wordSpacing;
104
//        ISimpleTextSymbol : ITextSymbol
105
//        BreakCharacter: Long
106
//        Clip: Boolean
107
        private TextPath textPath;
108
        private double xOffset;
109
        private double yOffset;
110
        private double angle;
111
//        Color: IColor
112

    
113
//        HorizontalAlignment:
114
//        esriTextHorizontalAlignment
115
        private boolean rightToLeft;
116
        //        VerticalAlignment
117
        private double maskSize;
118
//        MaskStyle
119
        private  IFillSymbol maskSymbol;
120
        private double margin;
121
        private int alignment;
122
        private boolean kerning = false;
123
        private TextPath tp;
124
        private IPlacementConstraints constraints;
125
        
126
        private boolean shapeVisible = true;
127
        private int unit = -1;
128
        private int referenceSystem = CartographicSupport.WORLD;
129
        private double rotation = 0;
130
        private String desc = "";
131
        private Color textColor = Color.BLACK;
132
        private Font font;
133
        private boolean autoresize = false;
134
        
135
        // =======================
136
        
137
        private boolean hasHalo = false;
138
        private Color haloColor = Color.WHITE;
139
        private float haloWidth = 3;
140
        private BasicStroke haloStroke = new BasicStroke(
141
                        6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
142
        
143
        // =======================
144
        
145

    
146
        public SmartTextSymbol(ITextSymbol sym, IPlacementConstraints constraints) {
147

    
148
//                if(sym instanceof SimpleTextSymbol){
149
//                        SimpleTextSymbol mySym = (SimpleTextSymbol)sym;
150

    
151
                        this.setAutoresizeEnabled(sym.isAutoresizeEnabled());
152
                        this.setDescription(sym.getDescription());
153
                        this.setFont(sym.getFont());
154
                        this.setFontSize(sym.getFont().getSize());
155
                        this.setIsShapeVisible(sym.isShapeVisible());
156
                        this.setText(sym.getText());
157
                        this.setTextColor(sym.getTextColor());
158
                        
159
                        this.setDrawWithHalo(sym.isDrawWithHalo());
160
                        this.setHaloColor(sym.getHaloColor());
161
                        this.setHaloWidth(sym.getHaloWidth());
162
                        
163
                        this.constraints = constraints;
164

    
165
                        setCharacterSpacing(2); //???
166
                        setWordSpacing(TextPath.DEFAULT_WORD_SPACING);
167
                        boolean rtl = false; // right to left text
168
                        if (constraints.isAtTheBeginingOfLine()) {
169
                                if (rtl) {
170
                                        setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_RIGHT);
171
                                }
172
                                else {
173
                                        setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_LEFT);
174
                                }
175
                        }
176
                        else if (constraints.isAtTheEndOfLine()) {
177
                                if (rtl) {
178
                                        setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_LEFT);
179
                                }
180
                                else {
181
                                        setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_RIGHT);
182
                                }
183
                        }
184
                        else { //constraints.isInTheMiddleOfLine() or constraints.isAtBestOfLine()
185
                                setAlignment(SYMBOL_STYLE_TEXTALIGNMENT_CENTERED);
186
                        }
187
                        setKerning(false);
188
                        setRightToLeft(rtl);
189
                // }
190
        }
191
        
192
        
193
        public void setIsShapeVisible(boolean v) {
194
                this.shapeVisible = v;
195
        }
196
        
197
        public boolean isShapeVisible() {
198
                return shapeVisible;
199
        }
200
        
201

    
202

    
203
        public SmartTextSymbol() {
204
                PointPlacementConstraints pc = new PointPlacementConstraints();
205
                this.constraints = pc;
206
                
207
                SymbolPreferences preferences =
208
                                MapContextLocator.getSymbolManager().getSymbolPreferences();
209
                font = preferences.getDefaultSymbolFont();
210
                textColor = preferences.getDefaultSymbolColor();
211
        }
212

    
213
        /**
214
         * Draws the text according. If this symbol has the text path set, then
215
         * it is used as the text line, otherwise shp <b>must be an FPoint2D</b>
216
         * indicating the starting point of the text and then the text will
217
         * be rendered from there and following the rotation previously set.
218
         */
219
        
220
        public void draw(Graphics2D g, AffineTransform affineTransform,
221
                        Geometry geom, Feature f, Cancellable cancel) {
222
        
223
                if (!isShapeVisible()) return;
224

    
225
                setMargin(0);
226

    
227

    
228
                char[] text_chars = text.toCharArray();
229
                tp = new TextPath(g, geom, text_chars, getFont(),
230
                                (float) characterSpacing, (float) characterWidth, kerning,
231
                                (float) leading, alignment, (float) wordSpacing, (float) margin, rightToLeft);
232
                Font font = getFont();
233
                g.setFont(font);
234
                FontRenderContext frc = g.getFontRenderContext();
235
                LineMetrics lineMetrics = font.getLineMetrics(getText(), frc);
236
                
237
//                GlyphVector glyph =  font.layoutGlyphVector(frc, charText, 0, charText.length, Font.LAYOUT_NO_START_CONTEXT);
238
                double cons = 0;
239

    
240
                /* Repartimos el leading (espacio de separaci?n entre lineas)
241
                 * arriba y abajo para que exista la misma separaci?n entre la
242
                 * caja de la letra y la linea tanto si se dibuja por abajo como
243
                 * si se dibuja por arriba. 
244
                 */
245
                if(this.constraints.isAboveTheLine()) {
246
                        cons = lineMetrics.getDescent()+lineMetrics.getLeading()/2;
247
                }
248
                else if (this.constraints.isBelowTheLine()) {
249
                        cons = -(lineMetrics.getAscent()+lineMetrics.getLeading()/2);
250
                }
251
                /* Dibujamos la letra de tal manera que el centro de la caja de letra
252
                 * coincida con la linea
253
                 */
254
                else if(this.constraints.isOnTheLine()) {
255
//                        cons = lineMetrics.getDescent()+(lineMetrics.getLeading()/2)-(lineMetrics.getHeight()/2);
256
                        cons = lineMetrics.getDescent()+lineMetrics.getLeading()-(lineMetrics.getHeight()/2);
257
                }
258
                
259
                double[] coords = tp.nextPosForGlyph(0);
260

    
261
                for (int i = 0; i < tp.getGlyphCount(); i++) {
262
                        coords = tp.nextPosForGlyph(i);
263
                        if (coords[0] == TextPath.NO_POS || coords[1] == TextPath.NO_POS)
264
                                continue;
265

    
266
                        // move the label 'cons" units above/below the line
267
                        double xOffset = cons * Math.sin(coords[2]);
268
                        double yOffset = cons * Math.cos(coords[2]);
269

    
270
                        g.translate(coords[0]+xOffset, coords[1]-yOffset);
271
                        g.rotate(coords[2]);
272

    
273
                        char[] aux = new char[1];
274
                        aux[0] = text_chars[i];
275
                        if (isDrawWithHalo()) {
276
                                GlyphVector glyph = font.createGlyphVector(frc, aux);
277
                                Shape outlineChar = glyph.getOutline();
278
                                g.setStroke(haloStroke);
279
                                g.setColor(getHaloColor());
280
                                
281
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
282
                                                RenderingHints.VALUE_ANTIALIAS_ON);
283
                                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
284
                                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
285
                                // =============================
286
                                g.draw(outlineChar);
287
                                // =============================
288
                                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
289
                                                RenderingHints.VALUE_ANTIALIAS_OFF);
290
                        }
291
                        
292
                        g.setColor(this.getTextColor());
293
                        g.drawString(String.valueOf(text_chars[i]), 0, 0);
294
                        g.rotate(-coords[2]);
295
                        g.translate(-coords[0]-xOffset, -coords[1]+yOffset);
296
                }
297
        }
298

    
299
        public void getPixExtentPlus(
300
                        Geometry shp, float[] distances, ViewPort viewPort, int dpi) {
301
                
302
                /*
303
                 * TODO Is this used?
304
                 */
305
                distances[0] = 0;
306
                distances[1] = 0;
307
                // throw new RuntimeException("Not yet implemented!");
308
        }
309

    
310
        public int getOnePointRgb() {
311
                return getTextColor().getRGB();
312
        }
313

    
314
        /*
315
        public XMLEntity getXMLEntity() {
316
                XMLEntity xml = new XMLEntity();
317
                xml.putProperty("className", getClassName());
318
                xml.putProperty("desc", getDescription());
319
                xml.putProperty("isShapeVisible", isShapeVisible());
320
                return xml;
321
        }
322
        */
323

    
324
        public int getSymbolType() {
325
                return Geometry.TYPES.GEOMETRY;
326
        }
327

    
328
        public boolean isSuitableFor(Geometry geom) {
329
                return geom.getGeometryType().isTypeOf(TYPES.CURVE);
330
        }
331
        
332
        public void drawInsideRectangle(
333
                        Graphics2D g,
334
                        AffineTransform scaleInstance,
335
                        Rectangle r,
336
                        PrintAttributes properties) throws SymbolDrawingException {
337
                // let's take the bottom segment of the rectangle as the line
338
                
339
                Surface surf = null;
340
                try {
341
                        surf = geoman.createSurface(SUBTYPES.GEOM2D);
342
                } catch (CreateGeometryException e) {
343
                        logger.info("Error while creating surface.", e);
344
                        throw new SymbolDrawingException(
345
                                        SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
346
                }
347
                surf.addVertex(r.getX(), r.getY());
348
                surf.addVertex(r.getX() + r.getWidth(), r.getY());
349
                
350
                if (properties == null) {
351
                        draw(g, scaleInstance, surf, null, null);
352
                } else {
353
                        print(g, scaleInstance, surf, properties);
354
                }
355
        }
356

    
357

    
358
        /*
359
        public void setXMLEntity(XMLEntity xml) {
360
                setFont(new Font("Arial", Font.PLAIN, 18));
361
                setText("this is my TEST text that follows a line");
362
                setDescription(xml.getStringProperty("desc"));
363
                setIsShapeVisible(xml.getBooleanProperty("isShapeVisible"));
364

365
        }
366
        */
367

    
368
        public void setText(String txt) {
369
                this.text = txt;
370
        }
371

    
372
        public String getText() {
373
                return text;
374
        }
375

    
376
        public void setCharacterSpacing(double charSpacing) {
377
                this.characterSpacing = charSpacing;
378
        }
379

    
380
        public void setWordSpacing(double wordSpacing) {
381
                this.wordSpacing = wordSpacing;
382
        }
383

    
384
        public void setAlignment(int alignment) {
385
                this.alignment = alignment;
386
        }
387

    
388
        public void setKerning(boolean kerning) {
389
                this.kerning = kerning;
390
        }
391

    
392
        public void setMargin(double margin) {
393
                this.margin = margin;
394
        }
395

    
396
        public void setRightToLeft(boolean rightToLeft) {
397
                this.rightToLeft = rightToLeft;
398
        }
399
        
400
        // ==============================================
401
        // ==============================================
402
        // ==============================================
403

    
404
        
405
        public ISymbol getSymbolForSelection() {
406
                return this;
407
        }
408

    
409
        public boolean isOneDotOrPixel(Geometry geom,
410
                        double[] positionOfDotOrPixel, ViewPort viewPort, int dpi) {
411
                
412
                int type = geom.getType();
413
                switch (type) {
414
                case Geometry.TYPES.NULL:
415
                case Geometry.TYPES.POINT:
416
                case Geometry.TYPES.MULTIPOINT:
417
                        return false;
418
                default:
419
                        Envelope geomBounds = geom.getEnvelope();
420
                        double dist1Pixel = viewPort.getDist1pixel();
421

    
422
                        float[] distances = new float[2];
423
                        this.getPixExtentPlus(geom, distances, viewPort, dpi);
424

    
425
                        boolean onePoint =
426
                                        ((geomBounds.getLength(0) + distances[0] <= dist1Pixel)
427
                                        && (geomBounds.getLength(1) + distances[1] <= dist1Pixel));
428

    
429
                        if (onePoint) {
430
                                positionOfDotOrPixel[0] = geomBounds.getMinimum(0);
431
                                positionOfDotOrPixel[1] = geomBounds.getMinimum(1);
432
                        }
433
                        return onePoint;
434
                }
435
        }
436
        
437

    
438

    
439
        public String getDescription() {
440
                return desc;
441
        }
442

    
443

    
444
        public void setDescription(String d) {
445
                desc = d;
446
        }
447

    
448

    
449
        public Color getColor() {
450
                return this.getTextColor();
451
        }
452

    
453

    
454
        public void setColor(Color color) {
455
                this.setTextColor(color);
456
        }
457

    
458

    
459
        public void print(Graphics2D g, AffineTransform at, Geometry geom,
460
                        PrintAttributes properties) {
461
                
462
                /*
463
                 * TODO Use properties
464
                 * (perhaps when using things of CartographicSupport)
465
                 */
466
                this.draw(g,  at, geom, null, null);
467
        }
468

    
469

    
470
        public void setFont(Font fnt) {
471
                this.font = fnt;
472
        }
473

    
474

    
475
        public Font getFont() {
476
                return font;
477
        }
478

    
479

    
480
        public Color getTextColor() {
481
                return this.textColor;
482
        }
483

    
484

    
485
        public void setTextColor(Color color) {
486
                this.textColor = color;
487
        }
488

    
489

    
490
        public void setFontSize(double d) {
491
                Font newFont = new Font(
492
                                font.getName(),
493
                                font.getStyle(),
494
                                Math.round((float) d));
495
                this.font = newFont;                
496
        }
497

    
498

    
499
        public Geometry getTextWrappingShape(Point p) {
500
                
501
                Font font = getFont();
502
                GlyphVector gv = font.createGlyphVector(frc, text);
503

    
504
                Shape shape = gv.getOutline((float) p.getX(), (float) p.getY());
505
                Geometry myFShape;
506
                try {
507
                        myFShape = geoman.createSurface(new GeneralPathX(shape
508
                                        .getBounds2D().getPathIterator(null)), SUBTYPES.GEOM2D);
509
                        myFShape.transform(AffineTransform.getTranslateInstance(p.getX(), p.getY()));
510

    
511
                        if (rotation != 0) {
512
                                myFShape.transform(AffineTransform.getRotateInstance(rotation));
513
                        }
514
                        return myFShape;
515
                } catch (CreateGeometryException e) {
516
                        logger.error("Error creating a surface", e);
517
                }
518
                return null;
519
        }
520

    
521

    
522
        public Rectangle getBounds() {
523
                
524
                Rectangle bounds = null;
525
                try {
526
                        Geometry aux = getTextWrappingShape(geoman.createPoint(0,0, SUBTYPES.GEOM2D));
527
                        Envelope env = aux.getEnvelope();
528
                        bounds = new Rectangle(
529
                                        (int) env.getMinimum(0),
530
                                        (int) env.getMinimum(1),
531
                                        (int) env.getLength(0),
532
                                        (int) env.getLength(1));
533
                } catch (CreateGeometryException e) {
534
                        logger.error("Error creating a point", e);
535
                }
536
                return bounds;
537
        }
538

    
539
        public double getRotation() {
540
                return this.rotation;
541
        }
542

    
543

    
544
        public void setRotation(double rot) {
545
                this.rotation = rot;
546
        }
547

    
548
        public void setAutoresizeEnabled(boolean ar) {
549
                autoresize = ar;
550
        }
551

    
552

    
553
        public boolean isAutoresizeEnabled() {
554
                return autoresize;
555
        }
556

    
557

    
558
        public Color getHaloColor() {
559
                return this.haloColor;
560
        }
561

    
562

    
563
        public void setHaloColor(Color co) {
564
                this.haloColor = co;
565
        }
566

    
567

    
568
        public float getHaloWidth() {
569
                return this.haloWidth;
570
        }
571

    
572

    
573
        public void setHaloWidth(float w) {
574
                this.haloWidth = w;
575
                this.haloStroke = new BasicStroke(
576
                                2*haloWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
577
        }
578

    
579

    
580
        public boolean isDrawWithHalo() {
581
                return this.hasHalo;
582
        }
583

    
584

    
585
        public void setDrawWithHalo(boolean h) {
586
                this.hasHalo = h;
587
        }
588

    
589
        // ==============================
590

    
591

    
592
        public void setUnit(int unitIndex) {
593
                unit = unitIndex;
594
        }
595

    
596

    
597
        public int getUnit() {
598
                return unit;
599
        }
600

    
601

    
602
        public int getReferenceSystem() {
603
                return this.referenceSystem;
604
        }
605

    
606

    
607
        public void setReferenceSystem(int rs) {
608
                this.referenceSystem = rs;
609
        }
610

    
611

    
612
        public void setCartographicSize(double cartographicSize, Geometry geom) {
613
                setFontSize(cartographicSize);
614
        }
615

    
616
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
617
                double oldSize = getFont().getSize();
618
                setCartographicSize(getCartographicSize(viewPort, dpi, geom), geom);
619
                return oldSize;
620
        }
621

    
622
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
623
                return SymbolUtils.        getCartographicLength(
624
                                this, getFont().getSize(), viewPort, dpi);
625
        }
626

    
627
        // ========================
628
        
629
        public Object clone() throws CloneNotSupportedException {
630
                return super.clone();
631
        }
632
        
633
        // ==========================
634
        
635
        public static void registerPersistent() {
636
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
637
                if( manager.getDefinition(SMART_TEXT_SYMBOL_PERSISTENCE_DEFINITION_NAME)==null ) {
638
                        DynStruct definition = manager.addDefinition(
639
                                        SmartTextSymbol.class,
640
                                        SMART_TEXT_SYMBOL_PERSISTENCE_DEFINITION_NAME,
641
                                        SMART_TEXT_SYMBOL_PERSISTENCE_DEFINITION_NAME+" Persistence definition",
642
                                        null, 
643
                                        null
644
                        );
645
                        
646
                        definition.addDynFieldString(FIELD_DESCRIPTION).setMandatory(true);
647
                        definition.addDynFieldBoolean(FIELD_IS_SHAPE_VISIBLE).setMandatory(true);
648
                        definition.addDynFieldInt(FIELD_REFERENCE_SYSTEM).setMandatory(true);
649
                        definition.addDynFieldInt(FIELD_UNIT).setMandatory(true);
650
                        definition.addDynFieldBoolean(FIELD_AUTO_RESIZE).setMandatory(true);
651
                        definition.addDynFieldObject(FIELD_FONT).setClassOfValue(Font.class).setMandatory(true);
652
                        definition.addDynFieldDouble(FIELD_ROTATION).setMandatory(true);
653
                        definition.addDynFieldString(FIELD_TEXT).setMandatory(true);
654
                        definition.addDynFieldObject(FIELD_TEXT_COLOR).setClassOfValue(Color.class).setMandatory(true);
655
                        // halo
656
                        definition.addDynFieldBoolean(FIELD_HAS_HALO).setMandatory(true);
657
                        definition.addDynFieldObject(FIELD_HALO_COLOR).setClassOfValue(
658
                                        Color.class).setMandatory(true);
659
                        definition.addDynFieldFloat(FIELD_HALO_WIDTH).setMandatory(true);
660
                }
661
                
662
        }
663
        
664
        public void loadFromState(PersistentState state)
665
                        throws PersistenceException {
666
                setDescription(state.getString(FIELD_DESCRIPTION));
667
                setIsShapeVisible(state.getBoolean(FIELD_IS_SHAPE_VISIBLE));
668
                setReferenceSystem(state.getInt(FIELD_REFERENCE_SYSTEM));
669
                setUnit(state.getInt(FIELD_UNIT));
670
                
671
                setAutoresizeEnabled(state.getBoolean(FIELD_AUTO_RESIZE));
672
                setFont((Font) state.get(FIELD_FONT));
673
                setRotation(state.getDouble(FIELD_ROTATION));
674
                setText(state.getString(FIELD_TEXT));
675
                setTextColor((Color) state.get(FIELD_TEXT_COLOR));
676
                // halo
677
                this.setDrawWithHalo(state.getBoolean(FIELD_HAS_HALO));
678
                this.setHaloColor((Color) state.get(FIELD_HALO_COLOR));
679
                this.setHaloWidth(state.getFloat(FIELD_HALO_WIDTH));
680
        }
681

    
682
        public void saveToState(PersistentState state) throws PersistenceException {
683
                state.set(FIELD_DESCRIPTION, getDescription());
684
                state.set(FIELD_IS_SHAPE_VISIBLE, isShapeVisible());
685
                state.set(FIELD_REFERENCE_SYSTEM, getReferenceSystem());
686
                state.set(FIELD_UNIT, getUnit());
687
                
688
                state.set(FIELD_AUTO_RESIZE, isAutoresizeEnabled());
689
                state.set(FIELD_FONT, getFont());
690
                state.set(FIELD_ROTATION, getRotation());
691
                state.set(FIELD_TEXT, getText());
692
                state.set(FIELD_TEXT_COLOR, getTextColor());
693
                // halo
694
                state.set(FIELD_HAS_HALO, this.isDrawWithHalo());
695
                state.set(FIELD_HALO_COLOR, this.getHaloColor());
696
                state.set(FIELD_HALO_WIDTH, this.getHaloWidth());
697
        }
698

    
699

    
700

    
701

    
702

    
703
}