4070adac2b906c5fafff7705b9871972685708dc
[scilab.git] / scilab / modules / renderer / src / java / org / scilab / modules / renderer / JoGLView / mark / MarkSpriteFactory.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009-2010 - DIGITEO - Pierre Lando
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  */
11
12 package org.scilab.modules.renderer.JoGLView.mark;
13
14 import org.scilab.forge.scirenderer.shapes.appearance.Appearance;
15 import org.scilab.forge.scirenderer.shapes.appearance.Color;
16 import org.scilab.forge.scirenderer.texture.Texture;
17 import org.scilab.forge.scirenderer.texture.TextureDrawer;
18 import org.scilab.forge.scirenderer.texture.TextureDrawingTools;
19 import org.scilab.forge.scirenderer.texture.TextureManager;
20 import org.scilab.modules.graphic_objects.contouredObject.Mark;
21 import org.scilab.modules.graphic_objects.figure.ColorMap;
22 import org.scilab.modules.renderer.JoGLView.util.ColorFactory;
23
24 import java.awt.Dimension;
25
26 /**
27  * @author Pierre Lando
28  */
29 public class MarkSpriteFactory {
30
31     /**
32      * Return a mark sprite corresponding to the given scilab mark.
33      *
34      *
35      * @param spriteManager the current sprite manager.
36      * @param mark the scilab mark.
37      * @param colorMap the scilab color map.
38      * @return a mark sprite corresponding to the given scilab mark.
39      */
40     public static Texture getMarkSprite(TextureManager spriteManager, Mark mark, ColorMap colorMap) {
41         int finalSize;
42
43         /**
44          * Compute the sprite pixel size.
45          */
46         if (mark.getMarkSizeUnit() == Mark.MarkSizeUnitType.TABULATED) {
47             // Special case for compatibility with older versions
48             // dot mark with tabulated size of 0 is a single pixel
49             // drawn in pixel size instead of tabulated size
50             if (mark.getStyle() == 0 && mark.getSize() == 0) {
51                 finalSize = 1;
52             } else {
53                 finalSize = (8 + 2 * mark.getSize());
54             }
55         } else {
56             finalSize = mark.getSize();
57         }
58
59         Texture sprite = spriteManager.createTexture();
60         sprite.setDrawer(getSpriteDrawer(mark, finalSize, colorMap));
61
62         return sprite;
63     }
64
65     /**
66      * Return the sprite drawer corresponding to the given mark.
67      * @param mark the mark to draw.
68      * @param finalSize the final mark size.
69      * @param colorMap the scilab colormap to use.
70      * @return the sprite drawer corresponding to the given mark.
71      */
72     private static TextureDrawer getSpriteDrawer(Mark mark, int finalSize, ColorMap colorMap) {
73
74         final Appearance appearance = new Appearance();
75         Color backgroundColor = ColorFactory.createColor(colorMap, mark.getBackground());
76         Color foregroundColor = ColorFactory.createColor(colorMap, mark.getForeground());
77
78         if (mark.getBackground() != 0) {
79             appearance.setFillColor(backgroundColor);
80         } else {
81             appearance.setFillColor(new Color(0.0f, 0.0f, 0.0f, 0.0f));
82         }
83         appearance.setLineColor(foregroundColor);
84
85         if (finalSize != 1) {
86             switch (mark.getStyle()) {
87             case  0:
88                 return new DotSpriteDrawer(foregroundColor, finalSize);
89             case  1:
90                 return new PlusSpriteDrawer(appearance, finalSize);
91             case  2:
92                 return new CrossSpriteDrawer(appearance, finalSize);
93             case  3:
94                 return new StarSpriteDrawer(appearance, finalSize);
95             case  4:
96                 return new FilledDiamondSpriteDrawer(foregroundColor, finalSize);
97             case  5:
98                 return new DiamondSpriteDrawer(appearance, finalSize);
99             case  6:
100                 return new TriangleUpSpriteDrawer(appearance, finalSize);
101             case  7:
102                 return new TriangleDownSpriteDrawer(appearance, finalSize);
103             case  8:
104                 return new DiamondPlusSpriteDrawer(appearance, finalSize);
105             case  9:
106                 return new CircleSpriteDrawer(appearance, finalSize);
107             case 10:
108                 return new AsteriskSpriteDrawer(appearance, finalSize);
109             case 11:
110                 return new SquareSpriteDrawer(appearance, finalSize);
111             case 12:
112                 return new TriangleRightSpriteDrawer(appearance, finalSize);
113             case 13:
114                 return new TriangleLeftSpriteDrawer(appearance, finalSize);
115             case 14:
116                 return new PentagramSpriteDrawer(appearance, finalSize);
117
118             default:
119                 return new PlusSpriteDrawer(appearance, finalSize);
120             }
121         } else {
122             return new PlusSpriteDrawer(appearance, finalSize);
123         }
124     }
125
126     /**
127      * Abstract class for all scilab mark sprites.
128      */
129     private static abstract class ScilabSpriteDrawer implements TextureDrawer {
130         protected final Appearance appearance;
131         protected final int size;
132
133         public ScilabSpriteDrawer(Appearance appearance, int size) {
134             this.appearance = appearance;
135             this.size = size;
136         }
137
138         @Override
139         public OriginPosition getOriginPosition() {
140             return TextureDrawer.OriginPosition.CENTER;
141         }
142
143         @Override
144         public Dimension getTextureSize() {
145
146             /** Add a margin such that (0, 0) was pixel aligned. */
147             int margin;
148             if (size % 2 == 0) {
149                 margin = 3;
150             } else {
151                 margin = 2;
152             }
153             return new Dimension(size + margin, size + margin);
154         }
155     }
156
157     /**
158      * Dot sprite
159      * Scilab ID = 0
160      */
161     private static class DotSpriteDrawer extends ScilabSpriteDrawer {
162         private final Color color;
163
164         public DotSpriteDrawer(Color color, int size) {
165             super(null, size);
166             this.color = color;
167         }
168
169         @Override
170         public void draw(TextureDrawingTools textureDrawingTools) {
171             textureDrawingTools.fillDisc(0, 0, size, color);
172         }
173     }
174
175     /**
176      * Plus sprite
177      * Scilab ID = 1
178      */
179     private static class PlusSpriteDrawer extends ScilabSpriteDrawer {
180
181         public PlusSpriteDrawer(Appearance appearance, int size) {
182             super(appearance, size);
183         }
184
185         @Override
186         public void draw(TextureDrawingTools textureDrawingTools) {
187             textureDrawingTools.drawPlus(size, appearance);
188         }
189     }
190
191     /**
192      * Cross sprite
193      * Scilab ID = 2
194      */
195     private static class CrossSpriteDrawer extends ScilabSpriteDrawer {
196         private final int[] coordinate1;
197         private final int[] coordinate2;
198
199         public CrossSpriteDrawer(Appearance appearance, int size) {
200             super(appearance, size);
201             int r = (int) (size * Math.sqrt(2.0) / 2.0);
202             coordinate1 = new int[] { -r, -r, r,  r};
203             coordinate2 = new int[] { -r,  r, r, -r};
204         }
205
206         @Override
207         public void draw(TextureDrawingTools textureDrawingTools) {
208             textureDrawingTools.drawPolyline(coordinate1, appearance);
209             textureDrawingTools.drawPolyline(coordinate2, appearance);
210         }
211     }
212
213     /**
214      * Star sprite
215      * Scilab ID = 3
216      */
217     private static class StarSpriteDrawer extends ScilabSpriteDrawer {
218         private final int[] coordinate1;
219         private final int[] coordinate2;
220
221         public StarSpriteDrawer(Appearance appearance, int size) {
222             super(appearance, size);
223             int r = size / 2;
224             coordinate1 = new int[] { -r, 0, r, 0};
225             coordinate2 = new int[] { 0, -r, 0, r};
226         }
227
228         @Override
229         public void draw(TextureDrawingTools textureDrawingTools) {
230             textureDrawingTools.fillDisc(0, 0, size, appearance.getFillColor());
231             textureDrawingTools.drawCircle(0, 0, size, appearance);
232             textureDrawingTools.drawPolyline(coordinate1, appearance);
233             textureDrawingTools.drawPolyline(coordinate2, appearance);
234         }
235     }
236
237     /**
238      * Filled diamond sprite
239      * Scilab ID = 4
240      */
241     private static class FilledDiamondSpriteDrawer extends ScilabSpriteDrawer {
242         private final Appearance appearance;
243         private final int[] coordinates;
244
245         public FilledDiamondSpriteDrawer(Color color, int size) {
246             super(null, size);
247             int r = size / 2;
248
249             appearance = new Appearance();
250             appearance.setFillColor(color);
251             appearance.setLineColor(color);
252
253             coordinates = new int[] { -r, 0, 0, -r, +r, 0, 0, +r};
254         }
255
256         @Override
257         public void draw(TextureDrawingTools textureDrawingTools) {
258             textureDrawingTools.fillPolygon(coordinates, appearance);
259         }
260     }
261
262     /**
263      * Abstract class for all the triangle mark sprites.
264      */
265     private static abstract class TriangleSpriteDrawer extends ScilabSpriteDrawer {
266         protected final int r;
267         protected final int basex;
268         protected final int basey;
269         protected int[] coordinates;
270
271         public TriangleSpriteDrawer(Appearance appearance, int size) {
272             super(appearance, size);
273             double tmpr = (double)(size / 2);
274
275             r = (int) (tmpr);
276
277             basex = (int) (tmpr * 0.5 * Math.sqrt(3));
278             basey = (int) (tmpr * 0.5);
279         }
280
281         @Override
282         public void draw(TextureDrawingTools textureDrawingTools) {
283             textureDrawingTools.fillPolygon(coordinates, appearance);
284         }
285     }
286
287     /**
288      * Diamond sprite
289      * Scilab ID = 5
290      */
291     private static class DiamondSpriteDrawer extends ScilabSpriteDrawer {
292         protected final int[] coordinates;
293
294         public DiamondSpriteDrawer(Appearance appearance, int size) {
295             super(appearance, size);
296             int r = size / 2;
297
298             coordinates = new int[] { -r, 0, 0, -r, r, 0, 0, r};
299         }
300
301         @Override
302         public void draw(TextureDrawingTools textureDrawingTools) {
303             textureDrawingTools.fillPolygon(coordinates, appearance);
304         }
305     }
306
307     /**
308      * Triangle up sprite
309      * Scilab ID = 6
310      */
311     private static class TriangleUpSpriteDrawer extends TriangleSpriteDrawer {
312         public TriangleUpSpriteDrawer(Appearance appearance, int size) {
313             super(appearance, size);
314
315             coordinates = new int[] { -basex, basey, 0, -r, basex, basey};
316         }
317     }
318
319     /**
320      * Triangle down sprite
321      * Scilab ID = 7
322      */
323     private static class TriangleDownSpriteDrawer extends TriangleSpriteDrawer {
324         public TriangleDownSpriteDrawer(Appearance appearance, int size) {
325             super(appearance, size);
326
327             coordinates = new int[] { -basex, -basey, basex, -basey, 0, r};
328         }
329     }
330
331     /**
332      * Diamond plus sprite
333      * Scilab ID = 8
334      */
335     private static class DiamondPlusSpriteDrawer extends DiamondSpriteDrawer {
336         private final int[] coordinate1;
337         private final int[] coordinate2;
338
339         public DiamondPlusSpriteDrawer(Appearance appearance, int size) {
340             super(appearance, size);
341             coordinate1 = new int[] {coordinates[0], coordinates[1], coordinates[4], coordinates[5]};
342             coordinate2 = new int[] {coordinates[2], coordinates[3], coordinates[6], coordinates[7]};
343         }
344
345         @Override
346         public void draw(TextureDrawingTools textureDrawingTools) {
347             super.draw(textureDrawingTools);
348             textureDrawingTools.drawPolyline(coordinate1, appearance);
349             textureDrawingTools.drawPolyline(coordinate2, appearance);
350         }
351     }
352
353     /**
354      * Circle sprite
355      * Scilab ID = 9
356      */
357     private static class CircleSpriteDrawer extends ScilabSpriteDrawer {
358
359         public CircleSpriteDrawer(Appearance appearance, int size) {
360             super(appearance, size);
361         }
362
363         @Override
364         public void draw(TextureDrawingTools textureDrawingTools) {
365             textureDrawingTools.fillDisc(0, 0, size, appearance.getFillColor());
366             textureDrawingTools.drawCircle(0, 0, size, appearance);
367         }
368     }
369
370     /**
371      * Asterisk sprite
372      * Scilab ID = 10
373      */
374     private static class AsteriskSpriteDrawer extends ScilabSpriteDrawer {
375         private final int[] coordinate1;
376         private final int[] coordinate2;
377         private final int[] coordinate3;
378         private final int[] coordinate4;
379
380         public AsteriskSpriteDrawer(Appearance appearance, int size) {
381             super(appearance, size);
382             int r = size / 2;
383             coordinate1 = new int[] { -r, 0, r, 0};
384             coordinate2 = new int[] { 0, -r, 0, r};
385             r = (int) (r * Math.sqrt(2.0) / 2.0);
386             coordinate3 = new int[] { -r, -r, r, r};
387             coordinate4 = new int[] { -r, r, +r, -r};
388         }
389
390         @Override
391         public void draw(TextureDrawingTools textureDrawingTools) {
392             textureDrawingTools.drawPolyline(coordinate1, appearance);
393             textureDrawingTools.drawPolyline(coordinate2, appearance);
394             textureDrawingTools.drawPolyline(coordinate3, appearance);
395             textureDrawingTools.drawPolyline(coordinate4, appearance);
396         }
397     }
398
399     /**
400      * Square sprite
401      * Scilab ID = 11
402      */
403     private static class SquareSpriteDrawer extends ScilabSpriteDrawer {
404         private final int[] coordinate;
405
406         public SquareSpriteDrawer(Appearance appearance, int size) {
407             super(appearance, size);
408             int r = size / 2;
409             coordinate = new int[] { -r, -r, +r, -r, +r, +r, -r, +r};
410         }
411
412         @Override
413         public void draw(TextureDrawingTools textureDrawingTools) {
414             textureDrawingTools.fillPolygon(coordinate, appearance);
415         }
416     }
417
418     /**
419      * Triangle right sprite
420      * Scilab ID = 12
421      */
422     private static class TriangleRightSpriteDrawer extends TriangleSpriteDrawer {
423         public TriangleRightSpriteDrawer(Appearance appearance, int size) {
424             super(appearance, size);
425
426             coordinates = new int[] { -basey, basex, -basey, -basex, r, 0};
427         }
428     }
429
430     /**
431      * Triangle left sprite
432      * Scilab ID = 13
433      */
434     private static class TriangleLeftSpriteDrawer extends TriangleSpriteDrawer {
435         public TriangleLeftSpriteDrawer(Appearance appearance, int size) {
436             super(appearance, size);
437
438             coordinates = new int[] {basey, basex, -r, 0, basey, -basex};
439         }
440     }
441
442     /**
443      * Pentagram sprite (five-pointed star)
444      * Scilab ID = 14
445      */
446     private static class PentagramSpriteDrawer extends ScilabSpriteDrawer {
447         private final int[] coordinates;
448
449         private static final double COS_PI_OVER_10 = Math.cos(Math.PI / 10.0);
450         private static final double SIN_PI_OVER_10 = Math.sin(Math.PI / 10.0);
451         private static final double COS_3_PI_OVER_10 = Math.cos(3.0 * Math.PI / 10.0);
452         private static final double SIN_3_PI_OVER_10 = Math.sin(3.0 * Math.PI / 10.0);
453
454         public PentagramSpriteDrawer(Appearance appearance, int size) {
455             super(appearance, size);
456
457             int r = size / 2;
458
459             double tmpy = SIN_PI_OVER_10 * (double)r;
460
461             int x = (int)(COS_PI_OVER_10 * (double)r);
462             int y = (int)(SIN_PI_OVER_10 * (double)r);
463
464             int x2 = (int)(COS_3_PI_OVER_10 * (double)r);
465             int y2 = (int)(SIN_3_PI_OVER_10 * (double)r);
466
467             double tmpinnr = tmpy / SIN_3_PI_OVER_10;
468
469
470             int xinn = (int)(tmpinnr * COS_3_PI_OVER_10);
471             int yinn = y;
472
473             int xinn2 = (int)(tmpinnr * COS_PI_OVER_10);
474             int yinn2 = (int)(tmpinnr * SIN_PI_OVER_10);
475
476             int innr = (int)tmpinnr;
477
478             coordinates = new int[] { -x2, y2, -xinn2, yinn2, -x, -y, -xinn, -yinn, 0, -r, xinn, -yinn, x, -y, xinn2, yinn2, x2, y2, 0, innr};
479         }
480
481         @Override
482         public void draw(TextureDrawingTools textureDrawingTools) {
483             textureDrawingTools.fillPolygon(coordinates, appearance);
484         }
485     }
486 }