X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fmath_xdata.C;h=fff922a5720c5b21e01e3ad14f21f2e28f0cf05b;hb=d359dd8fca52c4f0100f7cf4bf636113c5c4e49f;hp=cffec88712d762a48e5ac119cf2a6443e7b90bd0;hpb=c93e9dcbc59d0b404561dbc7c373716f11fc13f1;p=lyx.git diff --git a/src/mathed/math_xdata.C b/src/mathed/math_xdata.C index cffec88712..fff922a572 100644 --- a/src/mathed/math_xdata.C +++ b/src/mathed/math_xdata.C @@ -6,71 +6,214 @@ #include "math_scriptinset.h" #include "math_support.h" -#include "Painter.h" +#include "frontends/Painter.h" +#include "textpainter.h" #include "debug.h" +using std::max; +using std::min; +using std::abs; + + extern MathScriptInset const * asScript(MathArray::const_iterator it); MathXArray::MathXArray() - : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), size_() + : xo_(0), yo_(0), clean_(false), drawn_(false) {} -void MathXArray::metrics(MathMetricsInfo const & st) const +void MathXArray::touch() const { - size_ = st; - mathed_char_dim(LM_TC_VAR, st, 'I', ascent_, descent_, width_); + clean_ = false; + drawn_ = false; +} - if (data_.empty()) - return; - math_font_max_dim(LM_TC_TEXTRM, st, ascent_, descent_); - width_ = 0; +void MathXArray::metrics(MathMetricsInfo & mi) const +{ + //if (clean_) + // return; + + size_ = mi; + clean_ = true; + drawn_ = false; - //lyxerr << "MathXArray::metrics(): '" << data_ << "'\n"; - + if (data_.empty()) { + mathed_char_dim(mi.base.font, 'I', dim_.a, dim_.d, dim_.w); + 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); + int ww, aa, dd; if (q) { - q->metrics(p, st); - ascent_ = std::max(ascent_, q->ascent(p)); - descent_ = std::max(descent_, q->descent(p)); - width_ += q->width(p); + q->metrics(p, mi); + q->dimensions2(p, ww, aa, dd); ++it; } else { - p->metrics(st); - ascent_ = std::max(ascent_, p->ascent()); - descent_ = std::max(descent_, p->descent()); - width_ += p->width(); + p->metrics(mi); + p->dimensions(ww, aa, dd); } + dim_ += Dimension(ww, aa, dd); } - //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " - // << descent_ << " " << width_ << "'\n"; + + //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; } -void MathXArray::draw(Painter & pain, int x, int y) const +void MathXArray::metricsExternal(MathMetricsInfo & mi, + std::vector & v) const { - xo_ = x; - yo_ = y; + //if (clean_) + // return; + + size_ = mi; + clean_ = true; + drawn_ = false; if (data_.empty()) { - pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline); + mathed_char_dim(mi.base.font, 'I', dim_.a, dim_.d, dim_.w); 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); + int ww, aa, dd; if (q) { - q->draw(p, pain, x, y); - x += q->width(p); + q->metrics(p, mi); + q->dimensions2(p, ww, aa, dd); + ++it; + v.push_back(Row()); + v.back().dim = Dimension(ww, aa, dd); + v.push_back(Row()); + } else { + p->metrics(mi); + p->dimensions(ww, aa, dd); + v.push_back(Row()); + v.back().dim = Dimension(ww, aa, dd); + } + } + + //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; +} + + +void MathXArray::draw(MathPainterInfo & pi, int x, int y) const +{ + //if (drawn_ && x == xo_ && y == yo_) + // return; + + //lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl; + + xo_ = x; + yo_ = y; + drawn_ = true; + + if (y + descent() <= 0) // don't draw above the workarea + return; + if (y - ascent() >= pi.pain.paperHeight()) // don't draw below the workarea + return; + if (x + width() <= 0) // don't draw left of workarea + return; + if (x >= pi.pain.paperWidth()) // don't draw right of workarea + return; + + const_iterator it = begin(), et = end(); + + if (it == et) { + pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); + return; + } + + 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(pain, x, y); + p->draw(pi, x, y); + x += p->width(); + } + } +} + + +void MathXArray::drawExternal(MathPainterInfo & pi, int x, int y, + std::vector const & v) const +{ + for (size_type r = 0, pos = 0; r != v.size(); ++r) { + int xx = x; + int yy = y + v[r].yo; + for ( ; pos != v[r].end; ++pos) { + MathInset const * p = data_[pos].nucleus(); + MathScriptInset const * q = 0; + if (pos + 1 != data_.size()) + q = asScript(begin() + pos + 1); + if (q) { + q->draw(p, pi, xx, yy); + xx += q->width2(p); + ++pos; + } else { + p->draw(pi, xx, yy); + xx += p->width(); + } + } + } +} + + +void MathXArray::metricsT(TextMetricsInfo const & mi) const +{ + //if (clean_) + // 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); + int ww, aa, dd; + if (q) { + q->metricsT(p, mi); + q->dimensions2(p, ww, aa, dd); + ++it; + } else { + p->metricsT(mi); + p->dimensions(ww, aa, dd); + } + dim_ += Dimension(ww, aa, dd); + } +} + + +void MathXArray::drawT(TextPainter & pain, int x, int y) const +{ + //if (drawn_ && x == xo_ && y == yo_) + // return; + + //lyxerr << "x: " << x << " y: " << y << " " << pain.workAreaHeight() << endl; + + xo_ = x; + yo_ = y; + drawn_ = true; + + const_iterator it = begin(), et = end(); + + 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(); } } @@ -80,14 +223,14 @@ void MathXArray::draw(Painter & pain, int x, int y) const int MathXArray::pos2x(size_type targetpos) const { int x = 0; - const_iterator target = std::min(begin() + targetpos, end()); + const_iterator target = min(begin() + targetpos, end()); for (const_iterator it = begin(); it < target; ++it) { MathInset const * p = it->nucleus(); MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); if (q) { ++it; if (it < target) - x += q->width(p); + x += q->width2(p); else // "half" position x += q->dxx(p) + q->nwid(p); } else @@ -102,7 +245,7 @@ MathArray::size_type MathXArray::x2pos(int targetx) const const_iterator it = begin(); int lastx = 0; int currx = 0; - for ( ; currx < targetx && it < end(); ++it) { + for (; currx < targetx && it < end(); ++it) { lastx = currx; int wid = 0; @@ -111,7 +254,7 @@ MathArray::size_type MathXArray::x2pos(int targetx) const if (it + 1 != end()) q = asScript(it); if (q) { - wid = q->width(p); + wid = q->width2(p); ++it; } else wid = p->width(); @@ -122,3 +265,78 @@ MathArray::size_type MathXArray::x2pos(int targetx) const --it; return it - begin(); } + + +int MathXArray::dist(int x, int y) const +{ + int xx = 0; + int yy = 0; + + if (x < xo_) + xx = xo_ - x; + else if (x > xo_ + width()) + xx = x - xo_ - width(); + + if (y < yo_ - ascent()) + yy = yo_ - ascent() - y; + else if (y > yo_ + descent()) + yy = y - yo_ - descent(); + + return xx + yy; +} + + +void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2) +{ + x1 = xo_; + x2 = xo_ + width(); + y1 = yo_ - ascent(); + y2 = yo_ + descent(); +} + +/* +void MathXArray::findPos(MathPosFinder & f) const +{ + double x = xo_; + double y = yo_; + for (const_iterator it = begin(); it < end(); ++it) { + // check this position in the cell first + f.visit(x, y); + f.nextPos(); + + // 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(); + } + } +} +*/ + +void MathXArray::center(int & x, int & y) const +{ + x = xo_ + width() / 2; + y = yo_ + (descent() - ascent()) / 2; +} + + +void MathXArray::towards(int & x, int & y) const +{ + int cx = 0; + int cy = 0; + center(cx, cy); + + double r = 1.0; + //int dist = (x - cx) * (x - cx) + (y - cy) * (y - cy); + + x = cx + int(r * (x - cx)); + y = cy + int(r * (y - cy)); +}