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 }