From 9295f8236e01a5e425d808eb0d2bdd0460d1f423 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Fri, 12 Oct 2001 12:02:49 +0000 Subject: [PATCH] Use references instead of pointers where possible git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@2867 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/array.C | 69 ++-- src/mathed/array.h | 14 +- src/mathed/formula.C | 87 +++-- src/mathed/formula.h | 24 +- src/mathed/formulabase.C | 21 +- src/mathed/formulabase.h | 7 +- src/mathed/formulamacro.C | 62 ++-- src/mathed/formulamacro.h | 8 +- src/mathed/math_arrayinset.C | 5 + src/mathed/math_arrayinset.h | 4 +- src/mathed/math_atom.C | 349 +------------------- src/mathed/math_atom.h | 123 +------ src/mathed/math_cursor.C | 561 ++++++++++++-------------------- src/mathed/math_cursor.h | 61 ++-- src/mathed/math_factory.C | 44 +-- src/mathed/math_factory.h | 5 +- src/mathed/math_gridinset.C | 34 +- src/mathed/math_gridinset.h | 6 +- src/mathed/math_inset.h | 37 ++- src/mathed/math_macro.C | 16 +- src/mathed/math_macro.h | 5 +- src/mathed/math_macrotable.C | 119 ++++--- src/mathed/math_macrotable.h | 18 +- src/mathed/math_macrotemplate.C | 2 +- src/mathed/math_macrotemplate.h | 2 + src/mathed/math_matrixinset.C | 2 +- src/mathed/math_matrixinset.h | 4 + src/mathed/math_nestinset.C | 4 +- src/mathed/math_nestinset.h | 4 +- src/mathed/math_parser.C | 226 +++++++------ src/mathed/math_parser.h | 14 +- src/mathed/math_rootinset.C | 4 +- src/mathed/math_scriptinset.C | 273 +++++++++++++++- src/mathed/math_scriptinset.h | 68 +++- src/mathed/math_spaceinset.h | 4 +- src/mathed/xarray.C | 92 +++--- src/mathed/xarray.h | 17 +- 37 files changed, 1110 insertions(+), 1285 deletions(-) diff --git a/src/mathed/array.C b/src/mathed/array.C index 482d1c8d85..715350fda6 100644 --- a/src/mathed/array.C +++ b/src/mathed/array.C @@ -8,6 +8,7 @@ #include "debug.h" #include "array.h" #include "mathed/support.h" +#include "support/LAssert.h" using std::ostream; using std::endl; @@ -25,28 +26,38 @@ MathArray::MathArray(MathArray const & array, size_type from, size_type to) void MathArray::substitute(MathMacro const & m) { for (iterator it = begin(); it != end(); ++it) - it->substitute(m); + it->nucleus()->substitute(m); } -MathAtom * MathArray::at(size_type pos) +MathScriptInset const * MathArray::asScript(const_iterator it) const { - return pos < size() ? &bf_[pos] : 0; + if (it->nucleus()->asScriptInset()) + return 0; + const_iterator jt = it + 1; + if (jt == end()) + return 0; + return jt->nucleus()->asScriptInset(); } -MathAtom const * MathArray::at(size_type pos) const +MathAtom & MathArray::at(size_type pos) { - return pos < size() ? &bf_[pos] : 0; + lyx::Assert(pos < size()); + return bf_[pos]; } -void MathArray::insert(size_type pos, MathInset * p) +MathAtom const & MathArray::at(size_type pos) const { - //cerr << "\n 1: "; p->write(cerr, true); cerr << p << "\n"; - // inserting here invalidates the pointer! - bf_.insert(begin() + pos, MathAtom(p)); - //cerr << "\n 2: "; p->write(cerr, true); cerr << p << "\n"; + lyx::Assert(pos < size()); + return bf_[pos]; +} + + +void MathArray::insert(size_type pos, MathAtom const & t) +{ + bf_.insert(begin() + pos, t); } @@ -62,12 +73,6 @@ void MathArray::push_back(MathAtom const & t) } -void MathArray::push_back(MathInset * p) -{ - bf_.push_back(MathAtom(p)); -} - - void MathArray::push_back(MathArray const & array) { insert(size(), array); @@ -127,14 +132,14 @@ MathAtom & MathArray::back() void MathArray::dump2(ostream & os) const { for (const_iterator it = begin(); it != end(); ++it) - os << *it << ' '; + os << it->nucleus() << ' '; } void MathArray::dump(ostream & os) const { for (const_iterator it = begin(); it != end(); ++it) - os << "<" << *it << ">"; + os << "<" << it->nucleus() << ">"; } @@ -158,7 +163,7 @@ string charSequence(MathArray::const_iterator it, MathArray::const_iterator end) if (!it->nucleus()) break; p = it->nucleus()->asCharInset(); - if (!p || it->up() || it->down() || p->code() != c) + if (!p || p->code() != c) break; s += p->getChar(); } @@ -168,19 +173,27 @@ string charSequence(MathArray::const_iterator it, MathArray::const_iterator end) void MathArray::write(ostream & os, bool fragile) const { - for (const_iterator it = begin(); it != end(); ++it) { - if (it->nucleus() && it->nucleus()->asCharInset() - && !it->up() && !it->down()) - { - MathCharInset const * p = it->nucleus()->asCharInset(); + for (const_iterator it = begin(); it != end(); ++it) { + MathInset * p = it->nucleus(); + if (!p) + continue; + +/* + if (p->asCharInset()) { + MathCharInset const * c = p->asCharInset(); // special handling for character sequences with the same code string s = charSequence(it, end()); - p->writeHeader(os); + c->writeHeader(os); os << s; - p->writeTrailer(os); + c->writeTrailer(os); it += s.size() - 1; + } else +*/ + if (MathScriptInset const * q = asScript(it)) { + q->write(p, os, fragile); + ++it; } else { - it->write(os, fragile); + p->write(os, fragile); } } } @@ -200,7 +213,7 @@ void MathArray::writeNormal(ostream & os) const void MathArray::validate(LaTeXFeatures & features) const { for (const_iterator it = begin(); it != end(); ++it) - it->validate(features); + it->nucleus()->validate(features); } diff --git a/src/mathed/array.h b/src/mathed/array.h index 7914275065..2f7cbe6558 100644 --- a/src/mathed/array.h +++ b/src/mathed/array.h @@ -20,7 +20,7 @@ #include #include "math_atom.h" -class MathInset; +class MathScriptInset; class MathMacro; class LaTeXFeatures; @@ -64,7 +64,7 @@ public: void swap(MathArray &); /// - void insert(size_type pos, MathInset * inset); + void insert(size_type pos, MathAtom const &); /// void insert(size_type pos, MathArray const &); @@ -76,12 +76,10 @@ public: void erase(); /// - void push_back(MathInset * inset); + void push_back(MathAtom const &); /// void push_back(MathArray const &); /// - void push_back(MathAtom const &); - /// void pop_back(); /// MathAtom & back(); @@ -94,9 +92,9 @@ public: void substitute(MathMacro const &); /// - MathAtom * at(size_type pos); + MathAtom & at(size_type pos); /// - MathAtom const * at(size_type pos) const; + MathAtom const & at(size_type pos) const; /// void write(std::ostream &, bool) const; /// @@ -111,6 +109,8 @@ public: iterator begin(); /// iterator end(); + /// + MathScriptInset const * asScript(const_iterator it) const; private: /// Buffer buffer_type bf_; diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 1a66a3663c..0e4ab85af1 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -30,6 +30,7 @@ #include "debug.h" #include "lyx_gui_misc.h" #include "support/LOstream.h" +#include "support/LAssert.h" #include "support/lyxlib.h" #include "support/syscall.h" #include "support/lstrings.h" @@ -48,40 +49,32 @@ using std::vector; InsetFormula::InsetFormula() - : par_(new MathMatrixInset) -{} - - -InsetFormula::InsetFormula(const InsetFormula & f) - : InsetFormulaBase(f), par_(static_cast(f.par_->clone())) + : par_(MathAtom(new MathMatrixInset)) {} InsetFormula::InsetFormula(MathInsetTypes t) - : par_(new MathMatrixInset(t)) + : par_(MathAtom(new MathMatrixInset(t))) {} InsetFormula::InsetFormula(string const & s) - : par_(mathed_parse_normal(s)) { - if (!par_) - par_ = mathed_parse_normal("$" + s + "$"); + if (s.size()) { + bool res = mathed_parse_normal(par_, s); - if (!par_) { - lyxerr << "cannot interpret '" << s << "' as math\n"; - par_ = new MathMatrixInset(LM_OT_SIMPLE); + if (!res) + res = mathed_parse_normal(par_, "$" + s + "$"); + + if (!res) { + lyxerr << "cannot interpret '" << s << "' as math\n"; + par_ = MathAtom(new MathMatrixInset(LM_OT_SIMPLE)); + } } metrics(); } -InsetFormula::~InsetFormula() -{ - delete par_; -} - - Inset * InsetFormula::clone(Buffer const &, bool) const { return new InsetFormula(*this); @@ -123,7 +116,7 @@ int InsetFormula::docbook(Buffer const * buf, ostream & os) const void InsetFormula::read(Buffer const *, LyXLex & lex) { - par(mathed_parse_normal(lex)); + mathed_parse_normal(par_, lex); metrics(); } @@ -163,7 +156,7 @@ void InsetFormula::metrics() const vector const InsetFormula::getLabelList() const { - return par_->getLabelList(); + return mat()->getLabelList(); } @@ -187,9 +180,9 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, //lyxerr << "toggling all numbers\n"; if (display()) { bv->lockedInsetStoreUndo(Undo::INSERT); - bool old = par_->numberedType(); + bool old = mat()->numberedType(); for (MathInset::row_type row = 0; row < par_->nrows(); ++row) - par_->numbered(row, !old); + mat()->numbered(row, !old); bv->owner()->message(old ? _("No number") : _("Number")); updateLocal(bv, true); } @@ -202,9 +195,9 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, if (display()) { bv->lockedInsetStoreUndo(Undo::INSERT); MathCursor::row_type row = mathcursor->row(); - bool old = par_->numbered(row); + bool old = mat()->numbered(row); bv->owner()->message(old ? _("No number") : _("Number")); - par_->numbered(row, !old); + mat()->numbered(row, !old); updateLocal(bv, true); } break; @@ -215,7 +208,7 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, bv->lockedInsetStoreUndo(Undo::INSERT); MathCursor::row_type row = mathcursor->row(); - string old_label = par_->label(row); + string old_label = mat()->label(row); string new_label = arg; if (new_label.empty()) { @@ -236,13 +229,13 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, if (!new_label.empty()) { lyxerr << "setting label to '" << new_label << "'\n"; - par_->numbered(row, true); + mat()->numbered(row, true); } if (!new_label.empty() && bv->ChangeRefsIfUnique(old_label, new_label)) bv->redraw(); - par_->label(row, new_label); + mat()->label(row, new_label); updateLocal(bv, true); break; @@ -260,7 +253,7 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, int x; int y; mathcursor->getPos(x, y); - par_->mutate(arg); + mat()->mutate(arg); mathcursor->setPos(x, y); mathcursor->normalize(); updateLocal(bv, true); @@ -272,10 +265,10 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, int x; int y; mathcursor->getPos(x, y); - if (par_->getType() == LM_OT_SIMPLE) - par_->mutate(LM_OT_EQUATION); + if (mat()->getType() == LM_OT_SIMPLE) + mat()->mutate(LM_OT_EQUATION); else - par_->mutate(LM_OT_SIMPLE); + mat()->mutate(LM_OT_SIMPLE); mathcursor->setPos(x, y); mathcursor->normalize(); updateLocal(bv, true); @@ -286,15 +279,15 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, { string const clip = bv->getClipboard(); if (!clip.empty()) - par(mathed_parse_normal(clip)); + mathed_parse_normal(par_, clip); break; } case LFUN_MATH_COLUMN_INSERT: { - if (par_->getType() == LM_OT_ALIGN) - par_->mutate(LM_OT_ALIGNAT); - par_->addCol(par_->ncols()); + if (mat()->getType() == LM_OT_ALIGN) + mat()->mutate(LM_OT_ALIGNAT); + mat()->addCol(mat()->ncols()); mathcursor->normalize(); updateLocal(bv, true); } @@ -312,33 +305,35 @@ void InsetFormula::handleExtern(const string & arg, BufferView *) //string outfile = lyx::tempName("maple.out"); string outfile = "/tmp/lyx2" + arg + ".out"; ostringstream os; - par_->writeNormal(os); + mat()->writeNormal(os); string code = os.str().c_str(); string script = "lyx2" + arg + " '" + code + "' " + outfile; lyxerr << "calling: " << script << endl; Systemcalls cmd(Systemcalls::System, script, 0); ifstream is(outfile.c_str()); - par(mathed_parse_normal(is)); + mathed_parse_normal(par_, is); metrics(); } + bool InsetFormula::display() const { - return par_->getType() != LM_OT_SIMPLE; + return mat()->getType() != LM_OT_SIMPLE; } -MathInset const * InsetFormula::par() const +MathMatrixInset const * InsetFormula::mat() const { - return par_; + lyx::Assert(par_->asMatrixInset()); + return par_->asMatrixInset(); } -void InsetFormula::par(MathMatrixInset * p) -{ - delete par_; - par_ = p ? static_cast(p) : new MathMatrixInset; +MathMatrixInset * InsetFormula::mat() +{ + lyx::Assert(par_->asMatrixInset()); + return par_->asMatrixInset(); } @@ -381,5 +376,5 @@ int InsetFormula::width(BufferView *, LyXFont const &) const MathInsetTypes InsetFormula::getType() const { - return par_->getType(); + return mat()->getType(); } diff --git a/src/mathed/formula.h b/src/mathed/formula.h index bceefc0f33..501f1db2b1 100644 --- a/src/mathed/formula.h +++ b/src/mathed/formula.h @@ -23,6 +23,7 @@ #include "mathed/formulabase.h" #include "math_defs.h" +#include "math_atom.h" class MathMatrixInset; @@ -32,16 +33,10 @@ public: /// InsetFormula(); /// - InsetFormula(InsetFormula const &); - /// explicit InsetFormula(MathInsetTypes); /// explicit InsetFormula(string const &); /// - ~InsetFormula(); - /// - void operator=(InsetFormula const &); - /// int ascent(BufferView *, LyXFont const &) const; /// int descent(BufferView *, LyXFont const &) const; @@ -80,17 +75,22 @@ public: /// void handleExtern(string const & arg, BufferView * bv); /// - MathInset const * par() const; - /// bool display() const; /// bool ams() const; /// MathInsetTypes getType() const; -private: - /// Safe setting of contents - void par(MathMatrixInset *); /// - MathMatrixInset * par_; + MathAtom const & par() const { return par_; } + /// + MathAtom & par() { return par_; } +public: + /// + MathAtom par_; + + /// Access + MathMatrixInset * mat(); + /// Access + MathMatrixInset const * mat() const; }; #endif diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index 4b3e34f500..7d5f21c3a0 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -123,19 +123,14 @@ string const InsetFormulaBase::editMessage() const void InsetFormulaBase::edit(BufferView * bv, int x, int /*y*/, unsigned int) { - mathcursor = new MathCursor(this); - if (!bv->lockInset(this)) lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl; + mathcursor = new MathCursor(this, x == 0); metrics(); // if that is removed, we won't get the magenta box when entering an // inset for the first time bv->updateInset(this, false); - if (x == 0) - mathcursor->first(); - else - mathcursor->last(); sel_x = 0; sel_y = 0; sel_flag = false; @@ -467,7 +462,6 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, case LFUN_VECTOR: handleAccent(bv, "vec"); break; // Math fonts - case LFUN_GREEK: handleFont(bv, LM_TC_GREEK1); break; case LFUN_GREEK_TOGGLE: handleFont(bv, LM_TC_GREEK); break; case LFUN_BOLD: handleFont(bv, LM_TC_BF); break; case LFUN_SANS: handleFont(bv, LM_TC_SF); break; @@ -477,6 +471,12 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, case LFUN_NOUN: handleFont(bv, LM_TC_BB); break; case LFUN_DEFAULT: handleFont(bv, LM_TC_VAR); break; + case LFUN_GREEK: + handleFont(bv, LM_TC_GREEK1); + if (arg.size()) + mathcursor->interpret(arg[0]); + break; + case LFUN_MATH_MODE: handleFont(bv, LM_TC_TEXTRM); //bv->owner()->message(_("math text mode toggled")); @@ -513,7 +513,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, // p->incSpace(); //else // mathcursor->insert(new MathSpaceInset(1)); - mathcursor->insert(new MathSpaceInset(1)); + mathcursor->insert(MathAtom(new MathSpaceInset(1))); updateLocal(bv, true); break; } @@ -539,7 +539,7 @@ InsetFormulaBase::localDispatch(BufferView * bv, kb_action action, case LFUN_PROTECTEDSPACE: //lyxerr << " called LFUN_PROTECTEDSPACE\n"; bv->lockedInsetStoreUndo(Undo::INSERT); - mathcursor->insert(new MathSpaceInset(1)); + mathcursor->insert(MathAtom(new MathSpaceInset(1))); updateLocal(bv, true); break; @@ -776,8 +776,7 @@ void mathDispatchGreek(BufferView * bv, string const & arg) if (bv->available()) { InsetFormula * f = new InsetFormula; if (openNewInset(bv, f)) { - bv->theLockingInset()->localDispatch(bv, LFUN_GREEK, string()); - bv->theLockingInset()->localDispatch(bv, LFUN_SELFINSERT, arg); + bv->theLockingInset()->localDispatch(bv, LFUN_GREEK, arg); bv->unlockInset(f); } } diff --git a/src/mathed/formulabase.h b/src/mathed/formulabase.h index 022b635253..f35889641e 100644 --- a/src/mathed/formulabase.h +++ b/src/mathed/formulabase.h @@ -27,7 +27,7 @@ class Buffer; class BufferView; -class MathInset; +class MathAtom; /// class InsetFormulaBase : public UpdatableInset { @@ -85,10 +85,11 @@ public: /// virtual std::vector const getLabelList() const; /// - virtual MathInset const * par() const = 0; + virtual MathAtom const & par() const = 0; + /// + virtual MathAtom & par() = 0; /// virtual void metrics() const = 0; -protected: /// virtual void updateLocal(BufferView * bv, bool mark_dirty); private: diff --git a/src/mathed/formulamacro.C b/src/mathed/formulamacro.C index cffb87b422..d98c7b0530 100644 --- a/src/mathed/formulamacro.C +++ b/src/mathed/formulamacro.C @@ -52,16 +52,14 @@ InsetFormulaMacro::InsetFormulaMacro() InsetFormulaMacro::InsetFormulaMacro(string nm, int na) { setInsetName(nm); - MathMacroTable::createTemplate(nm, na, string()); + MathMacroTable::create(nm, na, string()); } InsetFormulaMacro::InsetFormulaMacro(string const & s) { - MathMacroTemplate * t = mathed_parse_macro(s); - MathMacroTable::insertTemplate(*t); - setInsetName(t->name()); - delete t; + string name = mathed_parse_macro(s); + setInsetName(name); metrics(); } @@ -75,20 +73,20 @@ Inset * InsetFormulaMacro::clone(Buffer const &, bool) const void InsetFormulaMacro::write(Buffer const *, ostream & os) const { os << "FormulaMacro "; - tmacro().write(os, false); + par()->write(os, false); } int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile, bool /*free_spacing*/) const { - tmacro().write(os, fragile); + par()->write(os, fragile); return 2; } int InsetFormulaMacro::ascii(Buffer const *, ostream & os, int) const { - tmacro().write(os, false); + par()->write(os, false); return 0; } @@ -107,38 +105,34 @@ int InsetFormulaMacro::docbook(Buffer const * buf, ostream & os) const void InsetFormulaMacro::read(Buffer const *, LyXLex & lex) { - MathMacroTemplate * t = mathed_parse_macro(lex); - if (!t) - t = new MathMacroTemplate("{parse error}", 0); - MathMacroTable::insertTemplate(*t); - setInsetName(t->name()); - delete t; + string name = mathed_parse_macro(lex); + setInsetName(name); metrics(); } string InsetFormulaMacro::prefix() const { - return string(" ") + _("Macro: ") + tmacro().name() + ": "; + return string(" ") + _("Macro: ") + getInsetName() + ": "; } int InsetFormulaMacro::ascent(BufferView *, LyXFont const &) const { - return tmacro().ascent() + 5; + return par()->ascent() + 5; } int InsetFormulaMacro::descent(BufferView *, LyXFont const &) const { - return tmacro().descent() + 5; + return par()->descent() + 5; } int InsetFormulaMacro::width(BufferView *, LyXFont const & f) const { metrics(); - return 10 + lyxfont::width(prefix(), f) + tmacro().width(); + return 10 + lyxfont::width(prefix(), f) + par()->width(); } @@ -152,12 +146,12 @@ InsetFormulaMacro::localDispatch(BufferView * bv, case LFUN_MATH_MACROARG: { int const i = lyx::atoi(arg); lyxerr << "inserting macro arg " << i << "\n"; - if (i > 0 && i <= tmacro().numargs()) { - mathcursor->insert(new MathMacroArgument(i)); + //if (i > 0 && i <= par()->numargs()) { + mathcursor->insert(MathAtom(new MathMacroArgument(i))); updateLocal(bv, true); - } else { - lyxerr << "not in range 0.." << tmacro().numargs() << "\n"; - } + //} else { + // lyxerr << "not in range 0.." << par()->numargs() << "\n"; + //} break; } @@ -168,33 +162,33 @@ InsetFormulaMacro::localDispatch(BufferView * bv, } -MathMacroTemplate const & InsetFormulaMacro::tmacro() const +MathAtom const & InsetFormulaMacro::par() const { - return MathMacroTable::provideTemplate(getInsetName()); + return MathMacroTable::provide(getInsetName()); } -Inset::Code InsetFormulaMacro::lyxCode() const +MathAtom & InsetFormulaMacro::par() { - return Inset::MATHMACRO_CODE; + return MathMacroTable::provide(getInsetName()); } -MathInsetTypes InsetFormulaMacro::getType() const +Inset::Code InsetFormulaMacro::lyxCode() const { - return LM_OT_MACRO; + return Inset::MATHMACRO_CODE; } -MathInset const * InsetFormulaMacro::par() const +MathInsetTypes InsetFormulaMacro::getType() const { - return &tmacro(); + return LM_OT_MACRO; } void InsetFormulaMacro::metrics() const { - tmacro().metrics(LM_ST_TEXT); + par()->metrics(LM_ST_TEXT); } @@ -222,9 +216,9 @@ void InsetFormulaMacro::draw(BufferView * bv, LyXFont const & f, x += width(bv, font); // formula - float t = tmacro().width() + 5; + float t = par()->width() + 5; x -= t; - tmacro().draw(pain, int(x), baseline); + par()->draw(pain, int(x), baseline); x += t; } diff --git a/src/mathed/formulamacro.h b/src/mathed/formulamacro.h index 4468277954..fdf37e37fa 100644 --- a/src/mathed/formulamacro.h +++ b/src/mathed/formulamacro.h @@ -68,12 +68,12 @@ public: /// MathInsetTypes getType() const; /// - MathInset const * par() const; - /// void metrics() const; -private: /// - MathMacroTemplate const & tmacro() const; + MathAtom const & par() const; + /// + MathAtom & par(); +private: /// prefix in inset string prefix() const; }; diff --git a/src/mathed/math_arrayinset.C b/src/mathed/math_arrayinset.C index b52d167f95..ae9cfabbf4 100644 --- a/src/mathed/math_arrayinset.C +++ b/src/mathed/math_arrayinset.C @@ -11,6 +11,11 @@ MathArrayInset::MathArrayInset(int m, int n) {} +MathArrayInset::MathArrayInset(int m, int n, char valign, string const & halign) + : MathGridInset(m, n, valign, halign) +{} + + MathInset * MathArrayInset::clone() const { return new MathArrayInset(*this); diff --git a/src/mathed/math_arrayinset.h b/src/mathed/math_arrayinset.h index 45325c92ed..ee7341d843 100644 --- a/src/mathed/math_arrayinset.h +++ b/src/mathed/math_arrayinset.h @@ -14,13 +14,15 @@ public: /// MathArrayInset(int m, int n); /// + MathArrayInset(int m, int n, char valign, string const & halign); + /// MathInset * clone() const; /// void write(std::ostream &, bool fragile) const; /// void metrics(MathStyles st) const; /// - bool isArray() const { return true; } + MathArrayInset * asArrayInset() { return this; } }; #endif diff --git a/src/mathed/math_atom.C b/src/mathed/math_atom.C index 0ab4f7737b..8c1c6ed85c 100644 --- a/src/mathed/math_atom.C +++ b/src/mathed/math_atom.C @@ -20,34 +20,18 @@ #endif #include "math_atom.h" -#include "math_scriptinset.h" -#include "debug.h" -#include "support.h" +#include "math_inset.h" #include "support/LAssert.h" MathAtom::MathAtom() - : nucleus_(0), limits_(0), xo_(0), yo_(0) -{ - script_[0] = 0; - script_[1] = 0; -} + : nucleus_(0) +{} MathAtom::MathAtom(MathInset * p) - : nucleus_(p), limits_(0), xo_(0), yo_(0) -{ - script_[0] = 0; - script_[1] = 0; -} - - -MathAtom::MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down) - : nucleus_(p), limits_(0), xo_(0), yo_(0) -{ - script_[0] = down; - script_[1] = up; -} + : nucleus_(p) +{} MathAtom::MathAtom(MathAtom const & p) @@ -74,73 +58,30 @@ MathAtom::~MathAtom() void MathAtom::done() { delete nucleus_; - delete script_[0]; - delete script_[1]; } void MathAtom::copy(MathAtom const & p) { //cerr << "calling MathAtom::copy\n"; - xo_ = p.xo_; - yo_ = p.yo_; - limits_ = p.limits_; nucleus_ = p.nucleus_; - script_[0] = p.script_[0]; - script_[1] = p.script_[1]; if (nucleus_) nucleus_ = nucleus_->clone(); - if (script_[0]) - script_[0] = new MathScriptInset(*script_[0]); - if (script_[1]) - script_[1] = new MathScriptInset(*script_[1]); } -int MathAtom::height() const +MathInset * MathAtom::nucleus() const { - return ascent() + descent(); + lyx::Assert(nucleus_); + return nucleus_; } -std::ostream & operator<<(std::ostream & os, MathAtom const & atom) +MathInset * MathAtom::operator->() const { - atom.write(os, false); - return os; + return nucleus(); } - -int MathAtom::xo() const -{ - return xo_; -} - - -int MathAtom::yo() const -{ - return yo_; -} - - -void MathAtom::xo(int x) const -{ - xo_ = x; -} - - -void MathAtom::yo(int y) const -{ - yo_ = y; -} - - -void MathAtom::getXY(int & x, int & y) const -{ - x = xo(); - y = yo(); -} - - /* void MathAtom::userSetSize(MathStyles sz) { @@ -150,273 +91,3 @@ void MathAtom::userSetSize(MathStyles sz) } } */ - -void MathAtom::writeNormal(std::ostream & os) const -{ - os << "[unknown] "; -} - - -void MathAtom::dump() const -{ - lyxerr << "---------------------------------------------\n"; - write(lyxerr, false); - lyxerr << "\n---------------------------------------------\n"; -} - - -bool MathAtom::covers(int x, int y) const -{ - return - x >= xo_ && - x <= xo_ + width() && - y >= yo_ - ascent() && - y <= yo_ + descent(); -} - - -MathScriptInset * MathAtom::ensure(bool up) -{ - if (!script_[up]) - script_[up] = new MathScriptInset(up); - return script_[up]; -} - - -void MathAtom::validate(LaTeXFeatures &) const -{} - - -void MathAtom::metrics(MathStyles st) const -{ - MathStyles tt = smallerStyleScript(st); - if (nucleus()) - nucleus()->metrics(st); - if (up()) - up()->metrics(tt); - if (down()) - down()->metrics(tt); -} - - -MathScriptInset * MathAtom::up() const -{ - return script_[1]; -} - - -MathScriptInset * MathAtom::down() const -{ - return script_[0]; -} - - -MathScriptInset * & MathAtom::up() -{ - return script_[1]; -} - - -MathScriptInset * & MathAtom::down() -{ - return script_[0]; -} - - -int MathAtom::dy0() const -{ - if (!down()) - return ndes(); - int des = down()->ascent(); - if (hasLimits()) - des += ndes() + 2; - else - des = std::max(des, ndes()); - return des; -} - - -int MathAtom::dy1() const -{ - if (!up()) - return nasc(); - int asc = up()->descent(); - if (hasLimits()) - asc += nasc() + 2; - else - asc = std::max(asc, nasc()); - asc = std::max(asc, mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I')); - return asc; -} - - -int MathAtom::dx0() const -{ - lyx::Assert(down()); - return hasLimits() ? (width() - down()->width()) / 2 : nwid(); -} - - -int MathAtom::dx1() const -{ - lyx::Assert(up()); - return hasLimits() ? (width() - up()->width()) / 2 : nwid(); -} - - -int MathAtom::dxx() const -{ - //lyx::Assert(nucleus()); - return hasLimits() ? (width() - nwid()) / 2 : 0; -} - - -int MathAtom::ascent() const -{ - return dy1() + (up() ? up()->ascent() : 0); -} - - -int MathAtom::descent() const -{ - return dy0() + (down() ? down()->descent() : 0); -} - - -int MathAtom::width() const -{ - int wid = 0; - if (hasLimits()) { - wid = nwid(); - if (up()) - wid = std::max(wid, up()->width()); - if (down()) - wid = std::max(wid, down()->width()); - } else { - if (up()) - wid = std::max(wid, up()->width()); - if (down()) - wid = std::max(wid, down()->width()); - wid += nwid(); - } - return wid; -} - - -int MathAtom::nwid() const -{ - return nucleus() ? - nucleus()->width() : - mathed_char_width(LM_TC_TEX, LM_ST_TEXT, '.'); -} - - -int MathAtom::nasc() const -{ - return nucleus() ? nucleus()->ascent() - : mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'); -} - - -int MathAtom::ndes() const -{ - return nucleus() ? nucleus()->descent() - : mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I'); -} - - -void MathAtom::draw(Painter & pain, int x, int y) const -{ - xo(x); - yo(y); - if (nucleus()) - nucleus()->draw(pain, x + dxx(), y); - else - drawStr(pain, LM_TC_TEX, LM_ST_TEXT, x + dxx(), y, "."); - if (up()) - up()->draw(pain, x + dx1(), y - dy1()); - if (down()) - down()->draw(pain, x + dx0(), y + dy0()); -} - - -void MathAtom::write(std::ostream & os, bool fragile) const -{ - if (nucleus()) { - nucleus()->write(os, fragile); - if (nucleus()->takesLimits()) { - if (limits_ == -1) - os << "\\nolimits "; - if (limits_ == 1) - os << "\\limits "; - } - } else - os << "{}"; - - if (down()) { - os << "_{"; - down()->write(os, fragile); - os << "}"; - } - - if (up()) { - os << "^{"; - up()->write(os, fragile); - os << "}"; - } -} - - -bool MathAtom::hasLimits() const -{ - return - limits_ == 1 || (limits_ == 0 && nucleus() && nucleus()->isScriptable()); -} - - -bool MathAtom::hasInner() const -{ - return nucleus_ && (script_[0] || script_[1]); -} - - -void MathAtom::substitute(MathMacro const & m) -{ - if (nucleus()) - nucleus()->substitute(m); - if (up()) - up()->substitute(m); - if (down()) - down()->substitute(m); -} - - -void MathAtom::removeEmptyScripts() -{ - for (int i = 0; i <= 1; ++i) - if (script_[i] && !script_[i]->cell(0).size()) { - delete script_[i]; - script_[i] = 0; - } -} - - -void MathAtom::removeNucleus() -{ - delete nucleus_; - nucleus_ = 0; -} - - -void MathAtom::removeUp() -{ - delete script_[1]; - script_[1] = 0; -} - - -void MathAtom::removeDown() -{ - delete script_[0]; - script_[0] = 0; -} diff --git a/src/mathed/math_atom.h b/src/mathed/math_atom.h index a97ad307bb..38c40469b0 100644 --- a/src/mathed/math_atom.h +++ b/src/mathed/math_atom.h @@ -3,15 +3,10 @@ #ifndef MATH_ATOM_H #define MATH_ATOM_H -#include -#include - #ifdef __GNUG__ #pragma interface #endif -#include "math_defs.h" - /** The 'atom' is the major blob in math typesetting. And 'atom' consists of a nucleus, an optional superscript, and an optional subscript. @@ -22,13 +17,7 @@ size, and type, of the nucleus they are attached to. Jules */ -class LaTeXFeatures; -class MathCharInset; -class MathScriptInset; class MathInset; -class MathMacro; -class MathArray; -class Painter; class MathAtom { public: @@ -38,129 +27,23 @@ public: MathAtom(MathAtom const &); /// explicit MathAtom(MathInset * p); - /// - MathAtom(MathInset * p, MathScriptInset * up, MathScriptInset * down); /// virtual ~MathAtom(); /// void operator=(MathAtom const &); /// - void swap(MathAtom &); - - /// draw the object, sets xo_ and yo_ cached values - virtual void draw(Painter &, int x, int y) const; - /// reproduce itself - void metrics(MathStyles st) const; - /// - int ascent() const; - /// - int descent() const; - /// - int width() const; - /// - int height() const; - - /// - int xo() const; - /// - int yo() const; - /// - void xo(int tx) const; - /// - void yo(int ty) const; - /// - - /// - void getXY(int & x, int & y) const; - /// - bool covers(int x, int y) const; - - /// - void dump() const; - /// - void validate(LaTeXFeatures & features) const; + MathInset * nucleus() const; /// - void handleFont(MathTextCodes) {} + MathInset * operator->() const; - /// make sure superscript is available - MathScriptInset * ensure(bool up); - /// delete subscript array if empty - void removeEmptyScripts(); - /// delete nucleus - void removeNucleus(); - /// delete superscript - void removeUp(); - /// delete subscript - void removeDown(); - /// can we add a super- or subscript? - virtual bool allows(bool up) const { return script_[up] == 0; } - /// can we add a super- or subscript? - virtual bool allowsLimits() const { return true; } - /// set limits - void limits(int lim) { limits_ = lim; } - /// - int limits() const { return limits_; } - /// - bool hasLimits() const; - /// true if we have an "inner" position - bool hasInner() const; - /// returns superscript - MathScriptInset * up() const; - /// returns subscript - MathScriptInset * down() const; - /// returns superscript - MathScriptInset * & up(); - /// returns subscript - MathScriptInset * & down(); - /// - MathInset * nucleus() const { return nucleus_; } - /// - MathInset * & nucleus() { return nucleus_; } - /// - void substitute(const MathMacro &); - /// - void write(std::ostream &, bool) const; - /// - void writeNormal(std::ostream &) const; - /// returns width of nucleus if any - int nwid() const; - -protected: - /// possible subscript (index 0) and superscript (index 1) - MathScriptInset * script_[2]; +private: /// MathInset * nucleus_; - /// - int limits_; - -private: - /// the following are used for positioning the cursor with the mouse - /// cached cursor start position in pixels from the document left - mutable int xo_; - /// cached cursor start position in pixels from the document top - mutable int yo_; /// raw copy void copy(MathAtom const & p); /// raw destruction void done(); - - /// returns y offset for superscript - int dy0() const; - /// returns y offset for subscript - int dy1() const; - /// returns x offset for main part - int dxx() const; - /// returns x offset for superscript - int dx0() const; - /// returns x offset for subscript - int dx1() const; - /// returns ascent of nucleus if any - int nasc() const; - /// returns descent of nucleus if any - int ndes() const; }; -std::ostream & operator<<(std::ostream &, MathAtom const &); - #endif diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 5db7ff3c26..a89acb2933 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -24,6 +24,7 @@ #include #include "support/lstrings.h" +#include "support/LAssert.h" #include "debug.h" #include "LColor.h" #include "Painter.h" @@ -58,24 +59,11 @@ struct Selection MathCursorPos i1; MathCursorPos i2; cursor.getSelection(i1, i2); - if (i1.idx_ == i2.idx_) { - MathArray ar; - if (i1.inner_) { - ar.push_back(*i1.at()); - ar.back().removeNucleus(); - ++i1.pos_; - } - ar.push_back(MathArray(i1.cell(), i1.pos_, i2.pos_)); - if (i2.inner_) { - ar.push_back(*i2.at()); - ar.back().removeUp(); - ar.back().removeDown(); - } - data_.push_back(ar); - } + if (i1.idx_ == i2.idx_) + data_.push_back(MathArray(i1.cell(), i1.pos_, i2.pos_)); else { std::vector indices = - i1.par_->idxBetween(i1.idx_, i2.idx_); + (*i1.par_)->idxBetween(i1.idx_, i2.idx_); for (MathInset::idx_type i = 0; i < indices.size(); ++i) data_.push_back(i1.cell(indices[i])); } @@ -87,20 +75,10 @@ struct Selection MathCursorPos i2; cursor.getSelection(i1, i2); if (i1.idx_ == i2.idx_) { - if (i1.inner_) { - i1.inner_ = false; - i1.at()->removeUp(); - i1.at()->removeDown(); - ++i1.pos_; - } - if (i2.inner_) { - i2.inner_ = false; - i2.at()->removeNucleus(); - } i1.cell().erase(i1.pos_, i2.pos_); } else { std::vector indices = - i1.par_->idxBetween(i1.idx_, i2.idx_); + (*i1.par_)->idxBetween(i1.idx_, i2.idx_); for (unsigned i = 0; i < indices.size(); ++i) i1.cell(indices[i]).erase(); } @@ -109,7 +87,8 @@ struct Selection void paste(MathCursor & cursor) const { - cursor.insert(glue()); + MathArray ar = glue(); + cursor.paste(ar); } // glues selection to one cell @@ -136,8 +115,7 @@ Selection theSelection; #if FILEDEBUG std::ostream & operator<<(std::ostream & os, MathCursorPos const & p) { - os << "(par: " << p.par_ << " idx: " << p.idx_ - << " pos: " << p.pos_ << " inner: " << p.inner_ << ")"; + os << "(par: " << p.par_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ")"; return os; } #endif @@ -145,56 +123,63 @@ std::ostream & operator<<(std::ostream & os, MathCursorPos const & p) } -MathCursor::MathCursor(InsetFormulaBase * formula) +MathCursor::MathCursor(InsetFormulaBase * formula, bool left) : formula_(formula), lastcode_(LM_TC_VAR), selection_(false) { - first(); + left ? first() : last(); } -void MathCursor::pushLeft(MathInset * par) +void MathCursor::push(MathAtom & t) { + //cerr << "Entering atom "; t->write(cerr, false); cerr << " left\n"; MathCursorPos p; - p.par_ = par; - p.inner_ = false; - par->idxFirst(p.idx_, p.pos_); + p.par_ = &t; Cursor_.push_back(p); } -void MathCursor::pushRight(MathInset * par) +void MathCursor::pushLeft(MathAtom & t) +{ + //cerr << "Entering atom "; t->write(cerr, false); cerr << " left\n"; + push(t); + t->idxFirst(idx(), pos()); +} + + +void MathCursor::pushRight(MathAtom & t) { + //cerr << "Entering atom "; t->write(cerr, false); cerr << " right\n"; posLeft(); - MathCursorPos p; - p.par_ = par; - p.inner_ = false; - par->idxLast(p.idx_, p.pos_); - Cursor_.push_back(p); + push(t); + t->idxLast(idx(), pos()); } bool MathCursor::popLeft() { + //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " left\n"; if (Cursor_.size() <= 1) return false; - if (nextAtom()) - nextAtom()->removeEmptyScripts(); + //if (nextInset()) + // nextInset()->removeEmptyScripts(); Cursor_.pop_back(); - if (nextAtom()) - nextAtom()->removeEmptyScripts(); + //if (nextAtom()) + // nextAtom()->removeEmptyScripts(); return true; } bool MathCursor::popRight() { + //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n"; if (Cursor_.size() <= 1) return false; - if (nextAtom()) - nextAtom()->removeEmptyScripts(); + //if (nextInset()) + // nextInset()->removeEmptyScripts(); Cursor_.pop_back(); - if (nextAtom()) - nextAtom()->removeEmptyScripts(); + //if (nextInset()) + // nextInset()->removeEmptyScripts(); posRight(); return true; } @@ -202,17 +187,25 @@ bool MathCursor::popRight() #if FILEDEBUG -void MathCursor::dump(char const *) const +void MathCursor::dump(char const * what) const { lyxerr << "MC: " << what << "\n"; for (unsigned i = 0; i < Cursor_.size(); ++i) lyxerr << " i: " << i - << " pos: " << Cursor_[i].pos_ + << " Cursor: pos: " << Cursor_[i].pos_ << " idx: " << Cursor_[i].idx_ << " par: " << Cursor_[i].par_ << "\n"; - //lyxerr << " sel: " << selection_ << " data: " << array() << "\n"; + + for (unsigned i = 0; i < Anchor_.size(); ++i) + lyxerr << " i: " << i + << " Anchor: pos: " << Anchor_[i].pos_ + << " idx: " << Anchor_[i].idx_ + << " par: " << Anchor_[i].par_ << "\n"; + + lyxerr << " sel: " << selection_ << "\n"; } + void MathCursor::seldump(char const * str) const { //lyxerr << "SEL: " << str << ": '" << theSelection << "'\n"; @@ -242,36 +235,33 @@ void MathCursor::dump(char const *) const {} bool MathCursor::isInside(MathInset const * p) const { for (unsigned i = 0; i < Cursor_.size(); ++i) - if (Cursor_[i].par_ == p) + if (Cursor_[i].par_->nucleus() == p) return true; return false; } -bool MathCursor::openable(MathInset * p, bool sel) const +bool MathCursor::openable(MathAtom const & t, bool sel) const { - if (!p) + if (!t->isActive()) return false; - if (!p->isActive()) + if (t->asScriptInset()) return false; if (sel) { // we can't move into anything new during selection if (Cursor_.size() == Anchor_.size()) return false; - if (p != Anchor_[Cursor_.size()].par_) + if (&t != Anchor_[Cursor_.size()].par_) return false; } return true; } -MathInset * MathCursor::positionable(MathAtom * t, int x, int y) const +bool MathCursor::positionable(MathAtom const & t, int x, int y) const { - if (!t) - return 0; - if (selection_) { // we can't move into anything new during selection if (Cursor_.size() == Anchor_.size()) @@ -280,58 +270,27 @@ MathInset * MathCursor::positionable(MathAtom * t, int x, int y) const // return 0; } - MathInset * p; - - p = t->nucleus(); - if (p && p->nargs() && p->covers(x, y)) - return p; - - p = t->up(); - if (p && p->nargs() && p->covers(x, y)) - return p; - - p = t->down(); - if (p && p->nargs() && p->covers(x, y)) - return p; - - return 0; + return t->nargs() && t->covers(x, y); } bool MathCursor::posLeft() { - if (inner()) { - inner() = false; - return true; - } - if (pos() == 0) return false; --pos(); - if (nextAtom()->hasInner()) - inner() = true; - return true; } bool MathCursor::posRight() { - if (inner()) { - ++pos(); - inner() = false; - return true; - } - if (pos() == size()) return false; - if (nextAtom()->hasInner()) - inner() = true; - else - ++pos(); + ++pos(); return true; } @@ -348,9 +307,8 @@ bool MathCursor::left(bool sel) selHandle(sel); lastcode_ = LM_TC_VAR; - MathInset * p = prevInset(); - if (openable(p, sel)) { - pushRight(p); + if (hasPrevAtom() && openable(prevAtom(), sel)) { + pushRight(prevAtom()); return true; } @@ -369,9 +327,8 @@ bool MathCursor::right(bool sel) selHandle(sel); lastcode_ = LM_TC_VAR; - MathInset * p = nextInset(); - if (openable(p, sel)) { - pushLeft(p); + if (hasNextAtom() && openable(nextAtom(), sel)) { + pushLeft(nextAtom()); return true; } @@ -382,7 +339,7 @@ bool MathCursor::right(bool sel) void MathCursor::first() { Cursor_.clear(); - pushLeft(outerPar()); + pushLeft(formula_->par()); } @@ -402,7 +359,7 @@ void MathCursor::setPos(int x, int y) lastcode_ = LM_TC_VAR; first(); - cursor().par_ = outerPar(); + cursor().par_ = &formula_->par(); while (1) { idx() = 0; @@ -414,7 +371,7 @@ void MathCursor::setPos(int x, int y) int x1 = x - ar.xo(); int y1 = y - ar.yo(); MathXArray::size_type c = ar.x2pos(x1); - int xx = abs(x1 - ar.pos2x(c, false)); + int xx = abs(x1 - ar.pos2x(c)); int yy = abs(y1); //lyxerr << "idx: " << i << " xx: " << xx << " yy: " << yy // << " c: " << c << " xo: " << ar.xo() << "\n"; @@ -426,10 +383,10 @@ void MathCursor::setPos(int x, int y) } //lyxerr << "found idx: " << idx() << " cursor: " // << pos() << "\n"; - if (MathInset * p = positionable(nextAtom(), x, y)) - pushLeft(p); - else if (MathInset * p = positionable(prevAtom(), x, y)) - pushRight(p); + if (hasNextAtom() && positionable(nextAtom(), x, y)) + pushLeft(nextAtom()); + else if (hasPrevAtom() && positionable(prevAtom(), x, y)) + pushRight(prevAtom()); else break; } @@ -467,25 +424,9 @@ void MathCursor::plainErase() } -void MathCursor::plainInsert(MathInset * p) +void MathCursor::plainInsert(MathAtom const & t) { - if (inner()) { - array().insert(pos(), p); - ++pos(); - if (prevAtom() && nextAtom()) // should be unnecessary - swap(prevAtom()->nucleus(), nextAtom()->nucleus()); - return; - } - - MathAtom * n = nextAtom(); - - if (n && !n->nucleus()) { - n->nucleus() = p; - inner() = true; - return; - } - - array().insert(pos(), p); // this invalidates the pointer! + array().insert(pos(), t); ++pos(); } @@ -493,36 +434,30 @@ void MathCursor::plainInsert(MathInset * p) void MathCursor::insert(char c, MathTextCodes t) { //lyxerr << "inserting '" << c << "'\n"; - plainInsert(new MathCharInset(c, t)); + plainInsert(MathAtom(new MathCharInset(c, t))); } -void MathCursor::insert(MathInset * p) +void MathCursor::insert(MathAtom const & t) { macroModeClose(); - if (p && selection_) { - if (p->nargs()) + if (selection_) { + if (t->nargs()) selCut(); else selDel(); } - plainInsert(p); + plainInsert(t); } -void MathCursor::niceInsert(MathInset * p) +void MathCursor::niceInsert(MathAtom const & t) { - if (!p) { - lyxerr << "MathCursor::niceInsert: should not happen\n"; - return; - } selCut(); - //cerr << "\n2: "; p->write(cerr, true); cerr << "\n"; - insert(p); // inserting invalidates the pointer! - p = prevAtom()->nucleus(); - //cerr << "\n3: "; p->write(cerr, true); cerr << "\n"; + insert(t); // inserting invalidates the pointer! + MathAtom const & p = prevAtom(); if (p->nargs()) { posLeft(); right(); // do not push for e.g. MathSymbolInset @@ -543,55 +478,35 @@ void MathCursor::insert(MathArray const & ar) } -void MathCursor::glueAdjacentAtoms() +void MathCursor::paste(MathArray const & ar) { - MathAtom * p = prevAtom(); - if (!p) - return; - - MathAtom * n = nextAtom(); - if (!n) - return; - - if (p->up() && n->up()) - return; - - if (p->down() && n->down()) - return; - - // move everything to the previous atom - if (n->up()) - swap(p->up(), n->up()); - - if (n->down()) - swap(p->down(), n->down()); - - plainErase(); - --pos(); - inner() = nextAtom()->hasInner(); + Anchor_ = Cursor_; + selection_ = true; + array().insert(pos(), ar); + pos() += ar.size(); } void MathCursor::backspace() { - if (inner()) { - nextAtom()->removeNucleus(); - inner() = false; - glueAdjacentAtoms(); - return; - } - if (pos() == 0) { pullArg(false); return; } - if (prevAtom()->hasInner()) { - --pos(); - inner() = true; + if (selection_) { + selDel(); 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; + } + --pos(); plainErase(); } @@ -617,28 +532,15 @@ void MathCursor::erase() return; } - MathAtom * n = nextAtom(); - - if (!n) + if (pos() == size()) return; - if (inner()) { - if (n->up()) - n->removeUp(); - else if (n->down()) - n->removeDown(); - if (!n->up() && !n->down()) { - ++pos(); - inner() = false; - } - return; - } - - if (n->hasInner()) { - n->removeNucleus(); - inner() = true; - glueAdjacentAtoms(); - 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; } plainErase(); @@ -665,18 +567,25 @@ bool MathCursor::up(bool sel) macroModeClose(); selHandle(sel); - if (selection_) - return goUp(); - - // check whether we could move into a superscript on the right or on the left - if (prevAtom() && prevAtom()->up()) { - pushRight(prevAtom()->up()); - return true; - } + if (!selection_) { + // check whether we could move into a superscript + if (hasPrevAtom()) { + MathAtom & p = prevAtom(); + if (p->asScriptInset() && p->asScriptInset()->hasUp()) { + pushRight(p); + pos() = size(); + return true; + } + } - if (nextAtom() && nextAtom()->up()) { - pushLeft(nextAtom()->up()); - return true; + if (hasNextAtom()) { + MathAtom & n = nextAtom(); + if (n->asScriptInset() && n->asScriptInset()->hasUp()) { + pushLeft(n); + pos() = 0; + return true; + } + } } return goUp(); @@ -689,18 +598,25 @@ bool MathCursor::down(bool sel) macroModeClose(); selHandle(sel); - if (selection_) - return goDown(); - - // check whether we could move into an subscript on the right or on the left - if (prevAtom() && prevAtom()->down()) { - pushRight(prevAtom()->down()); - return true; - } + if (!selection_) { + // check whether we could move into a subscript + if (hasPrevAtom()) { + MathAtom & p = prevAtom(); + if (p->asScriptInset() && p->asScriptInset()->hasDown()) { + pushRight(p); + pos() = size(); + return true; + } + } - if (nextAtom() && nextAtom()->down()) { - pushLeft(nextAtom()->down()); - return true; + if (hasNextAtom()) { + MathAtom & n = nextAtom(); + if (n->asScriptInset() && n->asScriptInset()->hasDown()) { + pushLeft(n); + pos() = 0; + return true; + } + } } return goDown(); @@ -709,7 +625,9 @@ bool MathCursor::down(bool sel) bool MathCursor::toggleLimits() { - MathAtom * t = prevAtom(); + if (!hasPrevAtom()) + return false; + MathScriptInset * t = prevAtom()->asScriptInset(); if (!t) return false; int old = t->limits(); @@ -739,8 +657,8 @@ void MathCursor::macroModeClose() int MathCursor::macroNamePos() const { for (int i = pos() - 1; i >= 0; --i) { - MathInset * p = array().at(i)->nucleus(); - if (p && p->code() == LM_TC_TEX && p->getChar() == '\\') + MathAtom & p = array().at(i); + if (p->code() == LM_TC_TEX && p->getChar() == '\\') return i; } return -1; @@ -751,7 +669,7 @@ string MathCursor::macroName() const { string s; for (int i = macroNamePos(); i >= 0 && i < int(pos()); ++i) - s += array().at(i)->nucleus()->getChar(); + s += array().at(i)->getChar(); return s; } @@ -793,7 +711,8 @@ void MathCursor::selPaste() { seldump("selPaste"); theSelection.paste(*this); - selClear(); + theSelection.grab(*this); + //selClear(); } @@ -840,13 +759,14 @@ void MathCursor::drawSelection(Painter & pain) const if (i1.idx_ == i2.idx_) { MathXArray & c = i1.xcell(); - int x1 = c.xo() + c.pos2x(i1.pos_, i1.inner_); + int x1 = c.xo() + c.pos2x(i1.pos_); int y1 = c.yo() - c.ascent(); - int x2 = c.xo() + c.pos2x(i2.pos_, i2.inner_); + int x2 = c.xo() + c.pos2x(i2.pos_); int y2 = c.yo() + c.descent(); pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection); } else { - std::vector indices = i1.par_->idxBetween(i1.idx_, i2.idx_); + std::vector indices + = (*i1.par_)->idxBetween(i1.idx_, i2.idx_); for (unsigned i = 0; i < indices.size(); ++i) { MathXArray & c = i1.xcell(indices[i]); int x1 = c.xo(); @@ -859,13 +779,6 @@ void MathCursor::drawSelection(Painter & pain) const } -MathTextCodes MathCursor::nextCode() const -{ - //return (pos() == size()) ? LM_TC_VAR : nextInset()->code(); - return LM_TC_VAR; -} - - void MathCursor::handleFont(MathTextCodes t) { macroModeClose(); @@ -875,12 +788,8 @@ void MathCursor::handleFont(MathTextCodes t) getSelection(i1, i2); if (i1.idx_ == i2.idx_) { MathArray & ar = i1.cell(); - for (MathInset::pos_type pos = i1.pos_; - pos != i2.pos_; ++pos) { - MathInset * p = ar.at(pos)->nucleus(); - if (p) - p->handleFont(t); - } + for (MathInset::pos_type pos = i1.pos_; pos != i2.pos_; ++pos) + ar.at(pos)->handleFont(t); } } else lastcode_ = (lastcode_ == t) ? LM_TC_VAR : t; @@ -899,9 +808,8 @@ void MathCursor::handleNest(MathInset * p) selCut(); p->cell(0) = theSelection.glue(); } - insert(p); // this invalidates p! - p = prevAtom()->nucleus(); - pushRight(p); + insert(MathAtom(p)); // this invalidates p! + pushRight(prevAtom()); } @@ -910,14 +818,14 @@ void MathCursor::getPos(int & x, int & y) #ifdef WITH_WARNINGS #warning This should probably take cellXOffset and cellYOffset into account #endif - x = xarray().xo() + xarray().pos2x(pos(), inner()); + x = xarray().xo() + xarray().pos2x(pos()); y = xarray().yo(); } -MathInset * MathCursor::par() const +MathAtom & MathCursor::par() const { - return cursor().par_; + return *cursor().par_; } @@ -951,18 +859,6 @@ MathCursor::pos_type & MathCursor::pos() } -bool MathCursor::inner() const -{ - return cursor().inner_; -} - - -bool & MathCursor::inner() -{ - return cursor().inner_; -} - - bool MathCursor::inMacroMode() const { return macroNamePos() != -1; @@ -978,9 +874,10 @@ bool MathCursor::selection() const MathArrayInset * MathCursor::enclosingArray(MathCursor::idx_type & idx) const { for (int i = Cursor_.size() - 1; i >= 0; --i) { - if (Cursor_[i].par_->isArray()) { + MathArrayInset * p = (*Cursor_[i].par_)->asArrayInset(); + if (p) { idx = Cursor_[i].idx_; - return static_cast(Cursor_[i].par_); + return p; } } return 0; @@ -995,14 +892,11 @@ void MathCursor::pullArg(bool goright) MathScriptInset const * p = par()->asScriptInset(); if (p) { // special handling for scripts - const bool up = p->up(); + const bool up = p->hasUp(); popLeft(); - if (nextAtom()) { - if (up) - nextAtom()->removeUp(); - else - nextAtom()->removeDown(); - } + MathScriptInset * q = nextAtom()->asScriptInset(); + if (q) + q->removeScript(up); ++pos(); array().insert(pos(), a); return; @@ -1064,64 +958,42 @@ MathCursor::row_type MathCursor::row() const } -/* -char MathCursorPos::getChar() const +bool MathCursor::hasPrevAtom() const { - return array().getChar(pos()); + return pos() > 0; } -string MathCursorPos::readString() +bool MathCursor::hasNextAtom() const { - string s; - int code = nextCode(); - for ( ; OK() && nextCode() == code; Next()) - s += getChar(); - - return s; -} -*/ - - -MathInset * MathCursor::prevInset() const -{ - return prevAtom() ? prevAtom()->nucleus() : 0; + return pos() < size(); } -MathInset * MathCursor::nextInset() const -{ - return nextAtom() ? nextAtom()->nucleus() : 0; -} - - -MathSpaceInset * MathCursor::prevSpaceInset() const -{ - MathInset * p = prevInset(); - return (p && p->isSpaceInset()) ? static_cast(p) : 0; -} - - -MathAtom const * MathCursor::prevAtom() const +MathAtom const & MathCursor::prevAtom() const { + lyx::Assert(pos() > 0); return array().at(pos() - 1); } -MathAtom * MathCursor::prevAtom() +MathAtom & MathCursor::prevAtom() { + lyx::Assert(pos() > 0); return array().at(pos() - 1); } -MathAtom const * MathCursor::nextAtom() const +MathAtom const & MathCursor::nextAtom() const { + lyx::Assert(pos() < size()); return array().at(pos()); } -MathAtom * MathCursor::nextAtom() +MathAtom & MathCursor::nextAtom() { + lyx::Assert(pos() < size()); return array().at(pos()); } @@ -1129,10 +1001,6 @@ MathAtom * MathCursor::nextAtom() MathArray & MathCursor::array() const { static MathArray dummy; - if (!par()) { - lyxerr << "############ par_ not valid\n"; - return dummy; - } if (idx() >= par()->nargs()) { lyxerr << "############ idx_ " << idx() << " not valid\n"; @@ -1180,7 +1048,10 @@ void MathCursor::breakLine() while (popRight()) ; - MathMatrixInset * p = outerPar(); + MathMatrixInset * p = formula()->par()->asMatrixInset(); + if (!p) + return; + if (p->getType() == LM_OT_SIMPLE || p->getType() == LM_OT_EQUATION) { p->mutate(LM_OT_EQNARRAY); idx() = 0; @@ -1259,7 +1130,7 @@ int MathCursor::cellYOffset() const int MathCursor::xpos() const { - return cellXOffset() + xarray().pos2x(pos(), inner()); + return cellXOffset() + xarray().pos2x(pos()); } @@ -1283,7 +1154,8 @@ bool MathCursor::goUp() return true; // leave subscript to the nearest side - if (par()->asScriptInset() && par()->asScriptInset()->down()) { + MathScriptInset * p = par()->asScriptInset(); + if (p && p->hasDown()) { if (pos() <= size() / 2) popLeft(); else @@ -1296,8 +1168,9 @@ bool MathCursor::goUp() int y0; getPos(x0, y0); std::vector save = Cursor_; + MathAtom const & out = formula()->par(); y0 -= xarray().ascent(); - for (int y = y0 - 4; y > outerPar()->yo() - outerPar()->ascent(); y -= 4) { + for (int y = y0 - 4; y > out->yo() - out->ascent(); y -= 4) { setPos(x0, y); if (save != Cursor_ && xarray().yo() < y0) return true; @@ -1314,7 +1187,8 @@ bool MathCursor::goDown() return true; // leave superscript to the nearest side - if (par()->asScriptInset() && par()->asScriptInset()->up()) { + MathScriptInset * p = par()->asScriptInset(); + if (p && p->hasUp()) { if (pos() <= size() / 2) popLeft(); else @@ -1327,8 +1201,9 @@ bool MathCursor::goDown() int y0; getPos(x0, y0); std::vector save = Cursor_; + MathAtom const & out = formula()->par(); y0 += xarray().descent(); - for (int y = y0 + 4; y < outerPar()->yo() + outerPar()->descent(); y += 4) { + for (int y = y0 + 4; y < out->yo() + out->descent(); y += 4) { setPos(x0, y); if (save != Cursor_ && xarray().yo() > y0) return true; @@ -1350,13 +1225,6 @@ bool MathCursor::idxRight() } -MathMatrixInset * MathCursor::outerPar() const -{ - return - static_cast(const_cast(formula_->par())); -} - - void MathCursor::interpret(string const & s) { //lyxerr << "interpret 1: '" << s << "'\n"; @@ -1384,19 +1252,16 @@ void MathCursor::interpret(string const & s) m = std::max(1u, m); n = std::max(1u, n); v_align += 'c'; - MathArrayInset * p = new MathArrayInset(m, n); - p->valign(v_align[0]); - p->halign(h_align); - niceInsert(p); + niceInsert(MathAtom(new MathArrayInset(m, n, v_align[0], h_align))); return; } if (s == "\\over" || s == "\\choose" || s == "\\atop") { MathArray ar = array(); - MathInset * p = createMathInset(s.substr(1)); - p->cell(0).swap(array()); + MathAtom t = createMathInset(s.substr(1)); + t->asNestInset()->cell(0).swap(array()); pos() = 0; - niceInsert(p); + niceInsert(t); popRight(); left(); return; @@ -1448,17 +1313,24 @@ void MathCursor::interpret(char c) // no macro mode if (c == '^' || c == '_') { const bool up = (c == '^'); - const bool in = inner(); selCut(); - if (in) - ++pos(); - if (!prevAtom()) - insert(0); - MathInset * par = prevAtom()->ensure(up); - if (in) - pushLeft(par); - else - pushRight(par); + if (hasPrevAtom() && prevAtom()->asScriptInset()) { + prevAtom()->asScriptInset()->ensure(up); + pushRight(prevAtom()); + pos() = size(); + idx() = up; + return; + } + if (hasNextAtom() && nextAtom()->asScriptInset()) { + nextAtom()->asScriptInset()->ensure(up); + pushLeft(nextAtom()); + pos() = 0; + idx() = up; + return; + } + plainInsert(MathAtom(new MathScriptInset(up))); + pushRight(prevAtom()); + idx() = up; selPaste(); return; } @@ -1494,7 +1366,7 @@ void MathCursor::interpret(char c) } if (strchr("#$%", c)) { - insert(new MathSpecialCharInset(c)); + insert(MathAtom(new MathSpecialCharInset(c))); lastcode_ = LM_TC_VAR; return; } @@ -1563,31 +1435,25 @@ bool operator<(MathCursorPos const & ti, MathCursorPos const & it) MathArray & MathCursorPos::cell(MathCursor::idx_type idx) const { - return par_->cell(idx); + return (*par_)->cell(idx); } MathArray & MathCursorPos::cell() const { - return par_->cell(idx_); + return (*par_)->cell(idx_); } MathXArray & MathCursorPos::xcell(MathCursor::idx_type idx) const { - return par_->xcell(idx); + return (*par_)->xcell(idx); } MathXArray & MathCursorPos::xcell() const { - return par_->xcell(idx_); -} - - -MathAtom * MathCursorPos::at() const -{ - return cell().at(pos_); + return (*par_)->xcell(idx_); } @@ -1602,3 +1468,10 @@ MathCursorPos MathCursor::normalAnchor() const return normal; } + +MathSpaceInset * MathCursor::prevSpaceInset() const +{ + if (!hasPrevAtom()) + return 0; + return prevAtom()->asSpaceInset(); +} diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index d8d7a5b49b..f6e50b218a 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -35,18 +35,17 @@ class InsetFormulaBase; class MathArray; class MathXArray; class Painter; +class Selection; class latexkeys; /// Description of a position struct MathCursorPos { /// inset - MathInset * par_; + MathAtom * par_; /// cell index MathInset::idx_type idx_; /// cell position MathInset::pos_type pos_; - /// faked position "inside an atom" - bool inner_; /// returns cell corresponding to this position MathArray & cell() const; @@ -56,9 +55,6 @@ struct MathCursorPos { MathXArray & xcell() const; /// returns xcell corresponding to this position MathXArray & xcell(MathInset::idx_type idx) const; - - /// returns atom corresponding to this position - MathAtom * at() const; }; /// @@ -82,12 +78,14 @@ public: typedef MathInset::col_type col_type; /// - explicit MathCursor(InsetFormulaBase *); + explicit MathCursor(InsetFormulaBase *, bool left); /// - void insert(MathInset *); + void insert(MathAtom const &); /// void insert(MathArray const &); /// + void paste(MathArray const &); + /// void erase(); /// void backspace(); @@ -114,9 +112,9 @@ public: /// void plainErase(); /// - void plainInsert(MathInset * p); + void plainInsert(MathAtom const &); /// - void niceInsert(MathInset * p); + void niceInsert(MathAtom const &); /// void delLine(); @@ -125,14 +123,12 @@ public: /// void getPos(int & x, int & y); /// - MathInset * par() const; + MathAtom & par() const; /// return the next enclosing grid inset and the cursor's index in it MathArrayInset * enclosingArray(idx_type &) const; /// InsetFormulaBase const * formula(); /// - bool inner() const; - /// pos_type pos() const; /// idx_type idx() const; @@ -202,11 +198,13 @@ public: MathStyles style() const; /// Make sure cursor position is valid void normalize() const; - + + /// enter a MathInset + void push(MathAtom & par); /// enter a MathInset from the front - void pushLeft(MathInset * par); + void pushLeft(MathAtom & par); /// enter a MathInset from the back - void pushRight(MathInset * par); + void pushRight(MathAtom & par); /// leave current MathInset to the left bool popLeft(); /// leave current MathInset to the left @@ -217,13 +215,17 @@ public: /// MathXArray & xarray() const; /// - MathAtom const * prevAtom() const; + bool hasPrevAtom() const; + /// + bool hasNextAtom() const; + /// + MathAtom const & prevAtom() const; /// - MathAtom * prevAtom(); + MathAtom & prevAtom(); /// - MathAtom const * nextAtom() const; + MathAtom const & nextAtom() const; /// - MathAtom * nextAtom(); + MathAtom & nextAtom(); /// returns the selection void getSelection(MathCursorPos &, MathCursorPos &) const; @@ -244,8 +246,6 @@ public: /// pos_type last() const; /// - MathMatrixInset * outerPar() const; - /// void seldump(char const * str) const; /// void dump(char const * str) const; @@ -253,13 +253,14 @@ public: /// void merge(MathArray const & arr); /// - MathInset * nextInset() const; - /// - MathInset * prevInset() const; - /// MathScriptInset * prevScriptInset() const; /// MathSpaceInset * prevSpaceInset() const; + /// glue adjacent atoms if possible + bool glueAdjacentAtoms(); + + /// + friend class Selection; private: /// moves cursor position one cell to the left @@ -274,8 +275,6 @@ private: bool goUp(); /// moves position somehow down bool goDown(); - /// glue adjacent atoms if possible - void glueAdjacentAtoms(); /// string macroName() const; @@ -284,11 +283,9 @@ private: /// void insert(char, MathTextCodes t); /// can we enter the inset? - bool openable(MathInset *, bool selection) const; + bool openable(MathAtom const &, bool selection) const; /// can the setPos routine enter that inset? - MathInset * positionable(MathAtom *, int x, int y) const; - /// write access to "inner" flag - bool & inner(); + bool positionable(MathAtom const &, int x, int y) const; /// write access to cursor cell position pos_type & pos(); /// write access to cursor cell index diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index 7152b27159..4a6d21c336 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -20,13 +20,13 @@ #include "math_stackrelinset.h" -MathInset * createMathInset(latexkeys const * l) +MathAtom createMathInset(latexkeys const * l) { switch (l->token) { case LM_TK_FUNCLIM: - return new MathFuncLimInset(l); + return MathAtom(new MathFuncLimInset(l)); case LM_TK_SPECIAL: - return new MathSpecialCharInset(l->id); + return MathAtom(new MathSpecialCharInset(l->id)); case LM_TK_SYM: case LM_TK_CMR: case LM_TK_CMSY: @@ -34,51 +34,51 @@ MathInset * createMathInset(latexkeys const * l) case LM_TK_CMEX: case LM_TK_MSA: case LM_TK_MSB: - return new MathSymbolInset(l); + return MathAtom(new MathSymbolInset(l)); case LM_TK_STACK: - return new MathStackrelInset; + return MathAtom(new MathStackrelInset); case LM_TK_KERN: - return new MathKernInset; + return MathAtom(new MathKernInset); case LM_TK_BINOM: case LM_TK_CHOOSE: - return new MathBinomInset; + return MathAtom(new MathBinomInset); case LM_TK_OVER: case LM_TK_FRAC: - return new MathFracInset; + return MathAtom(new MathFracInset); case LM_TK_ATOP: - return new MathFracInset(true); + return MathAtom(new MathFracInset(true)); case LM_TK_NOT: - return new MathNotInset; + return MathAtom(new MathNotInset); case LM_TK_SQRT: - return new MathSqrtInset; + return MathAtom(new MathSqrtInset); case LM_TK_ROOT: - return new MathRootInset; + return MathAtom(new MathRootInset); case LM_TK_DECORATION: - return new MathDecorationInset(l->name); + return MathAtom(new MathDecorationInset(l->name)); case LM_TK_SPACE: - return new MathSpaceInset(l->id); + return MathAtom(new MathSpaceInset(l->id)); case LM_TK_DOTS: - return new MathDotsInset(l->name); + return MathAtom(new MathDotsInset(l->name)); } - return new MathFuncInset(l->name); + return MathAtom(new MathFuncInset(l->name)); } -MathInset * createMathInset(string const & s) +MathAtom createMathInset(string const & s) { //cerr << "creating inset with name: '" << s << "'\n"; if (s.size() == 2 && s[0] == '#' && s[1] >= '1' && s[1] <= '9') - return new MathMacroArgument(s[1] - '0'); + return MathAtom(new MathMacroArgument(s[1] - '0')); if (s.size() == 3 && s[0] == '\\' && s[1] == '#' && s[2] >= '1' && s[2] <= '9') - return new MathMacroArgument(s[2] - '0'); + return MathAtom(new MathMacroArgument(s[2] - '0')); latexkeys const * l = in_word_set(s); if (l) return createMathInset(l); - if (MathMacroTable::hasTemplate(s)) - return new MathMacro(MathMacroTable::provideTemplate(s)); + if (MathMacroTable::has(s)) + return MathAtom(new MathMacro(s)); - return new MathFuncInset(s); + return MathAtom(new MathFuncInset(s)); } diff --git a/src/mathed/math_factory.h b/src/mathed/math_factory.h index 0123b5845c..56e0e91669 100644 --- a/src/mathed/math_factory.h +++ b/src/mathed/math_factory.h @@ -2,11 +2,12 @@ #define MATH_FACTORY_H #include "LString.h" +#include "math_atom.h" class MathInset; class latexkeys; -MathInset * createMathInset(string const &); -MathInset * createMathInset(latexkeys const *); +MathAtom createMathInset(string const &); +MathAtom createMathInset(latexkeys const *); #endif diff --git a/src/mathed/math_gridinset.C b/src/mathed/math_gridinset.C index 6e7da53213..074b76fbfe 100644 --- a/src/mathed/math_gridinset.C +++ b/src/mathed/math_gridinset.C @@ -19,6 +19,9 @@ int const MATH_BORDER = 2; } +////////////////////////////////////////////////////////////// + + MathGridInset::RowInfo::RowInfo() : upperline_(false), lowerline_(false) {} @@ -35,22 +38,33 @@ int MathGridInset::RowInfo::skipPixels() const +////////////////////////////////////////////////////////////// + + MathGridInset::ColInfo::ColInfo() : align_('c'), leftline_(false), rightline_(false), skip_(MATH_COLSEP) {} +////////////////////////////////////////////////////////////// + + MathGridInset::MathGridInset(col_type m, row_type n) : MathNestInset(m * n), rowinfo_(n), colinfo_(m), v_align_('c') { - if (m <= 0) - lyxerr << "positve number of columns expected\n"; - if (n <= 0) - lyxerr << "positve number of rows expected\n"; setDefaults(); } +MathGridInset::MathGridInset(int m, int n, char v, string const & h) + : MathNestInset(m * n), rowinfo_(n), colinfo_(m), v_align_(v) +{ + setDefaults(); + valign(v); + halign(h); +} + + MathInset::idx_type MathGridInset::index(row_type row, col_type col) const { return col + ncols() * row; @@ -59,6 +73,10 @@ MathInset::idx_type MathGridInset::index(row_type row, col_type col) const void MathGridInset::setDefaults() { + if (ncols() <= 0) + lyxerr << "positve number of columns expected\n"; + if (nrows() <= 0) + lyxerr << "positve number of rows expected\n"; for (col_type col = 0; col < ncols(); ++col) { colinfo_[col].align_ = defaultColAlign(col); colinfo_[col].skip_ = defaultColSpace(col); @@ -268,7 +286,7 @@ string MathGridInset::eolString(row_type row) const // make sure an upcoming '[' does not break anything MathArray const & c = cell(index(row + 1, 0)); - if (c.size() && c.begin()->nucleus()->getChar() == '[') + if (c.size() && (*c.begin())->getChar() == '[') return "\\\\[0pt]\n"; return "\\\\\n"; @@ -367,8 +385,9 @@ bool MathGridInset::idxUp(idx_type & idx, pos_type & pos) const { if (idx < ncols()) return false; + int x = cellXOffset(idx) + xcell(idx).pos2x(pos); idx -= ncols(); - pos = 0; + pos = xcell(idx).x2pos(x - cellXOffset(idx)); return true; } @@ -377,8 +396,9 @@ bool MathGridInset::idxDown(idx_type & idx, pos_type & pos) const { if (idx >= ncols() * (nrows() - 1)) return false; + int x = cellXOffset(idx) + xcell(idx).pos2x(pos); idx += ncols(); - pos = 0; + pos = xcell(idx).x2pos(x - cellXOffset(idx)); return true; } diff --git a/src/mathed/math_gridinset.h b/src/mathed/math_gridinset.h index 347441ee85..b7fbd2f4d6 100644 --- a/src/mathed/math_gridinset.h +++ b/src/mathed/math_gridinset.h @@ -62,6 +62,8 @@ public: /// Note: columns first! MathGridInset(col_type m, row_type n); /// + MathGridInset(int m, int n, char valign, string const & halign); + /// void write(std::ostream &, bool fragile) const; /// void metrics(MathStyles st) const; @@ -87,8 +89,8 @@ public: const RowInfo & rowinfo(row_type row) const; /// RowInfo & rowinfo(row_type row); - /// - bool isGrid() const { return true; } + /// identifies GridInset + virtual MathGridInset * asGridInset() { return this; } /// col_type ncols() const { return colinfo_.size(); } diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index d303aa2ca2..9894c9ee73 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -38,8 +38,14 @@ class LaTeXFeatures; +class MathArrayInset; class MathCharInset; +class MathGridInset; +class MathNestInset; class MathScriptInset; +class MathMatrixInset; +class MathSpaceInset; +class MathMacroTemplate; class MathInset { public: @@ -166,26 +172,37 @@ public: virtual void getXY(int & x, int & y) const; /// virtual bool covers(int x, int y) const; - /// identifies things that can get scripts - virtual bool isScriptable() const { return false; } - /// identifies ScriptInsets - virtual bool isScriptInset() const { return false; } - /// identifies SpaceInsets - virtual bool isSpaceInset() const { return false; } - /// identifies GridInsets - virtual bool isGrid() const { return false; } - /// identifies ArrayInsets - virtual bool isArray() const { return false; } + + /// identifies NestInsets + virtual MathNestInset * asNestInset() { return 0; } /// identifies CharInsets virtual MathCharInset const * asCharInset() const { return 0; } /// identifies ScriptInsets virtual MathScriptInset const * asScriptInset() const { return 0; } + /// identifies ScriptInsets + virtual MathScriptInset * asScriptInset() { return 0; } + /// identifies MatrixInsets + virtual MathMatrixInset const * asMatrixInset() const { return 0; } + /// identifies MatrixInsets + virtual MathMatrixInset * asMatrixInset() { return 0; } + /// identifies SpaceInset + virtual MathSpaceInset * asSpaceInset() { return 0; } + /// identifies GridInset + virtual MathGridInset * asGridInset() { return 0; } + /// identifies ArrayInsets + virtual MathArrayInset * asArrayInset() { return 0; } + /// identifies macro templates + virtual MathMacroTemplate * asMacroTemplate() { return 0; } + + /// identifies things that can get scripts + virtual bool isScriptable() const { return false; } /// virtual bool isActive() const { return nargs() > 0; } /// virtual bool isRelOp() const { return false; } /// virtual bool isMacro() const { return false; } + /// virtual char getChar() const { return 0; } /// diff --git a/src/mathed/math_macro.C b/src/mathed/math_macro.C index 9dcf8a9aec..7f6938b026 100644 --- a/src/mathed/math_macro.C +++ b/src/mathed/math_macro.C @@ -32,13 +32,15 @@ using std::endl; -MathMacro::MathMacro(MathMacroTemplate const & t) - : MathNestInset(t.numargs()), tmplate_(&t) +MathMacro::MathMacro(string const & name) + : MathNestInset(MathMacroTable::provide(name)->asMacroTemplate()->numargs()), + tmplate_(MathMacroTable::provide(name)) {} -MathMacro::MathMacro(MathMacro const & t) - : MathNestInset(t), tmplate_(t.tmplate_) // don't copy 'expanded_'! +MathMacro::MathMacro(MathMacro const & m) + : MathNestInset(m), + tmplate_(m.tmplate_) // don't copy 'expanded_'! {} @@ -51,7 +53,7 @@ MathInset * MathMacro::clone() const const char * MathMacro::name() const { - return tmplate_->name().c_str(); + return tmplate_->asMacroTemplate()->name().c_str(); } @@ -139,11 +141,11 @@ void MathMacro::dump() const MathMacroTable::dump(); lyxerr << "\n macro: '" << this << "'\n"; lyxerr << " name: '" << name() << "'\n"; - lyxerr << " template: '" << tmplate_ << "'\n"; - lyxerr << " template: '" << *tmplate_ << "'\n"; + lyxerr << " template: '"; tmplate_->write(lyxerr, false); lyxerr << "'\n"; lyxerr << endl; } + void MathMacro::write(std::ostream & os, bool fragile) const { os << '\\' << name(); diff --git a/src/mathed/math_macro.h b/src/mathed/math_macro.h index bfcfa94a26..8cf2107f56 100644 --- a/src/mathed/math_macro.h +++ b/src/mathed/math_macro.h @@ -26,6 +26,7 @@ #include "math_nestinset.h" #include "math_macroarg.h" +#include "LString.h" class MathMacroTemplate; @@ -37,7 +38,7 @@ class MathMacroTemplate; class MathMacro : public MathNestInset { public: /// A macro can be built from an existing template - explicit MathMacro(MathMacroTemplate const &); + explicit MathMacro(string const &); /// MathMacro(MathMacro const &); /// @@ -74,7 +75,7 @@ private: char const * name() const; /// - MathMacroTemplate const * const tmplate_; + MathAtom & tmplate_; /// mutable MathXArray expanded_; }; diff --git a/src/mathed/math_macrotable.C b/src/mathed/math_macrotable.C index 8f3e6383d3..1e6902618a 100644 --- a/src/mathed/math_macrotable.C +++ b/src/mathed/math_macrotable.C @@ -24,21 +24,14 @@ void MathMacroTable::dump() lyxerr << "\n------------------------------------------\n"; table_type::const_iterator it; for (it = macro_table.begin(); it != macro_table.end(); ++it) - lyxerr << it->first << " [" << it->second.nargs() << "] : " - << it->second << "\n"; + lyxerr << it->first + << " [" << it->second->asMacroTemplate()->nargs() << "] : " + << it->second->cell(0) << "\n"; lyxerr << "------------------------------------------\n"; } -void MathMacroTable::insertTemplate(MathMacroTemplate const & p) -{ - if (macro_table.find(p.name()) != macro_table.end()) - lyxerr << "macro '" << p.name() << "' not new\n"; - macro_table[p.name()] = p; -} - - -MathMacroTemplate & MathMacroTable::provideTemplate(string const & name) +MathAtom & MathMacroTable::provide(string const & name) { builtinMacros(); @@ -53,25 +46,27 @@ MathMacroTemplate & MathMacroTable::provideTemplate(string const & name) } -void MathMacroTable::createTemplate - (string const & name, int na, string const & text) +void MathMacroTable::create(string const & name, int na, string const & text) { - MathMacroTemplate t(name, na); - t.cell(0) = mathed_parse_cell(text); - insertTemplate(t); + MathAtom t(new MathMacroTemplate(name, na)); + t->cell(0) = mathed_parse_cell(text); + macro_table[name] = t; } -bool MathMacroTable::hasTemplate(string const & name) +void MathMacroTable::create(string const & name, int na, MathArray const & ar) { - builtinMacros(); - return macro_table.find(name) != macro_table.end(); + MathAtom t(new MathMacroTemplate(name, na)); + t->cell(0) = ar; + macro_table[name] = t; } -MathMacro * MathMacroTable::cloneTemplate(string const & name) + +bool MathMacroTable::has(string const & name) { - return new MathMacro(provideTemplate(name)); + builtinMacros(); + return macro_table.find(name) != macro_table.end(); } @@ -85,68 +80,68 @@ void MathMacroTable::builtinMacros() built = true; //lyxerr[Debug::MATHED] << "Building macros\n"; - //createTemplate("emptyset", 0, "\\not0"); - createTemplate("notin", 0, "\\not\\in"); - createTemplate("slash", 0, "/"); + //create("emptyset", 0, "\\not0"); + create("notin", 0, "\\not\\in"); + create("slash", 0, "/"); // fontmath.ltx - createTemplate("lnot", 0, "\\neg"); - createTemplate("land", 0, "\\wedge"); - createTemplate("lor", 0, "\\vee"); - createTemplate("ne", 0, "\\neq"); - createTemplate("le", 0, "\\leq"); - createTemplate("ge", 0, "\\geq"); - createTemplate("owns", 0, "\\ni"); - createTemplate("gets", 0, "\\leftarrow"); - createTemplate("to", 0, "\\rightarrow"); - createTemplate("|", 0, "\\parallel"); + create("lnot", 0, "\\neg"); + create("land", 0, "\\wedge"); + create("lor", 0, "\\vee"); + create("ne", 0, "\\neq"); + create("le", 0, "\\leq"); + create("ge", 0, "\\geq"); + create("owns", 0, "\\ni"); + create("gets", 0, "\\leftarrow"); + create("to", 0, "\\rightarrow"); + create("|", 0, "\\parallel"); - createTemplate("longleftrightarrow", 0, "\\leftarrow\\kern-6mu\\rightarrow"); - createTemplate("Longleftrightarrow", 0, "\\Leftarrow\\kern-6mu\\Rightarrow"); - createTemplate("doteq", 0, "\\stackrel{\\cdot}{=}"); + create("longleftrightarrow", 0, "\\leftarrow\\kern-6mu\\rightarrow"); + create("Longleftrightarrow", 0, "\\Leftarrow\\kern-6mu\\Rightarrow"); + create("doteq", 0, "\\stackrel{\\cdot}{=}"); - //createTemplate("models", 0, "|\\kern-9mu="); + //create("models", 0, "|\\kern-9mu="); if (math_font_available(LM_TC_CMSY)) { - createTemplate("longrightarrow", 0, "\\lyxbar\\kern-5mu\\rightarrow"); - createTemplate("longleftarrow", 0, "\\leftarrow\\kern-5mu\\lyxbar"); - createTemplate("mapsto", 0, "\\mapstochar\\rightarrow"); - createTemplate("longmapsto", 0, "\\mapstochar\\lyxbar\\kern-5mu\\rightarrow"); + create("longrightarrow", 0, "\\lyxbar\\kern-5mu\\rightarrow"); + create("longleftarrow", 0, "\\leftarrow\\kern-5mu\\lyxbar"); + create("mapsto", 0, "\\mapstochar\\rightarrow"); + create("longmapsto", 0, "\\mapstochar\\lyxbar\\kern-5mu\\rightarrow"); } if (math_font_available(LM_TC_CMR)) { - createTemplate("Longrightarrow", 0, "\\lyxeq\\kern-3mu\\Rightarrow"); - createTemplate("Longleftarrow", 0, "\\Leftarrow\\kern-9mu\\lyxeq"); + create("Longrightarrow", 0, "\\lyxeq\\kern-3mu\\Rightarrow"); + create("Longleftarrow", 0, "\\Leftarrow\\kern-9mu\\lyxeq"); } if (math_font_available(LM_TC_CMM)) { - createTemplate("hookrightarrow", 0, "\\lhook\\kern-5mu\\rightarrow"); - createTemplate("hookleftarrow", 0, "\\leftarrow\\kern-5mu\\rhook"); - createTemplate("bowtie", 0, "\\triangleright\\kern-3mu\\triangleleft"); + create("hookrightarrow", 0, "\\lhook\\kern-5mu\\rightarrow"); + create("hookleftarrow", 0, "\\leftarrow\\kern-5mu\\rhook"); + create("bowtie", 0, "\\triangleright\\kern-3mu\\triangleleft"); } if (math_font_available(LM_TC_MSA)) { //amsfonts.sty - createTemplate("dashrightarrow", 0, "\\lyxdabar\\lyxdabar\\lyxright"); - createTemplate("dashleftarrow", 0, "\\lyxleft\\lyxdabar\\lyxdabar"); - createTemplate("dasharrow", 0, "\\dashrightarrow"); - createTemplate("Box", 0, "\\square"); - createTemplate("Diamond", 0, "\\lozenge"); - createTemplate("leadsto", 0, "\\rightsquigarrow"); + create("dashrightarrow", 0, "\\lyxdabar\\lyxdabar\\lyxright"); + create("dashleftarrow", 0, "\\lyxleft\\lyxdabar\\lyxdabar"); + create("dasharrow", 0, "\\dashrightarrow"); + create("Box", 0, "\\square"); + create("Diamond", 0, "\\lozenge"); + create("leadsto", 0, "\\rightsquigarrow"); // amssymb.sty - createTemplate("restriction", 0, "\\upharpoonright"); - createTemplate("Doteq", 0, "\\doteqdot"); - createTemplate("doublecup", 0, "\\Cup"); - createTemplate("doublecap", 0, "\\Cap"); - createTemplate("llless", 0, "\\lll"); - createTemplate("gggtr", 0, "\\ggg"); + create("restriction", 0, "\\upharpoonright"); + create("Doteq", 0, "\\doteqdot"); + create("doublecup", 0, "\\Cup"); + create("doublecap", 0, "\\Cap"); + create("llless", 0, "\\lll"); + create("gggtr", 0, "\\ggg"); } - //createTemplate("lint", 4, "\\int_#1^#2#3 d#4"); - //createTemplate("silentmult", 0, "\\cdot"); - //createTemplate("binom", 2, "\\left(\\frac#1#2\\right)"); + //create("lint", 4, "\\int_#1^#2#3 d#4"); + //create("silentmult", 0, "\\cdot"); + //create("binom", 2, "\\left(\\frac#1#2\\right)"); } diff --git a/src/mathed/math_macrotable.h b/src/mathed/math_macrotable.h index 2feaa00d5f..44f59c1357 100644 --- a/src/mathed/math_macrotable.h +++ b/src/mathed/math_macrotable.h @@ -4,34 +4,30 @@ #include #include "LString.h" -#include "math_macrotemplate.h" +#include "math_atom.h" #ifdef __GNUG__ #pragma interface #endif - -class MathMacro; - +class MathArray; /// struct MathMacroTable { public: /// - static void insertTemplate(MathMacroTemplate const &); - /// - static MathMacroTemplate & provideTemplate(string const &); + static void create(string const &, int, string const &); /// - static bool hasTemplate(string const &); + static void create(string const &, int, MathArray const &); /// - static MathMacro * cloneTemplate(string const &); + static MathAtom & provide(string const &); /// - static void createTemplate(string const &, int, string const &); + static bool has(string const &); /// static void builtinMacros(); private: /// - typedef std::map table_type; + typedef std::map table_type; // static table_type macro_table; public: diff --git a/src/mathed/math_macrotemplate.C b/src/mathed/math_macrotemplate.C index 10ffb95ae4..822d0e9211 100644 --- a/src/mathed/math_macrotemplate.C +++ b/src/mathed/math_macrotemplate.C @@ -24,7 +24,7 @@ MathMacroTemplate::MathMacroTemplate(string const & nm, int numargs) MathInset * MathMacroTemplate::clone() const { - lyxerr << "cloning MacroTemplate!\n"; + //lyxerr << "cloning MacroTemplate!\n"; return new MathMacroTemplate(*this); } diff --git a/src/mathed/math_macrotemplate.h b/src/mathed/math_macrotemplate.h index 628a9bee68..aeefe5a2ce 100644 --- a/src/mathed/math_macrotemplate.h +++ b/src/mathed/math_macrotemplate.h @@ -36,6 +36,8 @@ public: void draw(Painter &, int x, int y) const; /// void metrics(MathStyles st) const; + /// identifies macro templates + MathMacroTemplate * asMacroTemplate() { return this; } private: /// int numargs_; diff --git a/src/mathed/math_matrixinset.C b/src/mathed/math_matrixinset.C index 6f0a9c0975..bada6e4756 100644 --- a/src/mathed/math_matrixinset.C +++ b/src/mathed/math_matrixinset.C @@ -36,7 +36,7 @@ int getCols(MathInsetTypes type) int firstRelOp(MathArray const & array) { for (MathArray::const_iterator it = array.begin(); it != array.end(); ++it) - if (it->nucleus()->isRelOp()) + if ((*it)->isRelOp()) return it - array.begin(); return array.size(); } diff --git a/src/mathed/math_matrixinset.h b/src/mathed/math_matrixinset.h index ffeeb60de1..b90279af3b 100644 --- a/src/mathed/math_matrixinset.h +++ b/src/mathed/math_matrixinset.h @@ -50,6 +50,10 @@ public: std::vector const getLabelList() const; /// void validate(LaTeXFeatures & features) const; + /// identifies MatrixInsets + virtual MathMatrixInset const * asMatrixInset() const { return this; } + /// identifies MatrixInsets + virtual MathMatrixInset * asMatrixInset() { return this; } /// void addRow(row_type); diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 54ef57e9b3..5dccb4b559 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -148,10 +148,10 @@ void MathNestInset::dump() const } -void MathNestInset::push_back(MathInset * p) +void MathNestInset::push_back(MathAtom const & t) { if (nargs()) - cells_.back().data_.push_back(p); + cells_.back().data_.push_back(t); else lyxerr << "can't push without a cell\n"; } diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index b6156e0a3e..5cf17786de 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -24,6 +24,8 @@ public: void draw(Painter &, int x, int y) const; /// appends itself with macro arguments substituted void substitute(MathMacro const & macro); + /// identifies NestInsets + MathNestInset * asNestInset() { return this; } /// The left key bool idxLeft(idx_type & idx, pos_type & pos) const; @@ -60,7 +62,7 @@ public: /// bool isActive() const { return nargs() > 0; } /// - void push_back(MathInset *); + void push_back(MathAtom const &); /// void dump() const; diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index 4e2f0b63e1..074ee0509b 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -62,6 +62,11 @@ bool stared(string const & s) } +void add(MathArray & ar, char c, MathTextCodes code) +{ + ar.push_back(MathAtom(new MathCharInset(c, code))); +} + // These are TeX's catcodes enum CatCode { @@ -199,9 +204,9 @@ public: Parser(istream & is); /// - MathMacroTemplate * parse_macro(); + string parse_macro(); /// - MathMatrixInset * parse_normal(); + bool parse_normal(MathAtom &); /// void parse_into(MathArray & array, unsigned flags, MathTextCodes = LM_TC_MIN); /// @@ -217,7 +222,7 @@ private: /// void error(string const & msg); /// - void parse_lines(MathGridInset * p, bool numbered, bool outmost); + bool parse_lines(MathAtom & t, bool numbered, bool outmost); private: /// @@ -426,8 +431,14 @@ void Parser::error(string const & msg) } -void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost) -{ +bool Parser::parse_lines(MathAtom & t, bool numbered, bool outmost) +{ + MathGridInset * p = t->asGridInset(); + if (!p) { + lyxerr << "error in Parser::parse_lines() 1\n"; + return false; + } + const int cols = p->ncols(); // save global variables @@ -453,7 +464,11 @@ void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost) } if (outmost) { - MathMatrixInset * m = static_cast(p); + MathMatrixInset * m = t->asMatrixInset(); + if (!m) { + lyxerr << "error in Parser::parse_lines() 2\n"; + return false; + } m->numbered(row, curr_num_); m->label(row, curr_label_); if (curr_skip_.size()) { @@ -474,41 +489,46 @@ void Parser::parse_lines(MathGridInset * p, bool numbered, bool outmost) // restore "global" variables curr_num_ = saved_num; curr_label_ = saved_label; + + return true; } -MathMacroTemplate * Parser::parse_macro() +string Parser::parse_macro() { + string name = "{error}"; + while (nextToken().cat() == catSpace) getToken(); if (getToken().cs() != "newcommand") { lyxerr << "\\newcommand expected\n"; - return 0; + return name; } if (getToken().cat() != catBegin) { lyxerr << "'{' expected\n"; - return 0; + return name; } - string name = getToken().cs(); + name = getToken().cs(); if (getToken().cat() != catEnd) { lyxerr << "'}' expected\n"; - return 0; + return name; } - string arg = getArg('[', ']'); - int narg = arg.empty() ? 0 : atoi(arg.c_str()); - //lyxerr << "creating macro " << name << " with " << narg << "args\n"; - MathMacroTemplate * p = new MathMacroTemplate(name, narg); - parse_into(p->cell(0), FLAG_BRACE | FLAG_BRACE_LAST); - return p; + string arg = getArg('[', ']'); + int narg = arg.empty() ? 0 : atoi(arg.c_str()); + MathArray ar; + parse_into(ar, FLAG_BRACE | FLAG_BRACE_LAST); + MathMacroTable::create(name, narg, ar); + + return name; } -MathMatrixInset * Parser::parse_normal() +bool Parser::parse_normal(MathAtom & matrix) { while (nextToken().cat() == catSpace) getToken(); @@ -516,14 +536,14 @@ MathMatrixInset * Parser::parse_normal() Token const & t = getToken(); if (t.cat() == catMath || t.cs() == "(") { - MathMatrixInset * p = new MathMatrixInset(LM_OT_SIMPLE); - parse_into(p->cell(0), 0); - return p; + matrix = MathAtom(new MathMatrixInset(LM_OT_SIMPLE)); + parse_into(matrix->cell(0), 0); + return true; } if (!t.cs().size()) { lyxerr << "start of math expected, got '" << t << "'\n"; - return 0; + return false; } string const & cs = t.cs(); @@ -531,7 +551,8 @@ MathMatrixInset * Parser::parse_normal() if (cs == "[") { curr_num_ = 0; curr_label_.erase(); - MathMatrixInset * p = new MathMatrixInset(LM_OT_EQUATION); + matrix = MathAtom(new MathMatrixInset(LM_OT_EQUATION)); + MathMatrixInset * p = matrix->asMatrixInset(); parse_into(p->cell(0), 0); p->numbered(0, curr_num_); p->label(0, curr_label_); @@ -540,7 +561,7 @@ MathMatrixInset * Parser::parse_normal() if (cs != "begin") { lyxerr << "'begin' of un-simple math expected, got '" << cs << "'\n"; - return 0; + return false; } string const name = getArg('{', '}'); @@ -548,60 +569,54 @@ MathMatrixInset * Parser::parse_normal() if (name == "equation" || name == "equation*") { curr_num_ = !stared(name); curr_label_.erase(); - MathMatrixInset * p = new MathMatrixInset(LM_OT_EQUATION); + matrix = MathAtom(new MathMatrixInset(LM_OT_EQUATION)); + MathMatrixInset * p = matrix->asMatrixInset(); parse_into(p->cell(0), FLAG_END); p->numbered(0, curr_num_); p->label(0, curr_label_); - return p; + return true; } if (name == "eqnarray" || name == "eqnarray*") { - MathMatrixInset * p = new MathMatrixInset(LM_OT_EQNARRAY); - parse_lines(p, !stared(name), true); - return p; + matrix = MathAtom(new MathMatrixInset(LM_OT_EQNARRAY)); + return parse_lines(matrix, !stared(name), true); } if (name == "align" || name == "align*") { - MathMatrixInset * p = new MathMatrixInset(LM_OT_ALIGN); - parse_lines(p, !stared(name), true); - return p; + matrix = MathAtom(new MathMatrixInset(LM_OT_ALIGN)); + return parse_lines(matrix, !stared(name), true); } if (name == "alignat" || name == "alignat*") { - MathMatrixInset * p = - new MathMatrixInset(LM_OT_ALIGNAT, 2 * atoi(getArg('{', '}').c_str())); - parse_lines(p, !stared(name), true); - return p; + int nc = 2 * atoi(getArg('{', '}').c_str()); + matrix = MathAtom(new MathMatrixInset(LM_OT_ALIGNAT, nc)); + return parse_lines(matrix, !stared(name), true); } if (name == "xalignat" || name == "xalignat*") { - MathMatrixInset * p = - new MathMatrixInset(LM_OT_XALIGNAT, 2 * atoi(getArg('{', '}').c_str())); - parse_lines(p, !stared(name), true); - return p; + int nc = 2 * atoi(getArg('{', '}').c_str()); + matrix = MathAtom(new MathMatrixInset(LM_OT_XALIGNAT, nc)); + return parse_lines(matrix, !stared(name), true); } if (name == "xxalignat") { - MathMatrixInset * p = - new MathMatrixInset(LM_OT_XXALIGNAT, 2 * atoi(getArg('{', '}').c_str())); - parse_lines(p, !stared(name), true); - return p; + int nc = 2 * atoi(getArg('{', '}').c_str()); + matrix = MathAtom(new MathMatrixInset(LM_OT_XXALIGNAT, nc)); + return parse_lines(matrix, !stared(name), true); } if (name == "multline" || name == "multline*") { - MathMatrixInset * p = new MathMatrixInset(LM_OT_MULTLINE); - parse_lines(p, !stared(name), true); - return p; + matrix = MathAtom(new MathMatrixInset(LM_OT_MULTLINE)); + return parse_lines(matrix, !stared(name), true); } if (name == "gather" || name == "gather*") { - MathMatrixInset * p = new MathMatrixInset(LM_OT_GATHER); - parse_lines(p, !stared(name), true); - return p; + matrix = MathAtom(new MathMatrixInset(LM_OT_GATHER)); + return parse_lines(matrix, !stared(name), true); } lyxerr[Debug::MATHED] << "1: unknown math environment: " << name << "\n"; - return 0; + return false; } @@ -610,6 +625,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) MathTextCodes yyvarcode = LM_TC_MIN; bool panic = false; + int limits = 0; while (good()) { Token const & t = getToken(); @@ -658,45 +674,52 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) break; else if (t.cat() == catLetter) - array.push_back(new MathCharInset(t.character(), yyvarcode)); + add(array, t.character(), yyvarcode); else if (t.cat() == catSpace && (yyvarcode == LM_TC_TEXTRM || code == LM_TC_TEXTRM)) - array.push_back(new MathCharInset(' ', yyvarcode)); + add(array, ' ', yyvarcode); else if (t.cat() == catParameter) { Token const & n = getToken(); - MathMacroArgument * p = new MathMacroArgument(n.character() - '0'); - array.push_back(p); + array.push_back(MathAtom(new MathMacroArgument(n.character() - '0'))); } else if (t.cat() == catBegin) { - array.push_back(new MathCharInset('{', LM_TC_TEX)); + add(array, '{', LM_TC_TEX); } else if (t.cat() == catEnd) { if (flags & FLAG_BRACE_LAST) return; - array.push_back(new MathCharInset('}', LM_TC_TEX)); + add(array, '}', LM_TC_TEX); } else if (t.cat() == catAlign) { lyxerr << "found tab unexpectedly, array: '" << array << "'\n"; - array.push_back(new MathCharInset('&', LM_TC_TEX)); + add(array, '&', LM_TC_TEX); } else if (t.cat() == catSuper || t.cat() == catSub) { bool up = (t.cat() == catSuper); - if (array.empty()) - array.push_back(new MathCharInset(' ')); - parse_into(array.back().ensure(up)->cell(0), FLAG_ITEM); + MathScriptInset * p = 0; + if (array.size()) + p = array.back()->asScriptInset(); + if (!p || p->has(up)) { + array.push_back(MathAtom(new MathScriptInset(up))); + p = array.back()->asScriptInset(); + } + p->ensure(up); + parse_into(p->cell(up), FLAG_ITEM); + p->limits(limits); + limits = 0; } else if (t.character() == ']' && (flags & FLAG_BRACK_END)) return; else if (t.cat() == catOther) - array.push_back(new MathCharInset(t.character(), yyvarcode)); + add(array, t.character(), yyvarcode); // // codesequences @@ -722,11 +745,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) array.push_back(createMathInset("\\")); } - else if (t.cs() == "limits" && array.size()) - array.back().limits(1); + else if (t.cs() == "limits") + limits = 1; - else if (t.cs() == "nolimits" && array.size()) - array.back().limits(-1); + else if (t.cs() == "nolimits") + limits = -1; else if (t.cs() == "nonumber") curr_num_ = false; @@ -737,13 +760,13 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) else if (t.cs() == "sqrt") { char c = getChar(); if (c == '[') { - array.push_back(new MathRootInset); - parse_into(array.back().nucleus()->cell(0), FLAG_BRACK_END); - parse_into(array.back().nucleus()->cell(1), FLAG_ITEM); + array.push_back(MathAtom(new MathRootInset)); + parse_into(array.back()->cell(0), FLAG_BRACK_END); + parse_into(array.back()->cell(1), FLAG_ITEM); } else { putback(); - array.push_back(new MathSqrtInset); - parse_into(array.back().nucleus()->cell(0), FLAG_ITEM); + array.push_back(MathAtom(new MathSqrtInset)); + parse_into(array.back()->cell(0), FLAG_ITEM); } } @@ -752,7 +775,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) MathArray ar; parse_into(ar, FLAG_RIGHT); string r = getToken().asString(); - MathDelimInset * dl = new MathDelimInset(l, r); + MathAtom dl(new MathDelimInset(l, r)); dl->cell(0) = ar; array.push_back(dl); } @@ -783,15 +806,12 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) if (name == "array") { string const valign = getArg('[', ']') + 'c'; string const halign = getArg('{', '}'); - MathArrayInset * m = new MathArrayInset(halign.size(), 1); - m->valign(valign[0]); - m->halign(halign); - parse_lines(m, false, false); - array.push_back(m); + array.push_back( + MathAtom(new MathArrayInset(halign.size(), 1, valign[0], halign))); + parse_lines(array.back(), false, false); } else if (name == "split") { - MathSplitInset * m = new MathSplitInset(1); - parse_lines(m, false, false); - array.push_back(m); + array.push_back(MathAtom(new MathSplitInset(1))); + parse_lines(array.back(), false, false); } else lyxerr[Debug::MATHED] << "unknow math inset begin '" << name << "'\n"; } @@ -811,7 +831,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) if (isValidLength(s)) break; } - array.push_back(new MathKernInset(s)); + array.push_back(MathAtom(new MathKernInset(s))); } else if (t.cs() == "label") { @@ -825,11 +845,11 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) } else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") { - MathInset * p = createMathInset(t.cs()); + MathAtom p = createMathInset(t.cs()); // search backward for position of last '{' if any int pos; for (pos = array.size() - 1; pos >= 0; --pos) - if (array.at(pos)->nucleus()->getChar() == '{') + if (array.at(pos)->getChar() == '{') break; if (pos >= 0) { // found it -> use the part after '{' as "numerator" @@ -849,7 +869,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) p->cell(0).swap(array); parse_into(p->cell(1), FLAG_BLOCK); } - array.push_back(p); + array.push_back(MathAtom(p)); } else if (t.cs().size()) { @@ -867,7 +887,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) MathArray ar; parse_into(ar, FLAG_ITEM, t); for (MathArray::iterator it = ar.begin(); it != ar.end(); ++it) - it->nucleus()->handleFont(t); + (*it)->handleFont(t); array.push_back(ar); // undo catcode changes @@ -879,7 +899,7 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) yyvarcode = static_cast(l->id); else { - MathInset * p = createMathInset(t.cs()); + MathAtom p = createMathInset(t.cs()); for (MathInset::idx_type i = 0; i < p->nargs(); ++i) parse_into(p->cell(i), FLAG_ITEM); array.push_back(p); @@ -887,16 +907,10 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) } else { - MathInset * p = createMathInset(t.cs()); - if (p) { - for (MathInset::idx_type i = 0; i < p->nargs(); ++i) - parse_into(p->cell(i), FLAG_ITEM); - array.push_back(p); - } else { - error("Unrecognized token"); - //lyxerr[Debug::MATHED] << "[" << t << "]\n"; - lyxerr << t << "\n"; - } + MathAtom p = createMathInset(t.cs()); + for (MathInset::idx_type i = 0; i < p->nargs(); ++i) + parse_into(p->cell(i), FLAG_ITEM); + array.push_back(p); } } @@ -917,6 +931,8 @@ void Parser::parse_into(MathArray & array, unsigned flags, MathTextCodes code) } } + + } // anonymous namespace @@ -932,20 +948,20 @@ MathArray mathed_parse_cell(string const & str) -MathMacroTemplate * mathed_parse_macro(string const & str) +string mathed_parse_macro(string const & str) { istringstream is(str.c_str()); Parser parser(is); return parser.parse_macro(); } -MathMacroTemplate * mathed_parse_macro(istream & is) +string mathed_parse_macro(istream & is) { Parser parser(is); return parser.parse_macro(); } -MathMacroTemplate * mathed_parse_macro(LyXLex & lex) +string mathed_parse_macro(LyXLex & lex) { Parser parser(lex); return parser.parse_macro(); @@ -953,21 +969,21 @@ MathMacroTemplate * mathed_parse_macro(LyXLex & lex) -MathMatrixInset * mathed_parse_normal(string const & str) +bool mathed_parse_normal(MathAtom & t, string const & str) { istringstream is(str.c_str()); Parser parser(is); - return parser.parse_normal(); + return parser.parse_normal(t); } -MathMatrixInset * mathed_parse_normal(istream & is) +bool mathed_parse_normal(MathAtom & t, istream & is) { Parser parser(is); - return parser.parse_normal(); + return parser.parse_normal(t); } -MathMatrixInset * mathed_parse_normal(LyXLex & lex) +bool mathed_parse_normal(MathAtom & t, LyXLex & lex) { Parser parser(lex); - return parser.parse_normal(); + return parser.parse_normal(t); } diff --git a/src/mathed/math_parser.h b/src/mathed/math_parser.h index 067d59b313..cf06a946ce 100644 --- a/src/mathed/math_parser.h +++ b/src/mathed/math_parser.h @@ -28,6 +28,8 @@ class MathMatrixInset; class MathMacroTemplate; +class MathAtom; +class MathArray; class LyXLex; /// @@ -133,12 +135,12 @@ latexkeys const * in_word_set(string const & str); /// void ReadSymbols(string const & file); -MathMatrixInset * mathed_parse_normal(string const &); -MathMatrixInset * mathed_parse_normal(std::istream &); -MathMatrixInset * mathed_parse_normal(LyXLex &); +bool mathed_parse_normal(MathAtom &, string const &); +bool mathed_parse_normal(MathAtom &, std::istream &); +bool mathed_parse_normal(MathAtom &, LyXLex &); -MathMacroTemplate * mathed_parse_macro(string const &); -MathMacroTemplate * mathed_parse_macro(std::istream &); -MathMacroTemplate * mathed_parse_macro(LyXLex &); +string mathed_parse_macro(string const &); +string mathed_parse_macro(std::istream &); +string mathed_parse_macro(LyXLex &); #endif diff --git a/src/mathed/math_rootinset.C b/src/mathed/math_rootinset.C index 5e2cf7c7ea..4760854461 100644 --- a/src/mathed/math_rootinset.C +++ b/src/mathed/math_rootinset.C @@ -79,15 +79,17 @@ void MathRootInset::writeNormal(std::ostream & os) const os << "] "; } + bool MathRootInset::idxUp(int & idx, int & pos) const { if (idx == 0) return false; idx = 0; - pos = 0; + pos = cell(0).size(); return true; } + bool MathRootInset::idxDown(int & idx, int & pos) const { if (idx == 1) diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 5fc4110ca4..305d22c86a 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -1,6 +1,8 @@ #include #include "debug.h" +#include "support.h" #include "support/LOstream.h" +#include "support/LAssert.h" #ifdef __GNUG__ #pragma implementation @@ -9,9 +11,21 @@ #include "math_scriptinset.h" +MathScriptInset::MathScriptInset() + : MathNestInset(2), limits_(0) +{ + script_[0] = false; + script_[1] = false; +} + + MathScriptInset::MathScriptInset(bool up) - : MathNestInset(1), up_(up) -{} + : MathNestInset(2), limits_(0) +{ + script_[0] = !up; + script_[1] = up; +} + MathInset * MathScriptInset::clone() const @@ -25,27 +39,258 @@ MathScriptInset const * MathScriptInset::asScriptInset() const return this; } -void MathScriptInset::write(std::ostream & os, bool fragile) const + +MathScriptInset * MathScriptInset::asScriptInset() { - cell(0).write(os, fragile); + return this; } -void MathScriptInset::metrics(MathStyles st) const +MathXArray const & MathScriptInset::up() const { - size_ = st; - xcell(0).metrics(st); - width_ = xcell(0).width(); - ascent_ = xcell(0).ascent(); - descent_ = xcell(0).descent(); - //lyxerr << "MathScriptInset::metrics: w: " << width_ << " a: " << ascent_ - // << " d: " << descent_ << "\n"; + return xcell(1); } -void MathScriptInset::draw(Painter & pain, int x, int y) const +MathXArray const & MathScriptInset::down() const +{ + return xcell(0); +} + + +MathXArray & MathScriptInset::up() +{ + return xcell(1); +} + + +MathXArray & MathScriptInset::down() { + return xcell(0); +} + + +void MathScriptInset::ensure(bool up) +{ + script_[up] = true; +} + + +int MathScriptInset::dy0(MathInset const * nuc) const +{ + 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; +} + + +int MathScriptInset::dy1(MathInset const * nuc) const +{ + 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, LM_ST_TEXT, 'I')); + return asc; +} + + +int MathScriptInset::dx0(MathInset const * nuc) const +{ + lyx::Assert(hasDown()); + return hasLimits(nuc) ? (width(nuc) - down().width()) / 2 : nwid(nuc); +} + + +int MathScriptInset::dx1(MathInset const * nuc) const +{ + lyx::Assert(hasUp()); + return hasLimits(nuc) ? (width(nuc) - up().width()) / 2 : nwid(nuc); +} + + +int MathScriptInset::dxx(MathInset const * nuc) const +{ + //lyx::Assert(nuc()); + return hasLimits(nuc) ? (width(nuc) - nwid(nuc)) / 2 : 0; +} + + +int MathScriptInset::ascent(MathInset const * nuc) const +{ + return dy1(nuc) + (hasUp() ? up().ascent() : 0); +} + + +int MathScriptInset::descent(MathInset const * nuc) const +{ + return dy0(nuc) + (hasDown() ? down().descent() : 0); +} + + +int MathScriptInset::width(MathInset const * nuc) const +{ + 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; +} + + +int MathScriptInset::nwid(MathInset const * nuc) const +{ + return nuc ? + nuc->width() : + mathed_char_width(LM_TC_TEX, LM_ST_TEXT, '.'); +} + + +int MathScriptInset::nasc(MathInset const * nuc) const +{ + return nuc ? nuc->ascent() + : mathed_char_ascent(LM_TC_VAR, LM_ST_TEXT, 'I'); +} + + +int MathScriptInset::ndes(MathInset const * nuc) const +{ + return nuc ? nuc->descent() + : mathed_char_descent(LM_TC_VAR, LM_ST_TEXT, 'I'); +} + + +void MathScriptInset::metrics(MathStyles st) const +{ + metrics(0, st); +} + + +void MathScriptInset::metrics(MathInset const * nuc, MathStyles st) const +{ + MathNestInset::metrics(st); + if (nuc) + nuc->metrics(st); + + ascent_ = ascent(nuc); + descent_ = descent(nuc); + width_ = width(nuc); +} + + +void MathScriptInset::draw(Painter & pain, int x, int y) const +{ + //lyxerr << "unexpected call to MathScriptInset::draw()\n"; + draw(0, pain, x, y); +} + + +void MathScriptInset::draw(MathInset const * nuc, Painter & pain, + int x, int y) const +{ xo(x); yo(y); - xcell(0).draw(pain, x, y); + if (nuc) + nuc->draw(pain, x + dxx(nuc), y); + else + drawStr(pain, LM_TC_TEX, LM_ST_TEXT, 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)); +} + + +void MathScriptInset::write(std::ostream & os, bool fragile) const +{ + //lyxerr << "unexpected call to MathScriptInset::write()\n"; + write(0, os, fragile); +} + + +void MathScriptInset::write(MathInset const * nuc, std::ostream & os, + bool fragile) const +{ + if (nuc) { + nuc->write(os, fragile); + if (nuc->takesLimits()) { + if (limits_ == -1) + os << "\\nolimits "; + if (limits_ == 1) + os << "\\limits "; + } + } + else + os << "{}"; + + if (hasDown() && down().data_.size()) { + os << "_{"; + down().data_.write(os, fragile); + os << "}"; + } + + if (hasUp() && up().data_.size()) { + os << "^{"; + up().data_.write(os, fragile); + os << "}"; + } +} + + +bool MathScriptInset::hasLimits(MathInset const * nuc) const +{ + return limits_ == 1 || (limits_ == 0 && nuc && nuc->isScriptable()); +} + + +void MathScriptInset::removeEmptyScripts() +{ + for (int i = 0; i <= 1; ++i) + if (script_[i] && !cell(i).size()) + script_[i] = false; +} + + +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]; } diff --git a/src/mathed/math_scriptinset.h b/src/mathed/math_scriptinset.h index 491d5a0e90..d4c5e62f40 100644 --- a/src/mathed/math_scriptinset.h +++ b/src/mathed/math_scriptinset.h @@ -14,6 +14,8 @@ class MathScriptInset : public MathNestInset { public: + /// + MathScriptInset(); /// explicit MathScriptInset(bool up); /// @@ -24,15 +26,75 @@ public: void metrics(MathStyles st) const; /// void draw(Painter &, int x, int y) const; + + /// + void write(MathInset const * nucleus, std::ostream &, bool fragile) const; + /// + void metrics(MathInset const * nucleus, MathStyles st) const; + /// + void draw(MathInset const * nucleus, Painter &, int x, int y) const; + /// + int ascent(MathInset const * nucleus) const; + /// + int descent(MathInset const * nucleus) const; + /// + int width(MathInset const * nucleus) const; + /// MathScriptInset const * asScriptInset() const; /// - bool up() const { return up_; } + MathScriptInset * asScriptInset(); + + /// set limits + void limits(int lim) { limits_ = lim; } + /// + int limits() const { return limits_; } + /// + bool hasLimits(MathInset const * nucleus) const; + /// 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(); + /// do we have a superscript? + bool hasUp() const; + /// do we have a subscript? + bool hasDown() const; + /// do we have a script? + bool has(bool up) const; + /// remove script + void removeScript(bool up); + /// remove script + void removeEmptyScripts(); /// - bool down() const { return !up_; } + void ensure(bool up); + +public: + /// returns x offset for main part + int dxx(MathInset const * nuc) const; + /// returns width of nucleus if any + int nwid(MathInset const * nuc) const; private: + /// returns y offset for superscript + int dy0(MathInset const * nuc) const; + /// returns y offset for subscript + int dy1(MathInset const * nuc) const; + /// returns x offset for superscript + int dx0(MathInset const * nuc) const; + /// returns x offset for subscript + int dx1(MathInset const * nuc) const; + /// returns ascent of nucleus if any + int nasc(MathInset const * nuc) const; + /// returns descent of nucleus if any + int ndes(MathInset const * nuc) const; + + /// possible subscript (index 0) and superscript (index 1) + bool script_[2]; /// - bool up_; + int limits_; }; #endif diff --git a/src/mathed/math_spaceinset.h b/src/mathed/math_spaceinset.h index b8afcb568b..96b43441f9 100644 --- a/src/mathed/math_spaceinset.h +++ b/src/mathed/math_spaceinset.h @@ -25,7 +25,9 @@ public: /// void metrics(MathStyles st) const; /// - bool isSpaceInset() const { return true; } + MathSpaceInset const * asSpaceInset() const { return this; } + /// + MathSpaceInset * asSpaceInset() { return this; } /// void incSpace(); private: diff --git a/src/mathed/xarray.C b/src/mathed/xarray.C index 2faafbed91..6f3ff8b3ca 100644 --- a/src/mathed/xarray.C +++ b/src/mathed/xarray.C @@ -6,6 +6,7 @@ #include "xarray.h" #include "math_inset.h" +#include "math_scriptinset.h" #include "mathed/support.h" #include "math_defs.h" #include "Painter.h" @@ -29,12 +30,21 @@ void MathXArray::metrics(MathStyles st) const width_ = 0; //lyxerr << "MathXArray::metrics(): '" << data_ << "'\n"; - for (size_type pos = 0; pos < data_.size(); ++pos) { - MathAtom const * p = data_.at(pos); - p->metrics(st); - ascent_ = std::max(ascent_, p->ascent()); - descent_ = std::max(descent_, p->descent()); - width_ += p->width(); + + for (const_iterator it = begin(); it != end(); ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + q->metrics(p, st); + ascent_ = std::max(ascent_, q->ascent(p)); + descent_ = std::max(descent_, q->descent(p)); + width_ += q->width(p); + ++it; + } else { + p->metrics(st); + ascent_ = std::max(ascent_, p->ascent()); + descent_ = std::max(descent_, p->descent()); + width_ += p->width(); + } } //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " // << descent_ << " " << width_ << "'\n"; @@ -51,52 +61,60 @@ void MathXArray::draw(Painter & pain, int x, int y) const return; } - for (size_type pos = 0; pos < data_.size(); ++pos) { - MathAtom const * p = data_.at(pos); - p->draw(pain, x, y); - x += p->width(); + for (const_iterator it = begin(); it != end(); ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + q->draw(p, pain, x, y); + x += q->width(p); + ++it; + } else { + p->draw(pain, x, y); + x += p->width(); + } } } -int MathXArray::pos2x(size_type targetpos, bool inner) const +int MathXArray::pos2x(size_type targetpos) const { int x = 0; - targetpos = std::min(targetpos, data_.size()); - for (size_type pos = 0; pos < targetpos; ++pos) - x += width(pos); - if (inner) - x += innerwidth(targetpos); + const_iterator target = std::min(begin() + targetpos, end()); + for (const_iterator it = begin(); it < target; ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + ++it; + if (it < target) + x += q->width(p); + else // "half" position + x += q->dxx(p) + q->nwid(p); + } else + x += p->width(); + } return x; } MathArray::size_type MathXArray::x2pos(int targetx) const { - size_type pos = 0; - int lastx = 0; - int currx = 0; - for ( ; currx < targetx && pos < data_.size(); ++pos) { + const_iterator it = begin(); + int lastx = 0; + int currx = 0; + for ( ; currx < targetx && it < end(); ++it) { lastx = currx; - currx += width(pos); - } - if (abs(lastx - targetx) < abs(currx - targetx) && pos > 0) - --pos; - return pos; -} + int wid = 0; + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + wid = q->width(p); + ++it; + } else + wid = p->width(); -int MathXArray::width(size_type pos) const -{ - MathAtom const * t = data_.at(pos); - return t ? t->width() : 0; -} - - -int MathXArray::innerwidth(size_type pos) const -{ - MathAtom const * t = data_.at(pos); - return t ? t->nwid() : 0; + currx += wid; + } + if (abs(lastx - targetx) < abs(currx - targetx) && it != begin()) + --it; + return it - begin(); } diff --git a/src/mathed/xarray.h b/src/mathed/xarray.h index ba5d073d7c..8627f5e62e 100644 --- a/src/mathed/xarray.h +++ b/src/mathed/xarray.h @@ -17,7 +17,9 @@ class MathXArray { public: /// - typedef MathArray::size_type size_type; + typedef MathArray::size_type size_type; + /// + typedef MathArray::const_iterator const_iterator; /// MathXArray(); @@ -31,13 +33,9 @@ public: /// int yo() const { return yo_; } /// - int pos2x(size_type pos, bool inner) const; + int pos2x(size_type pos) const; /// size_type x2pos(int pos) const; - /// - int width(size_type pos) const; - /// - int innerwidth(size_type pos) const; /// int ascent() const { return ascent_; } @@ -49,8 +47,13 @@ public: int width() const { return width_; } /// MathStyles style() const { return style_; } - + /// + const_iterator begin() const { return data_.begin(); } + /// + const_iterator end() const { return data_.end(); } + +public: /// MathArray data_; /// -- 2.39.2