001 /*
002 * Copyright 2002 - 2008 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id: MathVariant.java,v e6bd6c2d9bf4 2008/11/28 15:02:26 maxberger $ */
018
019 package net.sourceforge.jeuclid.elements.support.attributes;
020
021 import java.awt.Font;
022 import java.io.Serializable;
023 import java.util.HashMap;
024 import java.util.HashSet;
025 import java.util.List;
026 import java.util.Locale;
027 import java.util.Map;
028 import java.util.Set;
029
030 import net.sourceforge.jeuclid.LayoutContext;
031 import net.sourceforge.jeuclid.context.Parameter;
032 import net.sourceforge.jeuclid.elements.support.text.CharacterMapping;
033 import net.sourceforge.jeuclid.font.FontFactory;
034
035 import org.apache.commons.logging.Log;
036 import org.apache.commons.logging.LogFactory;
037
038 /**
039 * Class to represent and use MathVariants.
040 *
041 * @version $Revision: e6bd6c2d9bf4 $
042 */
043 public final class MathVariant implements Serializable {
044
045 /**
046 * Mathvariant constant. Bold style.
047 */
048 public static final MathVariant BOLD = new MathVariant(Font.BOLD,
049 FontFamily.SERIF);
050
051 /**
052 * Mathvariant constant. Bold fraktur style.
053 */
054 public static final MathVariant BOLD_FRAKTUR = new MathVariant(Font.BOLD,
055 FontFamily.FRAKTUR);
056
057 /**
058 * Mathvariant constant. Bold-italic style.
059 */
060 public static final MathVariant BOLD_ITALIC = new MathVariant(Font.BOLD
061 | Font.ITALIC, FontFamily.SERIF);
062
063 /**
064 * Mathvariant constant. Bold sans-serif style.
065 */
066 public static final MathVariant BOLD_SANS_SERIF = new MathVariant(
067 Font.BOLD, FontFamily.SANSSERIF);
068
069 /**
070 * Mathvariant constant. Bold script style.
071 */
072 public static final MathVariant BOLD_SCRIPT = new MathVariant(Font.BOLD,
073 FontFamily.SCRIPT);
074
075 /**
076 * Mathvariant constant. Double struck style.
077 */
078 public static final MathVariant DOUBLE_STRUCK = new MathVariant(
079 Font.PLAIN, FontFamily.DOUBLE_STRUCK);
080
081 /**
082 * Mathvariant constant. Fraktur style.
083 */
084 public static final MathVariant FRAKTUR = new MathVariant(Font.PLAIN,
085 FontFamily.FRAKTUR);
086
087 /**
088 * Mathvariant constant. Italic style.
089 */
090 public static final MathVariant ITALIC = new MathVariant(Font.ITALIC,
091 FontFamily.SERIF);
092
093 /**
094 * Mathvariant constant. Monospace style.
095 */
096 public static final MathVariant MONOSPACE = new MathVariant(Font.PLAIN,
097 FontFamily.MONOSPACED);
098
099 /**
100 * Mathvariant constant. Normal style.
101 */
102 public static final MathVariant NORMAL = new MathVariant(Font.PLAIN,
103 FontFamily.SERIF);
104
105 /**
106 * Mathvariant constant. Sans-serif style.
107 */
108 public static final MathVariant SANS_SERIF = new MathVariant(Font.PLAIN,
109 FontFamily.SANSSERIF);
110
111 /**
112 * Mathvariant constant. Bold italic sans-serif style.
113 */
114 public static final MathVariant SANS_SERIF_BOLD_ITALIC = new MathVariant(
115 Font.BOLD | Font.ITALIC, FontFamily.SANSSERIF);
116
117 /**
118 * Mathvariant constant. Italic sans-serif style.
119 */
120 public static final MathVariant SANS_SERIF_ITALIC = new MathVariant(
121 Font.ITALIC, FontFamily.SANSSERIF);
122
123 /**
124 * Mathvariant constant. Script style.
125 */
126 public static final MathVariant SCRIPT = new MathVariant(Font.PLAIN,
127 FontFamily.SCRIPT);
128
129 private static final Map<String, MathVariant> ATTRIBUTEMAP = new HashMap<String, MathVariant>();
130
131 private static final Map<FontFamily, Parameter> PARAMFORFONT = new HashMap<FontFamily, Parameter>();
132
133 /**
134 *
135 */
136 private static final long serialVersionUID = 1L;
137
138 /**
139 * Logger for this class.
140 */
141 private static final Log LOGGER = LogFactory
142 .getLog(CharacterMapping.class);
143
144 private static final Set<Integer> WARNED = new HashSet<Integer>();
145
146 private final int awtStyle;
147
148 private final FontFamily fontFamily;
149
150 /**
151 * Creates a Mathvariant with the given AWT-Style and font-family.
152 *
153 * @param awtstyle
154 * the awt Style
155 * @param family
156 * the font family
157 */
158 public MathVariant(final int awtstyle, final FontFamily family) {
159 this.awtStyle = awtstyle;
160 this.fontFamily = family;
161 };
162
163 /**
164 * Creates a Mathvariant object from an attribute value.
165 *
166 * @param variant
167 * the string representation of the attribute value
168 * @return a mathVariant object or null if none is found.
169 */
170 public static MathVariant stringToMathVariant(final String variant) {
171 synchronized (MathVariant.ATTRIBUTEMAP) {
172 // Needs to be initialized late due to chicken-egg problem.
173 if (MathVariant.ATTRIBUTEMAP.isEmpty()) {
174 MathVariant.ATTRIBUTEMAP.put("normal", MathVariant.NORMAL);
175 MathVariant.ATTRIBUTEMAP.put("bold", MathVariant.BOLD);
176 MathVariant.ATTRIBUTEMAP.put("italic", MathVariant.ITALIC);
177 MathVariant.ATTRIBUTEMAP.put("bold-italic",
178 MathVariant.BOLD_ITALIC);
179 MathVariant.ATTRIBUTEMAP.put("double-struck",
180 MathVariant.DOUBLE_STRUCK);
181 MathVariant.ATTRIBUTEMAP.put("bold-fraktur",
182 MathVariant.BOLD_FRAKTUR);
183 MathVariant.ATTRIBUTEMAP.put("script", MathVariant.SCRIPT);
184 MathVariant.ATTRIBUTEMAP.put("bold-script",
185 MathVariant.BOLD_SCRIPT);
186 MathVariant.ATTRIBUTEMAP.put("fraktur", MathVariant.FRAKTUR);
187 MathVariant.ATTRIBUTEMAP.put("sans-serif",
188 MathVariant.SANS_SERIF);
189 MathVariant.ATTRIBUTEMAP.put("bold-sans-serif",
190 MathVariant.BOLD_SANS_SERIF);
191 MathVariant.ATTRIBUTEMAP.put("sans-serif-italic",
192 MathVariant.SANS_SERIF_ITALIC);
193 MathVariant.ATTRIBUTEMAP.put("sans-serif-bold-italic",
194 MathVariant.SANS_SERIF_BOLD_ITALIC);
195 MathVariant.ATTRIBUTEMAP.put("monospace",
196 MathVariant.MONOSPACE);
197 }
198 return MathVariant.ATTRIBUTEMAP.get(variant
199 .toLowerCase(Locale.ENGLISH));
200 }
201 }
202
203 /**
204 * Create a font for the given attributes.
205 *
206 * @param size
207 * size of the font to create
208 * @param codepoint
209 * a character that must exist in this font
210 * @param context
211 * LayoutContext to use.
212 * @param force
213 * if true will always return a font, otherwise will return
214 * null.
215 * @return a font object.
216 */
217 @SuppressWarnings("unchecked")
218 public Font createFont(final float size, final int codepoint,
219 final LayoutContext context, final boolean force) {
220
221 final Parameter theParam = MathVariant.PARAMFORFONT
222 .get(this.fontFamily);
223 final Font font = FontFactory.getInstance().getFont(
224 (List<String>) context.getParameter(theParam), codepoint,
225 this.awtStyle, size);
226 if (force && font == null) {
227 if (!MathVariant.WARNED.contains(codepoint)) {
228 MathVariant.WARNED.add(codepoint);
229 final String hexString = Integer.toHexString(codepoint);
230 MathVariant.LOGGER
231 .warn("No font available to display character "
232 + hexString);
233 MathVariant.LOGGER
234 .info("Find a font at http://www.fileformat.info/info/unicode/char/"
235 + hexString
236 + "/fontsupport.htm or "
237 + "http://www.alanwood.net/unicode/search.html");
238 }
239 return FontFactory.getInstance().getFont(FontFactory.SANSSERIF,
240 this.awtStyle, size);
241 }
242 return font;
243 }
244
245 /**
246 * @return the awtStyle
247 */
248 public int getAwtStyle() {
249 return this.awtStyle;
250 }
251
252 /**
253 * @return the fontFamily
254 */
255 public FontFamily getFontFamily() {
256 return this.fontFamily;
257 }
258
259 static {
260 MathVariant.PARAMFORFONT.put(FontFamily.SERIF, Parameter.FONTS_SERIF);
261 MathVariant.PARAMFORFONT.put(FontFamily.SANSSERIF,
262 Parameter.FONTS_SANSSERIF);
263 MathVariant.PARAMFORFONT.put(FontFamily.MONOSPACED,
264 Parameter.FONTS_MONOSPACED);
265 MathVariant.PARAMFORFONT.put(FontFamily.SCRIPT,
266 Parameter.FONTS_SCRIPT);
267 MathVariant.PARAMFORFONT.put(FontFamily.FRAKTUR,
268 Parameter.FONTS_FRAKTUR);
269 MathVariant.PARAMFORFONT.put(FontFamily.DOUBLE_STRUCK,
270 Parameter.FONTS_DOUBLESTRUCK);
271 }
272
273 /** {@inheritDoc} */
274 @Override
275 public int hashCode() {
276 final int prime = 31;
277 int result;
278 if (this.fontFamily == null) {
279 result = 0;
280 } else {
281 result = this.fontFamily.hashCode();
282 }
283 result = prime * result + this.awtStyle;
284 return result;
285 }
286
287 /** {@inheritDoc} */
288 @Override
289 public boolean equals(final Object obj) {
290 if (this == obj) {
291 return true;
292 }
293 if (obj == null) {
294 return false;
295 }
296 if (this.getClass() != obj.getClass()) {
297 return false;
298 }
299 final MathVariant other = (MathVariant) obj;
300 if (this.awtStyle != other.awtStyle) {
301 return false;
302 }
303 if (this.fontFamily == null) {
304 if (other.fontFamily != null) {
305 return false;
306 }
307 } else if (!this.fontFamily.equals(other.fontFamily)) {
308 return false;
309 }
310 return true;
311 }
312
313 /** {@inheritDoc} */
314 @Override
315 public String toString() {
316 final StringBuilder b = new StringBuilder();
317 b.append('[');
318 b.append(this.fontFamily);
319 if (this.awtStyle > 0) {
320 b.append(' ');
321 }
322 if ((this.awtStyle & Font.BOLD) > 0) {
323 b.append('B');
324 }
325 if ((this.awtStyle & Font.ITALIC) > 0) {
326 b.append('I');
327 }
328 b.append(']');
329 return b.toString();
330 }
331 }