mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 18:08:10 +00:00
Reduce use of double variables in Row
All the code that is run before row metrics have been computed should use int arithmetic. After metrics have been computed, we still need doubles because fully justified rows use double for Row::Element::extra. Rename Row::x to Row::left_margin and change its type to int. Rename Row::Element::width() to full_width(). In some places of the code, use dim.wid (the int version without the extra separator) because metrics have not been computed. Let Row::Element::x2pos take a int& argument instead of double& Let Row::Element::breakAt take a int argument instead of double
This commit is contained in:
parent
8bab23384a
commit
e32a3e7f57
55
src/Row.cpp
55
src/Row.cpp
@ -48,9 +48,9 @@ double Row::Element::pos2x(pos_type const i) const
|
|||||||
double w = 0;
|
double w = 0;
|
||||||
//handle first the two bounds of the element
|
//handle first the two bounds of the element
|
||||||
if (i == endpos && !(inset && inset->lyxCode() == SEPARATOR_CODE))
|
if (i == endpos && !(inset && inset->lyxCode() == SEPARATOR_CODE))
|
||||||
w = rtl ? 0 : width();
|
w = rtl ? 0 : full_width();
|
||||||
else if (i == pos || type != STRING)
|
else if (i == pos || type != STRING)
|
||||||
w = rtl ? width() : 0;
|
w = rtl ? full_width() : 0;
|
||||||
else {
|
else {
|
||||||
FontMetrics const & fm = theFontMetrics(font);
|
FontMetrics const & fm = theFontMetrics(font);
|
||||||
w = fm.pos2x(str, i - pos, font.isVisibleRightToLeft());
|
w = fm.pos2x(str, i - pos, font.isVisibleRightToLeft());
|
||||||
@ -60,7 +60,7 @@ double Row::Element::pos2x(pos_type const i) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pos_type Row::Element::x2pos(double &x) const
|
pos_type Row::Element::x2pos(int &x) const
|
||||||
{
|
{
|
||||||
//lyxerr << "x2pos: x=" << x << " w=" << width() << " " << *this;
|
//lyxerr << "x2pos: x=" << x << " w=" << width() << " " << *this;
|
||||||
bool const rtl = font.isVisibleRightToLeft();
|
bool const rtl = font.isVisibleRightToLeft();
|
||||||
@ -69,24 +69,21 @@ pos_type Row::Element::x2pos(double &x) const
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case STRING: {
|
case STRING: {
|
||||||
FontMetrics const & fm = theFontMetrics(font);
|
FontMetrics const & fm = theFontMetrics(font);
|
||||||
// FIXME: is it really necessary for x to be a double?
|
i = fm.x2pos(str, x, rtl);
|
||||||
int xx = int(x);
|
|
||||||
i = fm.x2pos(str, xx, rtl);
|
|
||||||
x = xx;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VIRTUAL:
|
case VIRTUAL:
|
||||||
// those elements are actually empty (but they have a width)
|
// those elements are actually empty (but they have a width)
|
||||||
i = 0;
|
i = 0;
|
||||||
x = rtl ? width() : 0;
|
x = rtl ? int(full_width()) : 0;
|
||||||
break;
|
break;
|
||||||
case SEPARATOR:
|
case SEPARATOR:
|
||||||
case INSET:
|
case INSET:
|
||||||
case SPACE:
|
case SPACE:
|
||||||
// those elements contain only one position. Round to
|
// those elements contain only one position. Round to
|
||||||
// the closest side.
|
// the closest side.
|
||||||
if (x > width()) {
|
if (x > full_width()) {
|
||||||
x = width();
|
x = int(full_width());
|
||||||
i = !rtl;
|
i = !rtl;
|
||||||
} else {
|
} else {
|
||||||
x = 0;
|
x = 0;
|
||||||
@ -100,22 +97,22 @@ pos_type Row::Element::x2pos(double &x) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Row::Element::breakAt(double w)
|
bool Row::Element::breakAt(int w)
|
||||||
{
|
{
|
||||||
if (type != STRING || width() <= w)
|
if (type != STRING || dim.wid <= w)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool const rtl = font.isVisibleRightToLeft();
|
bool const rtl = font.isVisibleRightToLeft();
|
||||||
if (rtl)
|
if (rtl)
|
||||||
w = width() - w;
|
w = dim.wid - w;
|
||||||
pos_type new_pos = x2pos(w);
|
pos_type new_pos = x2pos(w);
|
||||||
if (new_pos == pos)
|
if (new_pos == pos)
|
||||||
return false;
|
return false;
|
||||||
str = str.substr(0, new_pos - pos);
|
str = str.substr(0, new_pos - pos);
|
||||||
if (rtl)
|
if (rtl)
|
||||||
dim.wid -= int(w);
|
dim.wid -= w;
|
||||||
else
|
else
|
||||||
dim.wid = int(w);
|
dim.wid = w;
|
||||||
endpos = new_pos;
|
endpos = new_pos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -134,7 +131,7 @@ pos_type Row::Element::right_pos() const
|
|||||||
|
|
||||||
|
|
||||||
Row::Row()
|
Row::Row()
|
||||||
: separator(0), label_hfill(0), x(0), right_margin(0),
|
: separator(0), label_hfill(0), left_margin(0), right_margin(0),
|
||||||
sel_beg(-1), sel_end(-1),
|
sel_beg(-1), sel_end(-1),
|
||||||
begin_margin_sel(false), end_margin_sel(false),
|
begin_margin_sel(false), end_margin_sel(false),
|
||||||
changed_(false), crc_(0), pos_(0), end_(0), right_boundary_(false)
|
changed_(false), crc_(0), pos_(0), end_(0), right_boundary_(false)
|
||||||
@ -236,7 +233,7 @@ ostream & operator<<(ostream & os, Row::Element const & e)
|
|||||||
os << "SPACE: ";
|
os << "SPACE: ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os << "width=" << e.width();
|
os << "width=" << e.full_width();
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +241,7 @@ ostream & operator<<(ostream & os, Row::Element const & e)
|
|||||||
ostream & operator<<(ostream & os, Row const & row)
|
ostream & operator<<(ostream & os, Row const & row)
|
||||||
{
|
{
|
||||||
os << " pos: " << row.pos_ << " end: " << row.end_
|
os << " pos: " << row.pos_ << " end: " << row.end_
|
||||||
<< " x: " << row.x
|
<< " left_margin: " << row.left_margin
|
||||||
<< " width: " << row.dim_.wid
|
<< " width: " << row.dim_.wid
|
||||||
<< " right_margin: " << row.right_margin
|
<< " right_margin: " << row.right_margin
|
||||||
<< " ascent: " << row.dim_.asc
|
<< " ascent: " << row.dim_.asc
|
||||||
@ -252,11 +249,11 @@ ostream & operator<<(ostream & os, Row const & row)
|
|||||||
<< " separator: " << row.separator
|
<< " separator: " << row.separator
|
||||||
<< " label_hfill: " << row.label_hfill
|
<< " label_hfill: " << row.label_hfill
|
||||||
<< " row_boundary: " << row.right_boundary() << "\n";
|
<< " row_boundary: " << row.right_boundary() << "\n";
|
||||||
double x = row.x;
|
double x = row.left_margin;
|
||||||
Row::Elements::const_iterator it = row.elements_.begin();
|
Row::Elements::const_iterator it = row.elements_.begin();
|
||||||
for ( ; it != row.elements_.end() ; ++it) {
|
for ( ; it != row.elements_.end() ; ++it) {
|
||||||
os << "x=" << x << " => " << *it << endl;
|
os << "x=" << x << " => " << *it << endl;
|
||||||
x += it->width();
|
x += it->full_width();
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@ -365,8 +362,8 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
|||||||
Elements::iterator const beg = elements_.begin();
|
Elements::iterator const beg = elements_.begin();
|
||||||
Elements::iterator const end = elements_.end();
|
Elements::iterator const end = elements_.end();
|
||||||
Elements::iterator last_sep = elements_.end();
|
Elements::iterator last_sep = elements_.end();
|
||||||
double last_width = 0;
|
int last_width = 0;
|
||||||
double wid = x;
|
int wid = left_margin;
|
||||||
|
|
||||||
Elements::iterator cit = beg;
|
Elements::iterator cit = beg;
|
||||||
for ( ; cit != end ; ++cit) {
|
for ( ; cit != end ; ++cit) {
|
||||||
@ -374,16 +371,16 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
|||||||
last_sep = cit;
|
last_sep = cit;
|
||||||
last_width = wid;
|
last_width = wid;
|
||||||
}
|
}
|
||||||
if (wid + cit->width() > w)
|
if (wid + cit->dim.wid > w)
|
||||||
break;
|
break;
|
||||||
wid += cit->width();
|
wid += cit->dim.wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_sep != end) {
|
if (last_sep != end) {
|
||||||
// We have found a suitable separator. This is the
|
// We have found a suitable separator. This is the
|
||||||
// common case.
|
// common case.
|
||||||
end_ = last_sep->endpos;
|
end_ = last_sep->endpos;
|
||||||
dim_.wid = int(last_width);
|
dim_.wid = last_width;
|
||||||
elements_.erase(last_sep, end);
|
elements_.erase(last_sep, end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -398,14 +395,14 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
|||||||
// It is not possible to separate a virtual element from the
|
// It is not possible to separate a virtual element from the
|
||||||
// previous one.
|
// previous one.
|
||||||
--cit;
|
--cit;
|
||||||
wid -= cit->width();
|
wid -= cit->dim.wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cit != beg) {
|
if (cit != beg) {
|
||||||
// There is no separator, but several elements (probably
|
// There is no separator, but several elements (probably
|
||||||
// insets) have been added. We can cut at this place.
|
// insets) have been added. We can cut at this place.
|
||||||
end_ = cit->pos;
|
end_ = cit->pos;
|
||||||
dim_.wid = int(wid);
|
dim_.wid = wid;
|
||||||
elements_.erase(cit, end);
|
elements_.erase(cit, end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -415,9 +412,9 @@ void Row::shortenIfNeeded(pos_type const keep, int const w)
|
|||||||
* something: when we have one big string, maybe with some
|
* something: when we have one big string, maybe with some
|
||||||
* other things after it.
|
* other things after it.
|
||||||
*/
|
*/
|
||||||
if (cit->breakAt(w - x)) {
|
if (cit->breakAt(w - left_margin)) {
|
||||||
end_ = cit->endpos;
|
end_ = cit->endpos;
|
||||||
dim_.wid = int(x + cit->width());
|
dim_.wid = left_margin + cit->dim.wid;
|
||||||
// If there are other elements, they should be removed.
|
// If there are other elements, they should be removed.
|
||||||
elements_.erase(boost::next(cit), end);
|
elements_.erase(boost::next(cit), end);
|
||||||
}
|
}
|
||||||
|
10
src/Row.h
10
src/Row.h
@ -76,7 +76,7 @@ public:
|
|||||||
extra(0), font(f), change(ch), final(false) {}
|
extra(0), font(f), change(ch), final(false) {}
|
||||||
|
|
||||||
// Return total width of element, including separator overhead
|
// Return total width of element, including separator overhead
|
||||||
double width() const { return dim.wid + extra; };
|
double full_width() const { return dim.wid + extra; };
|
||||||
/** Return position in pixels (from the left) of position
|
/** Return position in pixels (from the left) of position
|
||||||
* \param i in the row element.
|
* \param i in the row element.
|
||||||
*/
|
*/
|
||||||
@ -85,11 +85,11 @@ public:
|
|||||||
* pixel position \param x. The value \param x is
|
* pixel position \param x. The value \param x is
|
||||||
* adjusted to the actual pixel position.
|
* adjusted to the actual pixel position.
|
||||||
*/
|
*/
|
||||||
pos_type x2pos(double &x) const;
|
pos_type x2pos(int &x) const;
|
||||||
/** Break the element if possible, so that its width is
|
/** Break the element if possible, so that its width is
|
||||||
* less then \param w. Returns true on success.
|
* less then \param w. Returns true on success.
|
||||||
*/
|
*/
|
||||||
bool breakAt(double w);
|
bool breakAt(int w);
|
||||||
|
|
||||||
// Returns the position on left side of the element.
|
// Returns the position on left side of the element.
|
||||||
pos_type left_pos() const;
|
pos_type left_pos() const;
|
||||||
@ -243,8 +243,8 @@ public:
|
|||||||
double separator;
|
double separator;
|
||||||
/// width of hfills in the label
|
/// width of hfills in the label
|
||||||
double label_hfill;
|
double label_hfill;
|
||||||
/// the x position of the row (left margin)
|
/// the left margin position of the row
|
||||||
double x;
|
int left_margin;
|
||||||
/// the right margin of the row
|
/// the right margin of the row
|
||||||
int right_margin;
|
int right_margin;
|
||||||
///
|
///
|
||||||
|
@ -83,7 +83,7 @@ RowPainter::RowPainter(PainterInfo & pi,
|
|||||||
dotted_line_offset_ = int(0.5 * dotted_line_thickness_) + 1;
|
dotted_line_offset_ = int(0.5 * dotted_line_thickness_) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x_ = row_.x + xo_;
|
x_ = row_.left_margin + xo_;
|
||||||
|
|
||||||
//lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
|
//lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
|
||||||
//row_.dump();
|
//row_.dump();
|
||||||
|
@ -571,9 +571,9 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
|
|||||||
|
|
||||||
bool const is_rtl = text_->isRTL(par);
|
bool const is_rtl = text_->isRTL(par);
|
||||||
if (is_rtl)
|
if (is_rtl)
|
||||||
row.x = rightMargin(pit);
|
row.left_margin = rightMargin(pit);
|
||||||
else
|
else
|
||||||
row.x = leftMargin(max_width_, pit, row.pos());
|
row.left_margin = leftMargin(max_width_, pit, row.pos());
|
||||||
|
|
||||||
// is there a manual margin with a manual label
|
// is there a manual margin with a manual label
|
||||||
Layout const & layout = par.layout();
|
Layout const & layout = par.layout();
|
||||||
@ -619,16 +619,16 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
|
|||||||
row.dimension().wid = width;
|
row.dimension().wid = width;
|
||||||
} else if (is_rtl) {
|
} else if (is_rtl) {
|
||||||
row.dimension().wid = width;
|
row.dimension().wid = width;
|
||||||
row.x += w;
|
row.left_margin += w;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LYX_ALIGN_RIGHT:
|
case LYX_ALIGN_RIGHT:
|
||||||
row.x += w;
|
row.left_margin += w;
|
||||||
break;
|
break;
|
||||||
case LYX_ALIGN_CENTER:
|
case LYX_ALIGN_CENTER:
|
||||||
row.dimension().wid = width - int(w / 2);
|
row.dimension().wid = width - int(w / 2);
|
||||||
row.x += w / 2;
|
row.left_margin += w / 2;
|
||||||
break;
|
break;
|
||||||
case LYX_ALIGN_LEFT:
|
case LYX_ALIGN_LEFT:
|
||||||
case LYX_ALIGN_NONE:
|
case LYX_ALIGN_NONE:
|
||||||
@ -639,21 +639,6 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (is_rtl) {
|
|
||||||
pos_type body_pos = par.beginOfBody();
|
|
||||||
pos_type end = row.endpos();
|
|
||||||
|
|
||||||
if (body_pos > 0
|
|
||||||
&& (body_pos > end || !par.isLineSeparator(body_pos - 1))) {
|
|
||||||
row.x += theFontMetrics(text_->labelFont(par)).
|
|
||||||
width(layout.labelsep);
|
|
||||||
if (body_pos <= end)
|
|
||||||
row.x += row.label_hfill;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Finally, handle hfill insets
|
// Finally, handle hfill insets
|
||||||
pos_type const endpos = row.endpos();
|
pos_type const endpos = row.endpos();
|
||||||
pos_type body_pos = par.beginOfBody();
|
pos_type body_pos = par.beginOfBody();
|
||||||
@ -686,13 +671,13 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
|
|||||||
Paragraph const & par = text_->getPar(pit);
|
Paragraph const & par = text_->getPar(pit);
|
||||||
LBUFERR(par.beginOfBody() > 0 || par.isEnvSeparator(0));
|
LBUFERR(par.beginOfBody() > 0 || par.isEnvSeparator(0));
|
||||||
|
|
||||||
double w = 0;
|
int w = 0;
|
||||||
Row::const_iterator cit = row.begin();
|
Row::const_iterator cit = row.begin();
|
||||||
Row::const_iterator const end = row.end();
|
Row::const_iterator const end = row.end();
|
||||||
// iterate over elements before main body (except the last one,
|
// iterate over elements before main body (except the last one,
|
||||||
// which is extra space).
|
// which is extra space).
|
||||||
while (cit!= end && cit->endpos < par.beginOfBody()) {
|
while (cit!= end && cit->endpos < par.beginOfBody()) {
|
||||||
w += cit->width();
|
w += cit->dim.wid;
|
||||||
++cit;
|
++cit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,7 +688,7 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
|
|||||||
FontMetrics const & fm
|
FontMetrics const & fm
|
||||||
= theFontMetrics(text_->labelFont(par));
|
= theFontMetrics(text_->labelFont(par));
|
||||||
|
|
||||||
return max(0, fm.width(label) - int(w));
|
return max(0, fm.width(label) - w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -803,8 +788,8 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit
|
|||||||
pos_type const body_pos = par.beginOfBody();
|
pos_type const body_pos = par.beginOfBody();
|
||||||
row.clear();
|
row.clear();
|
||||||
// This make get changed in computeRowMetrics depending on RTL
|
// This make get changed in computeRowMetrics depending on RTL
|
||||||
row.x = leftMargin(max_width_, pit, pos);
|
row.left_margin = leftMargin(max_width_, pit, pos);
|
||||||
row.dimension().wid = int(row.x);
|
row.dimension().wid = row.left_margin;
|
||||||
row.right_margin = right_margin;
|
row.right_margin = right_margin;
|
||||||
|
|
||||||
if (pos >= end || row.width() > width) {
|
if (pos >= end || row.width() > width) {
|
||||||
@ -1117,25 +1102,25 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x,
|
|||||||
pos_type pos = row.pos();
|
pos_type pos = row.pos();
|
||||||
boundary = false;
|
boundary = false;
|
||||||
if (row.empty())
|
if (row.empty())
|
||||||
x = int(row.x);
|
x = row.left_margin;
|
||||||
else if (x <= row.x) {
|
else if (x <= row.left_margin) {
|
||||||
pos = row.front().left_pos();
|
pos = row.front().left_pos();
|
||||||
x = int(row.x);
|
x = row.left_margin;
|
||||||
} else if (x >= row.width()) {
|
} else if (x >= row.width()) {
|
||||||
pos = row.back().right_pos();
|
pos = row.back().right_pos();
|
||||||
x = row.width();
|
x = row.width();
|
||||||
} else {
|
} else {
|
||||||
double w = row.x;
|
double w = row.left_margin;
|
||||||
Row::const_iterator cit = row.begin();
|
Row::const_iterator cit = row.begin();
|
||||||
Row::const_iterator cend = row.end();
|
Row::const_iterator cend = row.end();
|
||||||
for ( ; cit != cend; ++cit) {
|
for ( ; cit != cend; ++cit) {
|
||||||
if (w <= x && w + cit->width() > x) {
|
if (w <= x && w + cit->full_width() > x) {
|
||||||
double x_offset = x - w;
|
int x_offset = int(x - w);
|
||||||
pos = cit->x2pos(x_offset);
|
pos = cit->x2pos(x_offset);
|
||||||
x = int(x_offset + w);
|
x = int(x_offset + w);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
w += cit->width();
|
w += cit->full_width();
|
||||||
}
|
}
|
||||||
if (cit == row.end()) {
|
if (cit == row.end()) {
|
||||||
pos = row.back().right_pos();
|
pos = row.back().right_pos();
|
||||||
@ -1484,10 +1469,10 @@ int TextMetrics::cursorX(CursorSlice const & sl,
|
|||||||
if (row.empty()
|
if (row.empty()
|
||||||
|| (pos == row.begin()->left_pos()
|
|| (pos == row.begin()->left_pos()
|
||||||
&& pos != row.begin()->right_pos()))
|
&& pos != row.begin()->right_pos()))
|
||||||
return int(row.x);
|
return row.left_margin;
|
||||||
|
|
||||||
Row::const_iterator cit = row.begin();
|
Row::const_iterator cit = row.begin();
|
||||||
double x = row.x;
|
double x = row.left_margin;
|
||||||
for ( ; cit != row.end() ; ++cit) {
|
for ( ; cit != row.end() ; ++cit) {
|
||||||
/** Look whether the cursor is inside the element's
|
/** Look whether the cursor is inside the element's
|
||||||
* span. Note that it is necessary to take the
|
* span. Note that it is necessary to take the
|
||||||
@ -1500,7 +1485,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
|
|||||||
x += cit->pos2x(pos);
|
x += cit->pos2x(pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
x += cit->width();
|
x += cit->full_width();
|
||||||
}
|
}
|
||||||
|
|
||||||
return int(x);
|
return int(x);
|
||||||
|
Loading…
Reference in New Issue
Block a user