X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathScript.cpp;h=c146e071b15e7fc9008d1e2d99c63c420e401b1f;hb=11a6b3c4c7a031fd3776f53c9c43f62116933cea;hp=fa6046a7151ddecd300f36263c5ddc82578a1265;hpb=6e3a75969b97a5db4c80c46be49d4deb122abfe7;p=lyx.git diff --git a/src/mathed/InsetMathScript.cpp b/src/mathed/InsetMathScript.cpp index fa6046a715..c146e071b1 100644 --- a/src/mathed/InsetMathScript.cpp +++ b/src/mathed/InsetMathScript.cpp @@ -10,28 +10,26 @@ #include +#include "BufferView.h" +#include "Cursor.h" +#include "DispatchResult.h" +#include "FuncRequest.h" +#include "InsetMathFont.h" #include "InsetMathScript.h" -#include "MathArray.h" +#include "InsetMathSymbol.h" +#include "MathData.h" #include "MathStream.h" #include "MathSupport.h" -#include "InsetMathSymbol.h" -#include "InsetMathFont.h" -#include "dispatchresult.h" -#include "cursor.h" -#include "debug.h" -#include "funcrequest.h" -#include "undo.h" -#include +#include "support/debug.h" +#include -namespace lyx { +#include -using std::string; -using std::max; -using std::auto_ptr; -using std::endl; +using namespace std; +namespace lyx { InsetMathScript::InsetMathScript() @@ -52,9 +50,9 @@ InsetMathScript::InsetMathScript(MathAtom const & at, bool up) } -auto_ptr InsetMathScript::doClone() const +Inset * InsetMathScript::clone() const { - return auto_ptr(new InsetMathScript(*this)); + return new InsetMathScript(*this); } @@ -70,7 +68,7 @@ InsetMathScript * InsetMathScript::asScriptInset() } -bool InsetMathScript::idxFirst(LCursor & cur) const +bool InsetMathScript::idxFirst(Cursor & cur) const { cur.idx() = 0; cur.pos() = 0; @@ -78,7 +76,7 @@ bool InsetMathScript::idxFirst(LCursor & cur) const } -bool InsetMathScript::idxLast(LCursor & cur) const +bool InsetMathScript::idxLast(Cursor & cur) const { cur.idx() = 0; cur.pos() = nuc().size(); @@ -86,7 +84,7 @@ bool InsetMathScript::idxLast(LCursor & cur) const } -MathArray const & InsetMathScript::down() const +MathData const & InsetMathScript::down() const { if (nargs() == 3) return cell(2); @@ -95,7 +93,7 @@ MathArray const & InsetMathScript::down() const } -MathArray & InsetMathScript::down() +MathData & InsetMathScript::down() { if (nargs() == 3) return cell(2); @@ -104,14 +102,14 @@ MathArray & InsetMathScript::down() } -MathArray const & InsetMathScript::up() const +MathData const & InsetMathScript::up() const { BOOST_ASSERT(nargs() > 1); return cell(1); } -MathArray & InsetMathScript::up() +MathData & InsetMathScript::up() { BOOST_ASSERT(nargs() > 1); return cell(1); @@ -122,26 +120,26 @@ void InsetMathScript::ensure(bool up) { if (nargs() == 1) { // just nucleus so far - cells_.push_back(MathArray()); + cells_.push_back(MathData()); cell_1_is_up_ = up; } else if (nargs() == 2 && !has(up)) { if (up) { cells_.push_back(cell(1)); cell(1).clear(); } else { - cells_.push_back(MathArray()); + cells_.push_back(MathData()); } } } -MathArray const & InsetMathScript::nuc() const +MathData const & InsetMathScript::nuc() const { return cell(0); } -MathArray & InsetMathScript::nuc() +MathData & InsetMathScript::nuc() { return cell(0); } @@ -157,7 +155,7 @@ bool isAlphaSymbol(MathAtom const & at) return true; if (at->asFontInset()) { - MathArray const & ar = at->asFontInset()->cell(0); + MathData const & ar = at->asFontInset()->cell(0); for (size_t i = 0; i < ar.size(); ++i) { if (!(ar[i]->asCharInset() || (ar[i]->asSymbolInset() && @@ -172,13 +170,14 @@ bool isAlphaSymbol(MathAtom const & at) } // namespace anon -int InsetMathScript::dy01(int asc, int des, int what) const +int InsetMathScript::dy01(BufferView const & bv, int asc, int des, int what) const { int dasc = 0; int slevel = 0; bool isCharBox = nuc().size() ? isAlphaSymbol(nuc().back()) : false; if (hasDown()) { - dasc = down().ascent(); + Dimension const & dimdown = down().dimension(bv); + dasc = dimdown.ascent(); slevel = nuc().slevel(); int ascdrop = dasc - slevel; int desdrop = isCharBox ? 0 : des + nuc().sshift(); @@ -187,9 +186,10 @@ int InsetMathScript::dy01(int asc, int des, int what) const des = max(mindes, des); } if (hasUp()) { + Dimension const & dimup = up().dimension(bv); int minasc = nuc().minasc(); int ascdrop = isCharBox ? 0 : asc - up().mindes(); - int udes = up().descent(); + int udes = dimup.descent(); asc = udes + nuc().sshift(); asc = max(ascdrop, asc); asc = max(minasc, asc); @@ -210,143 +210,156 @@ int InsetMathScript::dy01(int asc, int des, int what) const } -int InsetMathScript::dy0() const +int InsetMathScript::dy0(BufferView const & bv) const { - int nd = ndes(); + int nd = ndes(bv); if (!hasDown()) return nd; - int des = down().ascent(); + int des = down().dimension(bv).ascent(); if (hasLimits()) des += nd + 2; else { - int na = nasc(); - des = dy01(na, nd, 0); + int na = nasc(bv); + des = dy01(bv, na, nd, 0); } return des; } -int InsetMathScript::dy1() const +int InsetMathScript::dy1(BufferView const & bv) const { - int na = nasc(); + int na = nasc(bv); if (!hasUp()) return na; - int asc = up().descent(); + int asc = up().dimension(bv).descent(); if (hasLimits()) asc += na + 2; else { - int nd = ndes(); - asc = dy01(na, nd, 1); + int nd = ndes(bv); + asc = dy01(bv, na, nd, 1); } asc = max(asc, 5); return asc; } -int InsetMathScript::dx0() const +int InsetMathScript::dx0(BufferView const & bv) const { BOOST_ASSERT(hasDown()); - return hasLimits() ? (dim_.wid - down().width()) / 2 : nwid(); + Dimension const dim = dimension(bv); + return hasLimits() ? (dim.wid - down().dimension(bv).width()) / 2 : nwid(bv); } -int InsetMathScript::dx1() const +int InsetMathScript::dx1(BufferView const & bv) const { BOOST_ASSERT(hasUp()); - return hasLimits() ? (dim_.wid - up().width()) / 2 : nwid() + nker(); + Dimension const dim = dimension(bv); + return hasLimits() ? (dim.wid - up().dimension(bv).width()) / 2 : nwid(bv) + nker(&bv); } -int InsetMathScript::dxx() const +int InsetMathScript::dxx(BufferView const & bv) const { - return hasLimits() ? (dim_.wid - nwid()) / 2 : 0; + Dimension const dim = dimension(bv); + return hasLimits() ? (dim.wid - nwid(bv)) / 2 : 0; } -int InsetMathScript::nwid() const +int InsetMathScript::nwid(BufferView const & bv) const { - return nuc().size() ? nuc().width() : 2; + return nuc().size() ? nuc().dimension(bv).width() : 2; } -int InsetMathScript::nasc() const +int InsetMathScript::nasc(BufferView const & bv) const { - return nuc().size() ? nuc().ascent() : 5; + return nuc().size() ? nuc().dimension(bv).ascent() : 5; } -int InsetMathScript::ndes() const +int InsetMathScript::ndes(BufferView const & bv) const { - return nuc().size() ? nuc().descent() : 0; + return nuc().size() ? nuc().dimension(bv).descent() : 0; } -int InsetMathScript::nker() const +int InsetMathScript::nker(BufferView const * bv) const { if (nuc().size()) { - int kerning = nuc().kerning(); + int kerning = nuc().kerning(bv); return kerning > 0 ? kerning : 0; } return 0; } -bool InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetMathScript::metrics(MetricsInfo & mi, Dimension & dim) const { - cell(0).metrics(mi); + Dimension dim0; + Dimension dim1; + Dimension dim2; + cell(0).metrics(mi, dim0); ScriptChanger dummy(mi.base); if (nargs() > 1) - cell(1).metrics(mi); + cell(1).metrics(mi, dim1); if (nargs() > 2) - cell(2).metrics(mi); + cell(2).metrics(mi, dim2); + dim.wid = 0; + BufferView & bv = *mi.base.bv; + // FIXME: data copying... not very efficient. + Dimension dimup; + Dimension dimdown; + if (hasUp()) + dimup = up().dimension(bv); + if (hasDown()) + dimdown = down().dimension(bv); + if (hasLimits()) { - dim.wid = nwid(); + dim.wid = nwid(bv); if (hasUp()) - dim.wid = max(dim.wid, up().width()); + dim.wid = max(dim.wid, dimup.width()); if (hasDown()) - dim.wid = max(dim.wid, down().width()); + dim.wid = max(dim.wid, dimdown.width()); } else { if (hasUp()) - dim.wid = max(dim.wid, nker() + up().width()); + dim.wid = max(dim.wid, nker(mi.base.bv) + dimup.width()); if (hasDown()) - dim.wid = max(dim.wid, down().width()); - dim.wid += nwid(); + dim.wid = max(dim.wid, dimdown.width()); + dim.wid += nwid(bv); } - int na = nasc(); + int na = nasc(bv); if (hasUp()) { - int asc = dy1() + up().ascent(); + int asc = dy1(bv) + dimup.ascent(); dim.asc = max(na, asc); } else dim.asc = na; - int nd = ndes(); + int nd = ndes(bv); if (hasDown()) { - int des = dy0() + down().descent(); + int des = dy0(bv) + dimdown.descent(); dim.des = max(nd, des); } else dim.des = nd; metricsMarkers(dim); - if (dim_ == dim) - return false; - dim_ = dim; - return true; } void InsetMathScript::draw(PainterInfo & pi, int x, int y) const { + BufferView & bv = *pi.base.bv; if (nuc().size()) - nuc().draw(pi, x + dxx(), y); + nuc().draw(pi, x + dxx(bv), y); else { - nuc().setXY(*pi.base.bv, x + dxx(), y); - if (editing(pi.base.bv)) - pi.draw(x + dxx(), y, char_type('.')); + nuc().setXY(bv, x + dxx(bv), y); + if (editing(&bv)) + pi.draw(x + dxx(bv), y, char_type('.')); } ScriptChanger dummy(pi.base); if (hasUp()) - up().draw(pi, x + dx1(), y - dy1()); + up().draw(pi, x + dx1(bv), y - dy1(bv)); if (hasDown()) - down().draw(pi, x + dx0(), y + dy0()); + down().draw(pi, x + dx0(bv), y + dy0(bv)); drawMarkers(pi, x, y); } @@ -363,12 +376,13 @@ void InsetMathScript::metricsT(TextMetricsInfo const & mi, Dimension & dim) cons void InsetMathScript::drawT(TextPainter & pain, int x, int y) const { + // FIXME: BROKEN if (nuc().size()) - nuc().drawT(pain, x + dxx(), y); + nuc().drawT(pain, x + 1, y); if (hasUp()) - up().drawT(pain, x + dx1(), y - dy1()); + up().drawT(pain, x + 1, y - 1 /*dy1()*/); if (hasDown()) - down().drawT(pain, x + dx0(), y + dy0()); + down().drawT(pain, x + 1, y + 1 /*dy0()*/); } @@ -426,21 +440,21 @@ bool InsetMathScript::has(bool up) const bool InsetMathScript::hasUp() const { - //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; - //lyxerr << "hasUp: " << bool(idxOfScript(true)) << endl; + //lyxerr << "1up: " << bool(cell_1_is_up_)); + //lyxerr << "hasUp: " << bool(idxOfScript(true))); return idxOfScript(true); } bool InsetMathScript::hasDown() const { - //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; - //lyxerr << "hasDown: " << bool(idxOfScript(false)) << endl; + //LYXERR0("1up: " << bool(cell_1_is_up_)); + //LYXERR0("hasDown: " << bool(idxOfScript(false))); return idxOfScript(false); } -InsetBase::idx_type InsetMathScript::idxOfScript(bool up) const +Inset::idx_type InsetMathScript::idxOfScript(bool up) const { if (nargs() == 1) return 0; @@ -454,19 +468,19 @@ InsetBase::idx_type InsetMathScript::idxOfScript(bool up) const } -bool InsetMathScript::idxRight(LCursor &) const +bool InsetMathScript::idxForward(Cursor &) const { return false; } -bool InsetMathScript::idxLeft(LCursor &) const +bool InsetMathScript::idxBackward(Cursor &) const { return false; } -bool InsetMathScript::idxUpDown(LCursor & cur, bool up) const +bool InsetMathScript::idxUpDown(Cursor & cur, bool up) const { // in nucleus? if (cur.idx() == 0) { @@ -484,7 +498,7 @@ bool InsetMathScript::idxUpDown(LCursor & cur, bool up) const } // Are we 'up'? - if (has(up) && cur.idx() == idxOfScript(true)) { + if (cur.idx() == idxOfScript(true)) { // can't go further up if (up) return false; @@ -495,7 +509,7 @@ bool InsetMathScript::idxUpDown(LCursor & cur, bool up) const } // Are we 'down'? - if (has(up) && cur.idx() == idxOfScript(false)) { + if (cur.idx() == idxOfScript(false)) { // can't go further down if (!up) return false; @@ -521,8 +535,7 @@ void InsetMathScript::write(WriteStream & os) const //} } else { if (os.firstitem()) - LYXERR(Debug::MATHED) << "suppressing {} when writing" - << endl; + LYXERR(Debug::MATHED, "suppressing {} when writing"); else os << "{}"; } @@ -643,55 +656,75 @@ void InsetMathScript::infoize(odocstream & os) const void InsetMathScript::infoize2(odocstream & os) const { if (limits_) - os << (limits_ == 1 ? ", Displayed limits" : ", Inlined limits"); + os << from_ascii(limits_ == 1 ? ", Displayed limits" : ", Inlined limits"); } -bool InsetMathScript::notifyCursorLeaves(LCursor & cur) +bool InsetMathScript::notifyCursorLeaves(Cursor & cur) { InsetMathNest::notifyCursorLeaves(cur); - //lyxerr << "InsetMathScript::notifyCursorLeaves: 1 " << cur << endl; + //LYXERR0("InsetMathScript::notifyCursorLeaves: 1 " << cur); + + // Remove empty scripts if possible: - // remove empty scripts if possible - if (nargs() > 2) { - // Case of two scripts. In this case, 1 = super, 2 = sub - if (cur.idx() == 2 && cell(2).empty()) { + // The case of two scripts, but only one got empty (1 = super, 2 = sub). + // We keep the script inset, but remove the empty script. + if (nargs() > 2 && (!cell(1).empty() || !cell(2).empty())) { + if (cell(2).empty()) { // must be a subscript... - recordUndoInset(cur); removeScript(false); + cur.updateFlags(cur.disp_.update() | Update::SinglePar); return true; - } else if (cur.idx() == 1 && cell(1).empty()) { + } else if (cell(1).empty()) { // must be a superscript... - recordUndoInset(cur); removeScript(true); + cur.updateFlags(cur.disp_.update() | Update::SinglePar); return true; } - } else if (nargs() > 1 && cur.idx() == 1 && cell(1).empty()) { - // could be either subscript or super script - recordUndoInset(cur); - removeScript(cell_1_is_up_); + } + // Now the two suicide cases: + // * we have only one script which is empty + // * we have two scripts which are both empty. + // The script inset is removed completely. + if ((nargs() == 2 && cell(1).empty()) + || (nargs() == 3 && cell(1).empty() && cell(2).empty())) { + // Make undo step. We cannot use cur for this because + // it does not necessarily point to us. The BufferView + // cursor though should do. + int scriptSlice + = cur.bv().cursor().find(this); + BOOST_ASSERT(scriptSlice != -1); + Cursor & bvCur = cur.bv().cursor(); + bvCur.cutOff(scriptSlice); + bvCur.recordUndoInset(); + // Let the script inset commit suicide. This is - // modelled on LCursor.pullArg(), but tries not to + // modelled on Cursor.pullArg(), but tries not to // invoke notifyCursorLeaves again and does not touch // cur (since the top slice will be deleted - // afterwards)) - MathArray ar = cell(0); - LCursor tmpcur = cur; - tmpcur.pop(); - tmpcur.cell().erase(tmpcur.pos()); - tmpcur.cell().insert(tmpcur.pos(), ar); + // afterwards) + MathData ar = cell(0); + bvCur.pop(); + bvCur.cell().erase(bvCur.pos()); + bvCur.cell().insert(bvCur.pos(), ar); + + // put cursor behind + bvCur.pos() += ar.size(); + + // redraw + cur.updateFlags(cur.disp_.update() | Update::SinglePar); return true; } - //lyxerr << "InsetMathScript::notifyCursorLeaves: 2 " << cur << endl; + //LYXERR0("InsetMathScript::notifyCursorLeaves: 2 " << cur); return false; } -void InsetMathScript::doDispatch(LCursor & cur, FuncRequest & cmd) +void InsetMathScript::doDispatch(Cursor & cur, FuncRequest & cmd) { - //lyxerr << "InsetMathScript: request: " << cmd << std::endl; + //LYXERR("InsetMathScript: request: " << cmd); if (cmd.action == LFUN_MATH_LIMITS) { if (!cmd.argument().empty()) {