View Javadoc

1   /*
2    * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: ScriptSupport.java,v d02878fc1d01 2009/09/08 12:35:02 max $ */
18  
19  package net.sourceforge.jeuclid.elements.presentation.script;
20  
21  import java.awt.geom.Dimension2D;
22  
23  import net.sourceforge.jeuclid.LayoutContext;
24  import net.sourceforge.jeuclid.elements.JEuclidElement;
25  import net.sourceforge.jeuclid.elements.support.Dimension2DImpl;
26  import net.sourceforge.jeuclid.elements.support.ElementListSupport;
27  import net.sourceforge.jeuclid.elements.support.attributes.AttributesHelper;
28  import net.sourceforge.jeuclid.layout.LayoutInfo;
29  import net.sourceforge.jeuclid.layout.LayoutStage;
30  import net.sourceforge.jeuclid.layout.LayoutView;
31  
32  /**
33   * Support class for script elements.
34   * 
35   * @see AbstractSubSuper
36   * @see AbstractUnderOver
37   * @version $Revision: d02878fc1d01 $
38   */
39  public final class ScriptSupport {
40      /** Default Constructor. */
41      private ScriptSupport() {
42          // Empty on purpose.
43      }
44  
45      /**
46       * Info for baseline shifts.
47       * 
48       * @version $Revision: d02878fc1d01 $
49       */
50      static class ShiftInfo {
51          private float superShift;
52  
53          private float subShift;
54  
55          /**
56           * Creates a new ShiftInfo object.
57           * 
58           * @param sub
59           *            subShift.
60           * @param sup
61           *            superShift.
62           */
63          protected ShiftInfo(final float sub, final float sup) {
64              this.superShift = sup;
65              this.subShift = sub;
66          }
67  
68          /**
69           * Getter method for superShift.
70           * 
71           * @return the superShift
72           */
73          public float getSuperShift() {
74              return this.superShift;
75          }
76  
77          /**
78           * Getter method for subShift.
79           * 
80           * @return the subShift
81           */
82          public float getSubShift() {
83              return this.subShift;
84          }
85  
86          /**
87           * Adjust this shift to contain the max shift from current shit and
88           * other info.
89           * 
90           * @param otherInfo
91           *            other info to use.
92           */
93          public void max(final ShiftInfo otherInfo) {
94              this.subShift = Math.max(this.subShift, otherInfo.subShift);
95              this.superShift = Math.max(this.superShift, otherInfo.superShift);
96          }
97  
98      }
99  
100     // CHECKSTYLE:OFF
101     // More than 7 parameters. But only used internally, so that's ok.
102     static void layout(final LayoutView view, final LayoutInfo info,
103             final LayoutStage stage, final LayoutContext now,
104             final JEuclidElement parent, final JEuclidElement base,
105             final JEuclidElement sub, final JEuclidElement sup,
106             final String subScriptShift, final String superScriptShift) {
107         // CHECKSTYLE:ON
108         final LayoutInfo baseInfo = view.getInfo(base);
109         final float width = baseInfo.getWidth(stage);
110 
111         final LayoutInfo subInfo = view.getInfo(sub);
112         final LayoutInfo superInfo = view.getInfo(sup);
113 
114         final ShiftInfo shiftInfo = ScriptSupport.calculateScriptShfits(stage,
115                 now, subScriptShift, superScriptShift, baseInfo, subInfo,
116                 superInfo);
117 
118         if (subInfo != null) {
119             subInfo.moveTo(width, shiftInfo.getSubShift(), stage);
120         }
121         if (superInfo != null) {
122             superInfo.moveTo(width, -shiftInfo.getSuperShift(), stage);
123         }
124 
125         final Dimension2D borderLeftTop = new Dimension2DImpl(0.0f, 0.0f);
126         final Dimension2D borderRightBottom = new Dimension2DImpl(0.0f, 0.0f);
127         ElementListSupport.fillInfoFromChildren(view, info, parent, stage,
128                 borderLeftTop, borderRightBottom);
129         info.setStretchAscent(baseInfo.getStretchAscent());
130         info.setStretchDescent(baseInfo.getStretchDescent());
131     }
132 
133     static ShiftInfo calculateScriptShfits(final LayoutStage stage,
134             final LayoutContext now, final String subScriptShift,
135             final String superScriptShift, final LayoutInfo baseInfo,
136             final LayoutInfo subInfo, final LayoutInfo superInfo) {
137         float subShift = 0.0f;
138         float superShift = 0.0f;
139         if (subInfo != null) {
140             subShift = Math.max(baseInfo.getDescentHeight(stage)
141                     + (subInfo.getAscentHeight(stage) - subInfo
142                             .getDescentHeight(stage)) / 2.0f, AttributesHelper
143                     .convertSizeToPt(subScriptShift, now, AttributesHelper.PT));
144         }
145         if (superInfo != null) {
146             superShift = Math.max(baseInfo.getAscentHeight(stage)
147                     - (superInfo.getAscentHeight(stage) - superInfo
148                             .getDescentHeight(stage)) / 2.0f,
149                     AttributesHelper.convertSizeToPt(superScriptShift, now,
150                             AttributesHelper.PT));
151         }
152         if ((subInfo != null) && (superInfo != null)) {
153             final float topSub = -subShift + subInfo.getAscentHeight(stage)
154                     + 1.0f;
155             final float bottomSuper = superShift
156                     - superInfo.getDescentHeight(stage) - 1.0f;
157 
158             final float overlap = Math.max(0.0f, topSub - bottomSuper);
159             final float overlapShift = overlap / 2.0f;
160 
161             superShift += overlapShift;
162             subShift += overlapShift;
163         }
164         return new ShiftInfo(subShift, superShift);
165     }
166 
167 }