View Javadoc

1   /*
2    * Copyright 2002 - 2008 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: MathVariant.java,v e6bd6c2d9bf4 2008/11/28 15:02:26 maxberger $ */
18  
19  package net.sourceforge.jeuclid.elements.support.attributes;
20  
21  import java.awt.Font;
22  import java.io.Serializable;
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import net.sourceforge.jeuclid.LayoutContext;
31  import net.sourceforge.jeuclid.context.Parameter;
32  import net.sourceforge.jeuclid.elements.support.text.CharacterMapping;
33  import net.sourceforge.jeuclid.font.FontFactory;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  
38  /**
39   * Class to represent and use MathVariants.
40   * 
41   * @version $Revision: e6bd6c2d9bf4 $
42   */
43  public final class MathVariant implements Serializable {
44  
45      /**
46       * Mathvariant constant. Bold style.
47       */
48      public static final MathVariant BOLD = new MathVariant(Font.BOLD,
49              FontFamily.SERIF);
50  
51      /**
52       * Mathvariant constant. Bold fraktur style.
53       */
54      public static final MathVariant BOLD_FRAKTUR = new MathVariant(Font.BOLD,
55              FontFamily.FRAKTUR);
56  
57      /**
58       * Mathvariant constant. Bold-italic style.
59       */
60      public static final MathVariant BOLD_ITALIC = new MathVariant(Font.BOLD
61              | Font.ITALIC, FontFamily.SERIF);
62  
63      /**
64       * Mathvariant constant. Bold sans-serif style.
65       */
66      public static final MathVariant BOLD_SANS_SERIF = new MathVariant(
67              Font.BOLD, FontFamily.SANSSERIF);
68  
69      /**
70       * Mathvariant constant. Bold script style.
71       */
72      public static final MathVariant BOLD_SCRIPT = new MathVariant(Font.BOLD,
73              FontFamily.SCRIPT);
74  
75      /**
76       * Mathvariant constant. Double struck style.
77       */
78      public static final MathVariant DOUBLE_STRUCK = new MathVariant(
79              Font.PLAIN, FontFamily.DOUBLE_STRUCK);
80  
81      /**
82       * Mathvariant constant. Fraktur style.
83       */
84      public static final MathVariant FRAKTUR = new MathVariant(Font.PLAIN,
85              FontFamily.FRAKTUR);
86  
87      /**
88       * Mathvariant constant. Italic style.
89       */
90      public static final MathVariant ITALIC = new MathVariant(Font.ITALIC,
91              FontFamily.SERIF);
92  
93      /**
94       * Mathvariant constant. Monospace style.
95       */
96      public static final MathVariant MONOSPACE = new MathVariant(Font.PLAIN,
97              FontFamily.MONOSPACED);
98  
99      /**
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 }