001    /*
002     * Copyright 2007 - 2008 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: JEuclidElement.java,v 371548310efa 2010/08/09 21:15:33 max $ */
018    
019    /*
020     * Please note: This file was originally taken from the Apache FOP project,
021     * available at http://xmlgraphics.apache.org/fop/ It is therefore
022     * partially copyright (c) 1999-2007 The Apache Software Foundation.
023     * 
024     * Parts of the contents are heavily inspired by work done for Barcode4J by
025     * Jeremias Maerki, available at http://barcode4j.sf.net/
026     */
027    
028    package net.sourceforge.jeuclid.fop;
029    
030    import java.awt.Color;
031    import java.awt.geom.Point2D;
032    import java.util.ArrayList;
033    import java.util.List;
034    
035    import net.sourceforge.jeuclid.Constants;
036    import net.sourceforge.jeuclid.MutableLayoutContext;
037    import net.sourceforge.jeuclid.context.LayoutContextImpl;
038    import net.sourceforge.jeuclid.context.Parameter;
039    import net.sourceforge.jeuclid.layout.JEuclidView;
040    import net.sourceforge.jeuclid.xmlgraphics.PreloaderMathML;
041    
042    import org.apache.fop.apps.FOPException;
043    import org.apache.fop.apps.FOUserAgent;
044    import org.apache.fop.datatypes.Length;
045    import org.apache.fop.fo.FOEventHandler;
046    import org.apache.fop.fo.FONode;
047    import org.apache.fop.fo.PropertyList;
048    import org.apache.fop.fo.properties.CommonFont;
049    import org.apache.fop.fo.properties.FixedLength;
050    import org.apache.fop.fo.properties.Property;
051    import org.apache.fop.fonts.FontInfo;
052    import org.apache.fop.fonts.FontTriplet;
053    import org.w3c.dom.Document;
054    import org.w3c.dom.Element;
055    import org.xml.sax.Attributes;
056    import org.xml.sax.Locator;
057    
058    /**
059     * Defines the top-level element for MathML.
060     * 
061     * @version $Revision: 371548310efa $
062     */
063    public class JEuclidElement extends JEuclidObj {
064    
065        private Point2D size;
066    
067        private Length baseline;
068    
069        private final MutableLayoutContext layoutContext;
070    
071        /**
072         * Default constructor.
073         * 
074         * @param parent
075         *            Parent Node in the FO tree.
076         */
077        public JEuclidElement(final FONode parent) {
078            super(parent);
079            this.layoutContext = new LayoutContextImpl(LayoutContextImpl
080                    .getDefaultLayoutContext());
081        }
082    
083        /** {@inheritDoc} */
084        @Override
085        public void processNode(final String elementName, final Locator locator,
086                final Attributes attlist, final PropertyList propertyList)
087                throws FOPException {
088            super.processNode(elementName, locator, attlist, propertyList);
089            final Document d = this.createBasicDocument();
090            final Element e = d.getDocumentElement();
091            for (final Parameter p : Parameter.values()) {
092                final String localName = p.getOptionName();
093                final String attrName = "jeuclid:" + localName;
094                final String isSet = e.getAttributeNS(Constants.NS_JEUCLID_EXT,
095                        localName);
096                if ((isSet == null) || (isSet.length() == 0)) {
097                    e.setAttributeNS(Constants.NS_JEUCLID_EXT, attrName, p
098                            .toString(this.layoutContext.getParameter(p)));
099                }
100            }
101        }
102    
103        private void calculate() {
104            final JEuclidView view = new JEuclidView(this.doc, this.layoutContext,
105                    null);
106            final float descent = view.getDescentHeight();
107            this.size = new Point2D.Float(view.getWidth(), view.getAscentHeight()
108                    + descent);
109            this.baseline = FixedLength.getInstance(-descent, "pt");
110        }
111    
112        /** {@inheritDoc} */
113        @Override
114        public Point2D getDimension(final Point2D view) {
115            if (this.size == null) {
116                this.calculate();
117            }
118            return this.size;
119        }
120    
121        /** {@inheritDoc} */
122        @Override
123        public Length getIntrinsicAlignmentAdjust() {
124            if (this.baseline == null) {
125                this.calculate();
126            }
127            return this.baseline;
128        }
129    
130        /** {@inheritDoc} */
131        @SuppressWarnings("unchecked")
132        @Override
133        protected PropertyList createPropertyList(final PropertyList pList,
134                final FOEventHandler foEventHandler) throws FOPException {
135            final FOUserAgent userAgent = this.getUserAgent();
136            final CommonFont commonFont = pList.getFontProps();
137            final float msize = (float) (commonFont.fontSize.getNumericValue() / PreloaderMathML.MPT_FACTOR);
138            final Property colorProp = pList
139                    .get(org.apache.fop.fo.Constants.PR_COLOR);
140            if (colorProp != null) {
141                final Color color = colorProp.getColor(userAgent);
142                this.layoutContext.setParameter(Parameter.MATHCOLOR, color);
143            }
144            final Property bcolorProp = pList
145                    .get(org.apache.fop.fo.Constants.PR_BACKGROUND_COLOR);
146            if (bcolorProp != null) {
147                final Color bcolor = bcolorProp.getColor(userAgent);
148                this.layoutContext.setParameter(Parameter.MATHBACKGROUND, bcolor);
149            }
150            final FontInfo fi = this.getFOEventHandler().getFontInfo();
151            final FontTriplet[] fontkeys = commonFont.getFontState(fi);
152    
153            this.layoutContext.setParameter(Parameter.MATHSIZE, msize);
154            final List<String> defaultFonts = (List<String>) this.layoutContext
155                    .getParameter(Parameter.FONTS_SERIF);
156            final List<String> newFonts = new ArrayList<String>(fontkeys.length
157                    + defaultFonts.size());
158            for (final FontTriplet t : fontkeys) {
159                newFonts.add(t.getName());
160            }
161            newFonts.addAll(defaultFonts);
162            this.layoutContext.setParameter(Parameter.FONTS_SERIF, newFonts);
163            return super.createPropertyList(pList, foEventHandler);
164        }
165    }