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$ */
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
028package net.sourceforge.jeuclid.fop;
029
030import java.awt.Color;
031import java.awt.geom.Point2D;
032import java.util.ArrayList;
033import java.util.List;
034
035import net.sourceforge.jeuclid.Constants;
036import net.sourceforge.jeuclid.MutableLayoutContext;
037import net.sourceforge.jeuclid.context.LayoutContextImpl;
038import net.sourceforge.jeuclid.context.Parameter;
039import net.sourceforge.jeuclid.layout.JEuclidView;
040import net.sourceforge.jeuclid.xmlgraphics.PreloaderMathML;
041
042import org.apache.fop.apps.FOPException;
043import org.apache.fop.apps.FOUserAgent;
044import org.apache.fop.datatypes.Length;
045import org.apache.fop.fo.FOEventHandler;
046import org.apache.fop.fo.FONode;
047import org.apache.fop.fo.PropertyList;
048import org.apache.fop.fo.properties.CommonFont;
049import org.apache.fop.fo.properties.FixedLength;
050import org.apache.fop.fo.properties.Property;
051import org.apache.fop.fonts.FontInfo;
052import org.apache.fop.fonts.FontTriplet;
053import org.w3c.dom.Document;
054import org.w3c.dom.Element;
055import org.xml.sax.Attributes;
056import org.xml.sax.Locator;
057
058/**
059 * Defines the top-level element for MathML.
060 * 
061 * @version $Revision$
062 */
063public 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}