Source for gnu.javax.swing.text.html.css.FontSize

   1: /* FontSize.java -- Converts CSS font size values into real values
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.javax.swing.text.html.css;
  40: 
  41: /**
  42:  * Converts CSS font-size values into real (point) values.
  43:  *
  44:  * @author Roman Kennke (kennke@aicas.com)
  45:  */
  46: public class FontSize
  47: {
  48: 
  49:   /**
  50:    * The CSS value.
  51:    */
  52:   private String value;
  53: 
  54:   /**
  55:    * The actual font size.
  56:    */
  57:   private int size;
  58: 
  59:   /**
  60:    * The index of one of the standard sizes that this font size maps to.
  61:    * This is -1 if this fontsize doesn't map to one of the standard sizes.
  62:    *
  63:    * @see #SCALE
  64:    */
  65:   private int sizeIndex;
  66: 
  67:   /**
  68:    * True when this font size is relative.
  69:    */
  70:   private boolean isRelative;
  71: 
  72:   /**
  73:    * The default size for 'medium' absolute size. The other absolute sizes
  74:    * are calculated from this.
  75:    */
  76:   public static final int DEFAULT_FONT_SIZE = 12;
  77: 
  78:   /**
  79:    * The scaling factors relative to the medium size. Medium is at index 2.
  80:    */
  81:   private static final double[] SCALE = {0.8, 0.9, 1.0, 1.2, 1.4, 1.6, 1.8 };
  82: 
  83:   /**
  84:    * Creates a new FontSize for the specified value.
  85:    *
  86:    * @param val the value to convert
  87:    */
  88:   public FontSize(String val)
  89:   {
  90:     value = val;
  91:     sizeIndex = -1;
  92:     isRelative = false;
  93:     size = mapValue();
  94:   }
  95: 
  96:   /**
  97:    * Returns the font size value.
  98:    *
  99:    * @return the font size value
 100:    */
 101:   public int getValue(int p)
 102:   {
 103:     if (isRelative)
 104:       mapRelative(p);
 105:     return size;
 106:   }
 107: 
 108:   public int getValue()
 109:   {
 110:     assert ! isRelative;
 111:     return size;
 112:   }
 113: 
 114:   /**
 115:    * Returns the converted real value in point.
 116:    *
 117:    * @return the converted real value in point
 118:    */
 119:   private int mapValue()
 120:   {
 121:     int intVal;
 122:     if (value.contains("pt"))
 123:       intVal = mapPoints();
 124:     else if (value.contains("px"))
 125:       intVal = mapPixels();
 126:     else if (value.contains("em") || value.contains("%")
 127:         || value.contains("larger") || value.contains("smaller"))
 128:       {
 129:         intVal = -1;
 130:         isRelative = true;
 131:       }
 132:     else
 133:       intVal = mapAbsolute();
 134:     return intVal;
 135:   }
 136: 
 137:   /**
 138:    * Maps point values ('XXXpt').
 139:    *
 140:    * @return the real font size
 141:    */
 142:   private int mapPoints()
 143:   {
 144:     int end = value.indexOf("pt");
 145:     String number = value.substring(0, end);
 146:     int intVal = (int) Double.parseDouble(number);
 147:     return intVal;
 148:   }
 149: 
 150:   /**
 151:    * Maps pixel values ('XXXpx').
 152:    *
 153:    * @return the real font size
 154:    */
 155:   private int mapPixels()
 156:   {
 157:     int end = value.indexOf("px");
 158:     if (end == -1)
 159:       end = value.length();
 160:     String number = value.substring(0, end);
 161:     try
 162:       {
 163:         int intVal = (int) Double.parseDouble(number);
 164:         return intVal;
 165:       }
 166:     catch (NumberFormatException ex)
 167:       {
 168:         return DEFAULT_FONT_SIZE;
 169:       }
 170:   }
 171: 
 172:   private int mapPercent(int par)
 173:   {
 174:     int end = value.indexOf("%");
 175:     if (end == -1)
 176:       end = value.length();
 177:     String number = value.substring(0, end);
 178:     try
 179:       {
 180:         int intVal = (int) Double.parseDouble(number);
 181:         return intVal * par / 100;
 182:       }
 183:     catch (NumberFormatException ex)
 184:       {
 185:         System.err.println("couldn't map value: '" + value + "'");
 186:         return DEFAULT_FONT_SIZE;
 187:       }
 188:   }
 189: 
 190:   private int mapEM(int par)
 191:   {
 192:     int end = value.indexOf("em");
 193:     if (end == -1)
 194:       end = value.length();
 195:     String number = value.substring(0, end);
 196:     try
 197:       {
 198:         float factor = Float.parseFloat(number);
 199:         // FIXME: Should be relative to the parent element's size.
 200:         return (int) (factor * par);
 201:       }
 202:     catch (NumberFormatException ex)
 203:       {
 204:         return DEFAULT_FONT_SIZE;
 205:       }
 206:   }
 207: 
 208:   private int mapSmaller(int par)
 209:   {
 210:     return (int) (par * 0.9);
 211:   }
 212: 
 213:   private int mapLarger(int par)
 214:   {
 215:     return (int) (par * 0.9);
 216:   }
 217: 
 218:   /**
 219:    * Maps absolute font-size values.
 220:    *
 221:    * @return the real value
 222:    */
 223:   private int mapAbsolute()
 224:   {
 225:     int index;
 226:     if (value.equals("xx-small") || value.equals("x-small"))
 227:       index = 0;
 228:     else if (value.equals("small"))
 229:       index = 1;
 230:     else if (value.equals("medium"))
 231:       index = 2;
 232:     else if (value.equals("large"))
 233:       index = 3;
 234:     else if (value.equals("x-large"))
 235:       index = 4;
 236:     else if (value.equals("xx-large"))
 237:       index = 5;
 238:     else
 239:       index = 2;
 240:     double scale = SCALE[index];
 241:     // FIXME: Scale the real medium size of the document, rather than the
 242:     // constant here.
 243:     int intVal = (int) (scale * DEFAULT_FONT_SIZE);
 244:     sizeIndex = index;
 245:     return intVal;
 246:   }
 247: 
 248:   /**
 249:    * Returns the string representation.
 250:    */
 251:   public String toString()
 252:   {
 253:     return value;
 254:   }
 255: 
 256:   private int mapRelative(int par)
 257:   {
 258:     if (value.indexOf('%') != -1)
 259:       size = mapPercent(par);
 260:     else if (value.indexOf("em") != -1)
 261:       size = mapEM(par);
 262:     else if (value.indexOf("larger") != -1)
 263:       size = mapLarger(par);
 264:     else if (value.indexOf("smaller") != -1)
 265:       size = mapSmaller(par);
 266:     return size;
 267:   }
 268: 
 269:   public boolean isRelative()
 270:   {
 271:     return isRelative;
 272:   }
 273: }