From: André Pönitz Date: Tue, 16 Jul 2002 18:22:45 +0000 (+0000) Subject: more work on \parbox support X-Git-Tag: 1.6.10~18856 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=7c3cc29952efca546f407205a467bd7b27495c1e;p=features.git more work on \parbox support git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4657 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/mathed/dimension.C b/src/mathed/dimension.C index a756c7bf4f..04b30ff8e7 100644 --- a/src/mathed/dimension.C +++ b/src/mathed/dimension.C @@ -1,5 +1,10 @@ +#include #include "dimension.h" +#include "math_support.h" + +#include + void Dimension::operator+=(Dimension const & dim) { @@ -9,3 +14,17 @@ void Dimension::operator+=(Dimension const & dim) d = dim.d; w += dim.w; } + + +std::ostream & operator<<(std::ostream & os, Dimension const & dim) +{ + os << " (" << dim.w << 'x' << dim.a << '-' << dim.d << ") "; + return os; +} + + +void Dimension::clear(LyXFont const & font) +{ + math_font_max_dim(font, a, d); + w = 0; +} diff --git a/src/mathed/dimension.h b/src/mathed/dimension.h index ab672568a9..ca19dee251 100644 --- a/src/mathed/dimension.h +++ b/src/mathed/dimension.h @@ -1,6 +1,10 @@ #ifndef DIMENSION_H #define DIMENSION_H +#include + +class LyXFont; + class Dimension { public: /// constructor @@ -12,6 +16,8 @@ public: void operator+=(Dimension const & dim); /// set to empty box void clear() { w = a = d = 0; } + /// set to empty box suitble for given font + void clear(LyXFont const & font); /// get height int height() const { return a + d; } /// get ascent @@ -30,4 +36,6 @@ public: int d; }; +std::ostream & operator<<(std::ostream & os, Dimension const & dim); + #endif diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 18113f0920..e8c887262d 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -719,15 +719,7 @@ void MathCursor::handleNest(MathInset * p) void MathCursor::getPos(int & x, int & y) { -#ifdef WITH_WARNINGS -#warning This should probably take cellXOffset and cellYOffset into account -#endif - x = xarray().xo() + xarray().pos2x(pos()); - // move cursor visually into empty cells ("blue rectangles"); - if (array().empty()) - x += 2; - y = xarray().yo(); - //lyxerr << "getPos: " << x << " " << y << "\n"; + par()->getPos(idx(), pos(), x, y); } diff --git a/src/mathed/math_inset.C b/src/mathed/math_inset.C index dd2a838281..90138a48c0 100644 --- a/src/mathed/math_inset.C +++ b/src/mathed/math_inset.C @@ -173,6 +173,13 @@ bool MathInset::idxEnd(idx_type &, pos_type &) const } +void MathInset::getPos(idx_type, pos_type, int & x, int & y) const +{ + lyxerr << "MathInset::getPos() called directly!\n"; + x = y = 0; +} + + void MathInset::normalize(NormalStream & os) const { os << "[unknown "; diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 26b1e914c5..5becf7ed11 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -132,6 +132,8 @@ public: virtual void dimensions(Dimension & dim) const; /// total height (== ascent + descent) virtual int height() const; + /// get cursor position + virtual void getPos(idx_type idx, pos_type pos, int & x, int & y) const; /// Where should we go when we press the up or down cursor key? virtual bool idxUpDown(idx_type & idx, bool up) const; diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 16179f570b..520474d197 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -48,6 +48,15 @@ MathArray const & MathNestInset::cell(idx_type i) const } +void MathNestInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const +{ + x = cells_[idx].xo() + cells_[idx].pos2x(pos); + y = cells_[idx].yo(); + // move cursor visually into empty cells ("blue rectangles"); + if (!cells_[idx].data().size()) + x += 2; +} + void MathNestInset::substitute(MathMacro const & m) { for (idx_type i = 0; i < nargs(); ++i) diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index 32555e7a1d..ba791df4d7 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -36,6 +36,8 @@ public: void substitute(MathMacro const & macro); /// identifies NestInsets MathNestInset * asNestInset() { return this; } + /// get cursor position + void getPos(idx_type idx, pos_type pos, int & x, int & y) const; /// order of movement through the cells when pressing the left key bool idxLeft(idx_type & idx, pos_type & pos) const; diff --git a/src/mathed/math_parboxinset.C b/src/mathed/math_parboxinset.C index 410912d62c..60b748c19d 100644 --- a/src/mathed/math_parboxinset.C +++ b/src/mathed/math_parboxinset.C @@ -34,6 +34,22 @@ void MathParboxInset::setWidth(string const & w) } +void MathParboxInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const +{ + for (int r = 0, n = rows_.size(); r < n; ++r) { + if (pos >= rows_[r].begin && pos < rows_[r].end) { + //lyxerr << "found cursor at pos " << pos << " in row " << r << "\n"; + x = cells_[0].xo() + cells_[0].pos2x(rows_[r].begin, pos, rows_[r].glue); + y = cells_[0].yo() + rows_[r].yo; + break; + } + } + // move cursor visually into empty cells ("blue rectangles"); + if (cell(0).empty()) + x += 2; +} + + void MathParboxInset::metrics(MathMetricsInfo & mi) const { MathFontSetChanger dummy(mi.base, "textnormal"); @@ -42,68 +58,100 @@ void MathParboxInset::metrics(MathMetricsInfo & mi) const // delete old cache rows_.clear(); -#if 1 +#if 0 dim_ = xcell(0).metrics(mi); #else - xcell(0).metricsExternal(mi, rows_); + vector dims; + xcell(0).metricsExternal(mi, dims); int spaces = 0; - Dimension safe(0, 0, 0); - Dimension curr(0, 0, 0); + Dimension safe; + Dimension curr; + safe.clear(mi.base.font); + curr.clear(mi.base.font); + int begin = 0; int safepos = 0; int yo = 0; - for (size_type i = 0, n = cell(0).size(); i != n; ++i) { + for (size_type i = 0, n = cell(0).size(); i < n; ++i) { + //lyxerr << "at pos: " << i << " of " << n << " safepos: " << safepos + // << " curr: " << curr << " safe: " << safe + // << " spaces: " << spaces << endl; + + + // 0 1 2 3 4 5 6 + // + // ................... + // .......................... + // .................... + // Special handling of spaces. We reached a safe position for breaking. if (cell(0)[i]->getChar() == ' ') { + //lyxerr << "reached safe pos\n"; + // we don't count the space into the safe pos safe += curr; - safepos = i + 1; + // we reset to this safepos if the next chunk does not fit + safepos = i; ++spaces; - // restart chunk - curr = Dimension(0, 0, 0); + // restart chunk with size of the space + curr.clear(mi.base.font); + curr += dims[i]; continue; } - // This is a regular item. Go on if we either don't care for + // This is a regular char. Go on if we either don't care for // the width limit or have not reached that limit. - curr += rows_[i].dim; + curr += dims[i]; if (curr.w + safe.w <= lyx_width_) continue; // We passed the limit. Create a row entry. + //lyxerr << "passed limit\n"; MathXArray::Row row; if (spaces) { // but we had a space break before this position. - row.dim = safe; - row.glue = (lyx_width_ - safe.w) / spaces; - row.end = safepos; - i = safepos; + // so retreat to this position + row.dim = safe; + row.glue = (lyx_width_ - safe.w) / spaces; + row.begin = begin; + row.end = safepos; // this is position of the safe space + i = safepos; // i gets incremented at end of loop + begin = i + 1; // next chunk starts after the space + //lyxerr << "... but had safe pos. glue: " << row.glue << "\n"; spaces = 0; } else { + lyxerr << "... without safe pos\n"; // This item is too large and it is the only one. // We have no choice but to produce an overfull box. - row.dim = curr; // safe should be 0. - row.glue = 0; // does not matter - row.end = i + 1; + row.dim = curr; // safe should be 0. + row.glue = 0; // does not matter + row.begin = begin; + row.end = i + 1; + begin = i + 1; } - yo += rows_[i].dim.height(); row.yo = yo; + yo += row.dim.height(); rows_.push_back(row); + // in any case, start the new row with empty boxes + curr.clear(mi.base.font); + safe.clear(mi.base.font); } - // last row: + // last row: put in everything else MathXArray::Row row; - row.dim = safe; - row.dim += curr; - row.end = cell(0).size(); - row.glue = spaces ? (lyx_width_ - row.dim.w) / spaces : 0; - yo += row.dim.height(); - row.yo = yo; + row.dim = safe; + row.dim += curr; + row.begin = begin; + row.end = cell(0).size(); + row.glue = 0; // last line is left aligned + row.yo = yo; rows_.push_back(row); // what to report? - dim_ = xcell(0).dim(); + dim_.w = lyx_width_; + dim_.a = rows_.front().dim.a; + dim_.d = rows_.back().dim.d + yo; metricsMarkers(); #endif } @@ -112,7 +160,7 @@ void MathParboxInset::metrics(MathMetricsInfo & mi) const void MathParboxInset::draw(MathPainterInfo & pi, int x, int y) const { MathFontSetChanger dummy(pi.base, "textnormal"); -#if 1 +#if 0 xcell(0).draw(pi, x + 1, y); #else xcell(0).drawExternal(pi, x + 1, y, rows_); diff --git a/src/mathed/math_parboxinset.h b/src/mathed/math_parboxinset.h index 1b6785b5d4..f7305478cd 100644 --- a/src/mathed/math_parboxinset.h +++ b/src/mathed/math_parboxinset.h @@ -11,6 +11,8 @@ public: MathParboxInset * asParboxInset() { return this; } /// MathInset * clone() const; + /// get cursor position + void getPos(idx_type idx, pos_type pos, int & x, int & y) const; /// void metrics(MathMetricsInfo & mi) const; /// diff --git a/src/mathed/math_xdata.C b/src/mathed/math_xdata.C index 2216623f5a..a88b7fc813 100644 --- a/src/mathed/math_xdata.C +++ b/src/mathed/math_xdata.C @@ -67,7 +67,7 @@ Dimension const & MathXArray::metrics(MathMetricsInfo & mi) const void MathXArray::metricsExternal(MathMetricsInfo & mi, - std::vector & v) const + std::vector & v) const { //if (clean_) // return; @@ -89,18 +89,18 @@ void MathXArray::metricsExternal(MathMetricsInfo & mi, if (q) { q->metrics(p, mi); q->dimensions2(p, d); + v.push_back(d); + v.push_back(Dimension()); ++it; - v.push_back(Row()); - v.back().dim = d; - v.push_back(Row()); } else { p->metrics(mi); p->dimensions(d); - v.push_back(Row()); - v.back().dim = d; + v.push_back(d); } } + //for (int i = 0; i < data_.size(); ++i) + // lyxerr << "i: " << i << " dim: " << v[i] << endl; //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; } @@ -150,14 +150,28 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const 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) { + //for (size_type r = 0; r < v.size(); ++r) + // lyxerr << "row " << r << " to: " << v[r].end << endl; + //lyxerr << " data: " << data_ << endl; + + xo_ = x; + yo_ = y; + + for (size_type r = 0; r < v.size(); ++r) { int xx = x; int yy = y + v[r].yo; - for ( ; pos != v[r].end; ++pos) { + 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 + if (p->getChar() == ' ') + xx += v[r].glue; + MathScriptInset const * q = 0; - if (pos + 1 != data_.size()) - q = asScript(begin() + pos + 1); + if (pos + 1 < data_.size()) + q = asScript(begin() + pos); if (q) { q->draw(p, pi, xx, yy); xx += q->width2(p); @@ -222,16 +236,24 @@ void MathXArray::drawT(TextPainter & pain, int x, int y) const } -int MathXArray::pos2x(size_type targetpos) const +int MathXArray::pos2x(size_type pos) const +{ + return pos2x(0, pos, 0); +} + +int MathXArray::pos2x(size_type pos1, size_type pos2, int glue) const { int x = 0; - const_iterator target = min(begin() + targetpos, end()); - for (const_iterator it = begin(); it < target; ++it) { + size_type target = min(pos2, data_.size()); + for (size_type i = pos1; i < target; ++i) { + const_iterator it = begin() + i; MathInset const * p = it->nucleus(); - MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); + if (p->getChar() == ' ') + x += glue; + MathScriptInset const * q = (i + 1 == data_.size()) ? 0 : asScript(it); if (q) { - ++it; - if (it < target) + ++i; + if (i < target) x += q->width2(p); else // "half" position x += q->dxx(p) + q->nwid(p); diff --git a/src/mathed/math_xdata.h b/src/mathed/math_xdata.h index a22735eefd..2bb7a2ff0d 100644 --- a/src/mathed/math_xdata.h +++ b/src/mathed/math_xdata.h @@ -33,6 +33,8 @@ public: struct Row { /// constructor Row() {} + /// first position of this row + size_type begin; /// last position of this row plus one size_type end; /// y offset relative to yo @@ -48,8 +50,7 @@ public: /// rebuild cached metrics information Dimension const & metrics(MathMetricsInfo & mi) const; /// rebuild cached metrics information - void metricsExternal(MathMetricsInfo & mi, - std::vector &) const; + void metricsExternal(MathMetricsInfo & mi, std::vector &) const; /// redraw cell using cache metrics information void draw(MathPainterInfo & pi, int x, int y) const; /// redraw cell using external metrics information @@ -73,6 +74,8 @@ public: /// returns x coordinate of given position in the array int pos2x(size_type pos) const; /// returns position of given x coordinate + int pos2x(size_type pos1, size_type pos2, int glue) const; + /// returns position of given x coordinate size_type x2pos(int pos) const; /// returns distance of this cell to the point given by x and y // assumes valid position and size cache