ef8056778e7d384a4b6e61eec21b998ead3bf242
[scilab.git] / scilab / modules / renderer / src / java / org / scilab / modules / renderer / JoGLView / axes / ruler / AxesRulerSpriteFactory.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.axes.ruler;
13
14 import org.scilab.forge.scirenderer.ruler.RulerSpriteFactory;
15 import org.scilab.forge.scirenderer.texture.TextEntity;
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.axes.Axes;
21 import org.scilab.modules.graphic_objects.axes.AxisProperty;
22 import org.scilab.modules.graphic_objects.figure.ColorMap;
23 import org.scilab.modules.graphic_objects.figure.Figure;
24 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
25 import org.scilab.modules.graphic_objects.textObject.FormattedText;
26 import org.scilab.modules.renderer.JoGLView.util.ColorFactory;
27 import org.scilab.modules.renderer.JoGLView.util.FormattedTextSpriteDrawer;
28 import org.scilab.modules.renderer.utils.textRendering.FontManager;
29
30 import java.awt.Dimension;
31 import java.awt.Font;
32 import java.text.DecimalFormat;
33 import java.text.DecimalFormatSymbols;
34
35 /**
36  * This implementation of {@see RulerSpriteFactory} create ruler labels for the given {@see Axes}.
37  *
38  * @author Pierre Lando
39  */
40 class AxesRulerSpriteFactory implements RulerSpriteFactory {
41     /**
42      * The symbol used for ticks label in log and auto ticks mode.
43      */
44     private static final String MULTIPLICATION_SYMBOL = "x";
45
46     /**
47      * The exponent size is smaller than the mantissa size.
48      */
49     private static final float EXPONENT_SIZE_RATIO = 0.4f;
50
51     /**
52      * This factory create ruler label for this {@see Axis}.
53      */
54     private final AxisProperty axisProperty;
55
56     /**
57      * The current colormap.
58      */
59     private final ColorMap colorMap;
60
61     /**
62      * Default constructor.
63      * @param axes This factory create ruler label for one axis of this given {@see Axes}.
64      * @param axisId the id of the managed axis.
65      */
66     public AxesRulerSpriteFactory(Axes axes, int axisId) {
67         this.axisProperty = axes.getAxes()[axisId];
68         ColorMap figureColorMap;
69         try {
70             GraphicController controller = GraphicController.getController();
71             Figure parentFigure = (Figure) controller.getObjectFromId(axes.getParentFigure());
72             figureColorMap = parentFigure.getColorMap();
73         } catch (NullPointerException e) {
74             figureColorMap = null;
75         }
76         this.colorMap = figureColorMap;
77     }
78
79     @Override
80     public Texture create(double value, DecimalFormat adaptedFormat, TextureManager textureManager) {
81         // Simple ack to avoid ticks with "-0" as label.
82         if (value == -0) {
83             value = 0;
84         }
85
86         if (axisProperty.getAutoTicks()) {
87             setScilabStyle(adaptedFormat);
88             if (axisProperty.getLogFlag()) {
89                 return createScientificStyleSprite(value, textureManager);
90             } else {
91                 return createSimpleSprite(adaptedFormat.format(value), textureManager);
92             }
93         } else {
94             FormattedText formattedText = getTextAtValue(value);
95             FormattedTextSpriteDrawer textObjectSpriteDrawer = new FormattedTextSpriteDrawer(colorMap, formattedText);
96             Texture texture = textureManager.createTexture();
97             texture.setDrawer(textObjectSpriteDrawer);
98             return texture;
99         }
100     }
101
102     /**
103      * Set the given {@see DecimalFormat} to scilab style.
104      * @param format the given {@see DecimalFormat}.
105      */
106     public static void setScilabStyle(DecimalFormat format) {
107         DecimalFormatSymbols decimalFormatSymbols = format.getDecimalFormatSymbols();
108         decimalFormatSymbols.setDecimalSeparator('.');
109         decimalFormatSymbols.setExponentSeparator("e");
110         format.setDecimalFormatSymbols(decimalFormatSymbols);
111     }
112
113     /**
114      * Create and return a texture representing the given value.|| index >= axisProperty.getTicksLabels().size()
115      * The returned sprites will look like "5x10^2"
116      * @param value, the given value.
117      * @param textureManager used texture manager.
118      * @return a simple texture representing the given value with the adapted format.
119      */
120     private Texture createScientificStyleSprite(double value, TextureManager textureManager) {
121         Integer exponent = (int) Math.floor(Math.log10(value));
122         Double mantissa = value / Math.pow(10, exponent);
123
124         /**
125          * Create mantissa.
126          */
127         final TextEntity mantissaTextEntity;
128         if (mantissa != 1) {
129             mantissaTextEntity = new TextEntity(mantissa.toString() + MULTIPLICATION_SYMBOL + "10");
130         } else {
131             mantissaTextEntity = new TextEntity("10");
132         }
133
134         Font mantissaFont = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize());
135         mantissaTextEntity.setTextAntiAliased(true);
136         mantissaTextEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
137         mantissaTextEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
138         mantissaTextEntity.setFont(mantissaFont);
139         final Dimension mantissaSize = mantissaTextEntity.getSize();
140
141         /**
142          * Create exponent.
143          */
144         final TextEntity exponentTextEntity = new TextEntity(exponent.toString());
145         Font exponentFont = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize() * EXPONENT_SIZE_RATIO);
146         exponentTextEntity.setTextAntiAliased(true);
147         exponentTextEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
148         exponentTextEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
149         exponentTextEntity.setFont(exponentFont);
150         final Dimension exponentSize = exponentTextEntity.getSize();
151
152         Texture texture = textureManager.createTexture();
153
154         texture.setDrawer(new TextureDrawer() {
155
156             @Override
157             public void draw(TextureDrawingTools drawingTools) {
158                 drawingTools.draw(mantissaTextEntity, 0, exponentSize.height);
159                 drawingTools.draw(exponentTextEntity, mantissaSize.width, 0);
160             }
161
162             @Override
163             public Dimension getTextureSize() {
164                 return new Dimension(
165                            exponentSize.width + mantissaSize.width,
166                            exponentSize.height + mantissaSize.height
167                        );
168             }
169
170             @Override
171             public TextureDrawer.OriginPosition getOriginPosition() {
172                 return TextureDrawer.OriginPosition.UPPER_LEFT;
173             }
174         });
175
176         return texture;
177     }
178
179     /**
180      * Create and return a simple texture representing the given value.
181      * @param text the formatted string representing the value.
182      * @param textureManager used texture manager.
183      * @return a simple texture representing the given value with the adapted format.
184      */
185     private Texture createSimpleSprite(String text, TextureManager textureManager) {
186         Font font = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize());
187         final TextEntity textEntity = new TextEntity(text);
188         textEntity.setTextAntiAliased(true);
189         textEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
190         textEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
191         textEntity.setFont(font);
192
193         Texture texture = textureManager.createTexture();
194         texture.setDrawer(new TextureDrawer() {
195
196             @Override
197             public void draw(TextureDrawingTools drawingTools) {
198                 drawingTools.draw(textEntity, 0, 0);
199             }
200
201             @Override
202             public Dimension getTextureSize() {
203                 return textEntity.getSize();
204             }
205
206             @Override
207             public TextureDrawer.OriginPosition getOriginPosition() {
208                 return TextureDrawer.OriginPosition.UPPER_LEFT;
209             }
210         });
211
212         return texture;
213     }
214
215     /**
216      * Return the user defined {@see FormattedText} ticks label corresponding to the given value.
217      * @param value the given value.
218      * @return the user defined {@see FormattedText} ticks label corresponding to the given value.
219      */
220     private FormattedText getTextAtValue(double value) {
221         Double[] locations = axisProperty.getTicksLocations();
222         int index = -1;
223         for (int i = 0 ; i < locations.length ; i++) {
224             if (locations[i] == value) {
225                 index = i;
226                 break;
227             }
228         }
229         if (index == -1 || index >= axisProperty.getTicksLabels().size()) {
230             return null;
231         } else {
232             return axisProperty.getTicksLabels().get(index);
233         }
234     }
235 }