the up/down stuff reworked

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4806 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2002-07-30 13:56:02 +00:00
parent 3b7d5f2cf6
commit a794a45949
31 changed files with 451 additions and 729 deletions

View File

@ -73,6 +73,7 @@ void MathCharInset::metrics(MathMetricsInfo & mi) const
mathed_char_dim(font_, char_, dim_);
if (isBinaryOp(char_, code_))
width_ += 2 * font_metrics::width(' ', font_);
lyxerr << "MathCharInset::metrics: " << dim_ << "\n";
#endif
}

View File

@ -170,9 +170,6 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const
if (t->lock())
return false;
if (t->asScriptInset())
return false;
if (sel) {
// we can't move into anything new during selection
if (depth() == Anchor_.size())
@ -184,8 +181,16 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const
}
bool MathCursor::inNucleus() const
{
return par()->asScriptInset() && idx() == 2;
}
bool MathCursor::posLeft()
{
if (inNucleus())
return false;
if (pos() == 0)
return false;
--pos();
@ -281,10 +286,11 @@ void MathCursor::setPos(int x, int y)
formula()->xlow(), formula()->xhigh(),
formula()->ylow(), formula()->yhigh());
if (!res) {
// this ccan happen on creation of "math-display"
// this can happen on creation of "math-display"
dump("setPos 1.5");
first();
}
targetx_ = -1; // "no target"
dump("setPos 2");
}
@ -299,6 +305,7 @@ bool MathCursor::home(bool sel)
if (!par()->idxHome(idx(), pos()))
return popLeft();
dump("home 2");
targetx_ = -1; // "no target"
return true;
}
@ -312,6 +319,7 @@ bool MathCursor::end(bool sel)
if (!par()->idxEnd(idx(), pos()))
return popRight();
dump("end 2");
targetx_ = -1; // "no target"
return true;
}
@ -417,21 +425,22 @@ void MathCursor::paste(MathGridInset const & data)
for (row_type row = 0; row < numrows; ++row) {
for (col_type col = 0; col < numcols; ++col) {
idx_type i = p->index(row + p->row(idx), col + p->col(idx));
p->cell(i).push_back(data.cell(data.index(row, col)));
p->cell(i).append(data.cell(data.index(row, col)));
}
// append the left over horizontal cells to the last column
idx_type i = p->index(row + p->row(idx), p->ncols() - 1);
for (MathInset::col_type col = numcols; col < data.ncols(); ++col)
p->cell(i).push_back(data.cell(data.index(row, col)));
p->cell(i).append(data.cell(data.index(row, col)));
}
// append the left over vertical cells to the last _cell_
idx_type i = p->nargs() - 1;
for (row_type row = numrows; row < data.nrows(); ++row)
for (col_type col = 0; col < data.ncols(); ++col)
p->cell(i).push_back(data.cell(data.index(row, col)));
p->cell(i).append(data.cell(data.index(row, col)));
}
}
void MathCursor::backspace()
{
autocorrect_ = false;
@ -445,12 +454,16 @@ void MathCursor::backspace()
return;
}
MathScriptInset * p = prevAtom()->asScriptInset();
if (p) {
p->removeScript(p->hasUp());
// Don't delete if there is anything left
if (p->hasUp() || p->hasDown())
return;
if (prevAtom()->asScriptInset()) {
// simply enter nucleus
left();
return;
}
if (inNucleus()) {
// we are in nucleus
if (pos() == 1) {
}
}
--pos();
@ -480,12 +493,25 @@ void MathCursor::erase()
return;
}
MathScriptInset * p = nextAtom()->asScriptInset();
if (p) {
p->removeScript(p->hasUp());
// Don't delete if there is anything left
if (p->hasUp() || p->hasDown())
return;
// if we are standing in front of a script inset, grab item before us and
// move it into nucleus
// and remove first thing.
if (hasNextAtom() && nextAtom()->asScriptInset()) {
if (hasPrevAtom()) {
MathAtom at = prevAtom();
--pos();
array().erase(pos());
pushLeft(nextAtom());
if (array().empty())
array().push_back(at);
else
array()[0] = at;
pos() = 1;
} else {
pushLeft(nextAtom());
array().clear();
}
return;
}
plainErase();
@ -579,6 +605,7 @@ string MathCursor::macroName() const
void MathCursor::selClear()
{
Anchor_.clear();
selection_ = false;
}
@ -786,20 +813,6 @@ void MathCursor::pullArg()
{
dump("pullarg");
MathArray a = array();
MathScriptInset const * p = par()->asScriptInset();
if (p) {
// special handling for scripts
const bool up = p->hasUp();
popLeft();
MathScriptInset * q = nextAtom()->asScriptInset();
if (q)
q->removeScript(up);
++pos();
array().insert(pos(), a);
return;
}
if (popLeft()) {
plainErase();
array().insert(pos(), a);
@ -823,7 +836,7 @@ void MathCursor::normalize()
{
if (idx() >= par()->nargs()) {
lyxerr << "this should not really happen - 1: "
<< idx() << " " << par()->nargs() << "\n";
<< idx() << " " << par()->nargs() << " in: " << par() << "\n";
dump("error 2");
}
idx() = min(idx(), par()->nargs() - 1);
@ -995,11 +1008,11 @@ void MathCursor::breakLine()
// split line
const row_type r = hullRow();
for (col_type c = hullCol() + 1; c < p->ncols(); ++c)
p->cell(p->index(r, c)).swap(p->cell(p->index(r + 1, c)));
std::swap(p->cell(p->index(r, c)), p->cell(p->index(r + 1, c)));
// split cell
splitCell();
p->cell(idx()).swap(p->cell(idx() + p->ncols() - 1));
std::swap(p->cell(idx()), p->cell(idx() + p->ncols() - 1));
}
}
@ -1060,8 +1073,6 @@ bool MathCursor::goUpDown(bool up)
// Be warned: The 'logic' implemented in this function is highly fragile.
// A distance of one pixel or a '<' vs '<=' _really_ matters.
// So fiddle around with it only if you know what you are doing!
int xlow, xhigh, ylow, yhigh;
int xo, yo;
getPos(xo, yo);
@ -1112,31 +1123,12 @@ bool MathCursor::goUpDown(bool up)
while (1) {
///lyxerr << "updown: We are in " << *par() << " idx: " << idx() << '\n';
// ask inset first
if (par()->idxUpDown(idx(), pos(), up)) {
#ifdef WITH_WARNINGS
#warning this code should be moved to individual insets that handle this
#endif
// position might have changed, so re-compute it
getPos(xo, yo);
// we found a cell that thinks it has something "below" us.
//lyxerr << "updown: found inset that handles UpDown\n";
xarray().boundingBox(xlow, xhigh, ylow, yhigh);
// project (xo,yo) onto proper box
//lyxerr << "\n xo: " << xo << " yo: " << yo
// << "\n xlow: " << xlow << " ylow: " << ylow
// << "\n xhigh: " << xhigh << " yhigh: " << yhigh;
xo = min(max(xo, xlow), xhigh);
yo = min(max(yo, ylow), yhigh);
//lyxerr << "\n xo2: " << xo << " yo2: " << yo << "\n";
bruteFind(xo, yo, xlow, xhigh, ylow, yhigh);
//lyxerr << "updown: handled by final brute find\n";
if (par()->idxUpDown(idx(), pos(), up, targetx_))
return true;
}
// leave inset
if (!popLeft()) {
// no such inset found, just take something "above"
///lyxerr << "updown: handled by strange case\n";
// no such inset found, just take something "above"
///lyxerr << "updown: handled by strange case\n";
if (!popLeft())
return
bruteFind(xo, yo,
formula()->xlow(),
@ -1144,7 +1136,6 @@ bool MathCursor::goUpDown(bool up)
up ? formula()->ylow() : yo + 4,
up ? yo - 4 : formula()->yhigh()
);
}
// any improvement so far?
int xnew, ynew;
@ -1266,9 +1257,9 @@ bool MathCursor::interpret(string const & s)
string name = s.substr(1);
if (name == "over" || name == "choose" || name == "atop") {
MathArray ar = array();
MathAtom t(createMathInset(name));
t->asNestInset()->cell(0).swap(array());
t->asNestInset()->cell(0) = array();
array().clear();
pos() = 0;
niceInsert(t);
popRight();
@ -1302,13 +1293,19 @@ bool MathCursor::script(bool up)
macroModeClose();
MathGridInset safe = grabAndEraseSelection();
if (hasPrevAtom() && prevAtom()->asScriptInset()) {
if (inNucleus()) {
// we are in a nucleus of a script inset, move to _our_ script
par()->asScriptInset()->ensure(up);
idx() = up;
pos() = 0;
} else if (hasPrevAtom() && prevAtom()->asScriptInset()) {
prevAtom()->asScriptInset()->ensure(up);
pushRight(prevAtom());
idx() = up;
pos() = size();
} else if (hasNextAtom() && nextAtom()->asScriptInset()) {
nextAtom()->asScriptInset()->ensure(up);
} else if (hasPrevAtom()) {
--pos();
array()[pos()] = MathAtom(new MathScriptInset(nextAtom(), up));
pushLeft(nextAtom());
idx() = up;
pos() = 0;
@ -1559,7 +1556,8 @@ MathGridInset MathCursor::grabSelection() const
// shouldn't we assert on i1.par_ == i2.par_?
if (i1.idx_ == i2.idx_) {
MathGridInset data(1, 1);
data.cell(0) = MathArray(i1.cell(), i1.pos_, i2.pos_);
MathArray::const_iterator it = i1.cell().begin();
data.cell(0) = MathArray(it + i1.pos_, it + i2.pos_);
return data;
}
row_type r1, r2;
@ -1589,7 +1587,7 @@ void MathCursor::eraseSelection()
region(i1, i2, r1, r2, c1, c2);
for (row_type row = r1; row <= r2; ++row)
for (col_type col = c1; col <= c2; ++col)
p->cell(p->index(row, col)).erase();
p->cell(p->index(row, col)).clear();
}
cursor() = i1;
}
@ -1659,7 +1657,7 @@ void MathCursor::handleExtern(const string & arg)
ar = array();
lyxerr << "use whole cell: " << ar << "\n";
} else {
ar = MathArray(array(), pos + 1, size());
ar = MathArray(array().begin() + pos + 1, array().end());
lyxerr << "use partial cell form pos: " << pos << "\n";
}
end();

View File

@ -280,6 +280,8 @@ private:
bool goUpDown(bool up);
/// moves position into box
bool bruteFind(int xo, int yo, int xlow, int xhigh, int ylow, int yhigh);
/// are we in a nucleus of a script inset?
bool inNucleus() const;
/// grab grid marked by anchor and current cursor

View File

@ -18,17 +18,8 @@
#include "support/LAssert.h"
MathArray::MathArray()
{}
MathArray::MathArray(MathArray const & ar, size_type from, size_type to)
: bf_(ar.begin() + from, ar.begin() + to)
{}
MathArray::MathArray(iterator from, iterator to)
: bf_(from, to)
MathArray::MathArray(const_iterator from, const_iterator to)
: base_type(from, to)
{}
@ -39,75 +30,38 @@ void MathArray::substitute(MathMacro const & m)
}
MathAtom & MathArray::at(size_type pos)
MathAtom & MathArray::operator[](size_type pos)
{
lyx::Assert(pos < size());
return bf_[pos];
return base_type::operator[](pos);
}
MathAtom const & MathArray::at(size_type pos) const
MathAtom const & MathArray::operator[](size_type pos) const
{
lyx::Assert(pos < size());
return bf_[pos];
return base_type::operator[](pos);
}
void MathArray::insert(size_type pos, MathAtom const & t)
{
bf_.insert(begin() + pos, t);
base_type::insert(begin() + pos, t);
}
void MathArray::insert(size_type pos, MathArray const & ar)
{
bf_.insert(begin() + pos, ar.begin(), ar.end());
base_type::insert(begin() + pos, ar.begin(), ar.end());
}
void MathArray::push_back(MathAtom const & t)
{
bf_.push_back(t);
}
void MathArray::push_back(MathArray const & ar)
void MathArray::append(MathArray const & ar)
{
insert(size(), ar);
}
void MathArray::clear()
{
erase();
}
void MathArray::swap(MathArray & ar)
{
if (this != &ar)
bf_.swap(ar.bf_);
}
bool MathArray::empty() const
{
return bf_.empty();
}
MathArray::size_type MathArray::size() const
{
return bf_.size();
}
void MathArray::erase()
{
bf_.erase(begin(), end());
}
void MathArray::erase(size_type pos)
{
if (pos < size())
@ -117,37 +71,19 @@ void MathArray::erase(size_type pos)
void MathArray::erase(iterator pos1, iterator pos2)
{
bf_.erase(pos1, pos2);
base_type::erase(pos1, pos2);
}
void MathArray::erase(iterator pos)
{
bf_.erase(pos);
base_type::erase(pos);
}
void MathArray::erase(size_type pos1, size_type pos2)
{
bf_.erase(begin() + pos1, begin() + pos2);
}
MathAtom & MathArray::back()
{
return bf_.back();
}
MathAtom & MathArray::front()
{
return bf_.front();
}
MathAtom const & MathArray::front() const
{
return bf_.front();
base_type::erase(begin() + pos1, begin() + pos2);
}
@ -175,40 +111,6 @@ void MathArray::validate(LaTeXFeatures & features) const
}
void MathArray::pop_back()
{
if (!size()) {
lyxerr << "pop_back from empty array!\n";
return;
}
bf_.pop_back();
}
MathArray::const_iterator MathArray::begin() const
{
return bf_.begin();
}
MathArray::const_iterator MathArray::end() const
{
return bf_.end();
}
MathArray::iterator MathArray::begin()
{
return bf_.begin();
}
MathArray::iterator MathArray::end()
{
return bf_.end();
}
bool MathArray::match(MathArray const & ar) const
{
return size() == ar.size() && matchpart(ar, 0);
@ -247,7 +149,7 @@ bool MathArray::find1(MathArray const & ar, size_type pos) const
{
//lyxerr << "finding '" << ar << "' in '" << *this << "'\n";
for (size_type i = 0, n = ar.size(); i < n; ++i)
if (!at(pos + i)->match(ar[i].nucleus()))
if (!operator[](pos + i)->match(ar[i].nucleus()))
return false;
return true;
}

View File

@ -40,39 +40,35 @@ class ReplaceData;
\version February 2001
*/
class MathArray {
class MathArray : private std::vector<MathAtom> {
public:
/// 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:
///
typedef std::vector<MathAtom> buffer_type;
MathArray() {}
///
typedef buffer_type::const_iterator const_iterator;
MathArray(const_iterator from, const_iterator to);
///
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;
public:
///
MathArray();
///
MathArray(MathArray const & ar, size_type from, size_type to);
///
MathArray(iterator from, iterator to);
///
size_type size() const;
///
bool empty() const;
///
void clear();
///
void swap(MathArray &);
void append(MathArray const & ar);
/// inserts single atom at position pos
void insert(size_type pos, MathAtom const & at);
@ -87,22 +83,6 @@ public:
void erase(size_type pos1, size_type pos2);
/// erase single atom
void erase(size_type pos);
/// erase everythng
void erase();
///
void push_back(MathAtom const & at);
///
void push_back(MathArray const & ar);
///
void pop_back();
///
MathAtom & back();
///
MathAtom & front();
///
MathAtom const & front() const;
///
void dump() const;
@ -123,33 +103,16 @@ public:
size_type find_last(MathArray const & ar) const;
///
bool contains(MathArray const & ar) const;
/// write acccess to single atom
MathAtom & operator[](size_type pos) { return at(pos); }
/// read access o single atom
MathAtom const & operator[](size_type pos) const { return at(pos); }
///
const_iterator begin() const;
///
const_iterator end() const;
///
iterator begin();
///
iterator end();
///
void validate(LaTeXFeatures &) const;
/// checked write access
MathAtom & operator[](pos_type);
/// checked read access
MathAtom const & operator[](pos_type) const;
private:
/// is this an exact match at this position?
bool find1(MathArray const & ar, size_type pos) const;
/// write acccess to single atom
MathAtom & at(size_type pos);
/// read access o single atom
MathAtom const & at(size_type pos) const;
/// Buffer
buffer_type bf_;
};
///

View File

@ -3,12 +3,6 @@
#include "textpainter.h"
void MathDimInset::dimensions(Dimension & dim) const
{
dim = dim_;
}
void MathDimInset::metricsT(TextMetricsInfo const &) const
{
std::ostringstream os;

View File

@ -18,7 +18,7 @@ public:
/// read width
int width() const { return dim_.width(); }
///
void dimensions(Dimension & dim) const;
Dimension dimensions() const { return dim_; }
///
void metricsT(TextMetricsInfo const &) const;
///

View File

@ -113,20 +113,6 @@ MathArray::iterator extractArgument(MathArray & ar,
}
MathScriptInset const * asScript(MathArray::const_iterator it)
{
if (!it->nucleus())
return 0;
if (it->nucleus()->asScriptInset())
return 0;
++it;
if (!it->nucleus())
return 0;
return it->nucleus()->asScriptInset();
}
// returns sequence of char with same code starting at it up to end
// it might be less, though...
string charSequence
@ -300,7 +286,7 @@ void splitScripts(MathArray & ar)
// create extra script inset and move superscript over
MathScriptInset * q = new MathScriptInset;
q->ensure(true);
q->up().data().swap(p->up().data());
std::swap(q->up(), p->up());
p->removeScript(true);
// insert new inset behind
@ -799,8 +785,8 @@ void extractLims(MathArray & ar)
continue;
// the -> splits the subscript int x and x0
MathArray x = MathArray(s, 0, st - s.begin());
MathArray x0 = MathArray(s, st - s.begin() + 1, s.size());
MathArray x = MathArray(s.begin(), st);
MathArray x0 = MathArray(st + 1, s.end());
// use something behind the script as core
MathArray f;
@ -842,18 +828,8 @@ void write(MathArray const & dat, WriteStream & wi)
{
MathArray ar = dat;
extractStrings(ar);
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
wi.firstitem() = (it == ar.begin());
MathInset const * p = it->nucleus();
if (it + 1 != ar.end()) {
if (MathScriptInset const * q = asScript(it)) {
q->write2(p, wi);
++it;
continue;
}
}
p->write(wi);
}
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->write(wi);
}
@ -868,17 +844,8 @@ void octavize(MathArray const & dat, OctaveStream & os)
{
MathArray ar = dat;
extractStructure(ar);
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
MathInset const * p = it->nucleus();
if (it + 1 != ar.end()) {
if (MathScriptInset const * q = asScript(it)) {
q->octavize2(p, os);
++it;
continue;
}
}
p->octavize(os);
}
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->octavize(os);
}
@ -886,17 +853,8 @@ void maplize(MathArray const & dat, MapleStream & os)
{
MathArray ar = dat;
extractStructure(ar);
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
MathInset const * p = it->nucleus();
if (it + 1 != ar.end()) {
if (MathScriptInset const * q = asScript(it)) {
q->maplize2(p, os);
++it;
continue;
}
}
p->maplize(os);
}
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->maplize(os);
}
@ -904,17 +862,8 @@ void mathematicize(MathArray const & dat, MathematicaStream & os)
{
MathArray ar = dat;
extractStructure(ar);
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
MathInset const * p = it->nucleus();
if (it + 1 != ar.end()) {
if (MathScriptInset const * q = asScript(it)) {
q->mathematicize2(p, os);
++it;
continue;
}
}
p->mathematicize(os);
}
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathematicize(os);
}
@ -928,17 +877,8 @@ void mathmlize(MathArray const & dat, MathMLStream & os)
os << ar.begin()->nucleus();
else {
os << MTag("mrow");
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it) {
MathInset const * p = it->nucleus();
if (it + 1 != ar.end()) {
if (MathScriptInset const * q = asScript(it)) {
q->mathmlize2(p, os);
++it;
continue;
}
}
p->mathmlize(os);
}
for (MathArray::const_iterator it = ar.begin(); it != ar.end(); ++it)
(*it)->mathmlize(os);
os << ETag("mrow");
}
}
@ -1099,7 +1039,7 @@ namespace {
MathArrayInset const * mat = at.nucleus()->asArrayInset();
MathArray res;
if (mat->ncols() == 1 && mat->nrows() == 1)
res.push_back(mat->cell(0));
res.append(mat->cell(0));
else {
res.push_back(MathAtom(new MathDelimInset("(", ")")));
res.back()->cell(0).push_back(at);

View File

@ -23,11 +23,13 @@ bool MathFracbaseInset::idxLeft(idx_type &, pos_type &) const
}
bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
bool MathFracbaseInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
int targetx) const
{
MathInset::idx_type target = !up; // up ? 0 : 1, since upper cell has idx 0
if (idx == target)
return false;
idx = target;
pos = xcell(idx).x2pos(targetx);
return true;
}

View File

@ -13,7 +13,7 @@ public:
///
MathFracbaseInset();
///
bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///

View File

@ -630,17 +630,20 @@ int MathGridInset::cellYOffset(idx_type idx) const
}
bool MathGridInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
bool MathGridInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
int targetx) const
{
if (up) {
if (idx < ncols())
return false;
idx -= ncols();
pos = xcell(idx).x2pos(targetx - xcell(idx).xo());
return true;
} else {
if (idx >= ncols() * (nrows() - 1))
return false;
idx += ncols();
pos = xcell(idx).x2pos(targetx - xcell(idx).xo());
return true;
}
}
@ -759,7 +762,7 @@ bool MathGridInset::idxDelete(idx_type & idx)
// move cells if necessary
for (idx_type i = index(row(idx), 0); i < idx; ++i)
cell(i).swap(cell(i + ncols()));
std::swap(cell(i), cell(i + ncols()));
delRow(row(idx));
@ -783,14 +786,14 @@ void MathGridInset::idxGlue(idx_type idx)
if (c + 1 == ncols()) {
if (row(idx) + 1 != nrows()) {
for (col_type cc = 0; cc < ncols(); ++cc)
cell(idx).push_back(cell(idx + cc + 1));
cell(idx).append(cell(idx + cc + 1));
delRow(row(idx) + 1);
}
} else {
cell(idx).push_back(cell(idx + 1));
cell(idx).append(cell(idx + 1));
for (col_type cc = c + 2; cc < ncols(); ++cc)
cell(idx - c + cc - 1) = cell(idx - c + cc);
cell(idx - c + ncols() - 1).erase();
cell(idx - c + ncols() - 1).clear();
}
}

View File

@ -82,15 +82,15 @@ public:
///
MathInset * clone() const;
///
void metrics(MathMetricsInfo & st) const;
void metrics(MathMetricsInfo & mi) const;
///
void draw(MathPainterInfo &, int x, int y) const;
void draw(MathPainterInfo & pi, int x, int y) const;
///
void metricsT(TextMetricsInfo const & st) const;
void metricsT(TextMetricsInfo const & mi) const;
///
void drawT(TextPainter &, int x, int y) const;
void drawT(TextPainter & pi, int x, int y) const;
///
void halign(string const &);
void halign(string const & align);
///
void halign(char c, col_type col);
///
@ -126,13 +126,9 @@ public:
col_type col(idx_type idx) const;
///
row_type row(idx_type idx) const;
///
int cellXOffset(idx_type idx) const;
///
int cellYOffset(idx_type idx) const;
///
bool idxUpDown(idx_type & idx, pos_type & pos, bool) const;
bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///
@ -202,6 +198,10 @@ public:
//void octavize(OctaveStream &) const;
protected:
/// returns x offset of cell comapared to inset
int cellXOffset(idx_type idx) const;
/// returns y offset of cell comapared to inset
int cellYOffset(idx_type idx) const;
/// returns proper 'end of line' code for LaTeX
string eolString(row_type row, bool fragile = false) const;
/// returns proper 'end of column' code for LaTeX

View File

@ -444,7 +444,7 @@ void MathHullInset::glueall()
{
MathArray ar;
for (idx_type i = 0; i < nargs(); ++i)
ar.push_back(cell(i));
ar.append(cell(i));
*this = MathHullInset("simple");
cell(0) = ar;
setDefaults();
@ -506,11 +506,11 @@ void MathHullInset::mutate(string const & newtype)
// split it "nicely" on the firest relop
pos_type pos = firstRelOp(cell(0));
cell(1) = MathArray(cell(0), pos, cell(0).size());
cell(1) = MathArray(cell(0).begin() + pos, cell(0).end());
cell(0).erase(pos, cell(0).size());
if (cell(1).size()) {
cell(2) = MathArray(cell(1), 1, cell(1).size());
cell(2) = MathArray(cell(1).begin() + 1, cell(1).end());
cell(1).erase(1, cell(1).size());
}
setType("eqnarray");
@ -551,7 +551,7 @@ void MathHullInset::mutate(string const & newtype)
} else { // align & Co.
for (row_type row = 0; row < nrows(); ++row) {
idx_type c = 3 * row + 1;
cell(c).push_back(cell(c + 1));
cell(c).append(cell(c + 1));
}
MathGridInset::delCol(2);
setType("align");

View File

@ -62,17 +62,17 @@ ostream & operator<<(ostream & os, MathInset const & inset)
return os;
}
MathInset::size_type MathInset::nargs() const
{
return 0;
}
void MathInset::dimensions(Dimension & dim) const
Dimension MathInset::dimensions() const
{
dim.w = width();
dim.a = ascent();
dim.d = descent();
lyxerr << "call MathInset::dimensions()\n";
return Dimension(width(), ascent(), descent());
}
@ -143,7 +143,7 @@ bool MathInset::idxLeft(idx_type &, pos_type &) const
}
bool MathInset::idxUpDown(idx_type &, pos_type &, bool) const
bool MathInset::idxUpDown(idx_type &, pos_type &, bool, int) const
{
return false;
}

View File

@ -128,12 +128,13 @@ public:
/// total width
virtual int width() const { return 2; }
/// all in one batch
virtual void dimensions(Dimension & dim) const;
virtual Dimension dimensions() const;
/// total height (== ascent + descent)
virtual int height() const;
/// Where should we go when we press the up or down cursor key?
virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
virtual bool idxUpDown(idx_type & idx, pos_type & pos, bool up,
int targetx) const;
/// The left key
virtual bool idxLeft(idx_type & idx, pos_type & pos) const;
/// The right key

View File

@ -160,11 +160,20 @@ void MathMacro::dump() const
}
bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up) const
bool MathMacro::idxUpDown(idx_type & idx, pos_type &, bool up, int x) const
{
pos_type pos;
return
up ? MathNestInset::idxLeft(idx, pos) : MathNestInset::idxRight(idx, pos);
if (up) {
if (!MathNestInset::idxLeft(idx, pos))
return false;
pos = xcell(idx).x2pos(x);
return true;
} else {
if (!MathNestInset::idxRight(idx, pos))
return false;
pos = xcell(idx).x2pos(x);
return true;
}
}

View File

@ -51,7 +51,7 @@ public:
void dump() const;
///
bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
bool idxLeft(idx_type & idx, pos_type & pos) const;
///

View File

@ -297,7 +297,7 @@ MathArray MathNestInset::glue() const
{
MathArray ar;
for (unsigned i = 0; i < nargs(); ++i)
ar.push_back(cell(i));
ar.append(cell(i));
return ar;
}

View File

@ -65,7 +65,8 @@ void MathParboxInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const
}
bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up) const
bool MathParboxInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
int targetx) const
{
// try to move only one screen row up or down if possible
int row = pos2row(pos);

View File

@ -31,7 +31,7 @@ public:
///
void setPosition(string const & pos);
/// moves cursor up or down
bool idxUpDown(idx_type &, pos_type & pos, bool up) const;
bool idxUpDown(idx_type &, pos_type & pos, bool up, int targetx) const;
private:
/// number of rows on screen
int screenrows() const;

View File

@ -497,7 +497,6 @@ void Parser::error(string const & msg)
}
bool Parser::parse(MathAtom & at)
{
skipSpaces();
@ -632,7 +631,7 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
// do not create a BraceInset if they were written by LyX
// this helps to keep the annoyance of "a choose b" to a minimum
if (ar.size() == 1 && ar[0]->extraBraces())
cell->push_back(ar);
cell->append(ar);
else
cell->push_back(MathAtom(new MathBraceInset(ar)));
}
@ -657,14 +656,16 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
else if (t.cat() == catSuper || t.cat() == catSub) {
bool up = (t.cat() == catSuper);
MathScriptInset * p = 0;
if (cell->size())
p = cell->back()->asScriptInset();
if (!p || p->has(up)) {
// we need no new script inset if the last thing was a scriptinset,
// which has that script already not the same script already
if (cell->size() && cell->back()->asScriptInset() &&
!cell->back()->asScriptInset()->has(up))
cell->back()->asScriptInset()->ensure(up);
else if (cell->back()->asScriptInset())
cell->push_back(MathAtom(new MathScriptInset(up)));
p = cell->back()->asScriptInset();
}
p->ensure(up);
else
cell->back() = MathAtom(new MathScriptInset(cell->back(), up));
MathScriptInset * p = cell->back()->asScriptInset();
parse(p->cell(up), FLAG_ITEM, mathmode);
p->limits(limits);
limits = 0;
@ -987,7 +988,8 @@ void Parser::parse1(MathGridInset & grid, unsigned flags,
else if (t.cs() == "choose" || t.cs() == "over" || t.cs() == "atop") {
MathAtom p = createMathInset(t.cs());
cell->swap(p->cell(0));
p->cell(0) = *cell;
cell->clear();
parse(p->cell(1), flags, mathmode);
cell->push_back(p);
return;

View File

@ -40,6 +40,7 @@ void MathRootInset::metrics(MathMetricsInfo & mi) const
dim_.a = max(xcell(0).ascent() + 5, xcell(1).ascent()) + 2;
dim_.d = max(xcell(1).descent() + 5, xcell(0).descent()) + 2;
dim_.w = xcell(0).width() + xcell(1).width() + 10;
metricsMarkers();
}
@ -60,6 +61,7 @@ void MathRootInset::draw(MathPainterInfo & pi, int x, int y) const
xp[3] = x + w - 2; yp[3] = y + (d - a)/2 + 2;
xp[4] = x; yp[4] = y + (d - a)/2 + 2;
pi.pain.lines(xp, yp, 5, LColor::math);
drawMarkers(pi, x, y);
}
@ -75,12 +77,13 @@ void MathRootInset::normalize(NormalStream & os) const
}
bool MathRootInset::idxUpDown(idx_type & idx, pos_type &, bool up) const
bool MathRootInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, int) const
{
bool target = !up; // up ? 0 : 1;
if (idx == target)
return false;
idx = target;
pos = target ? 0 : cell(0).size();
return true;
}

View File

@ -32,7 +32,7 @@ public:
///
MathInset * clone() const;
///
bool idxUpDown(idx_type & idx, pos_type & pos, bool up) const;
bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
///
void metrics(MathMetricsInfo & mi) const;
///

View File

@ -14,7 +14,7 @@ using std::max;
MathScriptInset::MathScriptInset()
: MathNestInset(2), limits_(0)
: MathNestInset(3), limits_(0)
{
script_[0] = false;
script_[1] = false;
@ -22,13 +22,23 @@ MathScriptInset::MathScriptInset()
MathScriptInset::MathScriptInset(bool up)
: MathNestInset(2), limits_(0)
: MathNestInset(3), limits_(0)
{
script_[0] = !up;
script_[1] = up;
}
MathScriptInset::MathScriptInset(MathAtom const & at, bool up)
: MathNestInset(3), limits_(0)
{
script_[0] = !up;
script_[1] = up;
cell(2).push_back(at);
}
MathInset * MathScriptInset::clone() const
{
return new MathScriptInset(*this);
@ -47,9 +57,19 @@ MathScriptInset * MathScriptInset::asScriptInset()
}
MathXArray const & MathScriptInset::up() const
bool MathScriptInset::idxFirst(idx_type & idx, pos_type & pos) const
{
return xcell(1);
idx = 2;
pos = nuc().size();
return true;
}
bool MathScriptInset::idxLast(idx_type & idx, pos_type & pos) const
{
idx = 2;
pos = nuc().size();
return true;
}
@ -59,15 +79,21 @@ MathXArray const & MathScriptInset::down() const
}
MathXArray & MathScriptInset::up()
MathXArray & MathScriptInset::down()
{
return xcell(0);
}
MathXArray const & MathScriptInset::up() const
{
return xcell(1);
}
MathXArray & MathScriptInset::down()
MathXArray & MathScriptInset::up()
{
return xcell(0);
return xcell(1);
}
@ -77,13 +103,25 @@ void MathScriptInset::ensure(bool up)
}
int MathScriptInset::dy0(MathInset const * nuc) const
MathXArray const & MathScriptInset::nuc() const
{
int nd = ndes(nuc);
return xcell(2);
}
MathXArray & MathScriptInset::nuc()
{
return xcell(2);
}
int MathScriptInset::dy0() const
{
int nd = ndes();
if (!hasDown())
return nd;
int des = down().ascent();
if (hasLimits(nuc))
if (hasLimits())
des += nd + 2;
else
des = max(des, nd);
@ -91,13 +129,13 @@ int MathScriptInset::dy0(MathInset const * nuc) const
}
int MathScriptInset::dy1(MathInset const * nuc) const
int MathScriptInset::dy1() const
{
int na = nasc(nuc);
int na = nasc();
if (!hasUp())
return na;
int asc = up().descent();
if (hasLimits(nuc))
if (hasLimits())
asc += na + 2;
else
asc = max(asc, na);
@ -106,154 +144,106 @@ int MathScriptInset::dy1(MathInset const * nuc) const
}
int MathScriptInset::dx0(MathInset const * nuc) const
int MathScriptInset::dx0() const
{
lyx::Assert(hasDown());
return hasLimits(nuc) ? (width2(nuc) - down().width()) / 2 : nwid(nuc);
return hasLimits() ? (dim_.w - down().width()) / 2 : nwid();
}
int MathScriptInset::dx1(MathInset const * nuc) const
int MathScriptInset::dx1() const
{
lyx::Assert(hasUp());
return hasLimits(nuc) ? (width2(nuc) - up().width()) / 2 : nwid(nuc);
return hasLimits() ? (dim_.w - up().width()) / 2 : nwid();
}
int MathScriptInset::dxx(MathInset const * nuc) const
int MathScriptInset::dxx() const
{
//lyx::Assert(nuc());
return hasLimits(nuc) ? (width2(nuc) - nwid(nuc)) / 2 : 0;
return hasLimits() ? (dim_.w - nwid()) / 2 : 0;
}
void MathScriptInset::dimensions2(MathInset const * nuc, Dimension & dim) const
int MathScriptInset::nwid() const
{
dim.a = dy1(nuc) + (hasUp() ? up().ascent() : 0);
dim.d = dy0(nuc) + (hasDown() ? down().descent() : 0);
dim.w = width2(nuc);
return nuc().size() ? nuc().width() : mathed_char_width(font_, '.');
}
int MathScriptInset::width2(MathInset const * nuc) const
int MathScriptInset::nasc() 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 nuc().size() ? nuc().ascent() : mathed_char_ascent(font_, 'I');
}
int MathScriptInset::nwid(MathInset const * nuc) const
int MathScriptInset::ndes() const
{
return nuc ? nuc->width() : mathed_char_width(font_, '.');
}
int MathScriptInset::nasc(MathInset const * nuc) const
{
return nuc ? nuc->ascent() : mathed_char_ascent(font_, 'I');
}
int MathScriptInset::ndes(MathInset const * nuc) const
{
return nuc ? nuc->descent() : mathed_char_descent(font_, 'I');
return nuc().size() ? nuc().descent() : mathed_char_descent(font_, 'I');
}
void MathScriptInset::metrics(MathMetricsInfo & mi) const
{
metrics(0, mi);
}
void MathScriptInset::metrics(MathInset const * nuc, MathMetricsInfo & mi) const
{
if (nuc)
nuc->metrics(mi);
MathNestInset::metrics(mi);
MathScriptChanger dummy(mi.base);
dimensions2(nuc, dim_);
dim_.w = 0;
if (hasLimits()) {
dim_.w = nwid();
if (hasUp())
dim_.w = max(dim_.w, up().width());
if (hasDown())
dim_.w = max(dim_.w, down().width());
} else {
if (hasUp())
dim_.w = max(dim_.w, up().width());
if (hasDown())
dim_.w = max(dim_.w, down().width());
dim_.w += nwid();
}
dim_.a = dy1() + (hasUp() ? up().ascent() : 0);
dim_.d = dy0() + (hasDown() ? down().descent() : 0);
metricsMarkers();
}
void MathScriptInset::draw(MathPainterInfo & pi, int x, int y) const
{
//lyxerr << "unexpected call to MathScriptInset::draw()\n";
draw(0, pi, x, y);
}
void MathScriptInset::draw(MathInset const * nuc, MathPainterInfo & pi,
int x, int y) const
{
if (nuc)
nuc->draw(pi, x + dxx(nuc), y);
if (nuc().size())
nuc().draw(pi, x + dxx(), y);
else if (editing())
drawStr(pi, font_, x + dxx(nuc), y, ".");
drawStr(pi, font_, x + dxx(), y, ".");
MathScriptChanger dummy(pi.base);
if (hasUp())
up().draw(pi, x + dx1(nuc), y - dy1(nuc));
up().draw(pi, x + dx1(), y - dy1());
if (hasDown())
down().draw(pi, x + dx0(nuc), y + dy0(nuc));
down().draw(pi, x + dx0(), y + dy0());
drawMarkers(pi, x, y);
}
void MathScriptInset::metricsT(TextMetricsInfo const & mi) const
{
metricsT(0, mi);
}
void MathScriptInset::metricsT(MathInset const * nuc,
TextMetricsInfo const & mi) const
{
if (hasUp())
up().metricsT(mi);
if (hasDown())
down().metricsT(mi);
if (nuc)
nuc->metricsT(mi);
//ascent_ = ascent2(nuc);
//descent_ = descent2(nuc);
//width_ = width2(nuc);
nuc().metricsT(mi);
}
void MathScriptInset::drawT(TextPainter & pain, int x, int y) const
{
//lyxerr << "unexpected call to MathScriptInset::draw()\n";
drawT(0, pain, x, y);
}
void MathScriptInset::drawT(MathInset const * nuc, TextPainter & pain,
int x, int y) const
{
if (nuc)
nuc->drawT(pain, x + dxx(nuc), y);
if (nuc().size())
nuc().drawT(pain, x + dxx(), y);
if (hasUp())
up().drawT(pain, x + dx1(nuc), y - dy1(nuc));
up().drawT(pain, x + dx1(), y - dy1());
if (hasDown())
down().drawT(pain, x + dx0(nuc), y + dy0(nuc));
down().drawT(pain, x + dx0(), y + dy0());
}
bool MathScriptInset::hasLimits(MathInset const * nuc) const
bool MathScriptInset::hasLimits() const
{
// obvious cases
if (limits_ == 1)
@ -262,14 +252,14 @@ bool MathScriptInset::hasLimits(MathInset const * nuc) const
return false;
// we can only display limits if the nucleus wants some
if (!nuc)
if (!nuc().size())
return false;
if (!nuc->isScriptable())
if (!nuc().back()->isScriptable())
return false;
// per default \int has limits beside the \int even in displayed formulas
if (nuc->asSymbolInset())
if (nuc->asSymbolInset()->name().find("int") != string::npos)
if (nuc().back()->asSymbolInset())
if (nuc().back()->asSymbolInset()->name().find("int") != string::npos)
return false;
// assume "real" limits for everything else
@ -302,7 +292,7 @@ bool MathScriptInset::has(bool up) const
bool MathScriptInset::empty() const
{
return !script_[0] && !script_[1];
return !script_[0] && !script_[1] && cell(2).empty();
}
@ -318,42 +308,52 @@ bool MathScriptInset::hasDown() const
}
bool MathScriptInset::idxRight(MathInset::idx_type &,
MathInset::pos_type &) const
bool MathScriptInset::idxRight(idx_type &, pos_type &) const
{
return false;
}
bool MathScriptInset::idxLeft(MathInset::idx_type &,
MathInset::pos_type &) const
bool MathScriptInset::idxLeft(idx_type &, pos_type &) const
{
return false;
}
bool MathScriptInset::idxUpDown(idx_type & idx, pos_type & pos, bool up,
int) const
{
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::write(WriteStream & os) const
{
//lyxerr << "unexpected call to MathScriptInset::write()\n";
write2(0, os);
}
void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const
{
if (nuc) {
os << nuc;
if (nuc->takesLimits()) {
if (nuc().size()) {
os << nuc().data();
if (nuc().back()->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
if (limits_ == 1)
os << "\\limits ";
}
} else
if (os.firstitem())
lyxerr[Debug::MATHED] << "suppressing {} when writing\n";
else
os << "{}";
} else {
if (os.firstitem())
lyxerr[Debug::MATHED] << "suppressing {} when writing\n";
else
os << "{}";
}
if (hasDown() && down().data().size())
os << "_{" << down().data() << '}';
@ -365,23 +365,16 @@ void MathScriptInset::write2(MathInset const * nuc, WriteStream & os) const
void MathScriptInset::normalize(NormalStream & os) const
{
//lyxerr << "unexpected call to MathScriptInset::normalize()\n";
normalize2(0, os);
}
void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const
{
bool d = hasDown() && down().data().size();
bool u = hasUp() && up().data().size();
bool d = hasDown() && down().size();
bool u = hasUp() && up().size();
if (u)
os << "[sup ";
if (d)
os << "[sub ";
if (nuc)
os << nuc << ' ';
if (nuc().size())
os << nuc().data() << ' ';
else
os << "[par]";
@ -392,37 +385,39 @@ void MathScriptInset::normalize2(MathInset const * nuc, NormalStream & os) const
}
void MathScriptInset::maplize2(MathInset const * nuc, MapleStream & os) const
void MathScriptInset::maplize(MapleStream & os) const
{
if (nuc)
os << nuc;
if (hasDown() && down().data().size())
if (nuc().size())
os << nuc().data();
if (hasDown() && down().size())
os << '[' << down().data() << ']';
if (hasUp() && up().data().size())
if (hasUp() && up().size())
os << "^(" << up().data() << ')';
}
void MathScriptInset::mathematicize2(MathInset const * nuc, MathematicaStream & os) const
void MathScriptInset::mathematicize(MathematicaStream & os) const
{
bool d = hasDown() && down().data().size();
bool u = hasUp() && up().data().size();
bool d = hasDown() && down().size();
bool u = hasUp() && up().size();
if (nuc)
if (d) //subscript only if nuc !
os << "Subscript[" << nuc;
if (nuc().size()) {
if (d)
os << "Subscript[" << nuc().data();
else
os << nuc;
os << nuc().data();
}
if (u)
os << "^(" << up().data() << ")";
if (nuc)
if (nuc().size())
if (d)
os << "," << down().data() << "]";
os << "," << down().data() << "]";
}
void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const
void MathScriptInset::mathmlize( MathMLStream & os) const
{
bool d = hasDown() && down().data().size();
bool u = hasUp() && up().data().size();
@ -434,8 +429,8 @@ void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const
else if (d)
os << MTag("msub");
if (nuc)
os << nuc;
if (nuc().size())
os << nuc().data();
else
os << "<mrow/>";
@ -448,13 +443,13 @@ void MathScriptInset::mathmlize2(MathInset const * nuc, MathMLStream & os) const
}
void MathScriptInset::octavize2(MathInset const * nuc, OctaveStream & os) const
void MathScriptInset::octavize(OctaveStream & os) const
{
if (nuc)
os << nuc;
if (hasDown() && down().data().size())
if (nuc().size())
os << nuc().data();
if (hasDown() && down().size())
os << '[' << down().data() << ']';
if (hasUp() && up().data().size())
if (hasUp() && up().size())
os << "^(" << up().data() << ')';
}

View File

@ -18,38 +18,41 @@ public:
MathScriptInset();
/// create inset with single script
explicit MathScriptInset(bool up);
/// create inset with single script and given nucleus
MathScriptInset(MathAtom const & at, bool up);
///
MathInset * clone() const;
///
void metrics(MathMetricsInfo & mi) const;
///
void draw(MathPainterInfo & pi, int x, int y) const;
///
void metricsT(TextMetricsInfo const & mi) const;
///
void drawT(TextPainter & pi, int x, int y) const;
/// write LaTeX and Lyx code
void write(WriteStream & os) const;
///
void normalize(NormalStream & os) const;
///
void metrics(MathMetricsInfo & st) const;
///
void draw(MathPainterInfo &, int x, int y) const;
///
void metricsT(TextMetricsInfo const & st) const;
///
void drawT(TextPainter &, 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 normalized content
void normalize(NormalStream &) const;
/// write content as something readable by Maple
void maplize(MapleStream &) const;
/// write content as something readable by Mathematica
void mathematicize(MathematicaStream &) const;
/// write content as something resembling MathML
void mathmlize(MathMLStream &) const;
/// write content as something readable by Octave
void octavize(OctaveStream &) const;
/// move cursor left
bool idxLeft(idx_type &, pos_type &) const;
///
/// move cursor right
bool idxRight(idx_type &, pos_type &) const;
/// move cursor up or down
bool idxUpDown(idx_type & idx, pos_type & pos, bool up, int targetx) const;
/// Target pos when we enter the inset from the left by pressing "Right"
bool idxFirst(idx_type & idx, pos_type & pos) const;
/// Target pos when we enter the inset from the right by pressing "Left"
bool idxLast(idx_type & idx, pos_type & pos) const;
/// can we enter this cell?
bool validCell(idx_type i) const { return script_[i]; }
@ -62,14 +65,18 @@ public:
void limits(int lim) { limits_ = lim; }
/// get limits
int limits() const { return limits_; }
/// true if we have an "inner" position
MathXArray const & up() const;
/// returns subscript
MathXArray const & down() const;
/// returns superscript
MathXArray & up();
/// returns subscript
MathXArray & down();
/// returns superscript
MathXArray const & up() const;
/// returns superscript
MathXArray & up();
/// returns nucleus
MathXArray const & nuc() const;
/// returns nucleus
MathXArray & nuc();
/// do we have a superscript?
bool hasUp() const;
/// do we have a subscript?
@ -87,34 +94,25 @@ public:
///
void infoize(std::ostream & os) const;
// call these methods ...2 to make compaq cxx in anal mode happy...
/// suppresses empty braces if necessary
virtual void write2(MathInset const * nuc, WriteStream & os) const;
virtual void normalize2(MathInset const * nuc, NormalStream & os) const;
virtual void octavize2(MathInset const * nuc, OctaveStream & os) const;
virtual void maplize2(MathInset const * nuc, MapleStream & os) const;
virtual void mathematicize2(MathInset const * nuc, MathematicaStream & os) const;
virtual void mathmlize2(MathInset const * nuc, MathMLStream & os) const;
public:
/// 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 x offset for main part
int dxx() const;
/// returns width of nucleus if any
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];

View File

@ -26,12 +26,13 @@ void MathSqrtInset::metrics(MathMetricsInfo & mi) const
dim_.a = xcell(0).ascent() + 4;
dim_.d = xcell(0).descent() + 2;
dim_.w = xcell(0).width() + 12;
metricsMarkers();
}
void MathSqrtInset::draw(MathPainterInfo & pain, int x, int y) const
void MathSqrtInset::draw(MathPainterInfo & pi, int x, int y) const
{
xcell(0).draw(pain, x + 10, y);
xcell(0).draw(pi, x + 10, y);
int const a = ascent();
int const d = descent();
int xp[4];
@ -40,7 +41,8 @@ void MathSqrtInset::draw(MathPainterInfo & pain, int x, int y) const
xp[1] = x + 8; yp[1] = y - a + 1;
xp[2] = x + 5; yp[2] = y + d - 1;
xp[3] = x; yp[3] = y + (d - a)/2;
pain.pain.lines(xp, yp, 4, LColor::math);
pi.pain.lines(xp, yp, 4, LColor::math);
drawMarkers(pi, x, y);
}

View File

@ -18,9 +18,9 @@ public:
///
MathInset * clone() const;
///
void metrics(MathMetricsInfo & st) const;
void metrics(MathMetricsInfo & mi) const;
///
void draw(MathPainterInfo &, int x, int y) const;
void draw(MathPainterInfo & pi, int x, int y) const;
///
void write(WriteStream & os) const;

View File

@ -20,9 +20,9 @@ public:
///
MathInset * clone() const;
///
void metrics(MathMetricsInfo & st) const;
void metrics(MathMetricsInfo & mi) const;
///
void draw(MathPainterInfo &, int x, int y) const;
void draw(MathPainterInfo & pi, int x, int y) const;
///
string str() const { return str_; }
///

View File

@ -16,7 +16,7 @@ public:
///
MathInset * clone() const;
///
void metrics(MathMetricsInfo & st) const;
void metrics(MathMetricsInfo & mi) const;
///
MathSubstackInset const * asSubstackInset() const { return this; }

View File

@ -4,8 +4,9 @@
#pragma implementation
#endif
#include "math_scriptinset.h"
#include "math_xdata.h"
#include "math_support.h"
#include "math_inset.h"
#include "frontends/Painter.h"
#include "textpainter.h"
#include "debug.h"
@ -16,9 +17,6 @@ using std::min;
using std::abs;
extern MathScriptInset const * asScript(MathArray::const_iterator it);
MathXArray::MathXArray()
: xo_(0), yo_(0), clean_(false), drawn_(false)
{}
@ -35,33 +33,19 @@ Dimension const & MathXArray::metrics(MathMetricsInfo & mi) const
{
//if (clean_)
// return;
size_ = mi;
clean_ = true;
drawn_ = false;
if (data_.empty()) {
if (empty()) {
mathed_char_dim(mi.base.font, 'I', dim_);
return dim_;
}
dim_.clear();
for (const_iterator it = begin(); it != end(); ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
Dimension d;
if (q) {
q->metrics(p, mi);
q->dimensions2(p, d);
++it;
} else {
p->metrics(mi);
p->dimensions(d);
}
dim_ += d;
for (const_iterator it = begin(), et = end(); it != et; ++it) {
(*it)->metrics(mi);
dim_ += (*it)->dimensions();
}
//lyxerr << "MathXArray::metrics(): '" << dim_ << "\n";
return dim_;
}
@ -72,33 +56,21 @@ void MathXArray::metricsExternal(MathMetricsInfo & mi,
//if (clean_)
// return;
size_ = mi;
clean_ = true;
drawn_ = false;
if (data_.empty()) {
if (empty()) {
mathed_char_dim(mi.base.font, 'I', dim_);
return;
}
dim_.clear();
for (const_iterator it = begin(); it != end(); ++it) {
for (const_iterator it = begin(), et = end(); it != et; ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
Dimension d;
if (q) {
q->metrics(p, mi);
q->dimensions2(p, d);
v.push_back(d);
v.push_back(Dimension());
++it;
} else {
p->metrics(mi);
p->dimensions(d);
v.push_back(d);
}
p->metrics(mi);
v.push_back(p->dimensions());
}
//for (int i = 0; i < data_.size(); ++i)
//for (int i = 0; i < size(); ++i)
// lyxerr << "i: " << i << " dim: " << v[i] << endl;
//lyxerr << "MathXArray::metrics(): '" << dim_ << "\n";
}
@ -132,16 +104,8 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const
}
for (; it != et; ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
if (q) {
q->draw(p, pi, x, y);
x += q->width2(p);
++it;
} else {
p->draw(pi, x, y);
x += p->width();
}
(*it)->draw(pi, x, y);
x += (*it)->width();
}
}
@ -151,7 +115,7 @@ void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y,
{
//for (size_type r = 0; r < v.size(); ++r)
// lyxerr << "row " << r << " to: " << v[r].end << endl;
//lyxerr << " data: " << data_ << endl;
//lyxerr << " data: " << *this << endl;
xo_ = x;
yo_ = y;
@ -159,26 +123,16 @@ void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y,
for (size_type r = 0; r < v.size(); ++r) {
int xx = x;
int yy = y + v[r].yo;
for (size_type pos = v[r].begin; pos < v[r].end && pos < data_.size(); ++pos) {
//lyxerr << "drawing pos " << pos << " of " << data_.size()
// << " " << int(data_[pos]->getChar()) << endl;
MathInset const * p = data_[pos].nucleus();
// insert extra glue
for (size_type pos = v[r].begin; pos < v[r].end && pos < size(); ++pos) {
//lyxerr << "drawing pos " << pos << " of " << size()
// << " " << int(operator[](pos)->getChar()) << endl;
MathInset const * p = operator[](pos).nucleus();
// insert extra glue if necessary
if (p->getChar() == ' ')
xx += v[r].glue;
MathScriptInset const * q = 0;
if (pos + 1 < data_.size())
q = asScript(begin() + pos);
if (q) {
q->draw(p, pi, xx, yy);
xx += q->width2(p);
++pos;
} else {
p->draw(pi, xx, yy);
xx += p->width();
}
// ordinary case
p->draw(pi, xx, yy);
xx += p->width();
}
}
}
@ -190,18 +144,8 @@ Dimension const & MathXArray::metricsT(TextMetricsInfo const & mi) const
// return;
dim_.clear();
for (const_iterator it = begin(); it != end(); ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
Dimension d;
if (q) {
q->metricsT(p, mi);
q->dimensions2(p, d);
++it;
} else {
p->metricsT(mi);
p->dimensions(d);
}
dim_ += d;
(*it)->metricsT(mi);
dim_ += (*it)->dimensions();
}
return dim_;
}
@ -222,15 +166,8 @@ void MathXArray::drawT(TextPainter & pain, int x, int y) const
for (; it != et; ++it) {
MathInset const * p = it->nucleus();
MathScriptInset const * q = (it + 1 == et) ? 0 : asScript(it);
if (q) {
q->drawT(p, pain, x, y);
x += q->width2(p);
++it;
} else {
p->drawT(pain, x, y);
x += p->width();
}
p->drawT(pain, x, y);
x += p->width();
}
}
@ -244,21 +181,13 @@ int MathXArray::pos2x(size_type pos) const
int MathXArray::pos2x(size_type pos1, size_type pos2, int glue) const
{
int x = 0;
size_type target = min(pos2, data_.size());
size_type target = min(pos2, size());
for (size_type i = pos1; i < target; ++i) {
const_iterator it = begin() + i;
MathInset const * p = it->nucleus();
if (p->getChar() == ' ')
x += glue;
MathScriptInset const * q = (i + 1 == data_.size()) ? 0 : asScript(it);
if (q) {
++i;
if (i < target)
x += q->width2(p);
else // "half" position
x += q->dxx(p) + q->nwid(p);
} else
x += p->width();
x += p->width();
}
return x;
}
@ -277,21 +206,11 @@ MathArray::size_type MathXArray::x2pos(size_type startpos, int targetx,
int lastx = 0;
int currx = 0;
for (; currx < targetx && it < end(); ++it) {
size_type pos = it - begin();
lastx = currx;
MathInset const * p = it->nucleus();
if (p->getChar() == ' ')
currx += glue;
MathScriptInset const * q = 0;
if (it + 1 != end())
q = asScript(it);
if (q) {
currx += q->width2(p);
++it;
} else {
currx += p->width();
}
currx += p->width();
}
if (abs(lastx - targetx) < abs(currx - targetx) && it != begin() + startpos)
--it;
@ -339,16 +258,7 @@ void MathXArray::findPos(MathPosFinder & f) const
// check inset
MathInset const * p = it->nucleus();
p->findPos(f);
// move on
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
if (q) {
x += q->width(p);
f.nextPos();
++it;
} else {
x += p->width();
}
x += p->width();
}
}
*/

View File

@ -20,13 +20,21 @@ class TextPainter;
/** This class extends a MathArray by drawing routines and caches for
* metric information.
*/
class MathXArray
class MathXArray : private MathArray
{
public:
/// type for positions and sizes
typedef MathArray::size_type size_type;
/// const iterator into the underlying MathArray
typedef MathArray::const_iterator const_iterator;
// re-use inherited stuff
using MathArray::size_type;
using MathArray::const_iterator;
using MathArray::begin;
using MathArray::end;
using MathArray::operator[];
using MathArray::clear;
using MathArray::size;
using MathArray::empty;
using MathArray::back;
MathArray & data() { return *this; }
MathArray const & data() const { return *this; }
// helper structure for external metrics computations as done
// in parboxes
@ -104,26 +112,14 @@ public:
/// adjust (x,y) to point on boundary on a straight line from the center
void towards(int & x, int & y) const;
/// begin iterator of the underlying MathArray
const_iterator begin() const { return data_.begin(); }
/// end iterator of the underlying MathArray
const_iterator end() const { return data_.end(); }
/// access to data
MathArray const & data() const { return data_; }
/// access to data
MathArray & data() { return data_; }
private:
/// the underlying MathArray
MathArray data_;
/// cached dimensions of cell
mutable Dimension dim_;
/// cached x coordinate of last drawing
mutable int xo_;
/// cached y coordinate of last drawing
mutable int yo_;
/// cache size information of last drawing
mutable MathMetricsInfo size_;
/// cached cleaness of cell
mutable bool clean_;
/// cached draw status of cell