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 MissingGlyph getGlyph(String unicode) 147 { 148 Glyph retVal = (Glyph) glyphs.get(unicode); 149 if (retVal == null) 150 { 151 return missingGlyph; 152 } 153 return retVal; 154 } 155 156 public int getHorizOriginX() 157 { 158 return horizOriginX; 159 } 160 161 public int getHorizOriginY() 162 { 163 return horizOriginY; 164 } 165 166 public int getHorizAdvX() 167 { 168 return horizAdvX; 169 } 170 171 public int getVertOriginX() 172 { 173 if (vertOriginX != -1) 174 { 175 return vertOriginX; 176 } 177 vertOriginX = getHorizAdvX() / 2; 178 return vertOriginX; 179 } 180 181 public int getVertOriginY() 182 { 183 if (vertOriginY != -1) 184 { 185 return vertOriginY; 186 } 187 vertOriginY = fontFace.getAscent(); 188 return vertOriginY; 189 } 190 191 public int getVertAdvY() 192 { 193 if (vertAdvY != -1) 194 { 195 return vertAdvY; 196 } 197 vertAdvY = fontFace.getUnitsPerEm(); 198 return vertAdvY; 199 } 200 201 /** 202 * Updates all attributes in this diagram associated with a time event. Ie, 203 * all attributes with track information. 204 * 205 * @return - true if this node has changed state as a result of the time 206 * update 207 */ 208 public boolean updateTime(double curTime) throws SVGException 209 { 210 //Fonts can't change 211 return false; 212 /* 213 if (trackManager.getNumTracks() == 0) return false; 214 215 //Get current values for parameters 216 StyleAttribute sty = new StyleAttribute(); 217 boolean stateChange = false; 218 219 if (getPres(sty.setName("horiz-origin-x"))) 220 { 221 int newVal = sty.getIntValue(); 222 if (newVal != horizOriginX) 223 { 224 horizOriginX = newVal; 225 stateChange = true; 226 } 227 } 228 229 if (getPres(sty.setName("horiz-origin-y"))) 230 { 231 int newVal = sty.getIntValue(); 232 if (newVal != horizOriginY) 233 { 234 horizOriginY = newVal; 235 stateChange = true; 236 } 237 } 238 239 if (getPres(sty.setName("horiz-adv-x"))) 240 { 241 int newVal = sty.getIntValue(); 242 if (newVal != horizAdvX) 243 { 244 horizAdvX = newVal; 245 stateChange = true; 246 } 247 } 248 249 if (getPres(sty.setName("vert-origin-x"))) 250 { 251 int newVal = sty.getIntValue(); 252 if (newVal != vertOriginX) 253 { 254 vertOriginX = newVal; 255 stateChange = true; 256 } 257 } 258 259 if (getPres(sty.setName("vert-origin-y"))) 260 { 261 int newVal = sty.getIntValue(); 262 if (newVal != vertOriginY) 263 { 264 vertOriginY = newVal; 265 stateChange = true; 266 } 267 } 268 269 if (getPres(sty.setName("vert-adv-y"))) 270 { 271 int newVal = sty.getIntValue(); 272 if (newVal != vertAdvY) 273 { 274 vertAdvY = newVal; 275 stateChange = true; 276 } 277 } 278 279 return shapeChange; 280 */ 281 } 282}