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"
22 #include "support/lassert.h"
28 InsetMathStackrel::InsetMathStackrel(Buffer * buf, bool sub)
29 : InsetMathFracBase(buf, sub ? 3 : 2)
33 Inset * InsetMathStackrel::clone() const
35 return new InsetMathStackrel(*this);
39 bool InsetMathStackrel::idxUpDown(Cursor & cur, bool up) const
41 idx_type const npos = 1234; // impossible number
42 idx_type target = npos;
44 idx_type const targets[] = { 1, npos, 0 };
45 target = targets[cur.idx()];
47 idx_type const targets[] = { 2, 0, npos };
48 target = targets[cur.idx()];
51 if (target == npos || target == nargs())
54 cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
59 bool InsetMathStackrel::idxFirst(Cursor & cur) const
61 LASSERT(&cur.inset() == this, return false);
68 bool InsetMathStackrel::idxLast(Cursor & cur) const
70 LASSERT(&cur.inset() == this, return false);
72 cur.pos() = cur.lastpos();
77 MathClass InsetMathStackrel::mathClass() const
79 // FIXME: update this when/if \stackbin is supported
84 void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
86 Changer dummy2 = mi.base.changeEnsureMath();
88 cell(0).metrics(mi, dim0);
89 Changer dummy = mi.base.changeScript();
91 cell(1).metrics(mi, dim1);
94 cell(2).metrics(mi, dim2);
95 dim.wid = max(max(dim1.width(), dim0.width()), dim2.width()) + 4;
96 dim.asc = dim0.ascent() + dim1.height() + 4;
97 dim.des = dim0.descent() + dim2.height() + dim2.descent() + 1;
99 dim.wid = max(dim1.width(), dim0.width()) + 4;
100 dim.asc = dim0.ascent() + dim1.height() + 4;
101 dim.des = dim0.descent();
106 void InsetMathStackrel::draw(PainterInfo & pi, int x, int y) const
108 Changer dummy2 = pi.base.changeEnsureMath();
109 Dimension const dim = dimension(*pi.base.bv);
110 Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
111 Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
112 int m = x + dim.width() / 2;
113 int yo = y - dim0.ascent() - dim1.descent() - 1;
114 cell(0).draw(pi, m - dim0.width() / 2, y);
115 Changer dummy = pi.base.changeScript();
116 cell(1).draw(pi, m - dim1.width() / 2, yo);
118 Dimension const & dim2 = cell(2).dimension(*pi.base.bv);
119 int y2 = y + dim0.descent() + dim2.ascent() + 1;
120 cell(2).draw(pi, m - dim2.width() / 2, y2);
125 void InsetMathStackrel::write(TeXMathStream & os) const
127 MathEnsurer ensurer(os);
130 os << '[' << cell(2) << ']';
131 os << '{' << cell(1) << "}{" << cell(0) << '}';
135 void InsetMathStackrel::normalize(NormalStream & os) const
137 os << "[stackrel " << cell(1) << ' ' << cell(0);
139 os << ' ' << cell(2);
144 void InsetMathStackrel::mathmlize(MathMLStream & ms) const
147 ms << "<" << from_ascii(ms.namespacedTag("munderover")) << ">"
148 << cell(0) << cell(2) << cell(1)
149 << "</" << from_ascii(ms.namespacedTag("munderover")) << ">";
151 ms << "<" << from_ascii(ms.namespacedTag("mover")) << " accent='false'>"
152 << cell(0) << cell(1)
153 << "</" << from_ascii(ms.namespacedTag("mover")) << ">";
157 void InsetMathStackrel::htmlize(HtmlStream & os) const
160 os << MTag("span", "class='underoverset'")
161 << MTag("span", "class='top'") << cell(1) << ETag("span")
162 << MTag("span") << cell(0) << ETag("span")
163 << MTag("span", "class='bottom'") << cell(2) << ETag("span");
165 // at the moment, this is exactly the same as overset
166 os << MTag("span", "class='overset'")
167 << MTag("span", "class='top'") << cell(1) << ETag("span")
168 << MTag("span") << cell(0) << ETag("span");
174 void InsetMathStackrel::validate(LaTeXFeatures & features) const
176 if (features.runparams().math_flavor == OutputParams::MathAsHTML) {
178 // FIXME: "vertical-align: middle" works only if the
179 // height of sub and super script is approximately equal.
180 features.addCSSSnippet(
181 "span.underoverset{display: inline-block; vertical-align: middle; text-align:center;}\n"
182 "span.underoverset span {display: block;}\n"
183 "span.bottom{font-size: 66%;}\n"
184 "span.top{font-size: 66%;}");
187 features.addCSSSnippet(
188 "span.overset{display: inline-block; vertical-align: bottom; text-align:center;}\n"
189 "span.overset span {display: block;}\n"
190 "span.top{font-size: 66%;}");
194 features.require("stackrel");
196 InsetMathNest::validate(features);