#include <config.h>
+#include "InsetMathSideset.h"
+
+#include "InsetMathSymbol.h"
+#include "MathData.h"
+#include "MathStream.h"
+#include "MathSupport.h"
+
#include "BufferView.h"
#include "Cursor.h"
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
-#include "InsetMathSideset.h"
-#include "InsetMathSymbol.h"
#include "LaTeXFeatures.h"
-#include "MathData.h"
-#include "MathStream.h"
-#include "MathSupport.h"
+#include "MetricsInfo.h"
#include "support/debug.h"
-
#include "support/lassert.h"
namespace {
/// x spacing between the nucleus and the scripts
int const dx = 2;
-}
+} // namespace
namespace lyx {
-InsetMathSideset::InsetMathSideset(Buffer * buf)
- : InsetMathNest(buf, 5)
+InsetMathSideset::InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr)
+ : InsetMathNest(buf, 3 + scriptl + scriptr), scriptl_(scriptl),
+ scriptr_(scriptr)
{}
-InsetMathSideset::InsetMathSideset(Buffer * buf, MathAtom const & at)
- : InsetMathNest(buf, 5)
+InsetMathSideset::InsetMathSideset(Buffer * buf, bool scriptl, bool scriptr,
+ MathAtom const & at)
+ : InsetMathNest(buf, 3 + scriptl + scriptr), scriptl_(scriptl),
+ scriptr_(scriptr)
{
nuc().push_back(at);
}
}
-bool InsetMathSideset::idxFirst(Cursor & cur) const
-{
- cur.idx() = 0;
- cur.pos() = 0;
- return true;
-}
-
-
-bool InsetMathSideset::idxLast(Cursor & cur) const
-{
- cur.idx() = 0;
- cur.pos() = nuc().size();
- return true;
-}
-
-
int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) const
{
bool isCharBox = nuc().empty() ? false : isAlphaSymbol(nuc().back());
- int dasc = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
+ int dasc = 0;
+ if (scriptl_ && scriptr_)
+ dasc = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
+ else if (scriptl_)
+ dasc = bl().dimension(bv).ascent();
+ else if (scriptr_)
+ dasc = br().dimension(bv).ascent();
int slevel = nuc().slevel();
int ascdrop = dasc - slevel;
int desdrop = isCharBox ? 0 : des + nuc().sshift();
des = max(desdrop, ascdrop);
des = max(mindes, des);
int minasc = nuc().minasc();
- ascdrop = isCharBox ? 0 : asc - min(tl().mindes(), tr().mindes());
- int udes = max(bl().dimension(bv).descent(), tr().dimension(bv).descent());
+ ascdrop = 0;
+ if (!isCharBox && (scriptl_ || scriptr_)) {
+ if (scriptl_ && scriptr_)
+ ascdrop = asc - min(tl().mindes(), tr().mindes());
+ else if (scriptl_)
+ ascdrop = asc - tl().mindes();
+ else if (scriptr_)
+ ascdrop = asc - tr().mindes();
+ }
+ int udes = 0;
+ if (scriptl_)
+ udes = bl().dimension(bv).descent();
+ if (scriptr_)
+ udes = max(udes, br().dimension(bv).descent());
asc = udes + nuc().sshift();
asc = max(ascdrop, asc);
asc = max(minasc, asc);
int InsetMathSideset::dyb(BufferView const & bv) const
{
int nd = ndes(bv);
- int des = max(bl().dimension(bv).ascent(), br().dimension(bv).ascent());
int na = nasc(bv);
- des = dybt(bv, na, nd, false);
+ int des = dybt(bv, na, nd, false);
return des;
}
int InsetMathSideset::dyt(BufferView const & bv) const
{
int na = nasc(bv);
- int asc = max(tl().dimension(bv).descent(), tr().dimension(bv).descent());
int nd = ndes(bv);
- asc = dybt(bv, na, nd, true);
+ int asc = dybt(bv, na, nd, true);
return asc;
}
void InsetMathSideset::metrics(MetricsInfo & mi, Dimension & dim) const
{
+ Changer dummy2 = mi.base.changeEnsureMath();
Dimension dimn;
Dimension dimbl;
Dimension dimtl;
Dimension dimbr;
Dimension dimtr;
nuc().metrics(mi, dimn);
- ScriptChanger dummy(mi.base);
- bl().metrics(mi, dimbl);
- tl().metrics(mi, dimtl);
- br().metrics(mi, dimbr);
- tr().metrics(mi, dimtr);
+ if (!scriptl_) {
+ bl().metrics(mi, dimbl);
+ dimtl = dimbl;
+ }
+ if (!scriptr_) {
+ br().metrics(mi, dimbr);
+ dimtr = dimbr;
+ }
+ Changer dummy = mi.base.changeScript();
+ if (scriptl_) {
+ bl().metrics(mi, dimbl);
+ tl().metrics(mi, dimtl);
+ }
+ if (scriptr_) {
+ br().metrics(mi, dimbr);
+ tr().metrics(mi, dimtr);
+ }
- BufferView & bv = *mi.base.bv;
+ BufferView const & bv = *mi.base.bv;
// FIXME: data copying... not very efficient.
dim.wid = nwid(bv) + nker(mi.base.bv) + 2 * dx;
int nd = ndes(bv);
int des = dyb(bv) + max(dimbl.descent(), dimbr.descent());
dim.des = max(nd, des);
- metricsMarkers(dim);
}
void InsetMathSideset::draw(PainterInfo & pi, int x, int y) const
{
- BufferView & bv = *pi.base.bv;
+ Changer dummy2 = pi.base.changeEnsureMath();
+ BufferView const & bv = *pi.base.bv;
nuc().draw(pi, x + dxn(bv), y);
- ScriptChanger dummy(pi.base);
- bl().draw(pi, x , y + dyb(bv));
- tl().draw(pi, x , y - dyt(bv));
- br().draw(pi, x + dxr(bv), y + dyb(bv));
- tr().draw(pi, x + dxr(bv), y - dyt(bv));
- drawMarkers(pi, x, y);
+ if (!scriptl_)
+ bl().draw(pi, x , y);
+ if (!scriptr_)
+ br().draw(pi, x + dxr(bv), y);
+ Changer dummy = pi.base.changeScript();
+ if (scriptl_) {
+ bl().draw(pi, x , y + dyb(bv));
+ tl().draw(pi, x , y - dyt(bv));
+ }
+ if (scriptr_) {
+ br().draw(pi, x + dxr(bv), y + dyb(bv));
+ tr().draw(pi, x + dxr(bv), y - dyt(bv));
+ }
}
-bool InsetMathSideset::idxForward(Cursor &) const
+bool InsetMathSideset::idxForward(Cursor & cur) const
{
+ if (!scriptl_ && cur.idx() == 1) {
+ // left => nucleus
+ cur.idx() = 0;
+ return true;
+ } else if (!scriptr_ && cur.idx() == 0) {
+ // nucleus => right
+ cur.idx() = 2 + scriptl_;
+ return true;
+ }
return false;
}
-bool InsetMathSideset::idxBackward(Cursor &) const
+bool InsetMathSideset::idxBackward(Cursor & cur) const
{
+ if (!scriptr_ && cur.idx() == (scriptl_ ? 3 : 2)) {
+ // right => nucleus
+ cur.idx() = 0;
+ return true;
+ } else if (!scriptl_ && cur.idx() == 0) {
+ // nucleus => left
+ cur.idx() = 1;
+ return true;
+ }
return false;
}
if (cur.idx() == 0) {
// go up/down only if in the last position
// or in the first position
- if (cur.pos() == cur.lastpos() || cur.pos() == 0) {
+ if ((scriptr_ && cur.pos() == cur.lastpos()) ||
+ (scriptl_ && cur.pos() == 0)) {
if (cur.pos() == 0)
cur.idx() = up ? 2 : 1;
else
- cur.idx() = up ? 4 : 3;
+ cur.idx() = (up ? 3 : 2) + scriptl_;
cur.pos() = 0;
return true;
}
}
// Are we 'up'?
- if (cur.idx() == 2 || cur.idx() == 4) {
+ if ((scriptl_ && cur.idx() == 2) ||
+ (scriptr_ && cur.idx() == (scriptl_ ? 4 : 3))) {
// can't go further up
if (up)
return false;
}
// Are we 'down'?
- if (cur.idx() == 1 || cur.idx() == 3) {
+ if ((scriptl_ && cur.idx() == 1) ||
+ (scriptr_ && cur.idx() == (scriptl_ ? 3 : 2))) {
// can't go further down
if (!up)
return false;
}
-void InsetMathSideset::write(WriteStream & os) const
+void InsetMathSideset::write(TeXMathStream & os) const
{
MathEnsurer ensurer(os);
os << "\\sideset";
- for (int i = 0; i < 2; ++i) {
- os << '{';
- if (!cell(2*i+1).empty())
- os << "_{" << cell(2*i+1) << '}';
- if (!cell(2*i+2).empty())
- os << "^{" << cell(2*i+2) << '}';
- os << '}';
- }
- os << '{' << nuc() << '}';
+ os << '{';
+ if (scriptl_) {
+ if (!bl().empty())
+ os << "_{" << bl() << '}';
+ if (!tl().empty())
+ os << "^{" << tl() << '}';
+ } else
+ os << bl();
+ os << "}{";
+ if (scriptr_) {
+ if (!br().empty())
+ os << "_{" << br() << '}';
+ if (!tr().empty())
+ os << "^{" << tr() << '}';
+ } else
+ os << br();
+ os << '}';
+ os << nuc();
if (lock_ && !os.latex())
os << "\\lyxlock ";
if (!bl().empty())
os << bl() << ' ';
- if (!tl().empty())
+ if (scriptl_ && !tl().empty())
os << tl() << ' ';
if (!nuc().empty())
if (!br().empty())
os << br() << ' ';
- if (!tr().empty())
+ if (scriptr_ && !tr().empty())
os << tr() << ' ';
os << ']';
}
-void InsetMathSideset::mathmlize(MathStream & os) const
+void InsetMathSideset::mathmlize(MathMLStream & ms) const
{
- os << MTag("mmultiscripts");
-
- if (nuc().empty())
- os << "<mrow />";
- else
- os << MTag("mrow") << nuc() << ETag("mrow");
+ // FIXME This is only accurate if both scriptl_ and scriptr_ are true
+ if (!scriptl_)
+ ms << MTag("mrow") << bl() << ETag("mrow");
+ if (scriptl_ || scriptr_) {
+ ms << MTag("mmultiscripts");
+
+ if (nuc().empty())
+ ms << "<" << from_ascii(ms.namespacedTag("mrow")) << " />";
+ else
+ ms << MTag("mrow") << nuc() << ETag("mrow");
- if (br().empty())
- os << "<none />";
- else
- os << MTag("mrow") << br() << ETag("mrow");
- if (tr().empty())
- os << "<none />";
- else
- os << MTag("mrow") << tr() << ETag("mrow");
+ if (br().empty() || !scriptr_)
+ ms << "<" << from_ascii(ms.namespacedTag("none")) << " />";
+ else
+ ms << MTag("mrow") << br() << ETag("mrow");
+ if (tr().empty() || !scriptr_)
+ ms << "<" << from_ascii(ms.namespacedTag("none")) << " />";
+ else
+ ms << MTag("mrow") << tr() << ETag("mrow");
- if (bl().empty())
- os << "<none />";
- else
- os << MTag("mrow") << bl() << ETag("mrow");
- if (tl().empty())
- os << "<none />";
- else
- os << MTag("mrow") << tl() << ETag("mrow");
+ if (bl().empty() || !scriptl_)
+ ms << "<" << from_ascii(ms.namespacedTag("none")) << " />";
+ else
+ ms << MTag("mrow") << bl() << ETag("mrow");
+ if (tl().empty() || !scriptl_)
+ ms << "<" << from_ascii(ms.namespacedTag("none")) << " />";
+ else
+ ms << MTag("mrow") << tl() << ETag("mrow");
- os << ETag("mmultiscripts");
+ ms << ETag("mmultiscripts");
+ }
+ if (!scriptr_)
+ ms << MTag("mrow") << br() << ETag("mrow");
}
void InsetMathSideset::htmlize(HtmlStream & os) const
{
- bool const havebl = !bl().empty();
- bool const havetl = !tl().empty();
- bool const havebr = !br().empty();
- bool const havetr = !tr().empty();
+ // FIXME This is only accurate if both scriptl_ and scriptr_ are true
+ bool const havebl = scriptl_ && !bl().empty();
+ bool const havetl = scriptl_ && !tl().empty();
+ bool const havebr = scriptr_ && !br().empty();
+ bool const havetr = scriptr_ && !tr().empty();
+
+ if (!scriptl_ && !bl().empty())
+ os << bl();
if (havebl && havetl)
os << MTag("span", "class='scripts'")
os << MTag("sub", "class='math'") << br() << ETag("sub");
else if (havetr)
os << MTag("sup", "class='math'") << tr() << ETag("sup");
+
+ if (!scriptr_ && !br().empty())
+ os << br();
}