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.awt.geom.*;
035 import java.awt.*;
036
037
038 /**
039 * Implements an embedded font.
040 *
041 * SVG specification: http://www.w3.org/TR/SVG/fonts.html
042 *
043 * @author Mark McKay
044 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
045 */
046 public class FontFace extends SVGElement
047 {
048 String fontFamily;
049
050 /** Em size of coordinate system font is defined in */
051 int unitsPerEm = 1000;
052
053 int ascent = -1;
054 int descent = -1;
055 int accentHeight = -1;
056
057 int underlinePosition = -1;
058 int underlineThickness = -1;
059 int strikethroughPosition = -1;
060 int strikethroughThickness = -1;
061 int overlinePosition = -1;
062 int overlineThickness = -1;
063
064 /** Creates a new instance of Font */
065 public FontFace()
066 {
067 }
068 /*
069 public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
070 {
071 //Load style string
072 super.loaderStartElement(helper, attrs, parent);
073
074 fontFamily = attrs.getValue("font-family");
075
076 String unitsPerEm = attrs.getValue("units-per-em");
077 String ascent = attrs.getValue("ascent");
078 String descent = attrs.getValue("descent");
079 String accentHeight = attrs.getValue("accent-height");
080
081 String underlinePosition = attrs.getValue("underline-position");
082 String underlineThickness = attrs.getValue("underline-thickness");
083 String strikethroughPosition = attrs.getValue("strikethrough-position");
084 String strikethroughThickness = attrs.getValue("strikethrough-thickness");
085 String overlinePosition = attrs.getValue("overline-position");
086 String overlineThickness = attrs.getValue("overline-thickness");
087
088
089 if (unitsPerEm != null) this.unitsPerEm = XMLParseUtil.parseInt(unitsPerEm);
090 if (ascent != null) this.ascent = XMLParseUtil.parseInt(ascent);
091 if (descent != null) this.descent = XMLParseUtil.parseInt(descent);
092 if (accentHeight != null) this.accentHeight = XMLParseUtil.parseInt(accentHeight);
093
094 if (underlinePosition != null) this.underlinePosition = XMLParseUtil.parseInt(underlinePosition);
095 if (underlineThickness != null) this.underlineThickness = XMLParseUtil.parseInt(underlineThickness);
096 if (strikethroughPosition != null) this.strikethroughPosition = XMLParseUtil.parseInt(strikethroughPosition);
097 if (strikethroughThickness != null) this.strikethroughThickness = XMLParseUtil.parseInt(strikethroughThickness);
098 if (overlinePosition != null) this.overlinePosition = XMLParseUtil.parseInt(overlinePosition);
099 if (overlineThickness != null) this.overlineThickness = XMLParseUtil.parseInt(overlineThickness);
100
101 // unitFontXform.setToScale(1.0 / (double)unitsPerEm, 1.0 / (double)unitsPerEm);
102 }
103 */
104 /*
105 public void loaderEndElement(SVGLoaderHelper helper)
106 {
107 super.loaderEndElement(helper);
108
109 build();
110
111 // unitFontXform.setToScale(1.0 / (double)unitsPerEm, 1.0 / (double)unitsPerEm);
112 }
113 */
114
115 protected void build() throws SVGException
116 {
117 super.build();
118
119 StyleAttribute sty = new StyleAttribute();
120
121 if (getPres(sty.setName("font-family"))) fontFamily = sty.getStringValue();
122
123 if (getPres(sty.setName("units-per-em"))) unitsPerEm = sty.getIntValue();
124 if (getPres(sty.setName("ascent"))) ascent = sty.getIntValue();
125 if (getPres(sty.setName("descent"))) descent = sty.getIntValue();
126 if (getPres(sty.setName("accent-height"))) accentHeight = sty.getIntValue();
127
128 if (getPres(sty.setName("underline-position"))) underlinePosition = sty.getIntValue();
129 if (getPres(sty.setName("underline-thickness"))) underlineThickness = sty.getIntValue();
130 if (getPres(sty.setName("strikethrough-position"))) strikethroughPosition = sty.getIntValue();
131 if (getPres(sty.setName("strikethrough-thickenss"))) strikethroughThickness = sty.getIntValue();
132 if (getPres(sty.setName("overline-position"))) overlinePosition = sty.getIntValue();
133 if (getPres(sty.setName("overline-thickness"))) overlineThickness = sty.getIntValue();
134 }
135
136
137 public String getFontFamily() { return fontFamily; }
138
139 public int getUnitsPerEm() { return unitsPerEm; }
140
141 public int getAscent()
142 {
143 if (ascent == -1)
144 ascent = unitsPerEm - ((Font)parent).getVertOriginY();
145 return ascent;
146 }
147
148 public int getDescent()
149 {
150 if (descent == -1)
151 descent = ((Font)parent).getVertOriginY();
152 return descent;
153 }
154
155 public int getAccentHeight()
156 {
157 if (accentHeight == -1)
158 accentHeight = getAscent();
159 return accentHeight;
160 }
161
162 public int getUnderlinePosition()
163 {
164 if (underlinePosition == -1)
165 underlinePosition = unitsPerEm * 5 / 6;
166 return underlinePosition;
167 }
168
169 public int getUnderlineThickness()
170 {
171 if (underlineThickness == -1)
172 underlineThickness = unitsPerEm / 20;
173 return underlineThickness;
174 }
175
176 public int getStrikethroughPosition()
177 {
178 if (strikethroughPosition == -1)
179 strikethroughPosition = unitsPerEm * 3 / 6;
180 return strikethroughPosition;
181 }
182
183 public int getStrikethroughThickness()
184 {
185 if (strikethroughThickness == -1)
186 strikethroughThickness = unitsPerEm / 20;
187 return strikethroughThickness;
188 }
189
190 public int getOverlinePosition()
191 {
192 if (overlinePosition == -1)
193 overlinePosition = unitsPerEm * 5 / 6;
194 return overlinePosition;
195 }
196
197 public int getOverlineThickness()
198 {
199 if (overlineThickness == -1)
200 overlineThickness = unitsPerEm / 20;
201 return overlineThickness;
202 }
203
204 /**
205 * Updates all attributes in this diagram associated with a time event.
206 * Ie, all attributes with track information.
207 * @return - true if this node has changed state as a result of the time
208 * update
209 */
210 public boolean updateTime(double curTime)
211 {
212 //Fonts can't change
213 return false;
214 }
215 }