From a794a4594906064b3b72f11c6d08b3953510d14a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Tue, 30 Jul 2002 13:56:02 +0000 Subject: [PATCH] the up/down stuff reworked git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4806 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/math_charinset.C | 1 + src/mathed/math_cursor.C | 138 +++++++------- src/mathed/math_cursor.h | 2 + src/mathed/math_data.C | 124 ++----------- src/mathed/math_data.h | 93 +++------- src/mathed/math_diminset.C | 6 - src/mathed/math_diminset.h | 2 +- src/mathed/math_extern.C | 88 ++------- src/mathed/math_fracbase.C | 4 +- src/mathed/math_fracbase.h | 2 +- src/mathed/math_gridinset.C | 13 +- src/mathed/math_gridinset.h | 20 +-- src/mathed/math_hullinset.C | 8 +- src/mathed/math_inset.C | 10 +- src/mathed/math_inset.h | 5 +- src/mathed/math_macro.C | 15 +- src/mathed/math_macro.h | 2 +- src/mathed/math_nestinset.C | 2 +- src/mathed/math_parboxinset.C | 3 +- src/mathed/math_parboxinset.h | 2 +- src/mathed/math_parser.C | 22 +-- src/mathed/math_rootinset.C | 5 +- src/mathed/math_rootinset.h | 2 +- src/mathed/math_scriptinset.C | 307 ++++++++++++++++---------------- src/mathed/math_scriptinset.h | 90 +++++----- src/mathed/math_sqrtinset.C | 8 +- src/mathed/math_stackrelinset.h | 4 +- src/mathed/math_stringinset.h | 4 +- src/mathed/math_substackinset.h | 2 +- src/mathed/math_xdata.C | 150 ++++------------ src/mathed/math_xdata.h | 30 ++-- 31 files changed, 443 insertions(+), 721 deletions(-) diff --git a/src/mathed/math_charinset.C b/src/mathed/math_charinset.C index e9936032fe..6ec00b0582 100644 --- a/src/mathed/math_charinset.C +++ b/src/mathed/math_charinset.C @@ -73,6 +73,7 @@ void MathCharInset::metrics(MathMetricsInfo & mi) const mathed_char_dim(font_, char_, dim_); if (isBinaryOp(char_, code_)) width_ += 2 * font_metrics::width(' ', font_); + lyxerr << "MathCharInset::metrics: " << dim_ << "\n"; #endif } diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 4b3a10a8de..7322a4e4b3 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -170,9 +170,6 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const if (t->lock()) return false; - if (t->asScriptInset()) - return false; - if (sel) { // we can't move into anything new during selection if (depth() == Anchor_.size()) @@ -184,8 +181,16 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const } +bool MathCursor::inNucleus() const +{ + return par()->asScriptInset() && idx() == 2; +} + + bool MathCursor::posLeft() { + if (inNucleus()) + return false; if (pos() == 0) return false; --pos(); @@ -281,10 +286,11 @@ void MathCursor::setPos(int x, int y) formula()->xlow(), formula()->xhigh(), formula()->ylow(), formula()->yhigh()); if (!res) { - // this ccan happen on creation of "math-display" + // this can happen on creation of "math-display" dump("setPos 1.5"); first(); } + targetx_ = -1; // "no target" dump("setPos 2"); } @@ -299,6 +305,7 @@ bool MathCursor::home(bool sel) if (!par()->idxHome(idx(), pos())) return popLeft(); dump("home 2"); + targetx_ = -1; // "no target" return true; } @@ -312,6 +319,7 @@ bool MathCursor::end(bool sel) if (!par()->idxEnd(idx(), pos())) return popRight(); dump("end 2"); + targetx_ = -1; // "no target" return true; } @@ -417,21 +425,22 @@ void MathCursor::paste(MathGridInset const & data) for (row_type row = 0; row < numrows; ++row) { for (col_type col = 0; col < numcols; ++col) { idx_type i = p->index(row + p->row(idx), col + p->col(idx)); - p->cell(i).push_back(data.cell(data.index(row, col))); + p->cell(i).append(data.cell(data.index(row, col))); } // append the left over horizontal cells to the last column idx_type i = p->index(row + p->row(idx), p->ncols() - 1); for (MathInset::col_type col = numcols; col < data.ncols(); ++col) - p->cell(i).push_back(data.cell(data.index(row, col))); + p->cell(i).append(data.cell(data.index(row, col))); } // append the left over vertical cells to the last _cell_ idx_type i = p->nargs() - 1; for (row_type row = numrows; row < data.nrows(); ++row) for (col_type col = 0; col < data.ncols(); ++col) - p->cell(i).push_back(data.cell(data.index(row, col))); + p->cell(i).append(data.cell(data.index(row, col))); } } + void MathCursor::backspace() { autocorrect_ = false; @@ -445,12 +454,16 @@ void MathCursor::backspace() return; } - MathScriptInset * p = prevAtom()->asScriptInset(); - if (p) { - p->removeScript(p->hasUp()); - // Don't delete if there is anything left - if (p->hasUp() || p->hasDown()) - return; + if (prevAtom()->asScriptInset()) { + // simply enter nucleus + left(); + return; + } + + if (inNucleus()) { + // we are in nucleus + if (pos() == 1) { + } } --pos(); @@ -480,12 +493,25 @@ void MathCursor::erase() return; } - MathScriptInset * p = nextAtom()->asScriptInset(); - if (p) { - p->removeScript(p->hasUp()); - // Don't delete if there is anything left - if (p->hasUp() || p->hasDown()) - return; + // if we are standing in front of a script inset, grab item before us and + // move it into nucleus + // and remove first thing. + if (hasNextAtom() && nextAtom()->asScriptInset()) { + if (hasPrevAtom()) { + MathAtom at = prevAtom(); + --pos(); + array().erase(pos()); + pushLeft(nextAtom()); + if (array().empty()) + array().push_back(at); + else + array()[0] = at; + pos() = 1; + } else { + pushLeft(nextAtom()); + array().clear(); + } + return; } plainErase(); @@ -579,6 +605,7 @@ string MathCursor::macroName() const void MathCursor::selClear() { + Anchor_.clear(); selection_ = false; } @@ -786,20 +813,6 @@ void MathCursor::pullArg() { dump("pullarg"); MathArray a = array(); - - MathScriptInset const * p = par()->asScriptInset(); - if (p) { - // special handling for scripts - const bool up = p->hasUp(); - popLeft(); - MathScriptInset * q = nextAtom()->asScriptInset(); - if (q) - q->removeScript(up); - ++pos(); - array().insert(pos(), a); - return; - } - if (popLeft()) { plainErase(); array().insert(pos(), a); @@ -823,7 +836,7 @@ void MathCursor::normalize() { if (idx() >= par()->nargs()) { lyxerr << "this should not really happen - 1: " - << idx() << " " << par()->nargs() << "\n"; + << idx() << " " << par()->nargs() << " in: " << par() << "\n"; dump("error 2"); } idx() = min(idx(), par()->nargs() - 1); @@ -995,11 +1008,11 @@ void MathCursor::breakLine() // split line const row_type r = hullRow(); for (col_type c = hullCol() + 1; c < p->ncols(); ++c) - p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c))); + std::swap(p->cell(p->index(r, c)), p->cell(p->index(r + 1, c))); // split cell splitCell(); - p->cell(idx()).swap(p->cell(idx() + p->ncols() - 1)); + std::swap(p->cell(idx()), p->cell(idx() + p->ncols() - 1)); } } @@ -1060,8 +1073,6 @@ bool MathCursor::goUpDown(bool up) // Be warned: The 'logic' implemented in this function is highly fragile. // A distance of one pixel or a '<' vs '<=' _really_ matters. // So fiddle around with it only if you know what you are doing! - int xlow, xhigh, ylow, yhigh; - int xo, yo; getPos(xo, yo); @@ -1112,31 +1123,12 @@ bool MathCursor::goUpDown(bool up) while (1) { ///lyxerr << "updown: We are in " << *par() << " idx: " << idx() << '\n'; // ask inset first - if (par()->idxUpDown(idx(), pos(), up)) { -#ifdef WITH_WARNINGS -#warning this code should be moved to individual insets that handle this -#endif - // position might have changed, so re-compute it - getPos(xo, yo); - // we found a cell that thinks it has something "below" us. - //lyxerr << "updown: found inset that handles UpDown\n"; - xarray().boundingBox(xlow, xhigh, ylow, yhigh); - // project (xo,yo) onto proper box - //lyxerr << "\n xo: " << xo << " yo: " << yo - // << "\n xlow: " << xlow << " ylow: " << ylow - // << "\n xhigh: " << xhigh << " yhigh: " << yhigh; - xo = min(max(xo, xlow), xhigh); - yo = min(max(yo, ylow), yhigh); - //lyxerr << "\n xo2: " << xo << " yo2: " << yo << "\n"; - bruteFind(xo, yo, xlow, xhigh, ylow, yhigh); - //lyxerr << "updown: handled by final brute find\n"; + if (par()->idxUpDown(idx(), pos(), up, targetx_)) return true; - } - // leave inset - if (!popLeft()) { - // no such inset found, just take something "above" - ///lyxerr << "updown: handled by strange case\n"; + // no such inset found, just take something "above" + ///lyxerr << "updown: handled by strange case\n"; + if (!popLeft()) return bruteFind(xo, yo, formula()->xlow(), @@ -1144,7 +1136,6 @@ bool MathCursor::goUpDown(bool up) up ? formula()->ylow() : yo + 4, up ? yo - 4 : formula()->yhigh() ); - } // any improvement so far? int xnew, ynew; @@ -1266,9 +1257,9 @@ bool MathCursor::interpret(string const & s) string name = s.substr(1); if (name == "over" || name == "choose" || name == "atop") { - MathArray ar = array(); MathAtom t(createMathInset(name)); - t->asNestInset()->cell(0).swap(array()); + t->asNestInset()->cell(0) = array(); + array().clear(); pos() = 0; niceInsert(t); popRight(); @@ -1302,13 +1293,19 @@ bool MathCursor::script(bool up) macroModeClose(); MathGridInset safe = grabAndEraseSelection(); - if (hasPrevAtom() && prevAtom()->asScriptInset()) { + if (inNucleus()) { + // we are in a nucleus of a script inset, move to _our_ script + par()->asScriptInset()->ensure(up); + idx() = up; + pos() = 0; + } else if (hasPrevAtom() && prevAtom()->asScriptInset()) { prevAtom()->asScriptInset()->ensure(up); pushRight(prevAtom()); idx() = up; pos() = size(); - } else if (hasNextAtom() && nextAtom()->asScriptInset()) { - nextAtom()->asScriptInset()->ensure(up); + } else if (hasPrevAtom()) { + --pos(); + array()[pos()] = MathAtom(new MathScriptInset(nextAtom(), up)); pushLeft(nextAtom()); idx() = up; pos() = 0; @@ -1559,7 +1556,8 @@ MathGridInset MathCursor::grabSelection() const // shouldn't we assert on i1.par_ == i2.par_? if (i1.idx_ == i2.idx_) { MathGridInset data(1, 1); - data.cell(0) = MathArray(i1.cell(), i1.pos_, i2.pos_); + MathArray::const_iterator it = i1.cell().begin(); + data.cell(0) = MathArray(it + i1.pos_, it + i2.pos_); return data; } row_type r1, r2; @@ -1589,7 +1587,7 @@ void MathCursor::eraseSelection() region(i1, i2, r1, r2, c1, c2); for (row_type row = r1; row <= r2; ++row) for (col_type col = c1; col <= c2; ++col) - p->cell(p->index(row, col)).erase(); + p->cell(p->index(row, col)).clear(); } cursor() = i1; } @@ -1659,7 +1657,7 @@ void MathCursor::handleExtern(const string & arg) ar = array(); lyxerr << "use whole cell: " << ar << "\n"; } else { - ar = MathArray(array(), pos + 1, size()); + ar = MathArray(array().begin() + pos + 1, array().end()); lyxerr << "use partial cell form pos: " << pos << "\n"; } end(); diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index 38481da483..855b8d4174 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -280,6 +280,8 @@ private: bool goUpDown(bool up); /// moves position into box bool bruteFind(int xo, int yo, int xlow, int xhigh, int ylow, int yhigh); + /// are we in a nucleus of a script inset? + bool inNucleus() const; /// grab grid marked by anchor and current cursor diff --git a/src/mathed/math_data.C b/src/mathed/math_data.C index 4aa7431b64..32cceead39 100644 --- a/src/mathed/math_data.C +++ b/src/mathed/math_data.C @@ -18,17 +18,8 @@ #include "support/LAssert.h" -MathArray::MathArray() -{} - - -MathArray::MathArray(MathArray const & ar, size_type from, size_type to) - : bf_(ar.begin() + from, ar.begin() + to) -{} - - -MathArray::MathArray(iterator from, iterator to) - : bf_(from, to) +MathArray::MathArray(const_iterator from, const_iterator to) + : base_type(from, to) {} @@ -39,75 +30,38 @@ void MathArray::substitute(MathMacro const & m) } -MathAtom & MathArray::at(size_type pos) +MathAtom & MathArray::operator[](size_type pos) { lyx::Assert(pos < size()); - return bf_[pos]; + return base_type::operator[](pos); } -MathAtom const & MathArray::at(size_type pos) const +MathAtom const & MathArray::operator[](size_type pos) const { lyx::Assert(pos < size()); - return bf_[pos]; + return base_type::operator[](pos); } void MathArray::insert(size_type pos, MathAtom const & t) { - bf_.insert(begin() + pos, t); + base_type::insert(begin() + pos, t); } void MathArray::insert(size_type pos, MathArray const & ar) { - bf_.insert(begin() + pos, ar.begin(), ar.end()); -} - - -void MathArray::push_back(MathAtom const & t) -{ - bf_.push_back(t); + base_type::insert(begin() + pos, ar.begin(), ar.end()); } -void MathArray::push_back(MathArray const & ar) +void MathArray::append(MathArray const & ar) { insert(size(), ar); } -void MathArray::clear() -{ - erase(); -} - - -void MathArray::swap(MathArray & ar) -{ - if (this != &ar) - bf_.swap(ar.bf_); -} - - -bool MathArray::empty() const -{ - return bf_.empty(); -} - - -MathArray::size_type MathArray::size() const -{ - return bf_.size(); -} - - -void MathArray::erase() -{ - bf_.erase(begin(), end()); -} - - void MathArray::erase(size_type pos) { if (pos < size()) @@ -117,37 +71,19 @@ void MathArray::erase(size_type pos) void MathArray::erase(iterator pos1, iterator pos2) { - bf_.erase(pos1, pos2); + base_type::erase(pos1, pos2); } void MathArray::erase(iterator pos) { - bf_.erase(pos); + base_type::erase(pos); } void MathArray::erase(size_type pos1, size_type pos2) { - bf_.erase(begin() + pos1, begin() + pos2); -} - - -MathAtom & MathArray::back() -{ - return bf_.back(); -} - - -MathAtom & MathArray::front() -{ - return bf_.front(); -} - - -MathAtom const & MathArray::front() const -{ - return bf_.front(); + base_type::erase(begin() + pos1, begin() + pos2); } @@ -175,40 +111,6 @@ void MathArray::validate(LaTeXFeatures & features) const } -void MathArray::pop_back() -{ - if (!size()) { - lyxerr << "pop_back from empty array!\n"; - return; - } - bf_.pop_back(); -} - - -MathArray::const_iterator MathArray::begin() const -{ - return bf_.begin(); -} - - -MathArray::const_iterator MathArray::end() const -{ - return bf_.end(); -} - - -MathArray::iterator MathArray::begin() -{ - return bf_.begin(); -} - - -MathArray::iterator MathArray::end() -{ - return bf_.end(); -} - - bool MathArray::match(MathArray const & ar) const { return size() == ar.size() && matchpart(ar, 0); @@ -247,7 +149,7 @@ bool MathArray::find1(MathArray const & ar, size_type pos) const { //lyxerr << "finding '" << ar << "' in '" << *this << "'\n"; for (size_type i = 0, n = ar.size(); i < n; ++i) - if (!at(pos + i)->match(ar[i].nucleus())) + if (!operator[](pos + i)->match(ar[i].nucleus())) return false; return true; } diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index 66994e7ccc..920746412d 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -40,39 +40,35 @@ class ReplaceData; \version February 2001 */ -class MathArray { +class MathArray : private std::vector { public: - /// - typedef std::vector buffer_type; - /// - typedef buffer_type::const_iterator const_iterator; - /// - typedef buffer_type::iterator iterator; - /// - typedef buffer_type::size_type size_type; - /// - typedef buffer_type::difference_type difference_type; - /// - typedef buffer_type::size_type idx_type; - /// - typedef buffer_type::size_type pos_type; - + /// re-use inhertited stuff + typedef std::vector base_type; + using base_type::const_iterator; + using base_type::iterator; + using base_type::size_type; + using base_type::difference_type; + using base_type::size; + using base_type::empty; + using base_type::clear; + using base_type::begin; + using base_type::end; + using base_type::push_back; + using base_type::pop_back; + using base_type::back; + using base_type::front; + using base_type::swap; + /// + typedef size_type idx_type; + typedef size_type pos_type; + public: /// - MathArray(); + MathArray() {} /// - MathArray(MathArray const & ar, size_type from, size_type to); + MathArray(const_iterator from, const_iterator to); /// - MathArray(iterator from, iterator to); - - /// - size_type size() const; - /// - bool empty() const; - /// - void clear(); - /// - void swap(MathArray &); + void append(MathArray const & ar); /// inserts single atom at position pos void insert(size_type pos, MathAtom const & at); @@ -87,22 +83,6 @@ public: void erase(size_type pos1, size_type pos2); /// erase single atom void erase(size_type pos); - /// erase everythng - void erase(); - - /// - void push_back(MathAtom const & at); - /// - void push_back(MathArray const & ar); - /// - void pop_back(); - /// - MathAtom & back(); - - /// - MathAtom & front(); - /// - MathAtom const & front() const; /// void dump() const; @@ -123,33 +103,16 @@ public: size_type find_last(MathArray const & ar) const; /// bool contains(MathArray const & ar) const; - - /// write acccess to single atom - MathAtom & operator[](size_type pos) { return at(pos); } - /// read access o single atom - MathAtom const & operator[](size_type pos) const { return at(pos); } - /// - const_iterator begin() const; - /// - const_iterator end() const; - /// - iterator begin(); - /// - iterator end(); - /// void validate(LaTeXFeatures &) const; + /// checked write access + MathAtom & operator[](pos_type); + /// checked read access + MathAtom const & operator[](pos_type) const; private: /// is this an exact match at this position? bool find1(MathArray const & ar, size_type pos) const; - /// write acccess to single atom - MathAtom & at(size_type pos); - /// read access o single atom - MathAtom const & at(size_type pos) const; - - /// Buffer - buffer_type bf_; }; /// diff --git a/src/mathed/math_diminset.C b/src/mathed/math_diminset.C index 02d7623f22..783e41a1d5 100644 --- a/src/mathed/math_diminset.C +++ b/src/mathed/math_diminset.C @@ -3,12 +3,6 @@ #include "textpainter.h" -void MathDimInset::dimensions(Dimension & dim) const -{ - dim = dim_; -} - - void MathDimInset::metricsT(TextMetricsInfo const &) const { std::ostringstream os; diff --git a/src/mathed/math_diminset.h b/src/mathed/math_diminset.h index 02835afc5c..064807bf49 100644 --- a/src/mathed/math_diminset.h +++ b/src/mathed/math_diminset.h @@ -18,7 +18,7 @@ public: /// read width int width() const { return dim_.width(); } /// - void dimensions(Dimension & dim) const; + Dimension dimensions() const { return dim_; } /// void metricsT(TextMetricsInfo const &) const; /// diff --git a/src/mathed/math_extern.C b/src/mathed/math_extern.C index 80f2df0d12..00055dec73 100644 --- a/src/mathed/math_extern.C +++ b/src/mathed/math_extern.C @@ -113,20 +113,6 @@ MathArray::iterator extractArgument(MathArray & ar, } -MathScriptInset const * asScript(MathArray::const_iterator it) -{ - if (!it->nucleus()) - return 0; - if (it->nucleus()->asScriptInset()) - return 0; - ++it; - if (!it->nucleus()) - return 0; - return it->nucleus()->asScriptInset(); -} - - - // returns sequence of char with same code starting at it up to end // it might be less, though... string charSequence @@ -300,7 +286,7 @@ void splitScripts(MathArray & ar) // create extra script inset and move superscript over MathScriptInset * q = new MathScriptInset; q->ensure(true); - q->up().data().swap(p->up().data()); + std::swap(q->up(), p->up()); p->removeScript(true); // insert new inset behind @@ -799,8 +785,8 @@ void extractLims(MathArray & ar) continue; // the -> splits the subscript int x and x0 - MathArray x = MathArray(s, 0, st - s.begin()); - MathArray x0 = MathArray(s, st - s.begin() + 1, s.size()); + MathArray x = MathArray(s.begin(), st); + MathArray x0 = MathArray(st + 1, s.end()); // use something behind the script as core MathArray f; @@ -842,18 +828,8 @@ void write(MathArray const & dat, WriteStream & wi) { MathArray ar = dat; extractStrings(ar); - for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) { - wi.firstitem() = (it == ar.begin()); - MathInset const * p = it->nucleus(); - if (it + 1 != ar.end()) { - if (MathScriptInset const * q = asScript(it)) { - q->write2(p, wi); - ++it; - continue; - } - } - p->write(wi); - } + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + (*it)->write(wi); } @@ -868,17 +844,8 @@ void octavize(MathArray const & dat, OctaveStream & os) { MathArray ar = dat; extractStructure(ar); - for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) { - MathInset const * p = it->nucleus(); - if (it + 1 != ar.end()) { - if (MathScriptInset const * q = asScript(it)) { - q->octavize2(p, os); - ++it; - continue; - } - } - p->octavize(os); - } + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + (*it)->octavize(os); } @@ -886,17 +853,8 @@ void maplize(MathArray const & dat, MapleStream & os) { MathArray ar = dat; extractStructure(ar); - for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) { - MathInset const * p = it->nucleus(); - if (it + 1 != ar.end()) { - if (MathScriptInset const * q = asScript(it)) { - q->maplize2(p, os); - ++it; - continue; - } - } - p->maplize(os); - } + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + (*it)->maplize(os); } @@ -904,17 +862,8 @@ void mathematicize(MathArray const & dat, MathematicaStream & os) { MathArray ar = dat; extractStructure(ar); - for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) { - MathInset const * p = it->nucleus(); - if (it + 1 != ar.end()) { - if (MathScriptInset const * q = asScript(it)) { - q->mathematicize2(p, os); - ++it; - continue; - } - } - p->mathematicize(os); - } + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + (*it)->mathematicize(os); } @@ -928,17 +877,8 @@ void mathmlize(MathArray const & dat, MathMLStream & os) os << ar.begin()->nucleus(); else { os << MTag("mrow"); - for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) { - MathInset const * p = it->nucleus(); - if (it + 1 != ar.end()) { - if (MathScriptInset const * q = asScript(it)) { - q->mathmlize2(p, os); - ++it; - continue; - } - } - p->mathmlize(os); - } + for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) + (*it)->mathmlize(os); os << ETag("mrow"); } } @@ -1099,7 +1039,7 @@ namespace { MathArrayInset const * mat = at.nucleus()->asArrayInset(); MathArray res; if (mat->ncols() == 1 && mat->nrows() == 1) - res.push_back(mat->cell(0)); + res.append(mat->cell(0)); else { res.push_back(MathAtom(new MathDelimInset("(", ")"))); res.back()->cell(0).push_back(at); diff --git a/src/mathed/math_fracbase.C b/src/mathed/math_fracbase.C index 329da0a0ce..13d5ae5f47 100644 --- a/src/mathed/math_fracbase.C +++ b/src/mathed/math_fracbase.C @@ -23,11 +23,13 @@ bool MathFracbaseInset::idxLeft(idx_type &, pos_type &) const } -bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type &, bool up) const +bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, + int targetx) const { MathInset::idx_type target = !up; // up ? 0 : 1, since upper cell has idx 0 if (idx == target) return false; idx = target; + pos = xcell(idx).x2pos(targetx); return true; } diff --git a/src/mathed/math_fracbase.h b/src/mathed/math_fracbase.h index 8ac0a9f2ba..9c13868614 100644 --- a/src/mathed/math_fracbase.h +++ b/src/mathed/math_fracbase.h @@ -13,7 +13,7 @@ public: /// MathFracbaseInset(); /// - bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const; + bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const; /// bool idxLeft(idx_type & idx, pos_type & pos) const; /// diff --git a/src/mathed/math_gridinset.C b/src/mathed/math_gridinset.C index b7f27f656c..b8d484e862 100644 --- a/src/mathed/math_gridinset.C +++ b/src/mathed/math_gridinset.C @@ -630,17 +630,20 @@ int MathGridInset::cellYOffset(idx_type idx) const } -bool MathGridInset::idxUpDown(idx_type & idx, pos_type &, bool up) const +bool MathGridInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, + int targetx) const { if (up) { if (idx < ncols()) return false; idx -= ncols(); + pos = xcell(idx).x2pos(targetx - xcell(idx).xo()); return true; } else { if (idx >= ncols() * (nrows() - 1)) return false; idx += ncols(); + pos = xcell(idx).x2pos(targetx - xcell(idx).xo()); return true; } } @@ -759,7 +762,7 @@ bool MathGridInset::idxDelete(idx_type & idx) // move cells if necessary for (idx_type i = index(row(idx), 0); i < idx; ++i) - cell(i).swap(cell(i + ncols())); + std::swap(cell(i), cell(i + ncols())); delRow(row(idx)); @@ -783,14 +786,14 @@ void MathGridInset::idxGlue(idx_type idx) if (c + 1 == ncols()) { if (row(idx) + 1 != nrows()) { for (col_type cc = 0; cc < ncols(); ++cc) - cell(idx).push_back(cell(idx + cc + 1)); + cell(idx).append(cell(idx + cc + 1)); delRow(row(idx) + 1); } } else { - cell(idx).push_back(cell(idx + 1)); + cell(idx).append(cell(idx + 1)); for (col_type cc = c + 2; cc < ncols(); ++cc) cell(idx - c + cc - 1) = cell(idx - c + cc); - cell(idx - c + ncols() - 1).erase(); + cell(idx - c + ncols() - 1).clear(); } } diff --git a/src/mathed/math_gridinset.h b/src/mathed/math_gridinset.h index f0037eead9..cecf1e8925 100644 --- a/src/mathed/math_gridinset.h +++ b/src/mathed/math_gridinset.h @@ -82,15 +82,15 @@ public: /// MathInset * clone() const; /// - void metrics(MathMetricsInfo & st) const; + void metrics(MathMetricsInfo & mi) const; /// - void draw(MathPainterInfo &, int x, int y) const; + void draw(MathPainterInfo & pi, int x, int y) const; /// - void metricsT(TextMetricsInfo const & st) const; + void metricsT(TextMetricsInfo const & mi) const; /// - void drawT(TextPainter &, int x, int y) const; + void drawT(TextPainter & pi, int x, int y) const; /// - void halign(string const &); + void halign(string const & align); /// void halign(char c, col_type col); /// @@ -126,13 +126,9 @@ public: col_type col(idx_type idx) const; /// row_type row(idx_type idx) const; - /// - int cellXOffset(idx_type idx) const; - /// - int cellYOffset(idx_type idx) const; /// - bool idxUpDown(idx_type & idx, pos_type & pos, bool) const; + bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const; /// bool idxLeft(idx_type & idx, pos_type & pos) const; /// @@ -202,6 +198,10 @@ public: //void octavize(OctaveStream &) const; protected: + /// returns x offset of cell comapared to inset + int cellXOffset(idx_type idx) const; + /// returns y offset of cell comapared to inset + int cellYOffset(idx_type idx) const; /// returns proper 'end of line' code for LaTeX string eolString(row_type row, bool fragile = false) const; /// returns proper 'end of column' code for LaTeX diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index a00d4afc13..504a86fea1 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -444,7 +444,7 @@ void MathHullInset::glueall() { MathArray ar; for (idx_type i = 0; i < nargs(); ++i) - ar.push_back(cell(i)); + ar.append(cell(i)); *this = MathHullInset("simple"); cell(0) = ar; setDefaults(); @@ -506,11 +506,11 @@ void MathHullInset::mutate(string const & newtype) // split it "nicely" on the firest relop pos_type pos = firstRelOp(cell(0)); - cell(1) = MathArray(cell(0), pos, cell(0).size()); + cell(1) = MathArray(cell(0).begin() + pos, cell(0).end()); cell(0).erase(pos, cell(0).size()); if (cell(1).size()) { - cell(2) = MathArray(cell(1), 1, cell(1).size()); + cell(2) = MathArray(cell(1).begin() + 1, cell(1).end()); cell(1).erase(1, cell(1).size()); } setType("eqnarray"); @@ -551,7 +551,7 @@ void MathHullInset::mutate(string const & newtype) } else { // align & Co. for (row_type row = 0; row < nrows(); ++row) { idx_type c = 3 * row + 1; - cell(c).push_back(cell(c + 1)); + cell(c).append(cell(c + 1)); } MathGridInset::delCol(2); setType("align"); diff --git a/src/mathed/math_inset.C b/src/mathed/math_inset.C index e1a6069046..0c7e88ad9f 100644 --- a/src/mathed/math_inset.C +++ b/src/mathed/math_inset.C @@ -62,17 +62,17 @@ ostream & operator<<(ostream & os, MathInset const & inset) return os; } + MathInset::size_type MathInset::nargs() const { return 0; } -void MathInset::dimensions(Dimension & dim) const +Dimension MathInset::dimensions() const { - dim.w = width(); - dim.a = ascent(); - dim.d = descent(); + lyxerr << "call MathInset::dimensions()\n"; + return Dimension(width(), ascent(), descent()); } @@ -143,7 +143,7 @@ bool MathInset::idxLeft(idx_type &, pos_type &) const } -bool MathInset::idxUpDown(idx_type &, pos_type &, bool) const +bool MathInset::idxUpDown(idx_type &, pos_type &, bool, int) const { return false; } diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 5a62a1bc82..456f53a156 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -128,12 +128,13 @@ public: /// total width virtual int width() const { return 2; } /// all in one batch - virtual void dimensions(Dimension & dim) const; + virtual Dimension dimensions() const; /// total height (== ascent + descent) virtual int height() const; /// Where should we go when we press the up or down cursor key? - virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const; + virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up, + int targetx) const; /// The left key virtual bool idxLeft(idx_type & idx, pos_type & pos) const; /// The right key diff --git a/src/mathed/math_macro.C b/src/mathed/math_macro.C index f25d081c13..67a8070e90 100644 --- a/src/mathed/math_macro.C +++ b/src/mathed/math_macro.C @@ -160,11 +160,20 @@ void MathMacro::dump() const } -bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up) const +bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up, int x) const { pos_type pos; - return - up ? MathNestInset::idxLeft(idx, pos) : MathNestInset::idxRight(idx, pos); + if (up) { + if (!MathNestInset::idxLeft(idx, pos)) + return false; + pos = xcell(idx).x2pos(x); + return true; + } else { + if (!MathNestInset::idxRight(idx, pos)) + return false; + pos = xcell(idx).x2pos(x); + return true; + } } diff --git a/src/mathed/math_macro.h b/src/mathed/math_macro.h index 4572a1d648..847a19f6ab 100644 --- a/src/mathed/math_macro.h +++ b/src/mathed/math_macro.h @@ -51,7 +51,7 @@ public: void dump() const; /// - bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const; + bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const; /// bool idxLeft(idx_type & idx, pos_type & pos) const; /// diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 639553660b..85b4e92469 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -297,7 +297,7 @@ MathArray MathNestInset::glue() const { MathArray ar; for (unsigned i = 0; i < nargs(); ++i) - ar.push_back(cell(i)); + ar.append(cell(i)); return ar; } diff --git a/src/mathed/math_parboxinset.C b/src/mathed/math_parboxinset.C index 609f9bdeb0..d96843ceb4 100644 --- a/src/mathed/math_parboxinset.C +++ b/src/mathed/math_parboxinset.C @@ -65,7 +65,8 @@ void MathParboxInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const } -bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up) const +bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, + int targetx) const { // try to move only one screen row up or down if possible int row = pos2row(pos); diff --git a/src/mathed/math_parboxinset.h b/src/mathed/math_parboxinset.h index ab129d9b66..bcf0dc606e 100644 --- a/src/mathed/math_parboxinset.h +++ b/src/mathed/math_parboxinset.h @@ -31,7 +31,7 @@ public: /// void setPosition(string const & pos); /// moves cursor up or down - bool idxUpDown(idx_type &, pos_type & pos, bool up) const; + bool idxUpDown(idx_type &, pos_type & pos, bool up, int targetx) const; private: /// number of rows on screen int screenrows() const; diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index 0e1e94e335..32cd4c7f9f 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -497,7 +497,6 @@ void Parser::error(string const & msg) } - bool Parser::parse(MathAtom & at) { skipSpaces(); @@ -632,7 +631,7 @@ void Parser::parse1(MathGridInset & grid, unsigned flags, // do not create a BraceInset if they were written by LyX // this helps to keep the annoyance of "a choose b" to a minimum if (ar.size() == 1 && ar[0]->extraBraces()) - cell->push_back(ar); + cell->append(ar); else cell->push_back(MathAtom(new MathBraceInset(ar))); } @@ -657,14 +656,16 @@ void Parser::parse1(MathGridInset & grid, unsigned flags, else if (t.cat() == catSuper || t.cat() == catSub) { bool up = (t.cat() == catSuper); - MathScriptInset * p = 0; - if (cell->size()) - p = cell->back()->asScriptInset(); - if (!p || p->has(up)) { + // we need no new script inset if the last thing was a scriptinset, + // which has that script already not the same script already + if (cell->size() && cell->back()->asScriptInset() && + !cell->back()->asScriptInset()->has(up)) + cell->back()->asScriptInset()->ensure(up); + else if (cell->back()->asScriptInset()) cell->push_back(MathAtom(new MathScriptInset(up))); - p = cell->back()->asScriptInset(); - } - p->ensure(up); + else + cell->back() = MathAtom(new MathScriptInset(cell->back(), up)); + MathScriptInset * p = cell->back()->asScriptInset(); parse(p->cell(up), FLAG_ITEM, mathmode); p->limits(limits); limits = 0; @@ -987,7 +988,8 @@ void Parser::parse1(MathGridInset & grid, unsigned flags, else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") { MathAtom p = createMathInset(t.cs()); - cell->swap(p->cell(0)); + p->cell(0) = *cell; + cell->clear(); parse(p->cell(1), flags, mathmode); cell->push_back(p); return; diff --git a/src/mathed/math_rootinset.C b/src/mathed/math_rootinset.C index bc8e60b3cf..1e0a14f027 100644 --- a/src/mathed/math_rootinset.C +++ b/src/mathed/math_rootinset.C @@ -40,6 +40,7 @@ void MathRootInset::metrics(MathMetricsInfo & mi) const dim_.a = max(xcell(0).ascent() + 5, xcell(1).ascent()) + 2; dim_.d = max(xcell(1).descent() + 5, xcell(0).descent()) + 2; dim_.w = xcell(0).width() + xcell(1).width() + 10; + metricsMarkers(); } @@ -60,6 +61,7 @@ void MathRootInset::draw(MathPainterInfo & pi, int x, int y) const xp[3] = x + w - 2; yp[3] = y + (d - a)/2 + 2; xp[4] = x; yp[4] = y + (d - a)/2 + 2; pi.pain.lines(xp, yp, 5, LColor::math); + drawMarkers(pi, x, y); } @@ -75,12 +77,13 @@ void MathRootInset::normalize(NormalStream & os) const } -bool MathRootInset::idxUpDown(idx_type & idx, pos_type &, bool up) const +bool MathRootInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, int) const { bool target = !up; // up ? 0 : 1; if (idx == target) return false; idx = target; + pos = target ? 0 : cell(0).size(); return true; } diff --git a/src/mathed/math_rootinset.h b/src/mathed/math_rootinset.h index 060339362b..6cc4c518a7 100644 --- a/src/mathed/math_rootinset.h +++ b/src/mathed/math_rootinset.h @@ -32,7 +32,7 @@ public: /// MathInset * clone() const; /// - bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const; + bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const; /// void metrics(MathMetricsInfo & mi) const; /// diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index a619ea7546..fb29ee2030 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -14,7 +14,7 @@ using std::max; MathScriptInset::MathScriptInset() - : MathNestInset(2), limits_(0) + : MathNestInset(3), limits_(0) { script_[0] = false; script_[1] = false; @@ -22,13 +22,23 @@ MathScriptInset::MathScriptInset() MathScriptInset::MathScriptInset(bool up) - : MathNestInset(2), limits_(0) + : MathNestInset(3), limits_(0) { script_[0] = !up; script_[1] = up; } +MathScriptInset::MathScriptInset(MathAtom const & at, bool up) + : MathNestInset(3), limits_(0) +{ + script_[0] = !up; + script_[1] = up; + cell(2).push_back(at); +} + + + MathInset * MathScriptInset::clone() const { return new MathScriptInset(*this); @@ -47,9 +57,19 @@ MathScriptInset * MathScriptInset::asScriptInset() } -MathXArray const & MathScriptInset::up() const +bool MathScriptInset::idxFirst(idx_type & idx, pos_type & pos) const { - return xcell(1); + idx = 2; + pos = nuc().size(); + return true; +} + + +bool MathScriptInset::idxLast(idx_type & idx, pos_type & pos) const +{ + idx = 2; + pos = nuc().size(); + return true; } @@ -59,15 +79,21 @@ MathXArray const & MathScriptInset::down() const } -MathXArray & MathScriptInset::up() +MathXArray & MathScriptInset::down() +{ + return xcell(0); +} + + +MathXArray const & MathScriptInset::up() const { return xcell(1); } -MathXArray & MathScriptInset::down() +MathXArray & MathScriptInset::up() { - return xcell(0); + return xcell(1); } @@ -77,13 +103,25 @@ void MathScriptInset::ensure(bool up) } -int MathScriptInset::dy0(MathInset const * nuc) const +MathXArray const & MathScriptInset::nuc() const +{ + return xcell(2); +} + + +MathXArray & MathScriptInset::nuc() +{ + return xcell(2); +} + + +int MathScriptInset::dy0() const { - int nd = ndes(nuc); + int nd = ndes(); if (!hasDown()) return nd; int des = down().ascent(); - if (hasLimits(nuc)) + if (hasLimits()) des += nd + 2; else des = max(des, nd); @@ -91,13 +129,13 @@ int MathScriptInset::dy0(MathInset const * nuc) const } -int MathScriptInset::dy1(MathInset const * nuc) const +int MathScriptInset::dy1() const { - int na = nasc(nuc); + int na = nasc(); if (!hasUp()) return na; int asc = up().descent(); - if (hasLimits(nuc)) + if (hasLimits()) asc += na + 2; else asc = max(asc, na); @@ -106,154 +144,106 @@ int MathScriptInset::dy1(MathInset const * nuc) const } -int MathScriptInset::dx0(MathInset const * nuc) const +int MathScriptInset::dx0() const { lyx::Assert(hasDown()); - return hasLimits(nuc) ? (width2(nuc) - down().width()) / 2 : nwid(nuc); + return hasLimits() ? (dim_.w - down().width()) / 2 : nwid(); } -int MathScriptInset::dx1(MathInset const * nuc) const +int MathScriptInset::dx1() const { lyx::Assert(hasUp()); - return hasLimits(nuc) ? (width2(nuc) - up().width()) / 2 : nwid(nuc); -} - - -int MathScriptInset::dxx(MathInset const * nuc) const -{ - //lyx::Assert(nuc()); - return hasLimits(nuc) ? (width2(nuc) - nwid(nuc)) / 2 : 0; -} - - -void MathScriptInset::dimensions2(MathInset const * nuc, Dimension & dim) const -{ - dim.a = dy1(nuc) + (hasUp() ? up().ascent() : 0); - dim.d = dy0(nuc) + (hasDown() ? down().descent() : 0); - dim.w = width2(nuc); + return hasLimits() ? (dim_.w - up().width()) / 2 : nwid(); } -int MathScriptInset::width2(MathInset const * nuc) const +int MathScriptInset::dxx() const { - int w = 0; - if (hasLimits(nuc)) { - w = nwid(nuc); - if (hasUp()) - w = max(w, up().width()); - if (hasDown()) - w = max(w, down().width()); - } else { - if (hasUp()) - w = max(w, up().width()); - if (hasDown()) - w = max(w, down().width()); - w += nwid(nuc); - } - return w; + return hasLimits() ? (dim_.w - nwid()) / 2 : 0; } -int MathScriptInset::nwid(MathInset const * nuc) const +int MathScriptInset::nwid() const { - return nuc ? nuc->width() : mathed_char_width(font_, '.'); + return nuc().size() ? nuc().width() : mathed_char_width(font_, '.'); } -int MathScriptInset::nasc(MathInset const * nuc) const +int MathScriptInset::nasc() const { - return nuc ? nuc->ascent() : mathed_char_ascent(font_, 'I'); + return nuc().size() ? nuc().ascent() : mathed_char_ascent(font_, 'I'); } -int MathScriptInset::ndes(MathInset const * nuc) const +int MathScriptInset::ndes() const { - return nuc ? nuc->descent() : mathed_char_descent(font_, 'I'); + return nuc().size() ? nuc().descent() : mathed_char_descent(font_, 'I'); } void MathScriptInset::metrics(MathMetricsInfo & mi) const { - metrics(0, mi); -} - - -void MathScriptInset::metrics(MathInset const * nuc, MathMetricsInfo & mi) const -{ - if (nuc) - nuc->metrics(mi); MathNestInset::metrics(mi); MathScriptChanger dummy(mi.base); - dimensions2(nuc, dim_); + dim_.w = 0; + if (hasLimits()) { + dim_.w = nwid(); + if (hasUp()) + dim_.w = max(dim_.w, up().width()); + if (hasDown()) + dim_.w = max(dim_.w, down().width()); + } else { + if (hasUp()) + dim_.w = max(dim_.w, up().width()); + if (hasDown()) + dim_.w = max(dim_.w, down().width()); + dim_.w += nwid(); + } + dim_.a = dy1() + (hasUp() ? up().ascent() : 0); + dim_.d = dy0() + (hasDown() ? down().descent() : 0); + metricsMarkers(); } void MathScriptInset::draw(MathPainterInfo & pi, int x, int y) const { - //lyxerr << "unexpected call to MathScriptInset::draw()\n"; - draw(0, pi, x, y); -} - - -void MathScriptInset::draw(MathInset const * nuc, MathPainterInfo & pi, - int x, int y) const -{ - if (nuc) - nuc->draw(pi, x + dxx(nuc), y); + if (nuc().size()) + nuc().draw(pi, x + dxx(), y); else if (editing()) - drawStr(pi, font_, x + dxx(nuc), y, "."); - + drawStr(pi, font_, x + dxx(), y, "."); MathScriptChanger dummy(pi.base); if (hasUp()) - up().draw(pi, x + dx1(nuc), y - dy1(nuc)); + up().draw(pi, x + dx1(), y - dy1()); if (hasDown()) - down().draw(pi, x + dx0(nuc), y + dy0(nuc)); + down().draw(pi, x + dx0(), y + dy0()); + drawMarkers(pi, x, y); } void MathScriptInset::metricsT(TextMetricsInfo const & mi) const -{ - metricsT(0, mi); -} - - -void MathScriptInset::metricsT(MathInset const * nuc, - TextMetricsInfo const & mi) const { if (hasUp()) up().metricsT(mi); if (hasDown()) down().metricsT(mi); - if (nuc) - nuc->metricsT(mi); - //ascent_ = ascent2(nuc); - //descent_ = descent2(nuc); - //width_ = width2(nuc); + nuc().metricsT(mi); } void MathScriptInset::drawT(TextPainter & pain, int x, int y) const { - //lyxerr << "unexpected call to MathScriptInset::draw()\n"; - drawT(0, pain, x, y); -} - - -void MathScriptInset::drawT(MathInset const * nuc, TextPainter & pain, - int x, int y) const -{ - if (nuc) - nuc->drawT(pain, x + dxx(nuc), y); + if (nuc().size()) + nuc().drawT(pain, x + dxx(), y); if (hasUp()) - up().drawT(pain, x + dx1(nuc), y - dy1(nuc)); + up().drawT(pain, x + dx1(), y - dy1()); if (hasDown()) - down().drawT(pain, x + dx0(nuc), y + dy0(nuc)); + down().drawT(pain, x + dx0(), y + dy0()); } -bool MathScriptInset::hasLimits(MathInset const * nuc) const +bool MathScriptInset::hasLimits() const { // obvious cases if (limits_ == 1) @@ -262,14 +252,14 @@ bool MathScriptInset::hasLimits(MathInset const * nuc) const return false; // we can only display limits if the nucleus wants some - if (!nuc) + if (!nuc().size()) return false; - if (!nuc->isScriptable()) + if (!nuc().back()->isScriptable()) return false; // per default \int has limits beside the \int even in displayed formulas - if (nuc->asSymbolInset()) - if (nuc->asSymbolInset()->name().find("int") != string::npos) + if (nuc().back()->asSymbolInset()) + if (nuc().back()->asSymbolInset()->name().find("int") != string::npos) return false; // assume "real" limits for everything else @@ -302,7 +292,7 @@ bool MathScriptInset::has(bool up) const bool MathScriptInset::empty() const { - return !script_[0] && !script_[1]; + return !script_[0] && !script_[1] && cell(2).empty(); } @@ -318,42 +308,52 @@ bool MathScriptInset::hasDown() const } -bool MathScriptInset::idxRight(MathInset::idx_type &, - MathInset::pos_type &) const +bool MathScriptInset::idxRight(idx_type &, pos_type &) const { return false; } -bool MathScriptInset::idxLeft(MathInset::idx_type &, - MathInset::pos_type &) const +bool MathScriptInset::idxLeft(idx_type &, pos_type &) const { return false; } -void MathScriptInset::write(WriteStream & os) const +bool MathScriptInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, + int) const { - //lyxerr << "unexpected call to MathScriptInset::write()\n"; - write2(0, os); + if ((idx == 1 && up) || (idx == 0 && !up)) + return false; + + // in nuclues? + if (idx == 2) { + idx = up; + pos = 0; + } else { + idx = 2; + pos = cell(2).size(); + } + return true; } -void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const +void MathScriptInset::write(WriteStream & os) const { - if (nuc) { - os << nuc; - if (nuc->takesLimits()) { + if (nuc().size()) { + os << nuc().data(); + if (nuc().back()->takesLimits()) { if (limits_ == -1) os << "\\nolimits "; if (limits_ == 1) os << "\\limits "; } - } else - if (os.firstitem()) - lyxerr[Debug::MATHED] << "suppressing {} when writing\n"; - else - os << "{}"; + } else { + if (os.firstitem()) + lyxerr[Debug::MATHED] << "suppressing {} when writing\n"; + else + os << "{}"; + } if (hasDown() && down().data().size()) os << "_{" << down().data() << '}'; @@ -365,23 +365,16 @@ void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const void MathScriptInset::normalize(NormalStream & os) const { - //lyxerr << "unexpected call to MathScriptInset::normalize()\n"; - normalize2(0, os); -} - - -void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const -{ - bool d = hasDown() && down().data().size(); - bool u = hasUp() && up().data().size(); + bool d = hasDown() && down().size(); + bool u = hasUp() && up().size(); if (u) os << "[sup "; if (d) os << "[sub "; - if (nuc) - os << nuc << ' '; + if (nuc().size()) + os << nuc().data() << ' '; else os << "[par]"; @@ -392,37 +385,39 @@ void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const } -void MathScriptInset::maplize2(MathInset const * nuc, MapleStream & os) const +void MathScriptInset::maplize(MapleStream & os) const { - if (nuc) - os << nuc; - if (hasDown() && down().data().size()) + if (nuc().size()) + os << nuc().data(); + if (hasDown() && down().size()) os << '[' << down().data() << ']'; - if (hasUp() && up().data().size()) + if (hasUp() && up().size()) os << "^(" << up().data() << ')'; } -void MathScriptInset::mathematicize2(MathInset const * nuc, MathematicaStream & os) const +void MathScriptInset::mathematicize(MathematicaStream & os) const { - bool d = hasDown() && down().data().size(); - bool u = hasUp() && up().data().size(); + bool d = hasDown() && down().size(); + bool u = hasUp() && up().size(); - if (nuc) - if (d) //subscript only if nuc ! - os << "Subscript[" << nuc; + if (nuc().size()) { + if (d) + os << "Subscript[" << nuc().data(); else - os << nuc; + os << nuc().data(); + } + if (u) os << "^(" << up().data() << ")"; - if (nuc) + if (nuc().size()) if (d) - os << "," << down().data() << "]"; + os << "," << down().data() << "]"; } -void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const +void MathScriptInset::mathmlize( MathMLStream & os) const { bool d = hasDown() && down().data().size(); bool u = hasUp() && up().data().size(); @@ -434,8 +429,8 @@ void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const else if (d) os << MTag("msub"); - if (nuc) - os << nuc; + if (nuc().size()) + os << nuc().data(); else os << ""; @@ -448,13 +443,13 @@ void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const } -void MathScriptInset::octavize2(MathInset const * nuc, OctaveStream & os) const +void MathScriptInset::octavize(OctaveStream & os) const { - if (nuc) - os << nuc; - if (hasDown() && down().data().size()) + if (nuc().size()) + os << nuc().data(); + if (hasDown() && down().size()) os << '[' << down().data() << ']'; - if (hasUp() && up().data().size()) + if (hasUp() && up().size()) os << "^(" << up().data() << ')'; } diff --git a/src/mathed/math_scriptinset.h b/src/mathed/math_scriptinset.h index 63e6cae7d5..c0964b107d 100644 --- a/src/mathed/math_scriptinset.h +++ b/src/mathed/math_scriptinset.h @@ -18,38 +18,41 @@ public: MathScriptInset(); /// create inset with single script explicit MathScriptInset(bool up); + /// create inset with single script and given nucleus + MathScriptInset(MathAtom const & at, bool up); /// MathInset * clone() const; /// - void write(WriteStream & os) const; - /// - void normalize(NormalStream & os) const; - /// - void metrics(MathMetricsInfo & st) const; + void metrics(MathMetricsInfo & mi) const; /// - void draw(MathPainterInfo &, int x, int y) const; + void draw(MathPainterInfo & pi, int x, int y) const; /// - void metricsT(TextMetricsInfo const & st) const; + void metricsT(TextMetricsInfo const & mi) const; /// - void drawT(TextPainter &, int x, int y) const; + void drawT(TextPainter & pi, int x, int y) const; - /// - void metrics(MathInset const * nuc, MathMetricsInfo & st) const; - /// - void draw(MathInset const * nuc, MathPainterInfo &, int x, int y) const; - /// - void metricsT(MathInset const * nuc, TextMetricsInfo const & st) const; - /// - void drawT(MathInset const * nuc, TextPainter &, int x, int y) const; - /// helper - void dimensions2(MathInset const * nuc, Dimension & dim) const; - /// only the width - int width2(MathInset const * nuc) const; - - /// + /// write LaTeX and Lyx code + void write(WriteStream & os) const; + /// write normalized content + void normalize(NormalStream &) const; + /// write content as something readable by Maple + void maplize(MapleStream &) const; + /// write content as something readable by Mathematica + void mathematicize(MathematicaStream &) const; + /// write content as something resembling MathML + void mathmlize(MathMLStream &) const; + /// write content as something readable by Octave + void octavize(OctaveStream &) const; + /// move cursor left bool idxLeft(idx_type &, pos_type &) const; - /// + /// move cursor right bool idxRight(idx_type &, pos_type &) const; + /// move cursor up or down + bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const; + /// Target pos when we enter the inset from the left by pressing "Right" + bool idxFirst(idx_type & idx, pos_type & pos) const; + /// Target pos when we enter the inset from the right by pressing "Left" + bool idxLast(idx_type & idx, pos_type & pos) const; /// can we enter this cell? bool validCell(idx_type i) const { return script_[i]; } @@ -62,14 +65,18 @@ public: void limits(int lim) { limits_ = lim; } /// get limits int limits() const { return limits_; } - /// true if we have an "inner" position - MathXArray const & up() const; /// returns subscript MathXArray const & down() const; - /// returns superscript - MathXArray & up(); /// returns subscript MathXArray & down(); + /// returns superscript + MathXArray const & up() const; + /// returns superscript + MathXArray & up(); + /// returns nucleus + MathXArray const & nuc() const; + /// returns nucleus + MathXArray & nuc(); /// do we have a superscript? bool hasUp() const; /// do we have a subscript? @@ -87,34 +94,25 @@ public: /// void infoize(std::ostream & os) const; - // call these methods ...2 to make compaq cxx in anal mode happy... - /// suppresses empty braces if necessary - virtual void write2(MathInset const * nuc, WriteStream & os) const; - virtual void normalize2(MathInset const * nuc, NormalStream & os) const; - virtual void octavize2(MathInset const * nuc, OctaveStream & os) const; - virtual void maplize2(MathInset const * nuc, MapleStream & os) const; - virtual void mathematicize2(MathInset const * nuc, MathematicaStream & os) const; - virtual void mathmlize2(MathInset const * nuc, MathMLStream & os) const; -public: +private: /// returns x offset for main part - int dxx(MathInset const * nuc) const; + int dxx() const; /// returns width of nucleus if any - int nwid(MathInset const * nuc) const; -private: + int nwid() const; /// returns y offset for superscript - int dy0(MathInset const * nuc) const; + int dy0() const; /// returns y offset for subscript - int dy1(MathInset const * nuc) const; + int dy1() const; /// returns x offset for superscript - int dx0(MathInset const * nuc) const; + int dx0() const; /// returns x offset for subscript - int dx1(MathInset const * nuc) const; + int dx1() const; /// returns ascent of nucleus if any - int nasc(MathInset const * nuc) const; + int nasc() const; /// returns descent of nucleus if any - int ndes(MathInset const * nuc) const; + int ndes() const; /// where do we have to draw the scripts? - bool hasLimits(MathInset const * nuc) const; + bool hasLimits() const; /// possible subscript (index 0) and superscript (index 1) bool script_[2]; diff --git a/src/mathed/math_sqrtinset.C b/src/mathed/math_sqrtinset.C index 5e7d9c9fcf..114d6df455 100644 --- a/src/mathed/math_sqrtinset.C +++ b/src/mathed/math_sqrtinset.C @@ -26,12 +26,13 @@ void MathSqrtInset::metrics(MathMetricsInfo & mi) const dim_.a = xcell(0).ascent() + 4; dim_.d = xcell(0).descent() + 2; dim_.w = xcell(0).width() + 12; + metricsMarkers(); } -void MathSqrtInset::draw(MathPainterInfo & pain, int x, int y) const +void MathSqrtInset::draw(MathPainterInfo & pi, int x, int y) const { - xcell(0).draw(pain, x + 10, y); + xcell(0).draw(pi, x + 10, y); int const a = ascent(); int const d = descent(); int xp[4]; @@ -40,7 +41,8 @@ void MathSqrtInset::draw(MathPainterInfo & pain, int x, int y) const xp[1] = x + 8; yp[1] = y - a + 1; xp[2] = x + 5; yp[2] = y + d - 1; xp[3] = x; yp[3] = y + (d - a)/2; - pain.pain.lines(xp, yp, 4, LColor::math); + pi.pain.lines(xp, yp, 4, LColor::math); + drawMarkers(pi, x, y); } diff --git a/src/mathed/math_stackrelinset.h b/src/mathed/math_stackrelinset.h index 5f6b8fe980..e1dab8e1e3 100644 --- a/src/mathed/math_stackrelinset.h +++ b/src/mathed/math_stackrelinset.h @@ -18,9 +18,9 @@ public: /// MathInset * clone() const; /// - void metrics(MathMetricsInfo & st) const; + void metrics(MathMetricsInfo & mi) const; /// - void draw(MathPainterInfo &, int x, int y) const; + void draw(MathPainterInfo & pi, int x, int y) const; /// void write(WriteStream & os) const; diff --git a/src/mathed/math_stringinset.h b/src/mathed/math_stringinset.h index f81d89b07a..f4f53986e7 100644 --- a/src/mathed/math_stringinset.h +++ b/src/mathed/math_stringinset.h @@ -20,9 +20,9 @@ public: /// MathInset * clone() const; /// - void metrics(MathMetricsInfo & st) const; + void metrics(MathMetricsInfo & mi) const; /// - void draw(MathPainterInfo &, int x, int y) const; + void draw(MathPainterInfo & pi, int x, int y) const; /// string str() const { return str_; } /// diff --git a/src/mathed/math_substackinset.h b/src/mathed/math_substackinset.h index d0ec7098a7..9c3d18291b 100644 --- a/src/mathed/math_substackinset.h +++ b/src/mathed/math_substackinset.h @@ -16,7 +16,7 @@ public: /// MathInset * clone() const; /// - void metrics(MathMetricsInfo & st) const; + void metrics(MathMetricsInfo & mi) const; /// MathSubstackInset const * asSubstackInset() const { return this; } diff --git a/src/mathed/math_xdata.C b/src/mathed/math_xdata.C index 8a9387376e..4137afd8e1 100644 --- a/src/mathed/math_xdata.C +++ b/src/mathed/math_xdata.C @@ -4,8 +4,9 @@ #pragma implementation #endif -#include "math_scriptinset.h" +#include "math_xdata.h" #include "math_support.h" +#include "math_inset.h" #include "frontends/Painter.h" #include "textpainter.h" #include "debug.h" @@ -16,9 +17,6 @@ using std::min; using std::abs; -extern MathScriptInset const * asScript(MathArray::const_iterator it); - - MathXArray::MathXArray() : xo_(0), yo_(0), clean_(false), drawn_(false) {} @@ -35,33 +33,19 @@ Dimension const & MathXArray::metrics(MathMetricsInfo & mi) const { //if (clean_) // return; - - size_ = mi; clean_ = true; drawn_ = false; - if (data_.empty()) { + if (empty()) { mathed_char_dim(mi.base.font, 'I', dim_); return dim_; } dim_.clear(); - for (const_iterator it = begin(); it != end(); ++it) { - MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); - Dimension d; - if (q) { - q->metrics(p, mi); - q->dimensions2(p, d); - ++it; - } else { - p->metrics(mi); - p->dimensions(d); - } - dim_ += d; + for (const_iterator it = begin(), et = end(); it != et; ++it) { + (*it)->metrics(mi); + dim_ += (*it)->dimensions(); } - - //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; return dim_; } @@ -72,33 +56,21 @@ void MathXArray::metricsExternal(MathMetricsInfo & mi, //if (clean_) // return; - size_ = mi; clean_ = true; drawn_ = false; - if (data_.empty()) { + if (empty()) { mathed_char_dim(mi.base.font, 'I', dim_); return; } dim_.clear(); - for (const_iterator it = begin(); it != end(); ++it) { + for (const_iterator it = begin(), et = end(); it != et; ++it) { MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); - Dimension d; - if (q) { - q->metrics(p, mi); - q->dimensions2(p, d); - v.push_back(d); - v.push_back(Dimension()); - ++it; - } else { - p->metrics(mi); - p->dimensions(d); - v.push_back(d); - } + p->metrics(mi); + v.push_back(p->dimensions()); } - //for (int i = 0; i < data_.size(); ++i) + //for (int i = 0; i < size(); ++i) // lyxerr << "i: " << i << " dim: " << v[i] << endl; //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; } @@ -132,16 +104,8 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const } for (; it != et; ++it) { - MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it); - if (q) { - q->draw(p, pi, x, y); - x += q->width2(p); - ++it; - } else { - p->draw(pi, x, y); - x += p->width(); - } + (*it)->draw(pi, x, y); + x += (*it)->width(); } } @@ -151,7 +115,7 @@ void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y, { //for (size_type r = 0; r < v.size(); ++r) // lyxerr << "row " << r << " to: " << v[r].end << endl; - //lyxerr << " data: " << data_ << endl; + //lyxerr << " data: " << *this << endl; xo_ = x; yo_ = y; @@ -159,26 +123,16 @@ void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y, for (size_type r = 0; r < v.size(); ++r) { int xx = x; int yy = y + v[r].yo; - for (size_type pos = v[r].begin; pos < v[r].end && pos < data_.size(); ++pos) { - //lyxerr << "drawing pos " << pos << " of " << data_.size() - // << " " << int(data_[pos]->getChar()) << endl; - MathInset const * p = data_[pos].nucleus(); - - // insert extra glue + for (size_type pos = v[r].begin; pos < v[r].end && pos < size(); ++pos) { + //lyxerr << "drawing pos " << pos << " of " << size() + // << " " << int(operator[](pos)->getChar()) << endl; + MathInset const * p = operator[](pos).nucleus(); + // insert extra glue if necessary if (p->getChar() == ' ') xx += v[r].glue; - - MathScriptInset const * q = 0; - if (pos + 1 < data_.size()) - q = asScript(begin() + pos); - if (q) { - q->draw(p, pi, xx, yy); - xx += q->width2(p); - ++pos; - } else { - p->draw(pi, xx, yy); - xx += p->width(); - } + // ordinary case + p->draw(pi, xx, yy); + xx += p->width(); } } } @@ -190,18 +144,8 @@ Dimension const & MathXArray::metricsT(TextMetricsInfo const & mi) const // return; dim_.clear(); for (const_iterator it = begin(); it != end(); ++it) { - MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); - Dimension d; - if (q) { - q->metricsT(p, mi); - q->dimensions2(p, d); - ++it; - } else { - p->metricsT(mi); - p->dimensions(d); - } - dim_ += d; + (*it)->metricsT(mi); + dim_ += (*it)->dimensions(); } return dim_; } @@ -222,15 +166,8 @@ void MathXArray::drawT(TextPainter & pain, int x, int y) const for (; it != et; ++it) { MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it); - if (q) { - q->drawT(p, pain, x, y); - x += q->width2(p); - ++it; - } else { - p->drawT(pain, x, y); - x += p->width(); - } + p->drawT(pain, x, y); + x += p->width(); } } @@ -244,21 +181,13 @@ int MathXArray::pos2x(size_type pos) const int MathXArray::pos2x(size_type pos1, size_type pos2, int glue) const { int x = 0; - size_type target = min(pos2, data_.size()); + size_type target = min(pos2, size()); for (size_type i = pos1; i < target; ++i) { const_iterator it = begin() + i; MathInset const * p = it->nucleus(); if (p->getChar() == ' ') x += glue; - MathScriptInset const * q = (i + 1 == data_.size()) ? 0 : asScript(it); - if (q) { - ++i; - if (i < target) - x += q->width2(p); - else // "half" position - x += q->dxx(p) + q->nwid(p); - } else - x += p->width(); + x += p->width(); } return x; } @@ -277,21 +206,11 @@ MathArray::size_type MathXArray::x2pos(size_type startpos, int targetx, int lastx = 0; int currx = 0; for (; currx < targetx && it < end(); ++it) { - size_type pos = it - begin(); lastx = currx; - MathInset const * p = it->nucleus(); if (p->getChar() == ' ') currx += glue; - MathScriptInset const * q = 0; - if (it + 1 != end()) - q = asScript(it); - if (q) { - currx += q->width2(p); - ++it; - } else { - currx += p->width(); - } + currx += p->width(); } if (abs(lastx - targetx) < abs(currx - targetx) && it != begin() + startpos) --it; @@ -339,16 +258,7 @@ void MathXArray::findPos(MathPosFinder & f) const // check inset MathInset const * p = it->nucleus(); p->findPos(f); - - // move on - MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); - if (q) { - x += q->width(p); - f.nextPos(); - ++it; - } else { - x += p->width(); - } + x += p->width(); } } */ diff --git a/src/mathed/math_xdata.h b/src/mathed/math_xdata.h index af418afe75..90b1bd9864 100644 --- a/src/mathed/math_xdata.h +++ b/src/mathed/math_xdata.h @@ -20,13 +20,21 @@ class TextPainter; /** This class extends a MathArray by drawing routines and caches for * metric information. */ -class MathXArray +class MathXArray : private MathArray { public: - /// type for positions and sizes - typedef MathArray::size_type size_type; - /// const iterator into the underlying MathArray - typedef MathArray::const_iterator const_iterator; + // re-use inherited stuff + using MathArray::size_type; + using MathArray::const_iterator; + using MathArray::begin; + using MathArray::end; + using MathArray::operator[]; + using MathArray::clear; + using MathArray::size; + using MathArray::empty; + using MathArray::back; + MathArray & data() { return *this; } + MathArray const & data() const { return *this; } // helper structure for external metrics computations as done // in parboxes @@ -104,26 +112,14 @@ public: /// adjust (x,y) to point on boundary on a straight line from the center void towards(int & x, int & y) const; - /// begin iterator of the underlying MathArray - const_iterator begin() const { return data_.begin(); } - /// end iterator of the underlying MathArray - const_iterator end() const { return data_.end(); } - /// access to data - MathArray const & data() const { return data_; } - /// access to data - MathArray & data() { return data_; } private: - /// the underlying MathArray - MathArray data_; /// cached dimensions of cell mutable Dimension dim_; /// cached x coordinate of last drawing mutable int xo_; /// cached y coordinate of last drawing mutable int yo_; - /// cache size information of last drawing - mutable MathMetricsInfo size_; /// cached cleaness of cell mutable bool clean_; /// cached draw status of cell -- 2.39.2