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    }