From 30b0c731b40ab9f604403c8210fe75ce30a01824 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Tue, 9 Jul 2002 08:24:33 +0000 Subject: [PATCH] some code shuffling. New 'Dimension' class instead of passing around three seperate ints git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4559 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/Makefile.am | 2 + src/mathed/math_gridinset.C | 5 +- src/mathed/math_parboxinset.C | 79 ++++++++++++++++++++-- src/mathed/math_parboxinset.h | 6 +- src/mathed/math_xdata.C | 124 ++++++++++++++++++++++------------ src/mathed/math_xdata.h | 53 ++++++++------- 6 files changed, 191 insertions(+), 78 deletions(-) diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index 8b1e7eba8a..643d13f94a 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -5,6 +5,8 @@ noinst_LTLIBRARIES = libmathed.la INCLUDES = -I$(srcdir)/../ $(SIGC_CFLAGS) $(BOOST_INCLUDES) libmathed_la_SOURCES = \ + dimension.C \ + dimension.h \ textpainter.C \ textpainter.h \ formulabase.C \ diff --git a/src/mathed/math_gridinset.C b/src/mathed/math_gridinset.C index 2b6ae2b92e..2b2adbb518 100644 --- a/src/mathed/math_gridinset.C +++ b/src/mathed/math_gridinset.C @@ -49,10 +49,7 @@ MathGridInset::RowInfo::RowInfo() int MathGridInset::RowInfo::skipPixels() const { -#ifdef WITH_WARNINGS -#warning fix this once the interface to LyXLength has improved -#endif - return int(crskip_.value()); + return crskip_.inBP(); } diff --git a/src/mathed/math_parboxinset.C b/src/mathed/math_parboxinset.C index 254a678767..93ebf41666 100644 --- a/src/mathed/math_parboxinset.C +++ b/src/mathed/math_parboxinset.C @@ -36,20 +36,91 @@ void MathParboxInset::setWidth(string const & w) void MathParboxInset::metrics(MathMetricsInfo & mi) const { - MathFontSetChanger dummy1(mi.base, "textnormal"); - MathWidthChanger dummy2(mi.base, lyx_width_); + MathFontSetChanger dummy(mi.base, "textnormal"); + + // we do our own metrics fiddling + // delete old cache + rows_.clear(); + +#if 1 + xcell(0).metrics(mi); + width_ = xcell(0).width(); + ascent_ = xcell(0).ascent(); + descent_ = xcell(0).descent(); + +#else + + xcell(0).metricsExternal(mi, rows_); + + int spaces = 0; + Dimension safe(0, 0, 0); + Dimension curr(0, 0, 0); + int safepos = 0; + int yo = 0; + for (size_type i = 0, n = cell(0).size(); i != n; ++i) { + // Special handling of spaces. We reached a safe position for breaking. + if (cell(0)[i]->getChar() == ' ') { + safe += curr; + safepos = i + 1; + ++spaces; + // restart chunk + curr = Dimension(0, 0, 0); + continue; + } + + // This is a regular item. Go on if we either don't care for + // the width limit or have not reached that limit. + curr += rows_[i].dim; + if (curr.w + safe.w <= lyx_width_) + continue; + + // We passed the limit. Create a row entry. + 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; + spaces = 0; + } else { + // 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; + } + yo += rows_[i].dim.height(); + row.yo = yo; + rows_.push_back(row); + } + // last row: + 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; + rows_.push_back(row); + + // what to report? ascent_ = xcell(0).ascent(); descent_ = xcell(0).descent() + 1; width_ = xcell(0).width() + 2; +#endif } void MathParboxInset::draw(MathPainterInfo & pi, int x, int y) const { - MathFontSetChanger dummy1(pi.base, "textnormal"); - MathWidthChanger dummy2(pi.base, lyx_width_); + MathFontSetChanger dummy(pi.base, "textnormal"); +#if 1 xcell(0).draw(pi, x + 1, y); +#else + xcell(0).drawExternal(pi, x + 1, y, rows_); +#endif drawMarkers(pi, x, y); } diff --git a/src/mathed/math_parboxinset.h b/src/mathed/math_parboxinset.h index 4b03a9150e..1b6785b5d4 100644 --- a/src/mathed/math_parboxinset.h +++ b/src/mathed/math_parboxinset.h @@ -24,14 +24,14 @@ public: /// void setPosition(string const & pos); private: - /// - void rebreak(); /// width on screen int lyx_width_; /// width for TeX string tex_width_; - /// + /// htb char position_; + /// cached metrics + mutable std::vector rows_; }; #endif diff --git a/src/mathed/math_xdata.C b/src/mathed/math_xdata.C index 8dd95ca65b..fff922a572 100644 --- a/src/mathed/math_xdata.C +++ b/src/mathed/math_xdata.C @@ -20,8 +20,7 @@ extern MathScriptInset const * asScript(MathArray::const_iterator it); MathXArray::MathXArray() - : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), - clean_(false), drawn_(false) + : xo_(0), yo_(0), clean_(false), drawn_(false) {} @@ -42,13 +41,11 @@ void MathXArray::metrics(MathMetricsInfo & mi) const drawn_ = false; if (data_.empty()) { - mathed_char_dim(mi.base.font, 'I', ascent_, descent_, width_); + mathed_char_dim(mi.base.font, 'I', dim_.a, dim_.d, dim_.w); return; } - width_ = 0; - ascent_ = 0; - descent_ = 0; + dim_.clear(); for (const_iterator it = begin(); it != end(); ++it) { MathInset const * p = it->nucleus(); MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); @@ -61,22 +58,49 @@ void MathXArray::metrics(MathMetricsInfo & mi) const p->metrics(mi); p->dimensions(ww, aa, dd); } - ascent_ = max(ascent_, aa); - descent_ = max(descent_, dd); - width_ += ww; + dim_ += Dimension(ww, aa, dd); } - //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " - // << descent_ << " " << width_ << "'\n"; + //lyxerr << "MathXArray::metrics(): '" << dim_ << "\n"; +} + + +void MathXArray::metricsExternal(MathMetricsInfo & mi, + std::vector & v) const +{ + //if (clean_) + // return; + + size_ = mi; + clean_ = true; + drawn_ = false; + if (data_.empty()) { + mathed_char_dim(mi.base.font, 'I', dim_.a, dim_.d, dim_.w); + return; + } - // - // re-break paragraph - // - if (mi.base.restrictwidth) { - width_ = mi.base.textwidth; - lyxerr << "restricting width to " << width_ << " pixel\n"; + 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, 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"; } @@ -91,11 +115,11 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const yo_ = y; drawn_ = true; - if (y + descent_ <= 0) // don't draw above the workarea + if (y + descent() <= 0) // don't draw above the workarea return; - if (y - ascent_ >= pi.pain.paperHeight()) // don't draw below the workarea + if (y - ascent() >= pi.pain.paperHeight()) // don't draw below the workarea return; - if (x + width_ <= 0) // don't draw left of workarea + if (x + width() <= 0) // don't draw left of workarea return; if (x >= pi.pain.paperWidth()) // don't draw right of workarea return; @@ -103,7 +127,7 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const const_iterator it = begin(), et = end(); if (it == et) { - pi.pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline); + pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); return; } @@ -119,11 +143,29 @@ void MathXArray::draw(MathPainterInfo & pi, int x, int y) const x += p->width(); } } +} + - // - // re-break paragraph - // - if (pi.base.restrictwidth) { +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(); + } + } } } @@ -132,11 +174,7 @@ void MathXArray::metricsT(TextMetricsInfo const & mi) const { //if (clean_) // return; - - ascent_ = 0; - descent_ = 0; - width_ = 0; - + dim_.clear(); for (const_iterator it = begin(); it != end(); ++it) { MathInset const * p = it->nucleus(); MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it); @@ -149,9 +187,7 @@ void MathXArray::metricsT(TextMetricsInfo const & mi) const p->metricsT(mi); p->dimensions(ww, aa, dd); } - ascent_ = max(ascent_, aa); - descent_ = max(descent_, dd); - width_ += ww; + dim_ += Dimension(ww, aa, dd); } } @@ -238,13 +274,13 @@ int MathXArray::dist(int x, int y) const if (x < xo_) xx = xo_ - x; - else if (x > xo_ + width_) - xx = x - xo_ - width_; + 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_; + if (y < yo_ - ascent()) + yy = yo_ - ascent() - y; + else if (y > yo_ + descent()) + yy = y - yo_ - descent(); return xx + yy; } @@ -253,9 +289,9 @@ int MathXArray::dist(int x, int y) const void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2) { x1 = xo_; - x2 = xo_ + width_; - y1 = yo_ - ascent_; - y2 = yo_ + descent_; + x2 = xo_ + width(); + y1 = yo_ - ascent(); + y2 = yo_ + descent(); } /* @@ -287,8 +323,8 @@ void MathXArray::findPos(MathPosFinder & f) const void MathXArray::center(int & x, int & y) const { - x = xo_ + width_ / 2; - y = yo_ + (descent_ - ascent_) / 2; + x = xo_ + width() / 2; + y = yo_ + (descent() - ascent()) / 2; } diff --git a/src/mathed/math_xdata.h b/src/mathed/math_xdata.h index 73d6008d41..fba7fb5b1b 100644 --- a/src/mathed/math_xdata.h +++ b/src/mathed/math_xdata.h @@ -7,6 +7,7 @@ #include "math_data.h" #include "math_metricsinfo.h" +#include "dimension.h" #ifdef __GNUG__ #pragma interface @@ -27,12 +28,33 @@ public: /// const iterator into the underlying MathArray typedef MathArray::const_iterator const_iterator; + // helper structure for external metrics computations as done + // in parboxes + struct Row { + /// constructor + Row() {} + /// last position of this row plus one + size_type end; + /// y offset relative to yo + int yo; + /// dimensions of this row + Dimension dim; + /// glue between words + int glue; + }; + /// constructor MathXArray(); /// rebuild cached metrics information void metrics(MathMetricsInfo & mi) const; + /// rebuild cached metrics information + 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 + void drawExternal(MathPainterInfo & pi, int x, int y, + std::vector const &) const; /// rebuild cached metrics information void metricsT(TextMetricsInfo const & mi) const; /// redraw cell using cache metrics information @@ -45,9 +67,9 @@ public: /// access to cached y coordinate of last drawing int yo() const { return yo_; } /// access to cached x coordinate of mid point of last drawing - int xm() const { return xo_ + width_ / 2; } + int xm() const { return xo_ + dim_.w / 2; } /// access to cached y coordinate of mid point of last drawing - int ym() const { return yo_ + (descent_ - ascent_) / 2; } + int ym() const { return yo_ + (dim_.d - dim_.a) / 2; } /// returns x coordinate of given position in the array int pos2x(size_type pos) const; /// returns position of given x coordinate @@ -57,13 +79,13 @@ public: int dist(int x, int y) const; /// ascent of this cell above the baseline - int ascent() const { return ascent_; } + int ascent() const { return dim_.a; } /// descent of this cell below the baseline - int descent() const { return descent_; } + int descent() const { return dim_.d; } /// height of the cell - int height() const { return ascent_ + descent_; } + int height() const { return dim_.a + dim_.d; } /// width of this cell - int width() const { return width_; } + int width() const { return dim_.w; } /// bounding box of this cell void boundingBox(int & xlow, int & xhigh, int & ylow, int & yhigh); /// find best position to do things @@ -85,12 +107,8 @@ public: private: /// the underlying MathArray MathArray data_; - /// cached width of cell - mutable int width_; - /// cached ascent of cell - mutable int ascent_; - /// cached descent of cell - mutable int descent_; + /// cached dimensions of cell + mutable Dimension dim_; /// cached x coordinate of last drawing mutable int xo_; /// cached y coordinate of last drawing @@ -101,17 +119,6 @@ private: mutable bool clean_; /// cached draw status of cell mutable bool drawn_; - - // cached metrics - struct Row { - /// - Row(); - /// y offset relative to yo - int yo; - /// glue between words - int glue; - }; - std::vector rows_; }; /// output cell on a stream -- 2.39.2