X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fxarray.C;h=54b83322bafa6f8ec9a74cb184c9aecd6ca98565;hb=970f0247f7d3ebbabc1348549ef4bd8d9b335545;hp=688ef4b83ba22a044380d65ba4afd122dc941f01;hpb=ec5d8718c51e86b6300de5de29732634cace81d3;p=lyx.git diff --git a/src/mathed/xarray.C b/src/mathed/xarray.C index 688ef4b83b..54b83322ba 100644 --- a/src/mathed/xarray.C +++ b/src/mathed/xarray.C @@ -1,4 +1,3 @@ - #include #ifdef __GNUG__ @@ -7,53 +6,52 @@ #include "xarray.h" #include "math_inset.h" +#include "math_scriptinset.h" #include "mathed/support.h" #include "math_defs.h" #include "Painter.h" +#include "debug.h" -using std::max; -using std::min; MathXArray::MathXArray() - : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), style_(LM_ST_TEXT) + : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), size_() {} -void MathXArray::Metrics(MathStyles st) +void MathXArray::metrics(MathMetricsInfo const & st) const { - if (data_.empty()) { - mathed_char_dim(LM_TC_VAR, st, 'I', ascent_, descent_, width_); + size_ = st; + mathed_char_dim(LM_TC_VAR, st, 'I', ascent_, descent_, width_); + + if (data_.empty()) return; - } + + math_font_max_dim(LM_TC_TEXTRM, st, ascent_, descent_); + width_ = 0; + + //lyxerr << "MathXArray::metrics(): '" << data_ << "'\n"; - ascent_ = 0; - descent_ = 0; - width_ = 0; - style_ = st; - - for (int pos = 0; pos < data_.size(); data_.next(pos)) { - MathInset * p = data_.GetInset(pos); - if (p) { - p->Metrics(st); - ascent_ = max(ascent_, p->ascent()); - descent_ = max(descent_, p->descent()); - width_ += p->width(); + for (const_iterator it = begin(); it != end(); ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + q->metrics(p, st); + ascent_ = std::max(ascent_, q->ascent(p)); + descent_ = std::max(descent_, q->descent(p)); + width_ += q->width(p); + ++it; } else { - char cx = data_.GetChar(pos); - MathTextCodes fc = data_.GetCode(pos); - int asc; - int des; - int wid; - mathed_char_dim(fc, style_, cx, asc, des, wid); - ascent_ = max(ascent_, asc); - descent_ = max(descent_, des); - width_ += wid; + p->metrics(st); + ascent_ = std::max(ascent_, p->ascent()); + descent_ = std::max(descent_, p->descent()); + width_ += p->width(); } } + //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " + // << descent_ << " " << width_ << "'\n"; } -void MathXArray::draw(Painter & pain, int x, int y) +void MathXArray::draw(Painter & pain, int x, int y) const { xo_ = x; yo_ = y; @@ -63,55 +61,65 @@ void MathXArray::draw(Painter & pain, int x, int y) return; } - for (int pos = 0; pos < data_.size(); data_.next(pos)) { - MathInset * p = data_.GetInset(pos); - if (p) { + for (const_iterator it = begin(); it != end(); ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + q->draw(p, pain, x, y); + x += q->width(p); + ++it; + } else { p->draw(pain, x, y); x += p->width(); - } else { - char cx = data_.GetChar(pos); - MathTextCodes fc = data_.GetCode(pos); - string s; - s += cx; - drawStr(pain, fc, style_, x, y, s); - x += mathed_char_width(fc, style_, cx); } } } -int MathXArray::pos2x(int targetpos) const +int MathXArray::pos2x(size_type targetpos) const { int x = 0; - targetpos = min(targetpos, data_.size()); - for (int pos = 0; pos < targetpos; data_.next(pos)) - x += width(pos); + const_iterator target = std::min(begin() + targetpos, end()); + for (const_iterator it = begin(); it < target; ++it) { + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + ++it; + if (it < target) + x += q->width(p); + else // "half" position + x += q->dxx(p) + q->nwid(p); + } else + x += p->width(); + } return x; } -int MathXArray::x2pos(int targetx) const +MathArray::size_type MathXArray::x2pos(int targetx) const { - int pos = 0; - for (int x = 0; x < targetx && pos < data_.size(); data_.next(pos)) - x += width(pos); - return pos; + const_iterator it = begin(); + int lastx = 0; + int currx = 0; + for ( ; currx < targetx && it < end(); ++it) { + lastx = currx; + + int wid = 0; + MathInset const * p = it->nucleus(); + if (MathScriptInset const * q = data_.asScript(it)) { + wid = q->width(p); + ++it; + } else + wid = p->width(); + + currx += wid; + } + if (abs(lastx - targetx) < abs(currx - targetx) && it != begin()) + --it; + return it - begin(); } -int MathXArray::width(int pos) const -{ - if (pos >= data_.size()) - return 0; - - if (data_.isInset(pos)) - return data_.GetInset(pos)->width(); - else - return mathed_char_width(data_.GetCode(pos), style_, data_.GetChar(pos)); -} std::ostream & operator<<(std::ostream & os, MathXArray const & ar) { os << ar.data_; return os; } -