2 * \file InsetMathStackrel.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include "InsetMathStackrel.h"
16 #include "MathStream.h"
19 #include "LaTeXFeatures.h"
20 #include "MetricsInfo.h"
26 InsetMathStackrel::InsetMathStackrel(Buffer * buf, bool sub)
27 : InsetMathFracBase(buf, sub ? 3 : 2)
31 Inset * InsetMathStackrel::clone() const
33 return new InsetMathStackrel(*this);
37 bool InsetMathStackrel::idxUpDown(Cursor & cur, bool up) const
39 idx_type const npos = 1234; // impossible number
40 idx_type target = npos;
42 idx_type const targets[] = { 1, npos, 0 };
43 target = targets[cur.idx()];
45 idx_type const targets[] = { 2, 0, npos };
46 target = targets[cur.idx()];
49 if (target == npos || target == nargs())
52 cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
57 MathClass InsetMathStackrel::mathClass() const
59 // FIXME: update this when/if \stackbin is supported
64 void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
66 Changer dummy2 = mi.base.changeEnsureMath();
68 cell(0).metrics(mi, dim0);
69 Changer dummy = mi.base.changeScript();
71 cell(1).metrics(mi, dim1);
74 cell(2).metrics(mi, dim2);
75 dim.wid = max(max(dim1.width(), dim0.width()), dim2.width()) + 4;
76 dim.asc = dim0.ascent() + dim1.height() + 4;
77 dim.des = dim0.descent() + dim2.height() + dim2.descent() + 1;
79 dim.wid = max(dim1.width(), dim0.width()) + 4;
80 dim.asc = dim0.ascent() + dim1.height() + 4;
81 dim.des = dim0.descent();
86 void InsetMathStackrel::draw(PainterInfo & pi, int x, int y) const
88 Changer dummy2 = pi.base.changeEnsureMath();
89 Dimension const dim = dimension(*pi.base.bv);
90 Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
91 Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
92 int m = x + dim.width() / 2;
93 int yo = y - dim0.ascent() - dim1.descent() - 1;
94 cell(0).draw(pi, m - dim0.width() / 2, y);
95 Changer dummy = pi.base.changeScript();
96 cell(1).draw(pi, m - dim1.width() / 2, yo);
98 Dimension const & dim2 = cell(2).dimension(*pi.base.bv);
99 int y2 = y + dim0.descent() + dim2.ascent() + 1;
100 cell(2).draw(pi, m - dim2.width() / 2, y2);
105 void InsetMathStackrel::write(WriteStream & os) const
107 MathEnsurer ensurer(os);
110 os << '[' << cell(2) << ']';
111 os << '{' << cell(1) << "}{" << cell(0) << '}';
115 void InsetMathStackrel::normalize(NormalStream & os) const
117 os << "[stackrel " << cell(1) << ' ' << cell(0);
119 os << ' ' << cell(2);
124 void InsetMathStackrel::mathmlize(MathStream & ms) const
127 ms << "<munderover>" << cell(0) << cell(2) << cell(1) << "</munderover>";
129 ms << "<mover accent='false'>" << cell(0) << cell(1) << "</mover>";
133 void InsetMathStackrel::htmlize(HtmlStream & os) const
136 os << MTag("span", "class='underoverset'")
137 << MTag("span", "class='top'") << cell(1) << ETag("span")
138 << MTag("span") << cell(0) << ETag("span")
139 << MTag("span", "class='bottom'") << cell(2) << ETag("span");
141 // at the moment, this is exactly the same as overset
142 os << MTag("span", "class='overset'")
143 << MTag("span", "class='top'") << cell(1) << ETag("span")
144 << MTag("span") << cell(0) << ETag("span");
150 void InsetMathStackrel::validate(LaTeXFeatures & features) const
152 if (features.runparams().math_flavor == OutputParams::MathAsHTML) {
154 // FIXME: "vertical-align: middle" works only if the
155 // height of sub and super script is approximately equal.
156 features.addCSSSnippet(
157 "span.underoverset{display: inline-block; vertical-align: middle; text-align:center;}\n"
158 "span.underoverset span {display: block;}\n"
159 "span.bottom{font-size: 66%;}\n"
160 "span.top{font-size: 66%;}");
163 features.addCSSSnippet(
164 "span.overset{display: inline-block; vertical-align: bottom; text-align:center;}\n"
165 "span.overset span {display: block;}\n"
166 "span.top{font-size: 66%;}");
170 features.require("stackrel");
172 InsetMathNest::validate(features);