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
This commit is contained in:
André Pönitz 2002-07-09 08:24:33 +00:00
parent a2d89110b9
commit 30b0c731b4
6 changed files with 191 additions and 78 deletions

View File

@ -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 \

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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<MathXArray::Row> rows_;
};
#endif

View File

@ -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";
}
//
// re-break paragraph
//
if (mi.base.restrictwidth) {
width_ = mi.base.textwidth;
lyxerr << "restricting width to " << width_ << " pixel\n";
void MathXArray::metricsExternal(MathMetricsInfo & mi,
std::vector<Row> & 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;
}
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<Row> 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;
}

View File

@ -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<MathXArray::Row> &) 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<MathXArray::Row> 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<Row> rows_;
};
/// output cell on a stream