X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fmath_scriptinset.C;h=a66ec9c67624912ff435eb340c65745d484e0484;hb=48a3633de7f7d32aa76b6b7bc81230809238de5f;hp=5157182f8ad881bf4a55c901431d6943f669198f;hpb=9ccefe810b24031894fff8cf3dd39c1bc7f31241;p=lyx.git diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 5157182f8a..a66ec9c676 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -1,275 +1,348 @@ + +#include +#include "Lsstream.h" + +#include "debug.h" +#include "support.h" +#include "support/LOstream.h" +#include "support/LAssert.h" + #ifdef __GNUG__ #pragma implementation #endif #include "math_scriptinset.h" -#include "support/LOstream.h" + +using std::ostream; +using std::ostringstream; MathScriptInset::MathScriptInset() - : MathInset(2), up_(false), down_(false), limits_(0), symbol_(0) -{} + : MathNestInset(2), limits_(0) +{ + script_[0] = false; + script_[1] = false; +} -MathScriptInset::MathScriptInset(bool up, bool down, MathInset * symbol) - : MathInset(2), up_(up), down_(down), limits_(0), symbol_(symbol) -{} +MathScriptInset::MathScriptInset(bool up) + : MathNestInset(2), limits_(0) +{ + script_[0] = !up; + script_[1] = up; +} -MathScriptInset::MathScriptInset(MathScriptInset const & p) - : MathInset(p), up_(p.up_), down_(p.down_), - limits_(p.limits_), symbol_(p.symbol_ ? p.symbol_->clone() : 0) -{} +MathInset * MathScriptInset::clone() const +{ + return new MathScriptInset(*this); +} -MathScriptInset::~MathScriptInset() +MathScriptInset const * MathScriptInset::asScriptInset() const { - delete symbol_; + return this; } -MathInset * MathScriptInset::clone() const -{ - return new MathScriptInset(*this); +MathScriptInset * MathScriptInset::asScriptInset() +{ + return this; } -bool MathScriptInset::up() const +MathXArray const & MathScriptInset::up() const { - return up_; + return xcell(1); } -bool MathScriptInset::down() const +MathXArray const & MathScriptInset::down() const { - return down_; + return xcell(0); } -void MathScriptInset::up(bool b) +MathXArray & MathScriptInset::up() { - up_ = b; + return xcell(1); } -void MathScriptInset::down(bool b) +MathXArray & MathScriptInset::down() { - down_ = b; + return xcell(0); } -bool MathScriptInset::idxRight(int &, int &) const +void MathScriptInset::ensure(bool up) { - return false; + script_[up] = true; } -bool MathScriptInset::idxLeft(int &, int &) const +int MathScriptInset::dy0(MathInset const * nuc) const { - return false; + int nd = ndes(nuc); + if (!hasDown()) + return nd; + int des = down().ascent(); + if (hasLimits(nuc)) + des += nd + 2; + else + des = std::max(des, nd); + return des; } -bool MathScriptInset::idxUp(int & idx, int & pos) const +int MathScriptInset::dy1(MathInset const * nuc) const { - if (idx == 0 || !up()) - return false; - idx = 0; - pos = 0; - return true; + int na = nasc(nuc); + if (!hasUp()) + return na; + int asc = up().descent(); + if (hasLimits(nuc)) + asc += na + 2; + else + asc = std::max(asc, na); + asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, mi_, 'I')); + return asc; } -bool MathScriptInset::idxDown(int & idx, int & pos) const + +int MathScriptInset::dx0(MathInset const * nuc) const { - if (idx == 1 || !down()) - return false; - idx = 1; - pos = 0; - return true; + lyx::Assert(hasDown()); + return hasLimits(nuc) ? (width(nuc) - down().width()) / 2 : nwid(nuc); } -bool MathScriptInset::idxFirst(int & idx, int & pos) const + +int MathScriptInset::dx1(MathInset const * nuc) const { - idx = up() ? 0 : 1; - pos = 0; - return true; + lyx::Assert(hasUp()); + return hasLimits(nuc) ? (width(nuc) - up().width()) / 2 : nwid(nuc); } -bool MathScriptInset::idxLast(int & idx, int & pos) const + +int MathScriptInset::dxx(MathInset const * nuc) const { - idx = down() ? 1 : 0; - pos = cell(idx).size(); - return true; + //lyx::Assert(nuc()); + return hasLimits(nuc) ? (width(nuc) - nwid(nuc)) / 2 : 0; } -bool MathScriptInset::idxFirstUp(int & idx, int & pos) const +int MathScriptInset::ascent(MathInset const * nuc) const { - if (!up()) - return false; - idx = 0; - pos = 0; - return true; + return dy1(nuc) + (hasUp() ? up().ascent() : 0); } -bool MathScriptInset::idxFirstDown(int & idx, int & pos) const +int MathScriptInset::descent(MathInset const * nuc) const { - if (!down()) - return false; - idx = 1; - pos = 0; - return true; + return dy0(nuc) + (hasDown() ? down().descent() : 0); } -bool MathScriptInset::idxLastUp(int & idx, int & pos) const +int MathScriptInset::width(MathInset const * nuc) const { - if (!up()) - return false; - idx = 0; - pos = cell(idx).size(); - return true; + int wid = 0; + if (hasLimits(nuc)) { + wid = nwid(nuc); + if (hasUp()) + wid = std::max(wid, up().width()); + if (hasDown()) + wid = std::max(wid, down().width()); + } else { + if (hasUp()) + wid = std::max(wid, up().width()); + if (hasDown()) + wid = std::max(wid, down().width()); + wid += nwid(nuc); + } + return wid; } -bool MathScriptInset::idxLastDown(int & idx, int & pos) const +int MathScriptInset::nwid(MathInset const * nuc) const { - if (!down()) - return false; - idx = 1; - pos = cell(idx).size(); - return true; + return nuc ? + nuc->width() : + mathed_char_width(LM_TC_TEX, mi_, '.'); } -void MathScriptInset::Write(std::ostream & os, bool fragile) const +int MathScriptInset::nasc(MathInset const * nuc) const { - if (symbol_) { - symbol_->Write(os, fragile); - if (limits()) - os << (limits() == 1 ? "\\limits" : "\\nolimits"); - } - if (up()) { - os << "^{"; - cell(0).Write(os, fragile); - os << "}"; - } - if (down()) { - os << "_{"; - cell(1).Write(os, fragile); - os << "}"; - } - os << " "; + return nuc ? nuc->ascent() + : mathed_char_ascent(LM_TC_VAR, mi_, 'I'); } -void MathScriptInset::idxDelete(int & idx, bool & popit, bool & deleteit) +int MathScriptInset::ndes(MathInset const * nuc) const { - if (idx == 0) - up(false); - else - down(false); - popit = true; - deleteit = !(up() || down()); + return nuc ? nuc->descent() + : mathed_char_descent(LM_TC_VAR, mi_, 'I'); +} + + +void MathScriptInset::metrics(MathMetricsInfo const & mi) const +{ + metrics(0, mi); +} + + +void MathScriptInset::metrics(MathInset const * nuc, + MathMetricsInfo const & mi) const +{ + MathNestInset::metrics(mi); + if (nuc) + nuc->metrics(mi); + + ascent_ = ascent(nuc); + descent_ = descent(nuc); + width_ = width(nuc); } -int MathScriptInset::limits() const +void MathScriptInset::draw(Painter & pain, int x, int y) const { - return limits_; + //lyxerr << "unexpected call to MathScriptInset::draw()\n"; + draw(0, pain, x, y); } -void MathScriptInset::limits(int limits) +void MathScriptInset::draw(MathInset const * nuc, Painter & pain, + int x, int y) const { - limits_ = limits; + if (nuc) + nuc->draw(pain, x + dxx(nuc), y); + else + drawStr(pain, LM_TC_TEX, mi_, x + dxx(nuc), y, "."); + + if (hasUp()) + up().draw(pain, x + dx1(nuc), y - dy1(nuc)); + + if (hasDown()) + down().draw(pain, x + dx0(nuc), y + dy0(nuc)); } -bool MathScriptInset::hasLimits() const -{ - return - symbol_ && (limits_ == 1 || (limits_ == 0 && size() == LM_ST_DISPLAY)); +void MathScriptInset::write(MathWriteInfo & os) const +{ + //lyxerr << "unexpected call to MathScriptInset::write()\n"; + write(0, os); } -void MathScriptInset::WriteNormal(std::ostream & os) const +void MathScriptInset::write(MathInset const * nuc, MathWriteInfo & os) const { - if (limits() && symbol_) - os << "[" << (limits() ? "limits" : "nolimits") << "]"; - if (up()) { - os << "[superscript "; - cell(0).WriteNormal(os); - os << "] "; + if (nuc) { + nuc->write(os); + if (nuc->takesLimits()) { + if (limits_ == -1) + os << "\\nolimits "; + if (limits_ == 1) + os << "\\limits "; + } } - if (down()) { - os << "[subscript "; - cell(1).WriteNormal(os); + else + os << "{}"; + + if (hasDown() && down().data_.size()) + os << "_{" << down().data_ << '}'; + + if (hasUp() && up().data_.size()) + os << "^{" << up().data_ << '}'; +} + + +void MathScriptInset::writeNormal(ostream & os) const +{ + //lyxerr << "unexpected call to MathScriptInset::writeNormal()\n"; + writeNormal(0, os); +} + + +void MathScriptInset::writeNormal(MathInset const * nuc, ostream & os) const +{ + bool d = hasDown() && down().data_.size(); + bool u = hasUp() && up().data_.size(); + + ostringstream osb; + if (nuc) + nuc->writeNormal(osb); + else + osb << "[par]"; + string base = osb.str(); + + if (u && d) { + os << "[sup [sub " << osb.str() << " "; + down().data_.writeNormal(os); os << "] "; + up().data_.writeNormal(os); + os << ']'; + } else if (u) { + os << "[sup " << osb.str() << " "; + up().data_.writeNormal(os); + os << ']'; + } else if (d) { + os << "[sub " << osb.str() << " "; + down().data_.writeNormal(os); + os << ']'; } } -void MathScriptInset::Metrics(MathStyles st) +bool MathScriptInset::hasLimits(MathInset const * nuc) const { - size_ = st; - MathStyles tt = smallerStyleScript(st); - - xcell(0).Metrics(tt); - xcell(1).Metrics(tt); - - width_ = std::max(xcell(0).width(), xcell(1).width()); - - if (hasLimits()) { - symbol_->Metrics(st); - int wid = symbol_->width(); - ascent_ = symbol_->ascent(); - descent_ = symbol_->descent(); - width_ = std::max(width_, wid); - if (up()) { - ascent_ += xcell(0).height() + 2; - dy0_ = - (ascent_ - xcell(0).ascent()); - } - if (down()) { - descent_ += xcell(1).height() + 2; - dy1_ = descent_ - xcell(1).descent(); - } - dxx_ = (width_ - wid) / 2; - dx0_ = (width_ - xcell(0).width()) / 2; - dx1_ = (width_ - xcell(1).width()) / 2; - } else { - int asc; - int des; - int wid = 0; - mathed_char_height(LM_TC_VAR, st, 'I', asc, des); - if (symbol_) { - symbol_->Metrics(st); - wid = symbol_->width(); - asc = symbol_->ascent(); - des = symbol_->descent(); - } - ascent_ = up() ? xcell(0).height() + asc : 0; - descent_ = down() ? xcell(1).height() + des : 0; - width_ += wid; - dy0_ = - asc - xcell(0).descent(); - dy1_ = des + xcell(1).ascent(); - dx0_ = wid; - dx1_ = wid; - dxx_ = 0; - } + return limits_ == 1 || (limits_ == 0 && nuc && nuc->isScriptable()); } -void MathScriptInset::draw(Painter & pain, int x, int y) -{ - xo(x); - yo(y); +void MathScriptInset::removeEmptyScripts() +{ + for (int i = 0; i <= 1; ++i) + if (script_[i] && !cell(i).size()) + script_[i] = false; +} + - if (symbol_) - symbol_->draw(pain, x + dxx_, y); - if (up()) - xcell(0).draw(pain, x + dx0_, y + dy0_); - if (down()) - xcell(1).draw(pain, x + dx1_, y + dy1_); +void MathScriptInset::removeScript(bool up) +{ + cell(up).clear(); + script_[up] = false; } + + +bool MathScriptInset::has(bool up) const +{ + return script_[up]; +} + + +bool MathScriptInset::hasUp() const +{ + return script_[1]; +} + + +bool MathScriptInset::hasDown() const +{ + return script_[0]; +} + + +bool MathScriptInset::idxRight(MathInset::idx_type &, + MathInset::pos_type &) const +{ + return false; +} + + +bool MathScriptInset::idxLeft(MathInset::idx_type &, + MathInset::pos_type &) const +{ + return false; +} + +