001 /*
002 * Copyright 2007 - 2009 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: AbstractTokenWithTextLayout.java,v 923658a2b249 2009/09/11 09:57:31 max $ */
018
019 package net.sourceforge.jeuclid.elements.presentation.token;
020
021 import java.awt.Color;
022 import java.awt.Graphics2D;
023 import java.awt.font.TextLayout;
024 import java.text.AttributedCharacterIterator;
025 import java.text.AttributedString;
026 import java.util.Collections;
027 import java.util.List;
028
029 import net.sourceforge.jeuclid.LayoutContext;
030 import net.sourceforge.jeuclid.context.Parameter;
031 import net.sourceforge.jeuclid.elements.AbstractJEuclidElement;
032 import net.sourceforge.jeuclid.elements.support.text.StringUtil;
033 import net.sourceforge.jeuclid.layout.LayoutInfo;
034 import net.sourceforge.jeuclid.layout.LayoutStage;
035 import net.sourceforge.jeuclid.layout.LayoutView;
036 import net.sourceforge.jeuclid.layout.LayoutableNode;
037 import net.sourceforge.jeuclid.layout.TextObject;
038
039 import org.apache.batik.dom.AbstractDocument;
040 import org.w3c.dom.mathml.MathMLPresentationToken;
041
042 /**
043 * Common functionality for all tokens based on a text layout.
044 *
045 * @version $Revision: 923658a2b249 $
046 */
047 public abstract class AbstractTokenWithTextLayout extends
048 AbstractJEuclidElement implements MathMLPresentationToken {
049
050 private static final long serialVersionUID = 1L;
051
052 /**
053 * Default constructor. Sets MathML Namespace.
054 *
055 * @param qname
056 * Qualified name.
057 * @param odoc
058 * Owner Document.
059 */
060 public AbstractTokenWithTextLayout(final String qname,
061 final AbstractDocument odoc) {
062 super(qname, odoc);
063 }
064
065 /** {@inheritDoc} */
066 @Override
067 public void layoutStageInvariant(final LayoutView view,
068 final LayoutInfo info, final LayoutStage stage,
069 final LayoutContext context) {
070 final Graphics2D g = view.getGraphics();
071 final TextLayout t = this.produceTextLayout(g, context);
072 if (t != null) {
073 final StringUtil.TextLayoutInfo tli = StringUtil.getTextLayoutInfo(
074 t, false);
075 info.setAscentHeight(tli.getAscent(), stage);
076 info.setDescentHeight(tli.getDescent(), stage);
077 final float width = tli.getWidth();
078 info.setHorizontalCenterOffset(width / 2.0f, stage);
079 info.setWidth(width, stage);
080 info.setGraphicsObject(new TextObject(t, tli.getOffset(),
081 (Color) this.applyLocalAttributesToContext(context)
082 .getParameter(Parameter.MATHCOLOR)));
083 }
084 }
085
086 private TextLayout produceTextLayout(final Graphics2D g2d,
087 final LayoutContext context) {
088 TextLayout layout;
089 final LayoutContext now = this.applyLocalAttributesToContext(context);
090
091 final AttributedCharacterIterator aci = StringUtil
092 .textContentAsAttributedCharacterIterator(now, this, this, 1.0f);
093
094 if (aci.getBeginIndex() == aci.getEndIndex()) {
095 return null;
096 } else {
097 layout = StringUtil.createTextLayoutFromAttributedString(g2d,
098 new AttributedString(aci), now);
099 return layout;
100 }
101 }
102
103 /** {@inheritDoc} */
104 @Override
105 public List<LayoutableNode> getChildrenToLayout() {
106 return Collections.emptyList();
107 }
108
109 /** {@inheritDoc} */
110 @Override
111 public List<LayoutableNode> getChildrenToDraw() {
112 return Collections.emptyList();
113 }
114
115 }