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 38db1a498ca5 2009/09/25 20:17:03 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.Graphics2D;
032    import java.awt.Image;
033    import java.awt.geom.Point2D;
034    import java.awt.image.BufferedImage;
035    import java.util.ArrayList;
036    import java.util.List;
037    
038    import net.sourceforge.jeuclid.Constants;
039    import net.sourceforge.jeuclid.MutableLayoutContext;
040    import net.sourceforge.jeuclid.context.LayoutContextImpl;
041    import net.sourceforge.jeuclid.context.Parameter;
042    import net.sourceforge.jeuclid.layout.JEuclidView;
043    import net.sourceforge.jeuclid.xmlgraphics.PreloaderMathML;
044    
045    import org.apache.fop.apps.FOPException;
046    import org.apache.fop.apps.FOUserAgent;
047    import org.apache.fop.datatypes.Length;
048    import org.apache.fop.fo.FOEventHandler;
049    import org.apache.fop.fo.FONode;
050    import org.apache.fop.fo.PropertyList;
051    import org.apache.fop.fo.properties.CommonFont;
052    import org.apache.fop.fo.properties.FixedLength;
053    import org.apache.fop.fo.properties.Property;
054    import org.apache.fop.fonts.FontInfo;
055    import org.apache.fop.fonts.FontTriplet;
056    import org.w3c.dom.Document;
057    import org.w3c.dom.Element;
058    import org.xml.sax.Attributes;
059    import org.xml.sax.Locator;
060    
061    /**
062     * Defines the top-level element for MathML.
063     * 
064     * @version $Revision: 38db1a498ca5 $
065     */
066    public class JEuclidElement extends JEuclidObj {
067    
068        private Point2D size;
069    
070        private Length baseline;
071    
072        private final MutableLayoutContext layoutContext;
073    
074        /**
075         * Default constructor.
076         * 
077         * @param parent
078         *            Parent Node in the FO tree.
079         */
080        public JEuclidElement(final FONode parent) {
081            super(parent);
082            this.layoutContext = new LayoutContextImpl(LayoutContextImpl
083                    .getDefaultLayoutContext());
084        }
085    
086        /** {@inheritDoc} */
087        @Override
088        public void processNode(final String elementName, final Locator locator,
089                final Attributes attlist, final PropertyList propertyList)
090                throws FOPException {
091            super.processNode(elementName, locator, attlist, propertyList);
092            final Document d = this.createBasicDocument();
093            final Element e = d.getDocumentElement();
094            for (final Parameter p : Parameter.values()) {
095                final String localName = p.getOptionName();
096                final String attrName = "jeuclid:" + localName;
097                final String isSet = e.getAttributeNS(Constants.NS_JEUCLID_EXT,
098                        localName);
099                if ((isSet == null) || (isSet.length() == 0)) {
100                    e.setAttributeNS(Constants.NS_JEUCLID_EXT, attrName, p
101                            .toString(this.layoutContext.getParameter(p)));
102                }
103            }
104        }
105    
106        private void calculate() {
107            final Image tempimage = new BufferedImage(1, 1,
108                    BufferedImage.TYPE_INT_ARGB);
109            final Graphics2D tempg = (Graphics2D) tempimage.getGraphics();
110            final JEuclidView view = new JEuclidView(this.doc, this.layoutContext,
111                    tempg);
112            final float descent = view.getDescentHeight();
113            this.size = new Point2D.Float(view.getWidth(), view.getAscentHeight()
114                    + descent);
115            this.baseline = FixedLength.getInstance(-descent, "pt");
116        }
117    
118        /** {@inheritDoc} */
119        @Override
120        public Point2D getDimension(final Point2D view) {
121            if (this.size == null) {
122                this.calculate();
123            }
124            return this.size;
125        }
126    
127        /** {@inheritDoc} */
128        @Override
129        public Length getIntrinsicAlignmentAdjust() {
130            if (this.baseline == null) {
131                this.calculate();
132            }
133            return this.baseline;
134        }
135    
136        /** {@inheritDoc} */
137        @SuppressWarnings("unchecked")
138        @Override
139        protected PropertyList createPropertyList(final PropertyList pList,
140                final FOEventHandler foEventHandler) throws FOPException {
141            final FOUserAgent userAgent = this.getUserAgent();
142            final CommonFont commonFont = pList.getFontProps();
143            final float msize = (float) (commonFont.fontSize.getNumericValue() / PreloaderMathML.MPT_FACTOR);
144            final Property colorProp = pList
145                    .get(org.apache.fop.fo.Constants.PR_COLOR);
146            if (colorProp != null) {
147                final Color color = colorProp.getColor(userAgent);
148                this.layoutContext.setParameter(Parameter.MATHCOLOR, color);
149            }
150            final Property bcolorProp = pList
151                    .get(org.apache.fop.fo.Constants.PR_BACKGROUND_COLOR);
152            if (bcolorProp != null) {
153                final Color bcolor = bcolorProp.getColor(userAgent);
154                this.layoutContext.setParameter(Parameter.MATHBACKGROUND, bcolor);
155            }
156            final FontInfo fi = this.getFOEventHandler().getFontInfo();
157            final FontTriplet[] fontkeys = commonFont.getFontState(fi);
158    
159            this.layoutContext.setParameter(Parameter.MATHSIZE, msize);
160            final List<String> defaultFonts = (List<String>) this.layoutContext
161                    .getParameter(Parameter.FONTS_SERIF);
162            final List<String> newFonts = new ArrayList<String>(fontkeys.length
163                    + defaultFonts.size());
164            for (final FontTriplet t : fontkeys) {
165                newFonts.add(t.getName());
166            }
167            newFonts.addAll(defaultFonts);
168            this.layoutContext.setParameter(Parameter.FONTS_SERIF, newFonts);
169            return super.createPropertyList(pList, foEventHandler);
170        }
171    }