Bug 11982 fixed: ticks computation were made when drawing
[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             if (formattedText != null && formattedText.getText() != null && !formattedText.getText().isEmpty()) {
96                 FormattedTextSpriteDrawer textObjectSpriteDrawer = new FormattedTextSpriteDrawer(colorMap, formattedText);
97                 Texture texture = textureManager.createTexture();
98                 texture.setMagnificationFilter(Texture.Filter.LINEAR);
99                 texture.setMinifyingFilter(Texture.Filter.LINEAR);
100                 texture.setDrawer(textObjectSpriteDrawer);
101
102                 return texture;
103             }
104
105             return null;
106         }
107     }
108
109     /**
110      * Set the given {@see DecimalFormat} to scilab style.
111      * @param format the given {@see DecimalFormat}.
112      */
113     public static void setScilabStyle(DecimalFormat format) {
114         DecimalFormatSymbols decimalFormatSymbols = format.getDecimalFormatSymbols();
115         decimalFormatSymbols.setDecimalSeparator('.');
116         decimalFormatSymbols.setExponentSeparator("e");
117         decimalFormatSymbols.setGroupingSeparator('\u00A0');
118         format.setDecimalFormatSymbols(decimalFormatSymbols);
119     }
120
121     /**
122      * Create and return a texture representing the given value.|| index >= axisProperty.getTicksLabels().size()
123      * The returned sprites will look like "5x10^2"
124      * @param value, the given value.
125      * @param textureManager used texture manager.
126      * @return a simple texture representing the given value with the adapted format.
127      */
128     private Texture createScientificStyleSprite(double value, TextureManager textureManager) {
129         Integer exponent = (int) Math.floor(Math.log10(value));
130         Double mantissa = value / Math.pow(10, exponent);
131
132         /**
133          * Create mantissa.
134          */
135         final TextEntity mantissaTextEntity;
136         if (mantissa != 1) {
137             mantissaTextEntity = new TextEntity(mantissa.toString() + MULTIPLICATION_SYMBOL + "10");
138         } else {
139             mantissaTextEntity = new TextEntity("10");
140         }
141
142         Font mantissaFont = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize());
143         mantissaTextEntity.setTextAntiAliased(true);
144         mantissaTextEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
145         mantissaTextEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
146         mantissaTextEntity.setFont(mantissaFont);
147         final Dimension mantissaSize = mantissaTextEntity.getSize();
148
149         /**
150          * Create exponent.
151          */
152         final TextEntity exponentTextEntity = new TextEntity(exponent.toString());
153         Font exponentFont = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize() * EXPONENT_SIZE_RATIO);
154         exponentTextEntity.setTextAntiAliased(true);
155         exponentTextEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
156         exponentTextEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
157         exponentTextEntity.setFont(exponentFont);
158         final Dimension exponentSize = exponentTextEntity.getSize();
159
160         Texture texture = textureManager.createTexture();
161
162         texture.setDrawer(new TextureDrawer() {
163
164             @Override
165             public void draw(TextureDrawingTools drawingTools) {
166                 drawingTools.draw(mantissaTextEntity, 0, exponentSize.height);
167                 drawingTools.draw(exponentTextEntity, mantissaSize.width, 0);
168             }
169
170             @Override
171             public Dimension getTextureSize() {
172                 return new Dimension(
173                            exponentSize.width + mantissaSize.width,
174                            exponentSize.height + mantissaSize.height
175                        );
176             }
177
178             @Override
179             public TextureDrawer.OriginPosition getOriginPosition() {
180                 return TextureDrawer.OriginPosition.UPPER_LEFT;
181             }
182         });
183
184         return texture;
185     }
186
187     /**
188      * Create and return a simple texture representing the given value.
189      * @param text the formatted string representing the value.
190      * @param textureManager used texture manager.
191      * @return a simple texture representing the given value with the adapted format.
192      */
193     private Texture createSimpleSprite(String text, TextureManager textureManager) {
194         Font font = FontManager.getSciFontManager().getFontFromIndex(axisProperty.getFontStyle(), axisProperty.getFontSize());
195         final TextEntity textEntity = new TextEntity(text);
196         textEntity.setTextAntiAliased(true);
197         textEntity.setTextUseFractionalMetrics(axisProperty.getFontFractional());
198         textEntity.setTextColor(ColorFactory.createColor(colorMap, axisProperty.getFontColor()));
199         textEntity.setFont(font);
200
201         Texture texture = textureManager.createTexture();
202         texture.setDrawer(new TextureDrawer() {
203
204             @Override
205             public void draw(TextureDrawingTools drawingTools) {
206                 drawingTools.draw(textEntity, 0, 0);
207             }
208
209             @Override
210             public Dimension getTextureSize() {
211                 return textEntity.getSize();
212             }
213
214             @Override
215             public TextureDrawer.OriginPosition getOriginPosition() {
216                 return TextureDrawer.OriginPosition.UPPER_LEFT;
217             }
218         });
219
220         return texture;
221     }
222
223     /**
224      * Return the user defined {@see FormattedText} ticks label corresponding to the given value.
225      * @param value the given value.
226      * @return the user defined {@see FormattedText} ticks label corresponding to the given value.
227      */
228     private FormattedText getTextAtValue(double value) {
229         Double[] locations = axisProperty.getTicksLocations();
230         int index = -1;
231         for (int i = 0 ; i < locations.length ; i++) {
232             if (locations[i] == value) {
233                 index = i;
234                 break;
235             }
236         }
237         if (index == -1 || index >= axisProperty.getTicksLabels().size()) {
238             return null;
239         } else {
240             return axisProperty.getTicksLabels().get(index);
241         }
242     }
243 }