}
// Look at paragraph heights on-screen
- for (pit_type pit = tm.firstPit(); pit <= tm.lastPit(); ++pit) {
+ pair<pit_type, ParagraphMetrics const *> first = tm.first();
+ pair<pit_type, ParagraphMetrics const *> last = tm.last();
+ for (pit_type pit = first.first; pit <= last.first; ++pit) {
d->par_height_[pit] = tm.parMetrics(pit).height();
LYXERR(Debug::SCROLLING, "storing height for pit " << pit << " : "
<< d->par_height_[pit]);
}
- bool first_visible = tm.firstPit() == 0 && tm.topPosition() >= 0;
- bool last_visible = tm.lastPit() + 1 == int(parsize) && tm.bottomPosition() <= height_;
+ int top_pos = first.second->position() - first.second->ascent();
+ int bottom_pos = last.second->position() + last.second->descent();
+ bool first_visible = first.first == 0 && top_pos >= 0;
+ bool last_visible = last.first + 1 == int(parsize) && bottom_pos <= height_;
if (first_visible && last_visible) {
d->scrollbarParameters_.min = 0;
d->scrollbarParameters_.max = 0;
return;
}
- d->scrollbarParameters_.min = tm.topPosition();
- for (size_t i = 0; i != size_t(tm.firstPit()); ++i)
+ d->scrollbarParameters_.min = top_pos;
+ for (size_t i = 0; i != size_t(first.first); ++i)
d->scrollbarParameters_.min -= d->par_height_[i];
- d->scrollbarParameters_.max = tm.bottomPosition();
- for (size_t i = tm.lastPit() + 1; i != parsize; ++i)
+ d->scrollbarParameters_.max = bottom_pos;
+ for (size_t i = last.first + 1; i != parsize; ++i)
d->scrollbarParameters_.max += d->par_height_[i];
// The reference is the top position so we remove one page.
bot_pit = max_pit;
}
- if (bot_pit == tm.firstPit() - 1)
+ if (bot_pit == tm.first().first - 1)
tm.newParMetricsUp();
- else if (bot_pit == tm.lastPit() + 1)
+ else if (bot_pit == tm.last().first + 1)
tm.newParMetricsDown();
if (tm.contains(bot_pit)) {
CursorSlice const & cs = dit.innerTextSlice();
int offset = coordOffset(dit).y_;
int ypos = pm.position() + offset;
- Row const & row = pm.getRow(cs.pos(), dit.boundary());
+ Dimension const & row_dim =
+ pm.getRow(cs.pos(), dit.boundary()).dim();
int scrolled = 0;
if (recenter)
scrolled = scroll(ypos - height_/2);
// the screen height, we scroll to a heuristic value of height_ / 4.
// FIXME: This heuristic value should be replaced by a recursive search
// for a row in the inset that can be visualized completely.
- else if (row.height() > height_) {
+ else if (row_dim.height() > height_) {
if (ypos < defaultRowHeight())
scrolled = scroll(ypos - height_ / 4);
else if (ypos > height_ - defaultRowHeight())
// If the top part of the row falls of the screen, we scroll
// up to align the top of the row with the top of the screen.
- else if (ypos - row.totalAscent() < 0 && ypos < height_) {
- int ynew = row.totalAscent();
+ else if (ypos - row_dim.ascent() < 0 && ypos < height_) {
+ int ynew = row_dim.ascent();
scrolled = scrollUp(ynew - ypos);
}
// If the bottom of the row falls of the screen, we scroll down.
- else if (ypos + row.totalDescent() > height_ && ypos > 0) {
- int ynew = height_ - row.totalDescent();
+ else if (ypos + row_dim.descent() > height_ && ypos > 0) {
+ int ynew = height_ - row_dim.descent();
scrolled = scrollDown(ypos - ynew);
}
d->anchor_pit_ = bot_pit;
CursorSlice const & cs = dit.innerTextSlice();
- Row const & row = pm.getRow(cs.pos(), dit.boundary());
+ Dimension const & row_dim =
+ pm.getRow(cs.pos(), dit.boundary()).dim();
if (recenter)
d->anchor_ypos_ = height_/2;
else if (d->anchor_pit_ == 0)
d->anchor_ypos_ = offset + pm.ascent();
else if (d->anchor_pit_ == max_pit)
- d->anchor_ypos_ = height_ - offset - row.totalDescent();
+ d->anchor_ypos_ = height_ - offset - row_dim.descent();
else if (offset > height_)
d->anchor_ypos_ = height_ - offset - defaultRowHeight();
else
TextMetrics & tm = d->text_metrics_[text];
int const ymax = height_ + offset;
while (true) {
- int bottom_pos = tm.bottomPosition();
+ pair<pit_type, ParagraphMetrics const *> last = tm.last();
+ int bottom_pos = last.second->position() + last.second->descent();
if (lyxrc.scroll_below_document)
bottom_pos += height_ - minVisiblePart();
- if (tm.lastPit() + 1 == int(text->paragraphs().size())) {
+ if (last.first + 1 == int(text->paragraphs().size())) {
if (bottom_pos <= height_)
return 0;
offset = min(offset, bottom_pos - height_);
TextMetrics & tm = d->text_metrics_[text];
int ymin = - offset;
while (true) {
- int const top_pos = tm.topPosition();
- if (tm.firstPit() == 0) {
+ pair<pit_type, ParagraphMetrics const *> first = tm.first();
+ int top_pos = first.second->position() - first.second->ascent();
+ if (first.first == 0) {
if (top_pos >= 0)
return 0;
offset = min(offset, - top_pos);
Text & buftext = buffer_.text();
pit_type const bottom_pit = d->cursor_.bottom().pit();
TextMetrics & tm = textMetrics(&buftext);
- int old_height = tm.parMetrics(bottom_pit).height();
+ Dimension const old_dim = tm.parMetrics(bottom_pit).dim();
// make sure inline completion pointer is ok
if (d->inlineCompletionPos_.fixIfBroken())
// (if this paragraph contains insets etc., rebreaking will
// recursively descend)
tm.redoParagraph(bottom_pit);
- ParagraphMetrics const & pm = tm.parMetrics(bottom_pit);
- if (pm.height() != old_height)
+ ParagraphMetrics & pm = tm.parMetrics(bottom_pit);
+ if (pm.height() != old_dim.height()) {
// Paragraph height has changed so we cannot proceed to
// the singlePar optimisation.
return false;
+ }
+ // Since position() points to the baseline of the first row, we
+ // may have to update it. See ticket #11601 for an example where
+ // the height does not change but the ascent does.
+ pm.setPosition(pm.position() - old_dim.ascent() + pm.ascent());
tm.updatePosCache(bottom_pit);
// Rebreak anchor paragraph.
tm.redoParagraph(d->anchor_pit_);
- ParagraphMetrics & anchor_pm = tm.par_metrics_[d->anchor_pit_];
+ ParagraphMetrics & anchor_pm = tm.parMetrics(d->anchor_pit_);
// position anchor
if (d->anchor_pit_ == 0) {
pit_type pit1 = d->anchor_pit_ - 1;
for (; pit1 >= 0 && y1 >= 0; --pit1) {
tm.redoParagraph(pit1);
- ParagraphMetrics & pm = tm.par_metrics_[pit1];
+ ParagraphMetrics & pm = tm.parMetrics(pit1);
y1 -= pm.descent();
// Save the paragraph position in the cache.
pm.setPosition(y1);
pit_type pit2 = d->anchor_pit_ + 1;
for (; pit2 < npit && y2 <= height_; ++pit2) {
tm.redoParagraph(pit2);
- ParagraphMetrics & pm = tm.par_metrics_[pit2];
+ ParagraphMetrics & pm = tm.parMetrics(pit2);
y2 += pm.ascent();
// Save the paragraph position in the cache.
pm.setPosition(y2);
ParagraphMetrics const & pm = tm.parMetrics(sl.pit());
LBUFERR(!pm.rows().empty());
- y -= pm.rows()[0].totalAscent();
+ y -= pm.rows()[0].ascent();
#if 1
// FIXME: document this mess
size_t rend;
#endif
for (size_t rit = 0; rit != rend; ++rit)
y += pm.rows()[rit].height();
- y += pm.rows()[rend].totalAscent();
+ y += pm.rows()[rend].ascent();
TextMetrics const & bottom_tm = textMetrics(dit.bottom().text());
: "\t\t*** START DRAWING ***"));
Text & text = buffer_.text();
TextMetrics const & tm = d->text_metrics_[&text];
- int const y = tm.parMetrics(tm.firstPit()).position();
+ int const y = tm.first().second->position();
PainterInfo pi(this, pain);
// Check whether the row where the cursor lives needs to be scrolled.
tm.draw(pi, 0, y);
// and possibly grey out below
- int const y2 = tm.bottomPosition();
+ pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
+ int const y2 = lastpm.second->position() + lastpm.second->descent();
if (y2 < height_) {
Color color = buffer().isInternal()
updateScrollbar();
// Normalize anchor for next time
- for (pit_type pit = tm.firstPit(); pit <= tm.lastPit(); ++pit) {
+ pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();
+ pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
+ for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
ParagraphMetrics const & pm = tm.parMetrics(pit);
if (pm.position() + pm.descent() > 0) {
if (d->anchor_pit_ != pit