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    }