001/* 002 * SVG Salamander 003 * Copyright (c) 2004, Mark McKay 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or 007 * without modification, are permitted provided that the following 008 * conditions are met: 009 * 010 * - Redistributions of source code must retain the above 011 * copyright notice, this list of conditions and the following 012 * disclaimer. 013 * - Redistributions in binary form must reproduce the above 014 * copyright notice, this list of conditions and the following 015 * disclaimer in the documentation and/or other materials 016 * provided with the distribution. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 029 * OF THE POSSIBILITY OF SUCH DAMAGE. 030 * 031 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other 032 * projects can be found at http://www.kitfox.com 033 * 034 * Created on February 20, 2004, 10:00 PM 035 */ 036package com.kitfox.svg; 037 038import com.kitfox.svg.xml.StyleAttribute; 039import java.util.HashMap; 040 041/** 042 * Implements an embedded font. 043 * 044 * SVG specification: http://www.w3.org/TR/SVG/fonts.html 045 * 046 * @author Mark McKay 047 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a> 048 */ 049public class Font extends SVGElement 050{ 051 052 public static final String TAG_NAME = "font"; 053 int horizOriginX = 0; 054 int horizOriginY = 0; 055 int horizAdvX = -1; //Must be specified 056 int vertOriginX = -1; //Defaults to horizAdvX / 2 057 int vertOriginY = -1; //Defaults to font's ascent 058 int vertAdvY = -1; //Defaults to one 'em'. See font-face 059 FontFace fontFace = null; 060 MissingGlyph missingGlyph = null; 061 final HashMap<String, SVGElement> glyphs = new HashMap<String, SVGElement>(); 062 063 /** 064 * Creates a new instance of Font 065 */ 066 public Font() 067 { 068 } 069 070 @Override 071 public String getTagName() 072 { 073 return TAG_NAME; 074 } 075 076 /** 077 * Called after the start element but before the end element to indicate 078 * each child tag that has been processed 079 */ 080 @Override 081 public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException 082 { 083 super.loaderAddChild(helper, child); 084 085 if (child instanceof Glyph) 086 { 087 glyphs.put(((Glyph) child).getUnicode(), child); 088 } else if (child instanceof MissingGlyph) 089 { 090 missingGlyph = (MissingGlyph) child; 091 } else if (child instanceof FontFace) 092 { 093 fontFace = (FontFace) child; 094 } 095 } 096 097 @Override 098 public void loaderEndElement(SVGLoaderHelper helper) throws SVGParseException 099 { 100 super.loaderEndElement(helper); 101 102 //build(); 103 104 helper.universe.registerFont(this); 105 } 106 107 @Override 108 protected void build() throws SVGException 109 { 110 super.build(); 111 112 StyleAttribute sty = new StyleAttribute(); 113 114 if (getPres(sty.setName("horiz-origin-x"))) 115 { 116 horizOriginX = sty.getIntValue(); 117 } 118 119 if (getPres(sty.setName("horiz-origin-y"))) 120 { 121 horizOriginY = sty.getIntValue(); 122 } 123 124 if (getPres(sty.setName("horiz-adv-x"))) 125 { 126 horizAdvX = sty.getIntValue(); 127 } 128 129 if (getPres(sty.setName("vert-origin-x"))) 130 { 131 vertOriginX = sty.getIntValue(); 132 } 133 134 if (getPres(sty.setName("vert-origin-y"))) 135 { 136 vertOriginY = sty.getIntValue(); 137 } 138 139 if (getPres(sty.setName("vert-adv-y"))) 140 { 141 vertAdvY = sty.getIntValue(); 142 } 143 } 144 145 public FontFace getFontFace() 146 { 147 return fontFace; 148 } 149 150 public void setFontFace(FontFace face) 151 { 152 fontFace = face; 153 } 154 155 public MissingGlyph getGlyph(String unicode) 156 { 157 Glyph retVal = (Glyph) glyphs.get(unicode); 158 if (retVal == null) 159 { 160 return missingGlyph; 161 } 162 return retVal; 163 } 164 165 public int getHorizOriginX() 166 { 167 return horizOriginX; 168 } 169 170 public int getHorizOriginY() 171 { 172 return horizOriginY; 173 } 174 175 public int getHorizAdvX() 176 { 177 return horizAdvX; 178 } 179 180 public int getVertOriginX() 181 { 182 if (vertOriginX != -1) 183 { 184 return vertOriginX; 185 } 186 vertOriginX = getHorizAdvX() / 2; 187 return vertOriginX; 188 } 189 190 public int getVertOriginY() 191 { 192 if (vertOriginY != -1) 193 { 194 return vertOriginY; 195 } 196 vertOriginY = fontFace.getAscent(); 197 return vertOriginY; 198 } 199 200 public int getVertAdvY() 201 { 202 if (vertAdvY != -1) 203 { 204 return vertAdvY; 205 } 206 vertAdvY = fontFace.getUnitsPerEm(); 207 return vertAdvY; 208 } 209 210 /** 211 * Updates all attributes in this diagram associated with a time event. Ie, 212 * all attributes with track information. 213 * 214 * @return - true if this node has changed state as a result of the time 215 * update 216 */ 217 @Override 218 public boolean updateTime(double curTime) throws SVGException 219 { 220 //Fonts can't change 221 return false; 222 /* 223 if (trackManager.getNumTracks() == 0) return false; 224 225 //Get current values for parameters 226 StyleAttribute sty = new StyleAttribute(); 227 boolean stateChange = false; 228 229 if (getPres(sty.setName("horiz-origin-x"))) 230 { 231 int newVal = sty.getIntValue(); 232 if (newVal != horizOriginX) 233 { 234 horizOriginX = newVal; 235 stateChange = true; 236 } 237 } 238 239 if (getPres(sty.setName("horiz-origin-y"))) 240 { 241 int newVal = sty.getIntValue(); 242 if (newVal != horizOriginY) 243 { 244 horizOriginY = newVal; 245 stateChange = true; 246 } 247 } 248 249 if (getPres(sty.setName("horiz-adv-x"))) 250 { 251 int newVal = sty.getIntValue(); 252 if (newVal != horizAdvX) 253 { 254 horizAdvX = newVal; 255 stateChange = true; 256 } 257 } 258 259 if (getPres(sty.setName("vert-origin-x"))) 260 { 261 int newVal = sty.getIntValue(); 262 if (newVal != vertOriginX) 263 { 264 vertOriginX = newVal; 265 stateChange = true; 266 } 267 } 268 269 if (getPres(sty.setName("vert-origin-y"))) 270 { 271 int newVal = sty.getIntValue(); 272 if (newVal != vertOriginY) 273 { 274 vertOriginY = newVal; 275 stateChange = true; 276 } 277 } 278 279 if (getPres(sty.setName("vert-adv-y"))) 280 { 281 int newVal = sty.getIntValue(); 282 if (newVal != vertAdvY) 283 { 284 vertAdvY = newVal; 285 stateChange = true; 286 } 287 } 288 289 return shapeChange; 290 */ 291 } 292}