]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathFrac.cpp
Partial support for units
[lyx.git] / src / mathed / InsetMathFrac.cpp
1 /**
2  * \file InsetMathFrac.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetMathFrac.h"
15 #include "MathData.h"
16 #include "MathStream.h"
17 #include "TextPainter.h"
18 #include "LaTeXFeatures.h"
19 #include "Color.h"
20 #include "frontends/Painter.h"
21
22
23 namespace lyx {
24
25 InsetMathFrac::InsetMathFrac(Kind kind)
26         : kind_(kind)
27 {}
28
29
30 Inset * InsetMathFrac::clone() const
31 {
32         return new InsetMathFrac(*this);
33 }
34
35
36 InsetMathFrac * InsetMathFrac::asFracInset()
37 {
38         return kind_ == ATOP ? 0 : this;
39 }
40
41
42 InsetMathFrac const * InsetMathFrac::asFracInset() const
43 {
44         return kind_ == ATOP ? 0 : this;
45 }
46
47
48 bool InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
49 {
50         FracChanger dummy(mi.base);
51         cell(0).metrics(mi);
52         cell(1).metrics(mi);
53         if (kind_ == NICEFRAC) {
54                 dim.wid = cell(0).width() + cell(1).width() + 5;
55                 dim.asc = cell(0).height() + 5;
56                 dim.des = cell(1).height() - 5;
57         } else if (kind_ == UNITFRAC) {
58                 ShapeChanger dummy2(mi.base.font, Font::UP_SHAPE);
59                 dim.wid = cell(0).width() + cell(1).width() + 5;
60                 dim.asc = cell(0).height() + 5;
61                 dim.des = cell(1).height() - 5;
62         } else {
63                 dim.wid = std::max(cell(0).width(), cell(1).width()) + 2;
64                 dim.asc = cell(0).height() + 2 + 5;
65                 dim.des = cell(1).height() + 2 - 5;
66         }
67         metricsMarkers(dim);
68         if (dim_ == dim)
69                 return false;
70         dim_ = dim;
71         return true;
72 }
73
74
75 void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
76 {
77         setPosCache(pi, x, y);
78         int m = x + dim_.wid / 2;
79         FracChanger dummy(pi.base);
80         if (kind_ == NICEFRAC) {
81                 cell(0).draw(pi, x + 2,
82                                 y - cell(0).descent() - 5);
83                 cell(1).draw(pi, x + cell(0).width() + 5,
84                                 y + cell(1).ascent() / 2);
85         } else if (kind_ == UNITFRAC) {
86                 ShapeChanger dummy2(pi.base.font, Font::UP_SHAPE);
87                 cell(0).draw(pi, x + 2,
88                                 y - cell(0).descent() - 5);
89                 cell(1).draw(pi, x + cell(0).width() + 5,
90                                 y + cell(1).ascent() / 2);
91         } else {
92                 cell(0).draw(pi, m - cell(0).width() / 2,
93                                 y - cell(0).descent() - 2 - 5);
94                 cell(1).draw(pi, m - cell(1).width() / 2,
95                                 y + cell(1).ascent()  + 2 - 5);
96         }
97         if (kind_ == NICEFRAC || kind_ == UNITFRAC) {
98                 pi.pain.line(x + cell(0).width(),
99                                 y + dim_.des - 2,
100                                 x + cell(0).width() + 5,
101                                 y - dim_.asc + 2, Color::math);
102         }
103         if (kind_ == FRAC || kind_ == OVER)
104                 pi.pain.line(x + 1, y - 5,
105                                 x + dim_.wid - 2, y - 5, Color::math);
106         drawMarkers(pi, x, y);
107 }
108
109
110 void InsetMathFrac::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
111 {
112         cell(0).metricsT(mi, dim);
113         cell(1).metricsT(mi, dim);
114         dim.wid = std::max(cell(0).width(), cell(1).width());
115         dim.asc = cell(0).height() + 1;
116         dim.des = cell(1).height();
117         //dim = dim_;
118 }
119
120
121 void InsetMathFrac::drawT(TextPainter & pain, int x, int y) const
122 {
123         int m = x + dim_.width() / 2;
124         cell(0).drawT(pain, m - cell(0).width() / 2, y - cell(0).descent() - 1);
125         cell(1).drawT(pain, m - cell(1).width() / 2, y + cell(1).ascent());
126         // ASCII art: ignore niceties
127         if (kind_ == FRAC || kind_ == OVER || kind_ == NICEFRAC || kind_ == UNITFRAC)
128                 pain.horizontalLine(x, y, dim_.width());
129 }
130
131
132 void InsetMathFrac::write(WriteStream & os) const
133 {
134         switch (kind_) {
135         case ATOP:
136                 os << '{' << cell(0) << "\\atop " << cell(1) << '}';
137                 break;
138         case OVER:
139                 // \\over is only for compatibility, normalize this to \\frac
140                 os << "\\frac{" << cell(0) << "}{" << cell(1) << '}';
141                 break;
142         case FRAC:
143         case NICEFRAC:
144         case UNITFRAC:
145                 InsetMathNest::write(os);
146                 break;
147         }
148 }
149
150
151 docstring InsetMathFrac::name() const
152 {
153         switch (kind_) {
154         case FRAC:
155                 return from_ascii("frac");
156         case OVER:
157                 return from_ascii("over");
158         case NICEFRAC:
159                 return from_ascii("nicefrac");
160         case UNITFRAC:
161                 return from_ascii("unitfrac");
162         case ATOP:
163                 return from_ascii("atop");
164         }
165         // shut up stupid compiler
166         return docstring();
167 }
168
169
170 bool InsetMathFrac::extraBraces() const
171 {
172         return kind_ == ATOP || kind_ == OVER;
173 }
174
175
176 void InsetMathFrac::maple(MapleStream & os) const
177 {
178         os << '(' << cell(0) << ")/(" << cell(1) << ')';
179 }
180
181
182 void InsetMathFrac::mathematica(MathematicaStream & os) const
183 {
184         os << '(' << cell(0) << ")/(" << cell(1) << ')';
185 }
186
187
188 void InsetMathFrac::octave(OctaveStream & os) const
189 {
190         os << '(' << cell(0) << ")/(" << cell(1) << ')';
191 }
192
193
194 void InsetMathFrac::mathmlize(MathStream & os) const
195 {
196         os << MTag("mfrac") << cell(0) << cell(1) << ETag("mfrac");
197 }
198
199
200 void InsetMathFrac::validate(LaTeXFeatures & features) const
201 {
202         if (kind_ == NICEFRAC || kind_ == UNITFRAC)
203                 features.require("units");
204         InsetMathNest::validate(features);
205 }
206
207
208
209 } // namespace lyx