Renderer: fix compilation after 47daa41a29
[scilab.git] / scilab / modules / renderer / src / java / org / scilab / modules / renderer / utils / textRendering / FontManager.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Jean-Baptiste Silvy
4  * Copyright (C) 2008 - INRIA - Allan CORNET
5  * desc : Singleton class used to set font of text objects
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18
19 package org.scilab.modules.renderer.utils.textRendering;
20
21 import java.io.FileInputStream;
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.awt.Font;
26 import java.awt.FontFormatException;
27 import java.awt.GraphicsEnvironment;
28 import java.util.ArrayList;
29
30 /**
31  * Singleton class used to set font of text objects.
32  * @author Jean-Baptiste Silvy
33  */
34 public class FontManager {
35
36     private static final String SCIDIR = System.getenv("SCI");
37     private static final float[] INTERVALS = {3.0f, 4.0f, 5.0f};
38     private static final float[] FIRST_POLY = {2.0f, 8.0f};
39     private static final float[] SECOND_POLY = {4.0f, 2.0f};
40     private static final float[] THIRD_POLY = {6.0f, -6.0f};
41     private static final float[] FOURTH_POLY = {10.0f, -26.0f};
42
43     private static final float SIX = 6.0f;
44
45     private static final float[] INV_INTERVALS = {14.0f, 18.0f, 24.0f};
46     private static final float[] INV_FIRST_POLY = {0.5f, -4.0f};
47     private static final float[] INV_SECOND_POLY = {0.25f, -0.5f};
48     private static final float[] INV_THIRD_POLY = {1.0f / SIX, 1.0f};
49     private static final float[] INV_FOURTH_POLY = {0.1f, 2.6f};
50
51
52     // logical awt fonts
53     // JRE Java guaranteed: "Dialog", "DialogInput",
54     // "Monospaced","Serif", "SansSerif", "Symbol", "Lucida"
55     // Scilab 4.x fonts --> fonts with JRE 1.5 or more
56     // Times            --> Serif
57     // Helvetica        --> SansSerif
58     // Courier          --> Monospaced
59     // Symbol           --> Scilab Symbols font
60
61     private static final String MONOSPACED = "Monospaced";
62     private static final String SANSSERIF = "SansSerif";
63     private static final String SERIF = "Serif";
64     private static final String SCILABSYMBOLSFONT = "ScilabSymbols";
65     private static final String SYMBOLSFONTPATH = "/thirdparty/fonts/scilabsymbols.ttf";
66     private static final Font DEFAULT_FONT = new Font("Default", Font.PLAIN, 1);
67
68     /** Singleton instance. */
69     private static final FontManager sciFontManager = new FontManager();
70
71     /**
72      * A list of fonts.
73      */
74     private static class FontList extends ArrayList<Font> {
75
76         private static final long serialVersionUID = 1L;
77
78         /**
79          * Default constructor.
80          */
81         public FontList() {
82             super();
83         }
84     }
85
86     private static FontList sciFonts;
87
88     /**
89      * Default constructor.
90      * Should not be called.
91      */
92     private FontManager() {
93         initializeFontManager();
94     }
95
96     /**
97      * Get the font manager instance
98      * @return the only instance of fontmanager.
99      */
100     public static FontManager getSciFontManager() {
101         return sciFontManager;
102     }
103
104     /**
105      * Convert sciab font size to awt font size.
106      * We use a degree 2 polygon to compute this.
107      * We use canonical form of the polygon so the inverse function is easy to compute
108      * Tthe equivalence list is (0 => 8, 1 => 10, 2 => 12, 3 => 14, 4 => 18, 5 => 24).
109      * @param sciSize scilab size
110      * @return awt size
111      */
112     public static float scilabSizeToAwtSize(double sciSize) {
113         float sciSizef = (float) sciSize;
114         // f(x) = | 2x + 8 if x < 3
115         //        | 4x + 2 if 3 < x < 4
116         //        | 6x - 6 if 4 < x
117         if (sciSizef < INTERVALS[0]) {
118             return FIRST_POLY[0] * sciSizef + FIRST_POLY[1];
119         } else if (sciSizef < INTERVALS[1]) {
120             return SECOND_POLY[0] * sciSizef + SECOND_POLY[1];
121         } else if (sciSizef < INTERVALS[2]) {
122             return THIRD_POLY[0] * sciSizef + THIRD_POLY[1];
123         } else {
124             return FOURTH_POLY[0] * sciSizef + FOURTH_POLY[1];
125         }
126     }
127
128     /**
129      * Inverse of scilabSizeToAwtSize function
130      * @param size size of a AWT font
131      * @return corresponding size in Scilab
132      */
133     public static double awtSizeToScilabSize(float size) {
134         // sqrt(|x - c| / a) - b
135         if (size < INV_INTERVALS[0]) {
136             return INV_FIRST_POLY[0] * size + INV_FIRST_POLY[1];
137         } else if (size < INV_INTERVALS[1]) {
138             return INV_SECOND_POLY[0] * size + INV_SECOND_POLY[1];
139         } else if (size < INV_INTERVALS[2]) {
140             return INV_THIRD_POLY[0] * size + INV_THIRD_POLY[1];
141         } else {
142             return INV_FOURTH_POLY[0] * size + INV_FOURTH_POLY[1];
143         }
144     }
145
146     /**
147      * Get a font from its index in Scilab.
148      * @param fontIndex scilab index of the font.
149      * @return font corresponding to the index with size 1.
150      */
151     public final Font getFontFromIndex(int fontIndex) {
152         if (fontIndex >= 0 && fontIndex < sciFonts.size()) {
153             return sciFonts.get(fontIndex);
154         } else if (fontIndex < 0) {
155             return sciFonts.get(0);
156         } else {
157             return sciFonts.get(sciFonts.size() - 1);
158         }
159     }
160
161     /**
162      * Get a font from its index in Scilab.
163      * @param fontIndex scilab index of the font.
164      * @param fontSize size of the font (scilab size).
165      * @return font corresponding to the index.
166      */
167     public final Font getFontFromIndex(int fontIndex, double fontSize) {
168         Font res = getFontFromIndex(fontIndex);
169         return res.deriveFont(scilabSizeToAwtSize(fontSize));
170     }
171     /**
172      * Add a new font in the font list.
173      * @param newFont font to add to the list
174      * @return index of added font.
175      */
176     public final int addFont(Font newFont) {
177         sciFonts.add(newFont);
178         return sciFonts.size() - 1;
179     }
180
181     /**
182      * Replace a font in the font list by a new one.
183      * @param index index of the font to replace
184      * @param newFont font to add in the font list.
185      * @return index of the added font or -1 if an error occurred.
186      */
187     public final int changeFont(int index, Font newFont) {
188         int nbFonts = sciFonts.size();
189         if (index > nbFonts) {
190             // we need to add fonts until index
191             for (int i = nbFonts; i < index; i++) {
192                 addFont(DEFAULT_FONT);
193             }
194             return addFont(newFont);
195         } else if (index == nbFonts) {
196             // add a new Font
197             return addFont(newFont);
198         } else {
199             sciFonts.set(index, newFont);
200             return index;
201         }
202
203     }
204
205     /**
206      * Create a new font knowing its name and size.
207      * @param fontName Name of the font.
208      * @return new font.
209      */
210     protected final Font createFont(String fontName) {
211         // size must be applied after.
212         // by default, we use PLAIN font.
213         return new Font(fontName, Font.PLAIN, 1);
214     }
215
216     /**
217      * Load scilab symbols font
218      * @return font.
219      */
220     protected final Font loadScilabSymbolFont() {
221         return loadFont(SCIDIR + SYMBOLSFONTPATH);
222     }
223
224     /**
225      * load a font from filename
226      * @param fontFileName filename of the font.
227      * @return font.
228      */
229     protected final Font loadFont(String fontFileName) {
230         Font loadedFont;
231         FileInputStream in;
232         File f = new File(fontFileName);
233         try {
234             in = new FileInputStream(f);
235         } catch (FileNotFoundException e) {
236             loadedFont = DEFAULT_FONT;
237             return loadedFont;
238         }
239
240         try {
241             loadedFont = Font.createFont(Font.TRUETYPE_FONT, in);
242             in.close();
243         } catch (IOException e) {
244             loadedFont = DEFAULT_FONT;
245         } catch (FontFormatException ffe) {
246             loadedFont = DEFAULT_FONT;
247         }
248
249         return loadedFont;
250     }
251
252     /**
253      * Create a new font knowing its name and size.
254      * @param fontName Name of the font.
255      * @param isBold whether the font is bold or not.
256      * @param isItalic whether the font is in italic or not.
257      * @return new font.
258      */
259     protected final Font createFont(String fontName, boolean isBold, boolean isItalic) {
260         int style;
261         if (isBold && isItalic) {
262             style = Font.BOLD | Font.ITALIC;
263         } else if (isBold) {
264             style = Font.BOLD;
265         } else if (isItalic) {
266             style = Font.ITALIC;
267         } else {
268             style = Font.PLAIN;
269         }
270         return new Font(fontName, style, 1);
271     }
272
273     /**
274      * Add a new font from its font name.
275      * @param fontName name of the font to add.
276      * @return index of the added font.
277      */
278     public final int addFont(String fontName) {
279         return addFont(createFont(fontName));
280     }
281
282     /**
283      * Add a new font from its font name.
284      * @param fontName name of the font to add.
285      * @param isBold whether the font is bold or not.
286      * @param isItalic whether the font is in italic or not.
287      * @return index of the added font.
288      */
289     public final int addFont(String fontName, boolean isBold, boolean isItalic) {
290         return addFont(createFont(fontName, isBold, isItalic));
291     }
292
293     /**
294      * Add a new font from its filename.
295      * @param fontFilename  filename of the font to add.
296      * @return index of the added font.
297      */
298     public final int addFontFromFilename(String fontFilename) {
299         return addFont(loadFont(fontFilename));
300     }
301
302     /**
303      * Replace a font in the font list by a new one.
304      * @param index index of the font to replace
305      * @param fontName Name of the font.
306      * @return index of the added font or -1 if an error occurred.
307      */
308
309     public final int changeFont(int index, String fontName) {
310         return changeFont(index, createFont(fontName));
311     }
312
313     /**
314     * Replace a font in the font list by a new one loaded from a file.
315     * @param index index of the font to replace
316     * @param fontFilename  filename of the font
317     * @return index of the added font or -1 if an error occurred.
318     */
319     public final int changeFontFromFilename(int index, String fontFilename) {
320         return changeFont(index, loadFont(fontFilename));
321     }
322
323     /**
324      * Replace a font in the font list by a new one.
325      * @param index index of the font to replace
326      * @param fontName Name of the font.
327      * @param isBold whether the font is bold or not.
328      * @param isItalic whether the font is in italic or not.
329      * @return index of the added font or -1 if an error occurred.
330      */
331     public final int changeFont(int index, String fontName, boolean isBold, boolean isItalic) {
332         return changeFont(index, createFont(fontName, isBold, isItalic));
333     }
334
335     /**
336      * Get the list of all fonts available.
337      * @return Names of the available fonts.
338      */
339     public final String[] getAvailableFontsName() {
340         return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
341     }
342
343     /**
344      * Get the size of list of all fonts available.
345      * @return size.
346      */
347     public final int getSizeAvailableFontsName() {
348         return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames().length;
349     }
350
351     /**
352      * Check if fontname is available
353      * @param fontname Name of the font.
354      * @return true or false.
355      */
356     public final boolean isAvailableFontName(String fontname) {
357         int i = getSizeAvailableFontsName();
358         String[] availableFontsName = getAvailableFontsName();
359         for (i = 0; i < availableFontsName.length; i++) {
360             if (fontname.compareTo(availableFontsName[i]) == 0) {
361                 return true;
362             }
363         }
364         return false;
365     }
366
367     /**
368      * returns fontnames installed (used) by scilab
369      * @return fonts name
370      */
371     public final String[] getInstalledFontsName() {
372         int nbFonts = sciFonts.size();
373         String[] fontnames = new String[nbFonts];
374
375         for (int i = 0; i < nbFonts; i++) {
376             Font res = getFontFromIndex(i);
377             fontnames[i] = res.getFamily();
378             if (res.isBold()) {
379                 fontnames[i] += " Bold";
380             }
381             if (res.isItalic()) {
382                 fontnames[i] += " Italic";
383             }
384         }
385
386         return fontnames;
387     }
388
389     /**
390      * Returns number of fonts installed.
391      * @return number of fonts installed.
392      */
393     public final int getSizeInstalledFontsName() {
394         return sciFonts.size();
395     }
396
397     /**
398      * initializeFontManager
399      */
400     public final void initializeFontManager() {
401         sciFonts = new FontList();
402         // set default font
403         /* Fonts order in Scilab 4.x for compatibility */
404         /* Courrier --> Monospaced
405           Symbol --> Symbol
406           Times --> Serif
407           Times Italic --> Serif Italic
408           Times Bold --> Serif Bold
409           Times Bold Italic --> Serif Bold Italic
410           Helvetica --> SansSerif
411           Helvetica Italic --> SansSerif Italic
412           Helvetica Bold --> SansSerif Bold
413           Helveticas Bold Italic --> SansSerif bold Italic
414         */
415
416         sciFonts.add(createFont(MONOSPACED));             /* scilab font_style 0 */
417         /* Symbols font */                               /* scilab font_style 1 */
418         /* on scilab 4.x a --> alpha (symbol) */
419         /* with java , symbols are not ascii codes , but unicodes */
420         /* if font exists on system, we use else we try to load scilab symbols font (truetype) */
421         if (isAvailableFontName(SCILABSYMBOLSFONT)) {
422             sciFonts.add(createFont(SCILABSYMBOLSFONT));
423         } else {
424             sciFonts.add(loadScilabSymbolFont());
425         }
426         sciFonts.add(createFont(SERIF));                  /* scilab font_style 2 */
427         sciFonts.add(createFont(SERIF, false, true));     /* scilab font_style 3 */
428         sciFonts.add(createFont(SERIF, true, false));     /* scilab font_style 4 */
429         sciFonts.add(createFont(SERIF, true, true));      /* scilab font_style 5 */
430         sciFonts.add(createFont(SANSSERIF));              /* scilab font_style 6 */
431         sciFonts.add(createFont(SANSSERIF, false, true)); /* scilab font_style 7 */
432         sciFonts.add(createFont(SANSSERIF, true, false)); /* scilab font_style 8 */
433         sciFonts.add(createFont(SANSSERIF, true, true));  /* scilab font_style 9 */
434         sciFonts.add(createFont(SANSSERIF, true, true));  /* scilab font_style 10 */
435     }
436 }