001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.ui.swingViewer.util;
033
034import java.awt.Font;
035import java.util.HashMap;
036import java.util.Map;
037
038import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants;
039
040/**
041 * A cache for fonts.
042 * 
043 * <p>
044 * This cache allows to avoid reloading fonts and allows to quickly lookup a
045 * font based on its name, its style (bold, italic) and its size.
046 * </p>
047 */
048public class FontCache {
049        /**
050         * The default font.
051         */
052        protected Font defaultFont;
053
054        /**
055         * Cached fonts.
056         */
057        protected HashMap<String, FontSlot> cache = new HashMap<String, FontSlot>();
058
059        /**
060         * The default font cache.
061         */
062        public static FontCache defaultFontCache;
063
064        /**
065         * New empty font cache.
066         */
067        public FontCache() {
068                defaultFont = new Font("SansSerif", Font.PLAIN, 11);
069                // This works only in JDK 1.6 :
070                // defaultFont = new Font( Font.SANS_SERIF, Font.PLAIN, 11 );
071        }
072
073        /**
074         * The default font.
075         * 
076         * @return A font.
077         */
078        public Font getDefaultFont() {
079                return defaultFont;
080        }
081
082        /**
083         * Default singleton instance for shared font cache. This method and cache
084         * can only be used in the Swing thread.
085         * 
086         * @return The default singleton font cache instance.
087         */
088        public static FontCache defaultFontCache() {
089                if (defaultFontCache == null)
090                        defaultFontCache = new FontCache();
091
092                return defaultFontCache;
093        }
094
095        public Font getDefaultFont(StyleConstants.TextStyle style, int size) {
096                return getFont("SansSerif", style, size);
097        }
098
099        /**
100         * Lookup a font, and if not found, try to load it, if still not available,
101         * return the default font.
102         * 
103         * @param name
104         *            The font name.
105         * @param style
106         *            A style, taken from the styles available in the style sheets.
107         * @param size
108         *            The font size in points.
109         * @return A font.
110         */
111        public Font getFont(String name, StyleConstants.TextStyle style, int size) {
112                FontSlot slot = cache.get(name);
113
114                if (slot == null) {
115                        slot = new FontSlot(name, style, size);
116                        cache.put(name, slot);
117                }
118
119                return slot.getFont(style, size);
120        }
121}
122
123/**
124 * simple container for a font name.
125 * 
126 * <p>
127 * This container allows to group all the fonts that match a name. It stores the
128 * font for sizes and styles.
129 * </p>
130 */
131class FontSlot {
132        String name;
133
134        public HashMap<Integer, Font> normal;
135
136        public HashMap<Integer, Font> bold;
137
138        public HashMap<Integer, Font> italic;
139
140        public HashMap<Integer, Font> boldItalic;
141
142        public FontSlot(String name, StyleConstants.TextStyle style, int size) {
143                this.name = name;
144                insert(style, size);
145        }
146
147        protected Map<Integer, Font> mapFromStyle(StyleConstants.TextStyle style) {
148                switch (style) {
149                case BOLD:
150                        if (bold == null)
151                                bold = new HashMap<Integer, Font>();
152                        return bold;
153                case ITALIC:
154                        if (italic == null)
155                                italic = new HashMap<Integer, Font>();
156                        return italic;
157                case BOLD_ITALIC:
158                        if (boldItalic == null)
159                                boldItalic = new HashMap<Integer, Font>();
160                        return boldItalic;
161                case NORMAL:
162                default:
163                        if (normal == null)
164                                normal = new HashMap<Integer, Font>();
165                        return normal;
166                }
167        }
168
169        protected int toJavaStyle(StyleConstants.TextStyle style) {
170                switch (style) {
171                case BOLD:
172                        return Font.BOLD;
173                case ITALIC:
174                        return Font.ITALIC;
175                case BOLD_ITALIC:
176                        return Font.BOLD + Font.ITALIC;
177                case NORMAL:
178                default:
179                        return Font.PLAIN;
180                }
181        }
182
183        public Font insert(StyleConstants.TextStyle style, int size) {
184                return insert(mapFromStyle(style), toJavaStyle(style), size);
185        }
186
187        protected Font insert(Map<Integer, Font> map, int style, int size) {
188                Font font = map.get(size);
189
190                if (font == null) {
191                        // System.err.printf( "new font %s %s %d%n", name, style, size );
192                        font = new Font(name, style, size);
193
194                        map.put(size, font);
195                }
196
197                return font;
198        }
199
200        protected Font getFont(StyleConstants.TextStyle style, int size) {
201                Map<Integer, Font> map = mapFromStyle(style);
202
203                Font font = map.get(size);
204
205                if (font == null)
206                        font = insert(map, toJavaStyle(style), size);
207
208                return font;
209        }
210}