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