001    /*
002     * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    /* $Id: Mglyph.java,v 923658a2b249 2009/09/11 09:57:31 max $ */
018    
019    package net.sourceforge.jeuclid.elements.presentation.token;
020    
021    import java.awt.Font;
022    import java.awt.font.TextAttribute;
023    import java.text.AttributedCharacterIterator;
024    import java.text.AttributedString;
025    
026    import net.sourceforge.jeuclid.LayoutContext;
027    import net.sourceforge.jeuclid.elements.support.GraphicsSupport;
028    import net.sourceforge.jeuclid.elements.support.text.StringUtil;
029    import net.sourceforge.jeuclid.elements.support.text.TextContentModifier;
030    import net.sourceforge.jeuclid.font.FontFactory;
031    
032    import org.apache.batik.dom.AbstractDocument;
033    import org.w3c.dom.Node;
034    import org.w3c.dom.mathml.MathMLGlyphElement;
035    
036    /**
037     * Implements the mglyph element.
038     * 
039     * <p>
040     * TODO: FontFamliy gives a "deprecated attribute" warning due to the current
041     * design.
042     * <p>
043     * TODO: other attributes (such as italic, bold, etc.) may be inherited from the
044     * context.
045     * 
046     * @version $Revision: 923658a2b249 $
047     */
048    public final class Mglyph extends AbstractTokenWithTextLayout implements
049            MathMLGlyphElement, TextContentModifier {
050    
051        /**
052         * The XML element from this class.
053         */
054        public static final String ELEMENT = "mglyph";
055    
056        private static final String ATTR_ALT = "alt";
057    
058        private static final String ATTR_FONTFAMILY = "fontfamily";
059    
060        private static final String ATTR_INDEX = "index";
061    
062        private static final long serialVersionUID = 1L;
063    
064        /**
065         * Default constructor. Sets MathML Namespace.
066         * 
067         * @param qname
068         *            Qualified name.
069         * @param odoc
070         *            Owner Document.
071         */
072        public Mglyph(final String qname, final AbstractDocument odoc) {
073            super(qname, odoc);
074        }
075    
076        /** {@inheritDoc} */
077        @Override
078        protected Node newNode() {
079            return new Mglyph(this.nodeName, this.ownerDocument);
080        }
081    
082        /** {@inheritDoc} */
083    
084        public AttributedCharacterIterator modifyTextContent(
085                final AttributedCharacterIterator aci, final LayoutContext now) {
086            final AttributedString retVal;
087            final String ffamily = this.getFontfamily();
088            final String fontFamily;
089            if (ffamily == null) {
090                fontFamily = "serif";
091            } else {
092                fontFamily = ffamily.trim();
093            }
094            final Font font = FontFactory.getInstance().getFont(fontFamily,
095                    Font.PLAIN, GraphicsSupport.getFontsizeInPoint(now));
096            final int codePoint = this.getIndex();
097            if ((codePoint > 0) && (font.getFamily().equalsIgnoreCase(fontFamily))
098                    && (font.canDisplay(codePoint))) {
099                retVal = new AttributedString(new String(new int[] { codePoint },
100                        0, 1));
101                retVal.addAttribute(TextAttribute.FONT, font);
102            } else {
103                retVal = StringUtil.convertStringtoAttributedString(this.getAlt(),
104                        this.getMathvariantAsVariant(), GraphicsSupport
105                                .getFontsizeInPoint(now), now);
106            }
107            return retVal.getIterator();
108        }
109    
110        /** {@inheritDoc} */
111        public String getAlt() {
112            return this.getMathAttribute(Mglyph.ATTR_ALT);
113        }
114    
115        /** {@inheritDoc} */
116        public String getFontfamily() {
117            return this.getMathAttribute(Mglyph.ATTR_FONTFAMILY);
118        }
119    
120        /** {@inheritDoc} */
121        public int getIndex() {
122            int retVal = 0;
123            final String indexStr = this.getMathAttribute(Mglyph.ATTR_INDEX);
124            try {
125                if (indexStr != null) {
126                    retVal = Integer.parseInt(indexStr);
127                }
128            } catch (final NumberFormatException e) {
129                retVal = 0;
130            }
131            return retVal;
132        }
133    
134        /** {@inheritDoc} */
135        public void setAlt(final String alt) {
136            this.setAttribute(Mglyph.ATTR_ALT, alt);
137        }
138    
139        /** {@inheritDoc} */
140        public void setFontfamily(final String fontfamily) {
141            this.setAttribute(Mglyph.ATTR_FONTFAMILY, fontfamily);
142        }
143    
144        /** {@inheritDoc} */
145        public void setIndex(final int index) {
146            this.setAttribute(Mglyph.ATTR_INDEX, Integer.toString(index));
147        }
148    
149    }