mathed_char_dim(font_, char_, dim_);
if (isBinaryOp(char_, code_))
width_ += 2 * font_metrics::width(' ', font_);
+ lyxerr << "MathCharInset::metrics: " << dim_ << "\n";
#endif
}
if (t->lock())
return false;
- if (t->asScriptInset())
- return false;
-
if (sel) {
// we can't move into anything new during selection
if (depth() == Anchor_.size())
}
+bool MathCursor::inNucleus() const
+{
+ return par()->asScriptInset() && idx() == 2;
+}
+
+
bool MathCursor::posLeft()
{
+ if (inNucleus())
+ return false;
if (pos() == 0)
return false;
--pos();
formula()->xlow(), formula()->xhigh(),
formula()->ylow(), formula()->yhigh());
if (!res) {
- // this ccan happen on creation of "math-display"
+ // this can happen on creation of "math-display"
dump("setPos 1.5");
first();
}
+ targetx_ = -1; // "no target"
dump("setPos 2");
}
if (!par()->idxHome(idx(), pos()))
return popLeft();
dump("home 2");
+ targetx_ = -1; // "no target"
return true;
}
if (!par()->idxEnd(idx(), pos()))
return popRight();
dump("end 2");
+ targetx_ = -1; // "no target"
return true;
}
for (row_type row = 0; row < numrows; ++row) {
for (col_type col = 0; col < numcols; ++col) {
idx_type i = p->index(row + p->row(idx), col + p->col(idx));
- p->cell(i).push_back(data.cell(data.index(row, col)));
+ p->cell(i).append(data.cell(data.index(row, col)));
}
// append the left over horizontal cells to the last column
idx_type i = p->index(row + p->row(idx), p->ncols() - 1);
for (MathInset::col_type col = numcols; col < data.ncols(); ++col)
- p->cell(i).push_back(data.cell(data.index(row, col)));
+ p->cell(i).append(data.cell(data.index(row, col)));
}
// append the left over vertical cells to the last _cell_
idx_type i = p->nargs() - 1;
for (row_type row = numrows; row < data.nrows(); ++row)
for (col_type col = 0; col < data.ncols(); ++col)
- p->cell(i).push_back(data.cell(data.index(row, col)));
+ p->cell(i).append(data.cell(data.index(row, col)));
}
}
+
void MathCursor::backspace()
{
autocorrect_ = false;
return;
}
- MathScriptInset * p = prevAtom()->asScriptInset();
- if (p) {
- p->removeScript(p->hasUp());
- // Don't delete if there is anything left
- if (p->hasUp() || p->hasDown())
- return;
+ if (prevAtom()->asScriptInset()) {
+ // simply enter nucleus
+ left();
+ return;
+ }
+
+ if (inNucleus()) {
+ // we are in nucleus
+ if (pos() == 1) {
+ }
}
--pos();
return;
}
- MathScriptInset * p = nextAtom()->asScriptInset();
- if (p) {
- p->removeScript(p->hasUp());
- // Don't delete if there is anything left
- if (p->hasUp() || p->hasDown())
- return;
+ // if we are standing in front of a script inset, grab item before us and
+ // move it into nucleus
+ // and remove first thing.
+ if (hasNextAtom() && nextAtom()->asScriptInset()) {
+ if (hasPrevAtom()) {
+ MathAtom at = prevAtom();
+ --pos();
+ array().erase(pos());
+ pushLeft(nextAtom());
+ if (array().empty())
+ array().push_back(at);
+ else
+ array()[0] = at;
+ pos() = 1;
+ } else {
+ pushLeft(nextAtom());
+ array().clear();
+ }
+ return;
}
plainErase();
void MathCursor::selClear()
{
+ Anchor_.clear();
selection_ = false;
}
{
dump("pullarg");
MathArray a = array();
-
- MathScriptInset const * p = par()->asScriptInset();
- if (p) {
- // special handling for scripts
- const bool up = p->hasUp();
- popLeft();
- MathScriptInset * q = nextAtom()->asScriptInset();
- if (q)
- q->removeScript(up);
- ++pos();
- array().insert(pos(), a);
- return;
- }
-
if (popLeft()) {
plainErase();
array().insert(pos(), a);
{
if (idx() >= par()->nargs()) {
lyxerr << "this should not really happen - 1: "
- << idx() << " " << par()->nargs() << "\n";
+ << idx() << " " << par()->nargs() << " in: " << par() << "\n";
dump("error 2");
}
idx() = min(idx(), par()->nargs() - 1);
// split line
const row_type r = hullRow();
for (col_type c = hullCol() + 1; c < p->ncols(); ++c)
- p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c)));
+ std::swap(p->cell(p->index(r, c)), p->cell(p->index(r + 1, c)));
// split cell
splitCell();
- p->cell(idx()).swap(p->cell(idx() + p->ncols() - 1));
+ std::swap(p->cell(idx()), p->cell(idx() + p->ncols() - 1));
}
}
// Be warned: The 'logic' implemented in this function is highly fragile.
// A distance of one pixel or a '<' vs '<=' _really_ matters.
// So fiddle around with it only if you know what you are doing!
- int xlow, xhigh, ylow, yhigh;
-
int xo, yo;
getPos(xo, yo);
while (1) {
///lyxerr << "updown: We are in " << *par() << " idx: " << idx() << '\n';
// ask inset first
- if (par()->idxUpDown(idx(), pos(), up)) {
-#ifdef WITH_WARNINGS
-#warning this code should be moved to individual insets that handle this
-#endif
- // position might have changed, so re-compute it
- getPos(xo, yo);
- // we found a cell that thinks it has something "below" us.
- //lyxerr << "updown: found inset that handles UpDown\n";
- xarray().boundingBox(xlow, xhigh, ylow, yhigh);
- // project (xo,yo) onto proper box
- //lyxerr << "\n xo: " << xo << " yo: " << yo
- // << "\n xlow: " << xlow << " ylow: " << ylow
- // << "\n xhigh: " << xhigh << " yhigh: " << yhigh;
- xo = min(max(xo, xlow), xhigh);
- yo = min(max(yo, ylow), yhigh);
- //lyxerr << "\n xo2: " << xo << " yo2: " << yo << "\n";
- bruteFind(xo, yo, xlow, xhigh, ylow, yhigh);
- //lyxerr << "updown: handled by final brute find\n";
+ if (par()->idxUpDown(idx(), pos(), up, targetx_))
return true;
- }
- // leave inset
- if (!popLeft()) {
- // no such inset found, just take something "above"
- ///lyxerr << "updown: handled by strange case\n";
+ // no such inset found, just take something "above"
+ ///lyxerr << "updown: handled by strange case\n";
+ if (!popLeft())
return
bruteFind(xo, yo,
formula()->xlow(),
up ? formula()->ylow() : yo + 4,
up ? yo - 4 : formula()->yhigh()
);
- }
// any improvement so far?
int xnew, ynew;
string name = s.substr(1);
if (name == "over" || name == "choose" || name == "atop") {
- MathArray ar = array();
MathAtom t(createMathInset(name));
- t->asNestInset()->cell(0).swap(array());
+ t->asNestInset()->cell(0) = array();
+ array().clear();
pos() = 0;
niceInsert(t);
popRight();
macroModeClose();
MathGridInset safe = grabAndEraseSelection();
- if (hasPrevAtom() && prevAtom()->asScriptInset()) {
+ if (inNucleus()) {
+ // we are in a nucleus of a script inset, move to _our_ script
+ par()->asScriptInset()->ensure(up);
+ idx() = up;
+ pos() = 0;
+ } else if (hasPrevAtom() && prevAtom()->asScriptInset()) {
prevAtom()->asScriptInset()->ensure(up);
pushRight(prevAtom());
idx() = up;
pos() = size();
- } else if (hasNextAtom() && nextAtom()->asScriptInset()) {
- nextAtom()->asScriptInset()->ensure(up);
+ } else if (hasPrevAtom()) {
+ --pos();
+ array()[pos()] = MathAtom(new MathScriptInset(nextAtom(), up));
pushLeft(nextAtom());
idx() = up;
pos() = 0;
// shouldn't we assert on i1.par_ == i2.par_?
if (i1.idx_ == i2.idx_) {
MathGridInset data(1, 1);
- data.cell(0) = MathArray(i1.cell(), i1.pos_, i2.pos_);
+ MathArray::const_iterator it = i1.cell().begin();
+ data.cell(0) = MathArray(it + i1.pos_, it + i2.pos_);
return data;
}
row_type r1, r2;
region(i1, i2, r1, r2, c1, c2);
for (row_type row = r1; row <= r2; ++row)
for (col_type col = c1; col <= c2; ++col)
- p->cell(p->index(row, col)).erase();
+ p->cell(p->index(row, col)).clear();
}
cursor() = i1;
}
ar = array();
lyxerr << "use whole cell: " << ar << "\n";
} else {
- ar = MathArray(array(), pos + 1, size());
+ ar = MathArray(array().begin() + pos + 1, array().end());
lyxerr << "use partial cell form pos: " << pos << "\n";
}
end();
bool goUpDown(bool up);
/// moves position into box
bool bruteFind(int xo, int yo, int xlow, int xhigh, int ylow, int yhigh);
+ /// are we in a nucleus of a script inset?
+ bool inNucleus() const;
/// grab grid marked by anchor and current cursor
#include "support/LAssert.h"
-MathArray::MathArray()
-{}
-
-
-MathArray::MathArray(MathArray const & ar, size_type from, size_type to)
- : bf_(ar.begin() + from, ar.begin() + to)
-{}
-
-
-MathArray::MathArray(iterator from, iterator to)
- : bf_(from, to)
+MathArray::MathArray(const_iterator from, const_iterator to)
+ : base_type(from, to)
{}
}
-MathAtom & MathArray::at(size_type pos)
+MathAtom & MathArray::operator[](size_type pos)
{
lyx::Assert(pos < size());
- return bf_[pos];
+ return base_type::operator[](pos);
}
-MathAtom const & MathArray::at(size_type pos) const
+MathAtom const & MathArray::operator[](size_type pos) const
{
lyx::Assert(pos < size());
- return bf_[pos];
+ return base_type::operator[](pos);
}
void MathArray::insert(size_type pos, MathAtom const & t)
{
- bf_.insert(begin() + pos, t);
+ base_type::insert(begin() + pos, t);
}
void MathArray::insert(size_type pos, MathArray const & ar)
{
- bf_.insert(begin() + pos, ar.begin(), ar.end());
-}
-
-
-void MathArray::push_back(MathAtom const & t)
-{
- bf_.push_back(t);
+ base_type::insert(begin() + pos, ar.begin(), ar.end());
}
-void MathArray::push_back(MathArray const & ar)
+void MathArray::append(MathArray const & ar)
{
insert(size(), ar);
}
-void MathArray::clear()
-{
- erase();
-}
-
-
-void MathArray::swap(MathArray & ar)
-{
- if (this != &ar)
- bf_.swap(ar.bf_);
-}
-
-
-bool MathArray::empty() const
-{
- return bf_.empty();
-}
-
-
-MathArray::size_type MathArray::size() const
-{
- return bf_.size();
-}
-
-
-void MathArray::erase()
-{
- bf_.erase(begin(), end());
-}
-
-
void MathArray::erase(size_type pos)
{
if (pos < size())
void MathArray::erase(iterator pos1, iterator pos2)
{
- bf_.erase(pos1, pos2);
+ base_type::erase(pos1, pos2);
}
void MathArray::erase(iterator pos)
{
- bf_.erase(pos);
+ base_type::erase(pos);
}
void MathArray::erase(size_type pos1, size_type pos2)
{
- bf_.erase(begin() + pos1, begin() + pos2);
-}
-
-
-MathAtom & MathArray::back()
-{
- return bf_.back();
-}
-
-
-MathAtom & MathArray::front()
-{
- return bf_.front();
-}
-
-
-MathAtom const & MathArray::front() const
-{
- return bf_.front();
+ base_type::erase(begin() + pos1, begin() + pos2);
}
}
-void MathArray::pop_back()
-{
- if (!size()) {
- lyxerr << "pop_back from empty array!\n";
- return;
- }
- bf_.pop_back();
-}
-
-
-MathArray::const_iterator MathArray::begin() const
-{
- return bf_.begin();
-}
-
-
-MathArray::const_iterator MathArray::end() const
-{
- return bf_.end();
-}
-
-
-MathArray::iterator MathArray::begin()
-{
- return bf_.begin();
-}
-
-
-MathArray::iterator MathArray::end()
-{
- return bf_.end();
-}
-
-
bool MathArray::match(MathArray const & ar) const
{
return size() == ar.size() && matchpart(ar, 0);
{
//lyxerr << "finding '" << ar << "' in '" << *this << "'\n";
for (size_type i = 0, n = ar.size(); i < n; ++i)
- if (!at(pos + i)->match(ar[i].nucleus()))
+ if (!operator[](pos + i)->match(ar[i].nucleus()))
return false;
return true;
}
\version February 2001
*/
-class MathArray {
+class MathArray : private std::vector<MathAtom> {
public:
- ///
- typedef std::vector<MathAtom> buffer_type;
- ///
- typedef buffer_type::const_iterator const_iterator;
- ///
- typedef buffer_type::iterator iterator;
- ///
- typedef buffer_type::size_type size_type;
- ///
- typedef buffer_type::difference_type difference_type;
- ///
- typedef buffer_type::size_type idx_type;
- ///
- typedef buffer_type::size_type pos_type;
-
+ /// re-use inhertited stuff
+ typedef std::vector<MathAtom> base_type;
+ using base_type::const_iterator;
+ using base_type::iterator;
+ using base_type::size_type;
+ using base_type::difference_type;
+ using base_type::size;
+ using base_type::empty;
+ using base_type::clear;
+ using base_type::begin;
+ using base_type::end;
+ using base_type::push_back;
+ using base_type::pop_back;
+ using base_type::back;
+ using base_type::front;
+ using base_type::swap;
+ ///
+ typedef size_type idx_type;
+ typedef size_type pos_type;
+
public:
///
- MathArray();
+ MathArray() {}
///
- MathArray(MathArray const & ar, size_type from, size_type to);
+ MathArray(const_iterator from, const_iterator to);
///
- MathArray(iterator from, iterator to);
-
- ///
- size_type size() const;
- ///
- bool empty() const;
- ///
- void clear();
- ///
- void swap(MathArray &);
+ void append(MathArray const & ar);
/// inserts single atom at position pos
void insert(size_type pos, MathAtom const & at);
void erase(size_type pos1, size_type pos2);
/// erase single atom
void erase(size_type pos);
- /// erase everythng
- void erase();
-
- ///
- void push_back(MathAtom const & at);
- ///
- void push_back(MathArray const & ar);
- ///
- void pop_back();
- ///
- MathAtom & back();
-
- ///
- MathAtom & front();
- ///
- MathAtom const & front() const;
///
void dump() const;
size_type find_last(MathArray const & ar) const;
///
bool contains(MathArray const & ar) const;
-
- /// write acccess to single atom
- MathAtom & operator[](size_type pos) { return at(pos); }
- /// read access o single atom
- MathAtom const & operator[](size_type pos) const { return at(pos); }
- ///
- const_iterator begin() const;
- ///
- const_iterator end() const;
- ///
- iterator begin();
- ///
- iterator end();
-
///
void validate(LaTeXFeatures &) const;
+ /// checked write access
+ MathAtom & operator[](pos_type);
+ /// checked read access
+ MathAtom const & operator[](pos_type) const;
private:
/// is this an exact match at this position?
bool find1(MathArray const & ar, size_type pos) const;
- /// write acccess to single atom
- MathAtom & at(size_type pos);
- /// read access o single atom
- MathAtom const & at(size_type pos) const;
-
- /// Buffer
- buffer_type bf_;
};
///
#include "textpainter.h"
-void MathDimInset::dimensions(Dimension & dim) const
-{
- dim = dim_;
-}
-
-
void MathDimInset::metricsT(TextMetricsInfo const &) const
{
std::ostringstream os;
/// read width
int width() const { return dim_.width(); }
///
- void dimensions(Dimension & dim) const;
+ Dimension dimensions() const { return dim_; }
///
void metricsT(TextMetricsInfo const &) const;
///
}
-MathScriptInset const * asScript(MathArray::const_iterator it)
-{
- if (!it->nucleus())
- return 0;
- if (it->nucleus()->asScriptInset())
- return 0;
- ++it;
- if (!it->nucleus())
- return 0;
- return it->nucleus()->asScriptInset();
-}
-
-
-
// returns sequence of char with same code starting at it up to end
// it might be less, though...
string charSequence
// create extra script inset and move superscript over
MathScriptInset * q = new MathScriptInset;
q->ensure(true);
- q->up().data().swap(p->up().data());
+ std::swap(q->up(), p->up());
p->removeScript(true);
// insert new inset behind
continue;
// the -> splits the subscript int x and x0
- MathArray x = MathArray(s, 0, st - s.begin());
- MathArray x0 = MathArray(s, st - s.begin() + 1, s.size());
+ MathArray x = MathArray(s.begin(), st);
+ MathArray x0 = MathArray(st + 1, s.end());
// use something behind the script as core
MathArray f;
{
MathArray ar = dat;
extractStrings(ar);
- for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
- wi.firstitem() = (it == ar.begin());
- MathInset const * p = it->nucleus();
- if (it + 1 != ar.end()) {
- if (MathScriptInset const * q = asScript(it)) {
- q->write2(p, wi);
- ++it;
- continue;
- }
- }
- p->write(wi);
- }
+ for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+ (*it)->write(wi);
}
{
MathArray ar = dat;
extractStructure(ar);
- for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (it + 1 != ar.end()) {
- if (MathScriptInset const * q = asScript(it)) {
- q->octavize2(p, os);
- ++it;
- continue;
- }
- }
- p->octavize(os);
- }
+ for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+ (*it)->octavize(os);
}
{
MathArray ar = dat;
extractStructure(ar);
- for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (it + 1 != ar.end()) {
- if (MathScriptInset const * q = asScript(it)) {
- q->maplize2(p, os);
- ++it;
- continue;
- }
- }
- p->maplize(os);
- }
+ for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+ (*it)->maplize(os);
}
{
MathArray ar = dat;
extractStructure(ar);
- for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (it + 1 != ar.end()) {
- if (MathScriptInset const * q = asScript(it)) {
- q->mathematicize2(p, os);
- ++it;
- continue;
- }
- }
- p->mathematicize(os);
- }
+ for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+ (*it)->mathematicize(os);
}
os << ar.begin()->nucleus();
else {
os << MTag("mrow");
- for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
- MathInset const * p = it->nucleus();
- if (it + 1 != ar.end()) {
- if (MathScriptInset const * q = asScript(it)) {
- q->mathmlize2(p, os);
- ++it;
- continue;
- }
- }
- p->mathmlize(os);
- }
+ for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
+ (*it)->mathmlize(os);
os << ETag("mrow");
}
}
MathArrayInset const * mat = at.nucleus()->asArrayInset();
MathArray res;
if (mat->ncols() == 1 && mat->nrows() == 1)
- res.push_back(mat->cell(0));
+ res.append(mat->cell(0));
else {
res.push_back(MathAtom(new MathDelimInset("(", ")")));
res.back()->cell(0).push_back(at);
}
-bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
+bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
+ int targetx) const
{
MathInset::idx_type target = !up; // up ? 0 : 1, since upper cell has idx 0
if (idx == target)
return false;
idx = target;
+ pos = xcell(idx).x2pos(targetx);
return true;
}
///
MathFracbaseInset();
///
- bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
+ bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///
}
-bool MathGridInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
+bool MathGridInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
+ int targetx) const
{
if (up) {
if (idx < ncols())
return false;
idx -= ncols();
+ pos = xcell(idx).x2pos(targetx - xcell(idx).xo());
return true;
} else {
if (idx >= ncols() * (nrows() - 1))
return false;
idx += ncols();
+ pos = xcell(idx).x2pos(targetx - xcell(idx).xo());
return true;
}
}
// move cells if necessary
for (idx_type i = index(row(idx), 0); i < idx; ++i)
- cell(i).swap(cell(i + ncols()));
+ std::swap(cell(i), cell(i + ncols()));
delRow(row(idx));
if (c + 1 == ncols()) {
if (row(idx) + 1 != nrows()) {
for (col_type cc = 0; cc < ncols(); ++cc)
- cell(idx).push_back(cell(idx + cc + 1));
+ cell(idx).append(cell(idx + cc + 1));
delRow(row(idx) + 1);
}
} else {
- cell(idx).push_back(cell(idx + 1));
+ cell(idx).append(cell(idx + 1));
for (col_type cc = c + 2; cc < ncols(); ++cc)
cell(idx - c + cc - 1) = cell(idx - c + cc);
- cell(idx - c + ncols() - 1).erase();
+ cell(idx - c + ncols() - 1).clear();
}
}
///
MathInset * clone() const;
///
- void metrics(MathMetricsInfo & st) const;
+ void metrics(MathMetricsInfo & mi) const;
///
- void draw(MathPainterInfo &, int x, int y) const;
+ void draw(MathPainterInfo & pi, int x, int y) const;
///
- void metricsT(TextMetricsInfo const & st) const;
+ void metricsT(TextMetricsInfo const & mi) const;
///
- void drawT(TextPainter &, int x, int y) const;
+ void drawT(TextPainter & pi, int x, int y) const;
///
- void halign(string const &);
+ void halign(string const & align);
///
void halign(char c, col_type col);
///
col_type col(idx_type idx) const;
///
row_type row(idx_type idx) const;
- ///
- int cellXOffset(idx_type idx) const;
- ///
- int cellYOffset(idx_type idx) const;
///
- bool idxUpDown(idx_type & idx, pos_type & pos, bool) const;
+ bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///
//void octavize(OctaveStream &) const;
protected:
+ /// returns x offset of cell comapared to inset
+ int cellXOffset(idx_type idx) const;
+ /// returns y offset of cell comapared to inset
+ int cellYOffset(idx_type idx) const;
/// returns proper 'end of line' code for LaTeX
string eolString(row_type row, bool fragile = false) const;
/// returns proper 'end of column' code for LaTeX
{
MathArray ar;
for (idx_type i = 0; i < nargs(); ++i)
- ar.push_back(cell(i));
+ ar.append(cell(i));
*this = MathHullInset("simple");
cell(0) = ar;
setDefaults();
// split it "nicely" on the firest relop
pos_type pos = firstRelOp(cell(0));
- cell(1) = MathArray(cell(0), pos, cell(0).size());
+ cell(1) = MathArray(cell(0).begin() + pos, cell(0).end());
cell(0).erase(pos, cell(0).size());
if (cell(1).size()) {
- cell(2) = MathArray(cell(1), 1, cell(1).size());
+ cell(2) = MathArray(cell(1).begin() + 1, cell(1).end());
cell(1).erase(1, cell(1).size());
}
setType("eqnarray");
} else { // align & Co.
for (row_type row = 0; row < nrows(); ++row) {
idx_type c = 3 * row + 1;
- cell(c).push_back(cell(c + 1));
+ cell(c).append(cell(c + 1));
}
MathGridInset::delCol(2);
setType("align");
return os;
}
+
MathInset::size_type MathInset::nargs() const
{
return 0;
}
-void MathInset::dimensions(Dimension & dim) const
+Dimension MathInset::dimensions() const
{
- dim.w = width();
- dim.a = ascent();
- dim.d = descent();
+ lyxerr << "call MathInset::dimensions()\n";
+ return Dimension(width(), ascent(), descent());
}
}
-bool MathInset::idxUpDown(idx_type &, pos_type &, bool) const
+bool MathInset::idxUpDown(idx_type &, pos_type &, bool, int) const
{
return false;
}
/// total width
virtual int width() const { return 2; }
/// all in one batch
- virtual void dimensions(Dimension & dim) const;
+ virtual Dimension dimensions() const;
/// total height (== ascent + descent)
virtual int height() const;
/// Where should we go when we press the up or down cursor key?
- virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
+ virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up,
+ int targetx) const;
/// The left key
virtual bool idxLeft(idx_type & idx, pos_type & pos) const;
/// The right key
}
-bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up) const
+bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up, int x) const
{
pos_type pos;
- return
- up ? MathNestInset::idxLeft(idx, pos) : MathNestInset::idxRight(idx, pos);
+ if (up) {
+ if (!MathNestInset::idxLeft(idx, pos))
+ return false;
+ pos = xcell(idx).x2pos(x);
+ return true;
+ } else {
+ if (!MathNestInset::idxRight(idx, pos))
+ return false;
+ pos = xcell(idx).x2pos(x);
+ return true;
+ }
}
void dump() const;
///
- bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
+ bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///
{
MathArray ar;
for (unsigned i = 0; i < nargs(); ++i)
- ar.push_back(cell(i));
+ ar.append(cell(i));
return ar;
}
}
-bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up) const
+bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
+ int targetx) const
{
// try to move only one screen row up or down if possible
int row = pos2row(pos);
///
void setPosition(string const & pos);
/// moves cursor up or down
- bool idxUpDown(idx_type &, pos_type & pos, bool up) const;
+ bool idxUpDown(idx_type &, pos_type & pos, bool up, int targetx) const;
private:
/// number of rows on screen
int screenrows() const;
}
-
bool Parser::parse(MathAtom & at)
{
skipSpaces();
// do not create a BraceInset if they were written by LyX
// this helps to keep the annoyance of "a choose b" to a minimum
if (ar.size() == 1 && ar[0]->extraBraces())
- cell->push_back(ar);
+ cell->append(ar);
else
cell->push_back(MathAtom(new MathBraceInset(ar)));
}
else if (t.cat() == catSuper || t.cat() == catSub) {
bool up = (t.cat() == catSuper);
- MathScriptInset * p = 0;
- if (cell->size())
- p = cell->back()->asScriptInset();
- if (!p || p->has(up)) {
+ // we need no new script inset if the last thing was a scriptinset,
+ // which has that script already not the same script already
+ if (cell->size() && cell->back()->asScriptInset() &&
+ !cell->back()->asScriptInset()->has(up))
+ cell->back()->asScriptInset()->ensure(up);
+ else if (cell->back()->asScriptInset())
cell->push_back(MathAtom(new MathScriptInset(up)));
- p = cell->back()->asScriptInset();
- }
- p->ensure(up);
+ else
+ cell->back() = MathAtom(new MathScriptInset(cell->back(), up));
+ MathScriptInset * p = cell->back()->asScriptInset();
parse(p->cell(up), FLAG_ITEM, mathmode);
p->limits(limits);
limits = 0;
else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") {
MathAtom p = createMathInset(t.cs());
- cell->swap(p->cell(0));
+ p->cell(0) = *cell;
+ cell->clear();
parse(p->cell(1), flags, mathmode);
cell->push_back(p);
return;
dim_.a = max(xcell(0).ascent() + 5, xcell(1).ascent()) + 2;
dim_.d = max(xcell(1).descent() + 5, xcell(0).descent()) + 2;
dim_.w = xcell(0).width() + xcell(1).width() + 10;
+ metricsMarkers();
}
xp[3] = x + w - 2; yp[3] = y + (d - a)/2 + 2;
xp[4] = x; yp[4] = y + (d - a)/2 + 2;
pi.pain.lines(xp, yp, 5, LColor::math);
+ drawMarkers(pi, x, y);
}
}
-bool MathRootInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
+bool MathRootInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, int) const
{
bool target = !up; // up ? 0 : 1;
if (idx == target)
return false;
idx = target;
+ pos = target ? 0 : cell(0).size();
return true;
}
///
MathInset * clone() const;
///
- bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
+ bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
void metrics(MathMetricsInfo & mi) const;
///
MathScriptInset::MathScriptInset()
- : MathNestInset(2), limits_(0)
+ : MathNestInset(3), limits_(0)
{
script_[0] = false;
script_[1] = false;
MathScriptInset::MathScriptInset(bool up)
- : MathNestInset(2), limits_(0)
+ : MathNestInset(3), limits_(0)
{
script_[0] = !up;
script_[1] = up;
}
+MathScriptInset::MathScriptInset(MathAtom const & at, bool up)
+ : MathNestInset(3), limits_(0)
+{
+ script_[0] = !up;
+ script_[1] = up;
+ cell(2).push_back(at);
+}
+
+
+
MathInset * MathScriptInset::clone() const
{
return new MathScriptInset(*this);
}
-MathXArray const & MathScriptInset::up() const
+bool MathScriptInset::idxFirst(idx_type & idx, pos_type & pos) const
{
- return xcell(1);
+ idx = 2;
+ pos = nuc().size();
+ return true;
+}
+
+
+bool MathScriptInset::idxLast(idx_type & idx, pos_type & pos) const
+{
+ idx = 2;
+ pos = nuc().size();
+ return true;
}
}
-MathXArray & MathScriptInset::up()
+MathXArray & MathScriptInset::down()
+{
+ return xcell(0);
+}
+
+
+MathXArray const & MathScriptInset::up() const
{
return xcell(1);
}
-MathXArray & MathScriptInset::down()
+MathXArray & MathScriptInset::up()
{
- return xcell(0);
+ return xcell(1);
}
}
-int MathScriptInset::dy0(MathInset const * nuc) const
+MathXArray const & MathScriptInset::nuc() const
+{
+ return xcell(2);
+}
+
+
+MathXArray & MathScriptInset::nuc()
+{
+ return xcell(2);
+}
+
+
+int MathScriptInset::dy0() const
{
- int nd = ndes(nuc);
+ int nd = ndes();
if (!hasDown())
return nd;
int des = down().ascent();
- if (hasLimits(nuc))
+ if (hasLimits())
des += nd + 2;
else
des = max(des, nd);
}
-int MathScriptInset::dy1(MathInset const * nuc) const
+int MathScriptInset::dy1() const
{
- int na = nasc(nuc);
+ int na = nasc();
if (!hasUp())
return na;
int asc = up().descent();
- if (hasLimits(nuc))
+ if (hasLimits())
asc += na + 2;
else
asc = max(asc, na);
}
-int MathScriptInset::dx0(MathInset const * nuc) const
+int MathScriptInset::dx0() const
{
lyx::Assert(hasDown());
- return hasLimits(nuc) ? (width2(nuc) - down().width()) / 2 : nwid(nuc);
+ return hasLimits() ? (dim_.w - down().width()) / 2 : nwid();
}
-int MathScriptInset::dx1(MathInset const * nuc) const
+int MathScriptInset::dx1() const
{
lyx::Assert(hasUp());
- return hasLimits(nuc) ? (width2(nuc) - up().width()) / 2 : nwid(nuc);
-}
-
-
-int MathScriptInset::dxx(MathInset const * nuc) const
-{
- //lyx::Assert(nuc());
- return hasLimits(nuc) ? (width2(nuc) - nwid(nuc)) / 2 : 0;
-}
-
-
-void MathScriptInset::dimensions2(MathInset const * nuc, Dimension & dim) const
-{
- dim.a = dy1(nuc) + (hasUp() ? up().ascent() : 0);
- dim.d = dy0(nuc) + (hasDown() ? down().descent() : 0);
- dim.w = width2(nuc);
+ return hasLimits() ? (dim_.w - up().width()) / 2 : nwid();
}
-int MathScriptInset::width2(MathInset const * nuc) const
+int MathScriptInset::dxx() const
{
- int w = 0;
- if (hasLimits(nuc)) {
- w = nwid(nuc);
- if (hasUp())
- w = max(w, up().width());
- if (hasDown())
- w = max(w, down().width());
- } else {
- if (hasUp())
- w = max(w, up().width());
- if (hasDown())
- w = max(w, down().width());
- w += nwid(nuc);
- }
- return w;
+ return hasLimits() ? (dim_.w - nwid()) / 2 : 0;
}
-int MathScriptInset::nwid(MathInset const * nuc) const
+int MathScriptInset::nwid() const
{
- return nuc ? nuc->width() : mathed_char_width(font_, '.');
+ return nuc().size() ? nuc().width() : mathed_char_width(font_, '.');
}
-int MathScriptInset::nasc(MathInset const * nuc) const
+int MathScriptInset::nasc() const
{
- return nuc ? nuc->ascent() : mathed_char_ascent(font_, 'I');
+ return nuc().size() ? nuc().ascent() : mathed_char_ascent(font_, 'I');
}
-int MathScriptInset::ndes(MathInset const * nuc) const
+int MathScriptInset::ndes() const
{
- return nuc ? nuc->descent() : mathed_char_descent(font_, 'I');
+ return nuc().size() ? nuc().descent() : mathed_char_descent(font_, 'I');
}
void MathScriptInset::metrics(MathMetricsInfo & mi) const
{
- metrics(0, mi);
-}
-
-
-void MathScriptInset::metrics(MathInset const * nuc, MathMetricsInfo & mi) const
-{
- if (nuc)
- nuc->metrics(mi);
MathNestInset::metrics(mi);
MathScriptChanger dummy(mi.base);
- dimensions2(nuc, dim_);
+ dim_.w = 0;
+ if (hasLimits()) {
+ dim_.w = nwid();
+ if (hasUp())
+ dim_.w = max(dim_.w, up().width());
+ if (hasDown())
+ dim_.w = max(dim_.w, down().width());
+ } else {
+ if (hasUp())
+ dim_.w = max(dim_.w, up().width());
+ if (hasDown())
+ dim_.w = max(dim_.w, down().width());
+ dim_.w += nwid();
+ }
+ dim_.a = dy1() + (hasUp() ? up().ascent() : 0);
+ dim_.d = dy0() + (hasDown() ? down().descent() : 0);
+ metricsMarkers();
}
void MathScriptInset::draw(MathPainterInfo & pi, int x, int y) const
{
- //lyxerr << "unexpected call to MathScriptInset::draw()\n";
- draw(0, pi, x, y);
-}
-
-
-void MathScriptInset::draw(MathInset const * nuc, MathPainterInfo & pi,
- int x, int y) const
-{
- if (nuc)
- nuc->draw(pi, x + dxx(nuc), y);
+ if (nuc().size())
+ nuc().draw(pi, x + dxx(), y);
else if (editing())
- drawStr(pi, font_, x + dxx(nuc), y, ".");
-
+ drawStr(pi, font_, x + dxx(), y, ".");
MathScriptChanger dummy(pi.base);
if (hasUp())
- up().draw(pi, x + dx1(nuc), y - dy1(nuc));
+ up().draw(pi, x + dx1(), y - dy1());
if (hasDown())
- down().draw(pi, x + dx0(nuc), y + dy0(nuc));
+ down().draw(pi, x + dx0(), y + dy0());
+ drawMarkers(pi, x, y);
}
void MathScriptInset::metricsT(TextMetricsInfo const & mi) const
-{
- metricsT(0, mi);
-}
-
-
-void MathScriptInset::metricsT(MathInset const * nuc,
- TextMetricsInfo const & mi) const
{
if (hasUp())
up().metricsT(mi);
if (hasDown())
down().metricsT(mi);
- if (nuc)
- nuc->metricsT(mi);
- //ascent_ = ascent2(nuc);
- //descent_ = descent2(nuc);
- //width_ = width2(nuc);
+ nuc().metricsT(mi);
}
void MathScriptInset::drawT(TextPainter & pain, int x, int y) const
{
- //lyxerr << "unexpected call to MathScriptInset::draw()\n";
- drawT(0, pain, x, y);
-}
-
-
-void MathScriptInset::drawT(MathInset const * nuc, TextPainter & pain,
- int x, int y) const
-{
- if (nuc)
- nuc->drawT(pain, x + dxx(nuc), y);
+ if (nuc().size())
+ nuc().drawT(pain, x + dxx(), y);
if (hasUp())
- up().drawT(pain, x + dx1(nuc), y - dy1(nuc));
+ up().drawT(pain, x + dx1(), y - dy1());
if (hasDown())
- down().drawT(pain, x + dx0(nuc), y + dy0(nuc));
+ down().drawT(pain, x + dx0(), y + dy0());
}
-bool MathScriptInset::hasLimits(MathInset const * nuc) const
+bool MathScriptInset::hasLimits() const
{
// obvious cases
if (limits_ == 1)
return false;
// we can only display limits if the nucleus wants some
- if (!nuc)
+ if (!nuc().size())
return false;
- if (!nuc->isScriptable())
+ if (!nuc().back()->isScriptable())
return false;
// per default \int has limits beside the \int even in displayed formulas
- if (nuc->asSymbolInset())
- if (nuc->asSymbolInset()->name().find("int") != string::npos)
+ if (nuc().back()->asSymbolInset())
+ if (nuc().back()->asSymbolInset()->name().find("int") != string::npos)
return false;
// assume "real" limits for everything else
bool MathScriptInset::empty() const
{
- return !script_[0] && !script_[1];
+ return !script_[0] && !script_[1] && cell(2).empty();
}
}
-bool MathScriptInset::idxRight(MathInset::idx_type &,
- MathInset::pos_type &) const
+bool MathScriptInset::idxRight(idx_type &, pos_type &) const
{
return false;
}
-bool MathScriptInset::idxLeft(MathInset::idx_type &,
- MathInset::pos_type &) const
+bool MathScriptInset::idxLeft(idx_type &, pos_type &) const
{
return false;
}
-void MathScriptInset::write(WriteStream & os) const
+bool MathScriptInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
+ int) const
{
- //lyxerr << "unexpected call to MathScriptInset::write()\n";
- write2(0, os);
+ if ((idx == 1 && up) || (idx == 0 && !up))
+ return false;
+
+ // in nuclues?
+ if (idx == 2) {
+ idx = up;
+ pos = 0;
+ } else {
+ idx = 2;
+ pos = cell(2).size();
+ }
+ return true;
}
-void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const
+void MathScriptInset::write(WriteStream & os) const
{
- if (nuc) {
- os << nuc;
- if (nuc->takesLimits()) {
+ if (nuc().size()) {
+ os << nuc().data();
+ if (nuc().back()->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
if (limits_ == 1)
os << "\\limits ";
}
- } else
- if (os.firstitem())
- lyxerr[Debug::MATHED] << "suppressing {} when writing\n";
- else
- os << "{}";
+ } else {
+ if (os.firstitem())
+ lyxerr[Debug::MATHED] << "suppressing {} when writing\n";
+ else
+ os << "{}";
+ }
if (hasDown() && down().data().size())
os << "_{" << down().data() << '}';
void MathScriptInset::normalize(NormalStream & os) const
{
- //lyxerr << "unexpected call to MathScriptInset::normalize()\n";
- normalize2(0, os);
-}
-
-
-void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const
-{
- bool d = hasDown() && down().data().size();
- bool u = hasUp() && up().data().size();
+ bool d = hasDown() && down().size();
+ bool u = hasUp() && up().size();
if (u)
os << "[sup ";
if (d)
os << "[sub ";
- if (nuc)
- os << nuc << ' ';
+ if (nuc().size())
+ os << nuc().data() << ' ';
else
os << "[par]";
}
-void MathScriptInset::maplize2(MathInset const * nuc, MapleStream & os) const
+void MathScriptInset::maplize(MapleStream & os) const
{
- if (nuc)
- os << nuc;
- if (hasDown() && down().data().size())
+ if (nuc().size())
+ os << nuc().data();
+ if (hasDown() && down().size())
os << '[' << down().data() << ']';
- if (hasUp() && up().data().size())
+ if (hasUp() && up().size())
os << "^(" << up().data() << ')';
}
-void MathScriptInset::mathematicize2(MathInset const * nuc, MathematicaStream & os) const
+void MathScriptInset::mathematicize(MathematicaStream & os) const
{
- bool d = hasDown() && down().data().size();
- bool u = hasUp() && up().data().size();
+ bool d = hasDown() && down().size();
+ bool u = hasUp() && up().size();
- if (nuc)
- if (d) //subscript only if nuc !
- os << "Subscript[" << nuc;
+ if (nuc().size()) {
+ if (d)
+ os << "Subscript[" << nuc().data();
else
- os << nuc;
+ os << nuc().data();
+ }
+
if (u)
os << "^(" << up().data() << ")";
- if (nuc)
+ if (nuc().size())
if (d)
- os << "," << down().data() << "]";
+ os << "," << down().data() << "]";
}
-void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const
+void MathScriptInset::mathmlize( MathMLStream & os) const
{
bool d = hasDown() && down().data().size();
bool u = hasUp() && up().data().size();
else if (d)
os << MTag("msub");
- if (nuc)
- os << nuc;
+ if (nuc().size())
+ os << nuc().data();
else
os << "<mrow/>";
}
-void MathScriptInset::octavize2(MathInset const * nuc, OctaveStream & os) const
+void MathScriptInset::octavize(OctaveStream & os) const
{
- if (nuc)
- os << nuc;
- if (hasDown() && down().data().size())
+ if (nuc().size())
+ os << nuc().data();
+ if (hasDown() && down().size())
os << '[' << down().data() << ']';
- if (hasUp() && up().data().size())
+ if (hasUp() && up().size())
os << "^(" << up().data() << ')';
}
MathScriptInset();
/// create inset with single script
explicit MathScriptInset(bool up);
+ /// create inset with single script and given nucleus
+ MathScriptInset(MathAtom const & at, bool up);
///
MathInset * clone() const;
///
- void write(WriteStream & os) const;
- ///
- void normalize(NormalStream & os) const;
- ///
- void metrics(MathMetricsInfo & st) const;
+ void metrics(MathMetricsInfo & mi) const;
///
- void draw(MathPainterInfo &, int x, int y) const;
+ void draw(MathPainterInfo & pi, int x, int y) const;
///
- void metricsT(TextMetricsInfo const & st) const;
+ void metricsT(TextMetricsInfo const & mi) const;
///
- void drawT(TextPainter &, int x, int y) const;
+ void drawT(TextPainter & pi, int x, int y) const;
- ///
- void metrics(MathInset const * nuc, MathMetricsInfo & st) const;
- ///
- void draw(MathInset const * nuc, MathPainterInfo &, int x, int y) const;
- ///
- void metricsT(MathInset const * nuc, TextMetricsInfo const & st) const;
- ///
- void drawT(MathInset const * nuc, TextPainter &, int x, int y) const;
- /// helper
- void dimensions2(MathInset const * nuc, Dimension & dim) const;
- /// only the width
- int width2(MathInset const * nuc) const;
-
- ///
+ /// write LaTeX and Lyx code
+ void write(WriteStream & os) const;
+ /// write normalized content
+ void normalize(NormalStream &) const;
+ /// write content as something readable by Maple
+ void maplize(MapleStream &) const;
+ /// write content as something readable by Mathematica
+ void mathematicize(MathematicaStream &) const;
+ /// write content as something resembling MathML
+ void mathmlize(MathMLStream &) const;
+ /// write content as something readable by Octave
+ void octavize(OctaveStream &) const;
+ /// move cursor left
bool idxLeft(idx_type &, pos_type &) const;
- ///
+ /// move cursor right
bool idxRight(idx_type &, pos_type &) const;
+ /// move cursor up or down
+ bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
+ /// Target pos when we enter the inset from the left by pressing "Right"
+ bool idxFirst(idx_type & idx, pos_type & pos) const;
+ /// Target pos when we enter the inset from the right by pressing "Left"
+ bool idxLast(idx_type & idx, pos_type & pos) const;
/// can we enter this cell?
bool validCell(idx_type i) const { return script_[i]; }
void limits(int lim) { limits_ = lim; }
/// get limits
int limits() const { return limits_; }
- /// true if we have an "inner" position
- MathXArray const & up() const;
/// returns subscript
MathXArray const & down() const;
- /// returns superscript
- MathXArray & up();
/// returns subscript
MathXArray & down();
+ /// returns superscript
+ MathXArray const & up() const;
+ /// returns superscript
+ MathXArray & up();
+ /// returns nucleus
+ MathXArray const & nuc() const;
+ /// returns nucleus
+ MathXArray & nuc();
/// do we have a superscript?
bool hasUp() const;
/// do we have a subscript?
///
void infoize(std::ostream & os) const;
- // call these methods ...2 to make compaq cxx in anal mode happy...
- /// suppresses empty braces if necessary
- virtual void write2(MathInset const * nuc, WriteStream & os) const;
- virtual void normalize2(MathInset const * nuc, NormalStream & os) const;
- virtual void octavize2(MathInset const * nuc, OctaveStream & os) const;
- virtual void maplize2(MathInset const * nuc, MapleStream & os) const;
- virtual void mathematicize2(MathInset const * nuc, MathematicaStream & os) const;
- virtual void mathmlize2(MathInset const * nuc, MathMLStream & os) const;
-public:
+private:
/// returns x offset for main part
- int dxx(MathInset const * nuc) const;
+ int dxx() const;
/// returns width of nucleus if any
- int nwid(MathInset const * nuc) const;
-private:
+ int nwid() const;
/// returns y offset for superscript
- int dy0(MathInset const * nuc) const;
+ int dy0() const;
/// returns y offset for subscript
- int dy1(MathInset const * nuc) const;
+ int dy1() const;
/// returns x offset for superscript
- int dx0(MathInset const * nuc) const;
+ int dx0() const;
/// returns x offset for subscript
- int dx1(MathInset const * nuc) const;
+ int dx1() const;
/// returns ascent of nucleus if any
- int nasc(MathInset const * nuc) const;
+ int nasc() const;
/// returns descent of nucleus if any
- int ndes(MathInset const * nuc) const;
+ int ndes() const;
/// where do we have to draw the scripts?
- bool hasLimits(MathInset const * nuc) const;
+ bool hasLimits() const;
/// possible subscript (index 0) and superscript (index 1)
bool script_[2];
dim_.a = xcell(0).ascent() + 4;
dim_.d = xcell(0).descent() + 2;
dim_.w = xcell(0).width() + 12;
+ metricsMarkers();
}
-void MathSqrtInset::draw(MathPainterInfo & pain, int x, int y) const
+void MathSqrtInset::draw(MathPainterInfo & pi, int x, int y) const
{
- xcell(0).draw(pain, x + 10, y);
+ xcell(0).draw(pi, x + 10, y);
int const a = ascent();
int const d = descent();
int xp[4];
xp[1] = x + 8; yp[1] = y - a + 1;
xp[2] = x + 5; yp[2] = y + d - 1;
xp[3] = x; yp[3] = y + (d - a)/2;
- pain.pain.lines(xp, yp, 4, LColor::math);
+ pi.pain.lines(xp, yp, 4, LColor::math);
+ drawMarkers(pi, x, y);
}
///
MathInset * clone() const;
///
- void metrics(MathMetricsInfo & st) const;
+ void metrics(MathMetricsInfo & mi) const;
///
- void draw(MathPainterInfo &, int x, int y) const;
+ void draw(MathPainterInfo & pi, int x, int y) const;
///
void write(WriteStream & os) const;
///
MathInset * clone() const;
///
- void metrics(MathMetricsInfo & st) const;
+ void metrics(MathMetricsInfo & mi) const;
///
- void draw(MathPainterInfo &, int x, int y) const;
+ void draw(MathPainterInfo & pi, int x, int y) const;
///
string str() const { return str_; }
///
///
MathInset * clone() const;
///
- void metrics(MathMetricsInfo & st) const;
+ void metrics(MathMetricsInfo & mi) const;
///
MathSubstackInset const * asSubstackInset() const { return this; }
#pragma implementation
#endif
-#include "math_scriptinset.h"
+#include "math_xdata.h"
#include "math_support.h"
+#include "math_inset.h"
#include "frontends/Painter.h"
#include "textpainter.h"
#include "debug.h"
using std::abs;
-extern MathScriptInset const * asScript(MathArray::const_iterator it);
-
-
MathXArray::MathXArray()
: xo_(0), yo_(0), clean_(false), drawn_(false)
{}
{
//if (clean_)
// return;
-
- size_ = mi;
clean_ = true;
drawn_ = false;
- if (data_.empty()) {
+ if (empty()) {
mathed_char_dim(mi.base.font, 'I', dim_);
return dim_;
}
dim_.clear();
- for (const_iterator it = begin(); it != end(); ++it) {
- MathInset const * p = it->nucleus();
- MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
- Dimension d;
- if (q) {
- q->metrics(p, mi);
- q->dimensions2(p, d);
- ++it;
- } else {
- p->metrics(mi);
- p->dimensions(d);
- }
- dim_ += d;
+ for (const_iterator it = begin(), et = end(); it != et; ++it) {
+ (*it)->metrics(mi);
+ dim_ += (*it)->dimensions();
}
-
- //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n";
return dim_;
}
//if (clean_)
// return;
- size_ = mi;
clean_ = true;
drawn_ = false;
- if (data_.empty()) {
+ if (empty()) {
mathed_char_dim(mi.base.font, 'I', dim_);
return;
}
dim_.clear();
- for (const_iterator it = begin(); it != end(); ++it) {
+ for (const_iterator it = begin(), et = end(); it != et; ++it) {
MathInset const * p = it->nucleus();
- MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
- Dimension d;
- if (q) {
- q->metrics(p, mi);
- q->dimensions2(p, d);
- v.push_back(d);
- v.push_back(Dimension());
- ++it;
- } else {
- p->metrics(mi);
- p->dimensions(d);
- v.push_back(d);
- }
+ p->metrics(mi);
+ v.push_back(p->dimensions());
}
- //for (int i = 0; i < data_.size(); ++i)
+ //for (int i = 0; i < size(); ++i)
// lyxerr << "i: " << i << " dim: " << v[i] << endl;
//lyxerr << "MathXArray::metrics(): '" << dim_ << "\n";
}
}
for (; it != et; ++it) {
- MathInset const * p = it->nucleus();
- MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
- if (q) {
- q->draw(p, pi, x, y);
- x += q->width2(p);
- ++it;
- } else {
- p->draw(pi, x, y);
- x += p->width();
- }
+ (*it)->draw(pi, x, y);
+ x += (*it)->width();
}
}
{
//for (size_type r = 0; r < v.size(); ++r)
// lyxerr << "row " << r << " to: " << v[r].end << endl;
- //lyxerr << " data: " << data_ << endl;
+ //lyxerr << " data: " << *this << endl;
xo_ = x;
yo_ = y;
for (size_type r = 0; r < v.size(); ++r) {
int xx = x;
int yy = y + v[r].yo;
- for (size_type pos = v[r].begin; pos < v[r].end && pos < data_.size(); ++pos) {
- //lyxerr << "drawing pos " << pos << " of " << data_.size()
- // << " " << int(data_[pos]->getChar()) << endl;
- MathInset const * p = data_[pos].nucleus();
-
- // insert extra glue
+ for (size_type pos = v[r].begin; pos < v[r].end && pos < size(); ++pos) {
+ //lyxerr << "drawing pos " << pos << " of " << size()
+ // << " " << int(operator[](pos)->getChar()) << endl;
+ MathInset const * p = operator[](pos).nucleus();
+ // insert extra glue if necessary
if (p->getChar() == ' ')
xx += v[r].glue;
-
- MathScriptInset const * q = 0;
- if (pos + 1 < data_.size())
- q = asScript(begin() + pos);
- if (q) {
- q->draw(p, pi, xx, yy);
- xx += q->width2(p);
- ++pos;
- } else {
- p->draw(pi, xx, yy);
- xx += p->width();
- }
+ // ordinary case
+ p->draw(pi, xx, yy);
+ xx += p->width();
}
}
}
// return;
dim_.clear();
for (const_iterator it = begin(); it != end(); ++it) {
- MathInset const * p = it->nucleus();
- MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
- Dimension d;
- if (q) {
- q->metricsT(p, mi);
- q->dimensions2(p, d);
- ++it;
- } else {
- p->metricsT(mi);
- p->dimensions(d);
- }
- dim_ += d;
+ (*it)->metricsT(mi);
+ dim_ += (*it)->dimensions();
}
return dim_;
}
for (; it != et; ++it) {
MathInset const * p = it->nucleus();
- MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
- if (q) {
- q->drawT(p, pain, x, y);
- x += q->width2(p);
- ++it;
- } else {
- p->drawT(pain, x, y);
- x += p->width();
- }
+ p->drawT(pain, x, y);
+ x += p->width();
}
}
int MathXArray::pos2x(size_type pos1, size_type pos2, int glue) const
{
int x = 0;
- size_type target = min(pos2, data_.size());
+ size_type target = min(pos2, size());
for (size_type i = pos1; i < target; ++i) {
const_iterator it = begin() + i;
MathInset const * p = it->nucleus();
if (p->getChar() == ' ')
x += glue;
- MathScriptInset const * q = (i + 1 == data_.size()) ? 0 : asScript(it);
- if (q) {
- ++i;
- if (i < target)
- x += q->width2(p);
- else // "half" position
- x += q->dxx(p) + q->nwid(p);
- } else
- x += p->width();
+ x += p->width();
}
return x;
}
int lastx = 0;
int currx = 0;
for (; currx < targetx && it < end(); ++it) {
- size_type pos = it - begin();
lastx = currx;
-
MathInset const * p = it->nucleus();
if (p->getChar() == ' ')
currx += glue;
- MathScriptInset const * q = 0;
- if (it + 1 != end())
- q = asScript(it);
- if (q) {
- currx += q->width2(p);
- ++it;
- } else {
- currx += p->width();
- }
+ currx += p->width();
}
if (abs(lastx - targetx) < abs(currx - targetx) && it != begin() + startpos)
--it;
// check inset
MathInset const * p = it->nucleus();
p->findPos(f);
-
- // move on
- MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
- if (q) {
- x += q->width(p);
- f.nextPos();
- ++it;
- } else {
- x += p->width();
- }
+ x += p->width();
}
}
*/
/** This class extends a MathArray by drawing routines and caches for
* metric information.
*/
-class MathXArray
+class MathXArray : private MathArray
{
public:
- /// type for positions and sizes
- typedef MathArray::size_type size_type;
- /// const iterator into the underlying MathArray
- typedef MathArray::const_iterator const_iterator;
+ // re-use inherited stuff
+ using MathArray::size_type;
+ using MathArray::const_iterator;
+ using MathArray::begin;
+ using MathArray::end;
+ using MathArray::operator[];
+ using MathArray::clear;
+ using MathArray::size;
+ using MathArray::empty;
+ using MathArray::back;
+ MathArray & data() { return *this; }
+ MathArray const & data() const { return *this; }
// helper structure for external metrics computations as done
// in parboxes
/// adjust (x,y) to point on boundary on a straight line from the center
void towards(int & x, int & y) const;
- /// begin iterator of the underlying MathArray
- const_iterator begin() const { return data_.begin(); }
- /// end iterator of the underlying MathArray
- const_iterator end() const { return data_.end(); }
- /// access to data
- MathArray const & data() const { return data_; }
- /// access to data
- MathArray & data() { return data_; }
private:
- /// the underlying MathArray
- MathArray data_;
/// cached dimensions of cell
mutable Dimension dim_;
/// cached x coordinate of last drawing
mutable int xo_;
/// cached y coordinate of last drawing
mutable int yo_;
- /// cache size information of last drawing
- mutable MathMetricsInfo size_;
/// cached cleaness of cell
mutable bool clean_;
/// cached draw status of cell