001 /*
002 * Font.java
003 *
004 *
005 * The Salamander Project - 2D and 3D graphics libraries in Java
006 * Copyright (C) 2004 Mark McKay
007 *
008 * This library is free software; you can redistribute it and/or
009 * modify it under the terms of the GNU Lesser General Public
010 * License as published by the Free Software Foundation; either
011 * version 2.1 of the License, or (at your option) any later version.
012 *
013 * This library is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public
019 * License along with this library; if not, write to the Free Software
020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021 *
022 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
023 * projects can be found at http://www.kitfox.com
024 *
025 * Created on February 20, 2004, 10:00 PM
026 */
027
028 package com.kitfox.svg;
029
030 import com.kitfox.svg.xml.StyleAttribute;
031 import com.kitfox.svg.xml.*;
032 import org.xml.sax.*;
033
034 import java.util.*;
035
036 /**
037 * Implements an embedded font.
038 *
039 * SVG specification: http://www.w3.org/TR/SVG/fonts.html
040 *
041 * @author Mark McKay
042 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
043 */
044 public class Font extends SVGElement
045 {
046 int horizOriginX = 0;
047 int horizOriginY = 0;
048 int horizAdvX = -1; //Must be specified
049 int vertOriginX = -1; //Defaults to horizAdvX / 2
050 int vertOriginY = -1; //Defaults to font's ascent
051 int vertAdvY = -1; //Defaults to one 'em'. See font-face
052
053 FontFace fontFace = null;
054 MissingGlyph missingGlyph = null;
055 final HashMap glyphs = new HashMap();
056
057 /** Creates a new instance of Font */
058 public Font()
059 {
060 }
061 /*
062 public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
063 {
064 //Load style string
065 super.loaderStartElement(helper, attrs, parent);
066
067 String horizOriginX = attrs.getValue("horiz-origin-x");
068 String horizOriginY = attrs.getValue("horiz-origin-y");
069 String horizAdvX = attrs.getValue("horiz-adv-x");
070 String vertOriginX = attrs.getValue("vert-origin-x");
071 String vertOriginY = attrs.getValue("vert-origin-y");
072 String vertAdvY = attrs.getValue("vert-adv-y");
073
074 if (horizOriginX != null) this.horizOriginX = XMLParseUtil.parseInt(horizOriginX);
075 if (horizOriginY != null) this.horizOriginY = XMLParseUtil.parseInt(horizOriginY);
076 if (horizAdvX != null) this.horizAdvX = XMLParseUtil.parseInt(horizAdvX);
077 if (vertOriginX != null) this.vertOriginX = XMLParseUtil.parseInt(vertOriginX);
078 if (vertOriginY != null) this.vertOriginY = XMLParseUtil.parseInt(vertOriginY);
079 if (vertAdvY != null) this.vertAdvY = XMLParseUtil.parseInt(vertAdvY);
080
081 }
082 */
083 /**
084 * Called after the start element but before the end element to indicate
085 * each child tag that has been processed
086 */
087 public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException
088 {
089 super.loaderAddChild(helper, child);
090
091 if (child instanceof Glyph)
092 {
093 glyphs.put(((Glyph)child).getUnicode(), child);
094 }
095 else if (child instanceof MissingGlyph)
096 {
097 missingGlyph = (MissingGlyph)child;
098 }
099 else if (child instanceof FontFace)
100 {
101 fontFace = (FontFace)child;
102 }
103 }
104
105 public void loaderEndElement(SVGLoaderHelper helper) throws SVGParseException
106 {
107 super.loaderEndElement(helper);
108
109 //build();
110
111 helper.universe.registerFont(this);
112 }
113
114 protected void build() throws SVGException
115 {
116 super.build();
117
118 StyleAttribute sty = new StyleAttribute();
119
120 if (getPres(sty.setName("horiz-origin-x"))) horizOriginX = sty.getIntValue();
121
122 if (getPres(sty.setName("horiz-origin-y"))) horizOriginY = sty.getIntValue();
123
124 if (getPres(sty.setName("horiz-adv-x"))) horizAdvX = sty.getIntValue();
125
126 if (getPres(sty.setName("vert-origin-x"))) vertOriginX = sty.getIntValue();
127
128 if (getPres(sty.setName("vert-origin-y"))) vertOriginY = sty.getIntValue();
129
130 if (getPres(sty.setName("vert-adv-y"))) vertAdvY = sty.getIntValue();
131 }
132
133 public FontFace getFontFace() { return fontFace; }
134
135 public MissingGlyph getGlyph(String unicode)
136 {
137 Glyph retVal = (Glyph)glyphs.get(unicode);
138 if (retVal == null) return missingGlyph;
139 return retVal;
140 }
141
142 public int getHorizOriginX() { return horizOriginX; }
143 public int getHorizOriginY() { return horizOriginY; }
144 public int getHorizAdvX() { return horizAdvX; }
145
146 public int getVertOriginX()
147 {
148 if (vertOriginX != -1) return vertOriginX;
149 vertOriginX = getHorizAdvX() / 2;
150 return vertOriginX;
151 }
152
153 public int getVertOriginY()
154 {
155 if (vertOriginY != -1) return vertOriginY;
156 vertOriginY = fontFace.getAscent();
157 return vertOriginY;
158 }
159
160 public int getVertAdvY()
161 {
162 if (vertAdvY != -1) return vertAdvY;
163 vertAdvY = fontFace.getUnitsPerEm();
164 return vertAdvY;
165 }
166
167 /**
168 * Updates all attributes in this diagram associated with a time event.
169 * Ie, all attributes with track information.
170 * @return - true if this node has changed state as a result of the time
171 * update
172 */
173 public boolean updateTime(double curTime) throws SVGException
174 {
175 //Fonts can't change
176 return false;
177 /*
178 if (trackManager.getNumTracks() == 0) return false;
179
180 //Get current values for parameters
181 StyleAttribute sty = new StyleAttribute();
182 boolean stateChange = false;
183
184 if (getPres(sty.setName("horiz-origin-x")))
185 {
186 int newVal = sty.getIntValue();
187 if (newVal != horizOriginX)
188 {
189 horizOriginX = newVal;
190 stateChange = true;
191 }
192 }
193
194 if (getPres(sty.setName("horiz-origin-y")))
195 {
196 int newVal = sty.getIntValue();
197 if (newVal != horizOriginY)
198 {
199 horizOriginY = newVal;
200 stateChange = true;
201 }
202 }
203
204 if (getPres(sty.setName("horiz-adv-x")))
205 {
206 int newVal = sty.getIntValue();
207 if (newVal != horizAdvX)
208 {
209 horizAdvX = newVal;
210 stateChange = true;
211 }
212 }
213
214 if (getPres(sty.setName("vert-origin-x")))
215 {
216 int newVal = sty.getIntValue();
217 if (newVal != vertOriginX)
218 {
219 vertOriginX = newVal;
220 stateChange = true;
221 }
222 }
223
224 if (getPres(sty.setName("vert-origin-y")))
225 {
226 int newVal = sty.getIntValue();
227 if (newVal != vertOriginY)
228 {
229 vertOriginY = newVal;
230 stateChange = true;
231 }
232 }
233
234 if (getPres(sty.setName("vert-adv-y")))
235 {
236 int newVal = sty.getIntValue();
237 if (newVal != vertAdvY)
238 {
239 vertAdvY = newVal;
240 stateChange = true;
241 }
242 }
243
244 return shapeChange;
245 */
246 }
247 }