Change TextMetrics::rowHeight to setRowHeight

This new function takes a row as parameter.

Also, add direct access to Row::dim_
This commit is contained in:
Jean-Marc Lasgouttes 2013-06-14 19:24:29 +02:00
parent fe8c3b4348
commit cf31077932
4 changed files with 52 additions and 63 deletions

View File

@ -41,12 +41,6 @@ void Row::setCrc(size_type crc) const
} }
void Row::setDimension(Dimension const & dim)
{
dim_ = dim;
}
void Row::pos(pos_type p) void Row::pos(pos_type p)
{ {
pos_ = p; pos_ = p;

View File

@ -61,10 +61,10 @@ public:
/// ///
pos_type endpos() const { return end_; } pos_type endpos() const { return end_; }
/// ///
void setDimension(Dimension const & dim);
///
Dimension const & dimension() const { return dim_; } Dimension const & dimension() const { return dim_; }
/// ///
Dimension & dimension() { return dim_; }
///
int height() const { return dim_.height(); } int height() const { return dim_.height(); }
/// ///
int width() const { return dim_.wid; } int width() const { return dim_.wid; }

View File

@ -460,32 +460,27 @@ bool TextMetrics::redoParagraph(pit_type const pit)
pos_type first = 0; pos_type first = 0;
size_t row_index = 0; size_t row_index = 0;
// maximum pixel width of a row // maximum pixel width of a row
int width = max_width_ - right_margin; // - leftMargin(max_width_, pit, row);
do { do {
Dimension dim; if (row_index == pm.rows().size())
pos_type end = rowBreakPoint(width, pit, first); pm.rows().push_back(Row());
if (row_index || end < par.size()) Row & row = pm.rows()[row_index];
row.pos(first);
breakRow(row, right_margin, pit);
setRowHeight(row, pit);
row.dimension().wid = rowWidth(right_margin, pit, first, row.endpos());
row.setChanged(false);
if (row_index || row.endpos() < par.size())
// If there is more than one row, expand the text to // If there is more than one row, expand the text to
// the full allowable width. This setting here is needed // the full allowable width. This setting here is needed
// for the computeRowMetrics() below. // for the computeRowMetrics() below.
dim_.wid = max_width_; dim_.wid = max_width_;
int const max_row_width = max(dim_.wid, row.width());
dim = rowHeight(pit, first, end);
dim.wid = rowWidth(right_margin, pit, first, end);
if (row_index == pm.rows().size())
pm.rows().push_back(Row());
Row & row = pm.rows()[row_index];
row.setChanged(false);
row.pos(first);
row.endpos(end);
row.setDimension(dim);
int const max_row_width = max(dim_.wid, dim.wid);
computeRowMetrics(pit, row, max_row_width); computeRowMetrics(pit, row, max_row_width);
first = end; first = row.endpos();
++row_index; ++row_index;
pm.dim().wid = max(pm.dim().wid, dim.wid); pm.dim().wid = max(pm.dim().wid, row.width());
pm.dim().des += dim.height(); pm.dim().des += row.height();
} while (first < par.size()); } while (first < par.size());
if (row_index < pm.rows().size()) if (row_index < pm.rows().size())
@ -494,18 +489,17 @@ bool TextMetrics::redoParagraph(pit_type const pit)
// Make sure that if a par ends in newline, there is one more row // Make sure that if a par ends in newline, there is one more row
// under it // under it
if (first > 0 && par.isNewline(first - 1)) { if (first > 0 && par.isNewline(first - 1)) {
Dimension dim = rowHeight(pit, first, first);
dim.wid = rowWidth(right_margin, pit, first, first);
if (row_index == pm.rows().size()) if (row_index == pm.rows().size())
pm.rows().push_back(Row()); pm.rows().push_back(Row());
Row & row = pm.rows()[row_index]; Row & row = pm.rows()[row_index];
row.setChanged(false);
row.pos(first); row.pos(first);
row.endpos(first); row.endpos(first);
row.setDimension(dim); row.dimension().wid = rowWidth(right_margin, pit, first, first);
int const max_row_width = max(dim_.wid, dim.wid); setRowHeight(row, pit);
row.setChanged(false);
int const max_row_width = max(dim_.wid, row.width());
computeRowMetrics(pit, row, max_row_width); computeRowMetrics(pit, row, max_row_width);
pm.dim().des += dim.height(); pm.dim().des += row.height();
} }
pm.dim().asc += pm.rows()[0].ascent(); pm.dim().asc += pm.rows()[0].ascent();
@ -719,7 +713,7 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const
#if 0 #if 0
// Not used, see TextMetrics::rowBreakPoint. // Not used, see TextMetrics::breakRow
// this needs special handling - only newlines count as a break point // this needs special handling - only newlines count as a break point
static pos_type addressBreakPoint(pos_type i, Paragraph const & par) static pos_type addressBreakPoint(pos_type i, Paragraph const & par)
{ {
@ -801,13 +795,17 @@ private:
} // anon namespace } // anon namespace
pos_type TextMetrics::rowBreakPoint(int const width, pit_type const pit, void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit) const
pos_type const pos) const
{ {
Paragraph const & par = text_->getPar(pit); Paragraph const & par = text_->getPar(pit);
pos_type const end = par.size(); pos_type const end = par.size();
if (pos == end || width < 0) pos_type const pos = row.pos();
return end; int const left = leftMargin(max_width_, pit, pos);
int const width = max_width_ - right_margin;
if (pos == end || width < 0) {
row.endpos(end);
return;
}
ParagraphMetrics const & pm = par_metrics_[pit]; ParagraphMetrics const & pm = par_metrics_[pit];
ParagraphList const & pars = text_->paragraphs(); ParagraphList const & pars = text_->paragraphs();
@ -831,7 +829,6 @@ pos_type TextMetrics::rowBreakPoint(int const width, pit_type const pit,
inlineCompletionLPos = inlineCompletionPos.pos() - 1; inlineCompletionLPos = inlineCompletionPos.pos() - 1;
} }
int const left = leftMargin(max_width_, pit, pos);
pos_type const body_pos = par.beginOfBody(); pos_type const body_pos = par.beginOfBody();
int x = left; int x = left;
pos_type point = end; pos_type point = end;
@ -940,7 +937,7 @@ pos_type TextMetrics::rowBreakPoint(int const width, pit_type const pit,
if (body_pos && point < body_pos) if (body_pos && point < body_pos)
point = body_pos; point = body_pos;
return point; row.endpos(point);
} }
@ -1018,8 +1015,8 @@ int TextMetrics::rowWidth(int right_margin, pit_type const pit,
} }
Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first, void TextMetrics::setRowHeight(Row & row, pit_type const pit,
pos_type const end, bool topBottomSpace) const bool topBottomSpace) const
{ {
Paragraph const & par = text_->getPar(pit); Paragraph const & par = text_->getPar(pit);
// get the maximum ascent and the maximum descent // get the maximum ascent and the maximum descent
@ -1037,7 +1034,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
// start with so we don't have to do the assignment below too // start with so we don't have to do the assignment below too
// often. // often.
Buffer const & buffer = bv_->buffer(); Buffer const & buffer = bv_->buffer();
Font font = displayFont(pit, first); Font font = displayFont(pit, row.pos());
FontSize const tmpsize = font.fontInfo().size(); FontSize const tmpsize = font.fontInfo().size();
font.fontInfo() = text_->layoutFont(pit); font.fontInfo() = text_->layoutFont(pit);
FontSize const size = font.fontInfo().size(); FontSize const size = font.fontInfo().size();
@ -1060,7 +1057,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
InsetList::const_iterator ii = par.insetList().begin(); InsetList::const_iterator ii = par.insetList().begin();
InsetList::const_iterator iend = par.insetList().end(); InsetList::const_iterator iend = par.insetList().end();
for ( ; ii != iend; ++ii) { for ( ; ii != iend; ++ii) {
if (ii->pos >= first && ii->pos < end) { if (ii->pos >= row.pos() && ii->pos < row.endpos()) {
Dimension const & dim = pm.insetDimension(ii->inset); Dimension const & dim = pm.insetDimension(ii->inset);
maxasc = max(maxasc, dim.ascent()); maxasc = max(maxasc, dim.ascent());
maxdesc = max(maxdesc, dim.descent()); maxdesc = max(maxdesc, dim.descent());
@ -1073,7 +1070,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
int labeladdon = 0; int labeladdon = 0;
FontSize maxsize = FontSize maxsize =
par.highestFontInRange(first, end, size); par.highestFontInRange(row.pos(), row.endpos(), size);
if (maxsize > font.fontInfo().size()) { if (maxsize > font.fontInfo().size()) {
// use standard paragraph font with the maximal size // use standard paragraph font with the maximal size
FontInfo maxfont = font.fontInfo(); FontInfo maxfont = font.fontInfo();
@ -1091,7 +1088,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
Inset const & inset = text_->inset(); Inset const & inset = text_->inset();
// is it a top line? // is it a top line?
if (first == 0 && topBottomSpace) { if (row.pos() == 0 && topBottomSpace) {
BufferParams const & bufparams = buffer.params(); BufferParams const & bufparams = buffer.params();
// some parskips VERY EASY IMPLEMENTATION // some parskips VERY EASY IMPLEMENTATION
if (bufparams.paragraph_separation == BufferParams::ParagraphSkipSeparation if (bufparams.paragraph_separation == BufferParams::ParagraphSkipSeparation
@ -1131,7 +1128,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
&& prevpar.getLabelWidthString() && prevpar.getLabelWidthString()
== par.getLabelWidthString()) { == par.getLabelWidthString()) {
layoutasc = layout.itemsep * dh; layoutasc = layout.itemsep * dh;
} else if (pit != 0 || first != 0) { } else if (pit != 0 || row.pos() != 0) {
if (layout.topsep > 0) if (layout.topsep > 0)
layoutasc = layout.topsep * dh; layoutasc = layout.topsep * dh;
} }
@ -1149,7 +1146,7 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
} }
// is it a bottom line? // is it a bottom line?
if (end >= par.size() && topBottomSpace) { if (row.endpos() >= par.size() && topBottomSpace) {
// add the layout spaces, for example before and after // add the layout spaces, for example before and after
// a section, or between the items of a itemize or enumerate // a section, or between the items of a itemize or enumerate
// environment // environment
@ -1184,15 +1181,16 @@ Dimension TextMetrics::rowHeight(pit_type const pit, pos_type const first,
// main Text. The following test is thus bogus. // main Text. The following test is thus bogus.
// Top and bottom margin of the document (only at top-level) // Top and bottom margin of the document (only at top-level)
if (main_text_ && topBottomSpace) { if (main_text_ && topBottomSpace) {
if (pit == 0 && first == 0) if (pit == 0 && row.pos() == 0)
maxasc += 20; maxasc += 20;
if (pit + 1 == pit_type(pars.size()) && if (pit + 1 == pit_type(pars.size()) &&
end == par.size() && row.endpos() == par.size() &&
!(end > 0 && par.isNewline(end - 1))) !(row.endpos() > 0 && par.isNewline(row.endpos() - 1)))
maxdesc += 20; maxdesc += 20;
} }
return Dimension(0, maxasc + labeladdon, maxdesc); row.dimension().asc = maxasc + labeladdon;
row.dimension().des = maxdesc;
} }
@ -1214,7 +1212,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
bidi.computeTables(par, buffer, row); bidi.computeTables(par, buffer, row);
pos_type vc = row.pos(); pos_type vc = row.pos();
pos_type end = row.endpos(); pos_type const end = row.endpos();
pos_type c = 0; pos_type c = 0;
Layout const & layout = par.layout(); Layout const & layout = par.layout();
@ -2230,7 +2228,11 @@ void TextMetrics::completionPosAndDim(Cursor const & cur, int & x, int & y,
Point rxy = cur.bv().getPos(bvcur); Point rxy = cur.bv().getPos(bvcur);
// calculate dimensions of the word // calculate dimensions of the word
dim = rowHeight(bvcur.pit(), wordStart.pos(), bvcur.pos(), false); Row row;
row.pos(wordStart.pos());
row.endpos(bvcur.pos());
setRowHeight(row, bvcur.pit(), false);
dim = row.dimension();
dim.wid = abs(rxy.x_ - lxy.x_); dim.wid = abs(rxy.x_ - lxy.x_);
// calculate position of word // calculate position of word

View File

@ -124,11 +124,8 @@ public:
/// Returns the height of the row (width member is set to 0). /// Returns the height of the row (width member is set to 0).
/// If \c topBottomSpace is true, extra space is added for the /// If \c topBottomSpace is true, extra space is added for the
/// top and bottom row. /// top and bottom row.
Dimension rowHeight( void setRowHeight(Row & row, pit_type const pit,
pit_type const pit, bool topBottomSpace = true) const;
pos_type const first,
pos_type const end,
bool topBottomSpace = true) const;
private: private:
/// ///
@ -142,11 +139,7 @@ private:
/// sets row.end to the pos value *after* which a row should break. /// sets row.end to the pos value *after* which a row should break.
/// for example, the pos after which isNewLine(pos) == true /// for example, the pos after which isNewLine(pos) == true
pos_type rowBreakPoint( void breakRow(Row & row, int right_margin, pit_type const pit) const;
int width,
pit_type const pit,
pos_type first
) const;
/// returns the minimum space a row needs on the screen in pixel /// returns the minimum space a row needs on the screen in pixel
int rowWidth( int rowWidth(