File: UnderOverAtom.java

package info (click to toggle)
libjmathtex-java 0.7~pre-4
  • links: PTS, VCS
  • area: main
  • in suites: lenny, squeeze
  • size: 952 kB
  • ctags: 1,112
  • sloc: java: 5,129; xml: 2,151; makefile: 24
file content (160 lines) | stat: -rw-r--r-- 6,085 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* UnderOverAtom.java
 * =========================================================================
 * This file is part of the JMathTeX Library - http://jmathtex.sourceforge.net
 *
 * Copyright (C) 2004-2007 Universiteit Gent
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * A copy of the GNU General Public License can be found in the file
 * LICENSE.txt provided with the source distribution of this program (see
 * the META-INF directory in the source jar). This license can also be
 * found on the GNU website at http://www.gnu.org/licenses/gpl.html.
 *
 * If you did not receive a copy of the GNU General Public License along
 * with this program, contact the lead developer, or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 */

package be.ugent.caagt.jmathtex;

/**
 * An atom representing another atom with an atom above it (if not null) seperated
 * by a kern and in a smaller size depending on "overScriptSize" and/or an atom under
 * it (if not null) seperated by a kern and in a smaller size depending on "underScriptSize"
 */
class UnderOverAtom extends Atom {
    
    // base, underscript and overscript
    private final Atom base;
    private final Atom under;
    private final Atom over;
    
    // kern between base and under- and overscript
    private final float underSpace;
    private final float overSpace;
    
    // units for the kerns
    private final int underUnit; // NOPMD
     // TODO: seems never to be used?
    private final int overUnit;
    
    // whether the under- and overscript should be drawn in a smaller size
    private final boolean underScriptSize;
    private final boolean overScriptSize;
    
    public UnderOverAtom(Atom base, Atom underOver, int underOverUnit,
            float underOverSpace, boolean underOverScriptSize, boolean over) {
        // check if unit is valid
        SpaceAtom.checkUnit(underOverUnit);
        
        // units valid
        this.base = base;
        // TODO: split into two different classes?
        
        if (over) {
            this.under = null;
            this.underSpace = 0.0f;
            this.underUnit = 0;
            this.underScriptSize = false;
            this.over = underOver;
            this.overUnit = underOverUnit;
            this.overSpace = underOverSpace;
            this.overScriptSize = underOverScriptSize;
        } else {
            this.under = underOver;
            this.underUnit = underOverUnit;
            this.underSpace = underOverSpace;
            this.underScriptSize = underOverScriptSize;
            this.overSpace = 0.0f;
            this.over = null;
            this.overUnit = 0;
            this.overScriptSize = false;
        }
    }
    
    public UnderOverAtom(Atom base, Atom under, int underUnit, float underSpace,
            boolean underScriptSize, Atom over, int overUnit, float overSpace,
            boolean overScriptSize) throws InvalidUnitException {
        // check if units are valid
        SpaceAtom.checkUnit(underUnit);
        SpaceAtom.checkUnit(overUnit);
        
        // units valid
        this.base = base;
        this.under = under;
        this.underUnit = underUnit;
        this.underSpace = underSpace;
        this.underScriptSize = underScriptSize;
        this.over = over;
        this.overUnit = overUnit;
        this.overSpace = overSpace;
        this.overScriptSize = overScriptSize;
    }
    
    public Box createBox(TeXEnvironment env) {
        
        // create boxes in right style and calculate maximum width
        Box b = (base == null ? new StrutBox(0, 0, 0, 0) : base.createBox(env));
        Box o = null, u = null;
        float max = b.getWidth();
        if (over != null) {
            o = over.createBox(overScriptSize ? env.subStyle() : env);
            max = Math.max(max, o.getWidth());
        }
        if (under != null) {
            u = under.createBox(underScriptSize ? env.subStyle() : env);
            max = Math.max(max, u.getWidth());
        }
        
        // create vertical box
        VerticalBox vBox = new VerticalBox();
        
        // last font used by the base (for Mspace atoms following)
        env.setLastFontId(b.getLastFontId());
        
        // overscript + space
        if (over != null) {
            vBox.add(changeWidth(o, max));
            // unit will be valid (checked in constructor)
            vBox.add(new SpaceAtom(overUnit, 0, overSpace, 0).createBox(env));
        }
        
        // base
        vBox.add(changeWidth(b, max));
        
        // calculate future height of the vertical box (to make sure that the base
        // stays on the baseline!)
        float h = vBox.getHeight() + vBox.getDepth() - b.getDepth();
        
        // underscript + space
        if (under != null) {
            // unit will be valid (checked in constructor)
            vBox.add(new SpaceAtom(overUnit, 0, underSpace, 0).createBox(env));
            vBox.add(changeWidth(u, max));
        }
        
        // set height and depth
        vBox.setDepth(vBox.getHeight() + vBox.getDepth() - h);
        vBox.setHeight(h);
        
        return vBox;
    }
    
    private static Box changeWidth(Box b, float maxWidth) {
        if (b != null && Math.abs(maxWidth - b.getWidth()) > TeXFormula.PREC)
            return new HorizontalBox(b, maxWidth, TeXConstants.ALIGN_CENTER);
        else
            return b;
    }
}