#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 & mi) const
+void MathXArray::touch() const
+{
+ clean_ = false;
+ drawn_ = false;
+}
+
+
+void MathXArray::metrics(MathMetricsInfo & mi) const
{
- size_ = mi;
+ //if (clean_)
+ // return;
+
+ size_ = mi;
+ clean_ = true;
+ drawn_ = false;
if (data_.empty()) {
- mathed_char_dim(LM_TC_VAR, mi, 'I', ascent_, descent_, width_);
+ mathed_char_dim(mi.base.font, 'I', dim_.a, dim_.d, dim_.w);
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);
+ int ww, aa, dd;
if (q) {
q->metrics(p, mi);
- ascent_ = std::max(ascent_, q->ascent2(p));
- descent_ = std::max(descent_, q->descent2(p));
- width_ += q->width2(p);
+ q->dimensions2(p, ww, aa, dd);
++it;
} else {
p->metrics(mi);
- ascent_ = std::max(ascent_, p->ascent());
- descent_ = std::max(descent_, p->descent());
- width_ += p->width();
+ 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<Row> & 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->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(pi, x, y);
+ x += p->width();
+ }
+ }
+}
+
+
+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();
+ }
+ }
+ }
+}
+
+
+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->draw(p, pain, x, y);
+ 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->draw(pain, x, y);
+ p->drawT(pain, x, y);
x += p->width();
}
}
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);
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;
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;
+ 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_;
+ x2 = xo_ + width();
+ y1 = yo_ - ascent();
+ y2 = yo_ + descent();
}
/*
void MathXArray::findPos(MathPosFinder & f) const
{
double x = xo_;
- double y = yo_;
+ double y = yo_;
for (const_iterator it = begin(); it < end(); ++it) {
// check this position in the cell first
f.visit(x, y);
}
}
*/
+
+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));
+}