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 glyphs = new HashMap(); 062 063 /** 064 * Creates a new instance of Font 065 */ 066 public Font() 067 { 068 } 069 070 public String getTagName() 071 { 072 return TAG_NAME; 073 } 074 075 /** 076 * Called after the start element but before the end element to indicate 077 * each child tag that has been processed 078 */ 079 public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException 080 { 081 super.loaderAddChild(helper, child); 082 083 if (child instanceof Glyph) 084 { 085 glyphs.put(((Glyph) child).getUnicode(), child); 086 } else if (child instanceof MissingGlyph) 087 { 088 missingGlyph = (MissingGlyph) child; 089 } else if (child instanceof FontFace) 090 { 091 fontFace = (FontFace) child; 092 } 093 } 094 095 public void loaderEndElement(SVGLoaderHelper helper) throws SVGParseException 096 { 097 super.loaderEndElement(helper); 098 099 //build(); 100 101 helper.universe.registerFont(this); 102 } 103 104 protected void build() throws SVGException 105 { 106 super.build(); 107 108 StyleAttribute sty = new StyleAttribute(); 109 110 if (getPres(sty.setName("horiz-origin-x"))) 111 { 112 horizOriginX = sty.getIntValue(); 113 } 114 115 if (getPres(sty.setName("horiz-origin-y"))) 116 { 117 horizOriginY = sty.getIntValue(); 118 } 119 120 if (getPres(sty.setName("horiz-adv-x"))) 121 { 122 horizAdvX = sty.getIntValue(); 123 } 124 125 if (getPres(sty.setName("vert-origin-x"))) 126 { 127 vertOriginX = sty.getIntValue(); 128 } 129 130 if (getPres(sty.setName("vert-origin-y"))) 131 { 132 vertOriginY = sty.getIntValue(); 133 } 134 135 if (getPres(sty.setName("vert-adv-y"))) 136 { 137 vertAdvY = sty.getIntValue(); 138 } 139 } 140 141 public FontFace getFontFace() 142 { 143 return fontFace; 144 } 145 146 public void setFontFace(FontFace face) 147 { 148 fontFace = face; 149 } 150 151 public MissingGlyph getGlyph(String unicode) 152 { 153 Glyph retVal = (Glyph) glyphs.get(unicode); 154 if (retVal == null) 155 { 156 return missingGlyph; 157 } 158 return retVal; 159 } 160 161 public int getHorizOriginX() 162 { 163 return horizOriginX; 164 } 165 166 public int getHorizOriginY() 167 { 168 return horizOriginY; 169 } 170 171 public int getHorizAdvX() 172 { 173 return horizAdvX; 174 } 175 176 public int getVertOriginX() 177 { 178 if (vertOriginX != -1) 179 { 180 return vertOriginX; 181 } 182 vertOriginX = getHorizAdvX() / 2; 183 return vertOriginX; 184 } 185 186 public int getVertOriginY() 187 { 188 if (vertOriginY != -1) 189 { 190 return vertOriginY; 191 } 192 vertOriginY = fontFace.getAscent(); 193 return vertOriginY; 194 } 195 196 public int getVertAdvY() 197 { 198 if (vertAdvY != -1) 199 { 200 return vertAdvY; 201 } 202 vertAdvY = fontFace.getUnitsPerEm(); 203 return vertAdvY; 204 } 205 206 /** 207 * Updates all attributes in this diagram associated with a time event. Ie, 208 * all attributes with track information. 209 * 210 * @return - true if this node has changed state as a result of the time 211 * update 212 */ 213 public boolean updateTime(double curTime) throws SVGException 214 { 215 //Fonts can't change 216 return false; 217 /* 218 if (trackManager.getNumTracks() == 0) return false; 219 220 //Get current values for parameters 221 StyleAttribute sty = new StyleAttribute(); 222 boolean stateChange = false; 223 224 if (getPres(sty.setName("horiz-origin-x"))) 225 { 226 int newVal = sty.getIntValue(); 227 if (newVal != horizOriginX) 228 { 229 horizOriginX = newVal; 230 stateChange = true; 231 } 232 } 233 234 if (getPres(sty.setName("horiz-origin-y"))) 235 { 236 int newVal = sty.getIntValue(); 237 if (newVal != horizOriginY) 238 { 239 horizOriginY = newVal; 240 stateChange = true; 241 } 242 } 243 244 if (getPres(sty.setName("horiz-adv-x"))) 245 { 246 int newVal = sty.getIntValue(); 247 if (newVal != horizAdvX) 248 { 249 horizAdvX = newVal; 250 stateChange = true; 251 } 252 } 253 254 if (getPres(sty.setName("vert-origin-x"))) 255 { 256 int newVal = sty.getIntValue(); 257 if (newVal != vertOriginX) 258 { 259 vertOriginX = newVal; 260 stateChange = true; 261 } 262 } 263 264 if (getPres(sty.setName("vert-origin-y"))) 265 { 266 int newVal = sty.getIntValue(); 267 if (newVal != vertOriginY) 268 { 269 vertOriginY = newVal; 270 stateChange = true; 271 } 272 } 273 274 if (getPres(sty.setName("vert-adv-y"))) 275 { 276 int newVal = sty.getIntValue(); 277 if (newVal != vertAdvY) 278 { 279 vertAdvY = newVal; 280 stateChange = true; 281 } 282 } 283 284 return shapeChange; 285 */ 286 } 287}