mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 19:07:45 +00:00
Handle metrics of not visible paragraphs
The code is not ready for situations where some paragraphs that are not visible have metrics available. In PararagraphMetrics, some methods are added to be able to handle the fact that paragraphs have or do not have a position. In TextMetrics, a new method returns the first visible paragraph. Finally, in BufferView::updateMetrics, the paragraphs' positions are reset (in the case where everything is not cleared) and some care is taken to skip the ones that are not relevant. The assumption outside of this method is that all the paragraphs that are in the TextMetrics are visible (we are talking about top-level TextMetrics here). This could be changed (in order to avoid recomputing paragraph metrics), but the cost is high in terms of complexity and it is not clear that the gain in terms of performance would be important. NOTE: contrary to the code in master which returns npos = -10000, this code still returns -1 when the position of a paragraph is unknown. (cherry picked from commit145af7c2ac
) (cherry picked from commit05bb851adf
) (cherry picked from commit8bc3799b35
)
This commit is contained in:
parent
f64349db8d
commit
10b8861d10
@ -3197,6 +3197,7 @@ void BufferView::updateMetrics(bool force)
|
|||||||
d->text_metrics_.clear();
|
d->text_metrics_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should not be moved earlier
|
||||||
TextMetrics & tm = textMetrics(&buftext);
|
TextMetrics & tm = textMetrics(&buftext);
|
||||||
|
|
||||||
// make sure inline completion pointer is ok
|
// make sure inline completion pointer is ok
|
||||||
@ -3212,14 +3213,16 @@ void BufferView::updateMetrics(bool force)
|
|||||||
|
|
||||||
// Check that the end of the document is not too high
|
// Check that the end of the document is not too high
|
||||||
int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() : height_;
|
int const min_visible = lyxrc.scroll_below_document ? minVisiblePart() : height_;
|
||||||
if (tm.last().first == lastpit && tm.last().second->bottom() < min_visible) {
|
if (tm.last().first == lastpit && tm.last().second->hasPosition()
|
||||||
|
&& tm.last().second->bottom() < min_visible) {
|
||||||
d->anchor_ypos_ += min_visible - tm.last().second->bottom();
|
d->anchor_ypos_ += min_visible - tm.last().second->bottom();
|
||||||
LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " << d->anchor_ypos_);
|
LYXERR(Debug::SCROLLING, "Too high, adjusting anchor ypos to " << d->anchor_ypos_);
|
||||||
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
|
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the start of the document is not too low
|
// Check that the start of the document is not too low
|
||||||
if (tm.first().first == 0 && tm.first().second->top() > 0) {
|
if (tm.first().first == 0 && tm.first().second->hasPosition()
|
||||||
|
&& tm.first().second->top() > 0) {
|
||||||
d->anchor_ypos_ -= tm.first().second->top();
|
d->anchor_ypos_ -= tm.first().second->top();
|
||||||
LYXERR(Debug::SCROLLING, "Too low, adjusting anchor ypos to " << d->anchor_ypos_);
|
LYXERR(Debug::SCROLLING, "Too low, adjusting anchor ypos to " << d->anchor_ypos_);
|
||||||
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
|
tm.updateMetrics(d->anchor_pit_, d->anchor_ypos_, height_);
|
||||||
@ -3232,11 +3235,11 @@ void BufferView::updateMetrics(bool force)
|
|||||||
* extra paragraphs are removed
|
* extra paragraphs are removed
|
||||||
*/
|
*/
|
||||||
// Remove paragraphs that are outside of screen
|
// Remove paragraphs that are outside of screen
|
||||||
while(tm.first().second->bottom() <= 0) {
|
while(!tm.first().second->hasPosition() || tm.first().second->bottom() <= 0) {
|
||||||
//LYXERR0("Forget pit: " << tm.first().first);
|
//LYXERR0("Forget pit: " << tm.first().first);
|
||||||
tm.forget(tm.first().first);
|
tm.forget(tm.first().first);
|
||||||
}
|
}
|
||||||
while(tm.last().second->top() > height_) {
|
while(!tm.last().second->hasPosition() || tm.last().second->top() > height_) {
|
||||||
//LYXERR0("Forget pit: " << tm.first().first);
|
//LYXERR0("Forget pit: " << tm.first().first);
|
||||||
tm.forget(tm.last().first);
|
tm.forget(tm.last().first);
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,10 @@ using namespace lyx::support;
|
|||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
|
const int pm_npos = -10000;
|
||||||
|
|
||||||
ParagraphMetrics::ParagraphMetrics(Paragraph const & par) :
|
ParagraphMetrics::ParagraphMetrics(Paragraph const & par) :
|
||||||
position_(-1), id_(par.id()), par_(&par)
|
position_(pm_npos), id_(par.id()), par_(&par)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +62,14 @@ void ParagraphMetrics::reset(Paragraph const & par)
|
|||||||
{
|
{
|
||||||
par_ = ∥
|
par_ = ∥
|
||||||
dim_ = Dimension();
|
dim_ = Dimension();
|
||||||
//position_ = -1;
|
//position_ = pm_npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ParagraphMetrics::position() const
|
||||||
|
{
|
||||||
|
LASSERT(hasPosition(), return -1);
|
||||||
|
return position_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,6 +79,18 @@ void ParagraphMetrics::setPosition(int position)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ParagraphMetrics::resetPosition()
|
||||||
|
{
|
||||||
|
position_ = pm_npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ParagraphMetrics::hasPosition() const
|
||||||
|
{
|
||||||
|
return position_ != pm_npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Row const & ParagraphMetrics::getRow(pos_type pos, bool boundary) const
|
Row const & ParagraphMetrics::getRow(pos_type pos, bool boundary) const
|
||||||
{
|
{
|
||||||
LBUFERR(!rows().empty());
|
LBUFERR(!rows().empty());
|
||||||
|
@ -70,8 +70,12 @@ public:
|
|||||||
bool hfillExpansion(Row const & row, pos_type pos) const;
|
bool hfillExpansion(Row const & row, pos_type pos) const;
|
||||||
|
|
||||||
/// The vertical position of the baseline of the first line of the paragraph
|
/// The vertical position of the baseline of the first line of the paragraph
|
||||||
int position() const { return position_; }
|
int position() const;
|
||||||
void setPosition(int position);
|
void setPosition(int position);
|
||||||
|
/// Set position to unknown
|
||||||
|
void resetPosition();
|
||||||
|
/// Return true when the position of the paragraph is known
|
||||||
|
bool hasPosition() const;
|
||||||
/// The vertical position of the top of the paragraph
|
/// The vertical position of the top of the paragraph
|
||||||
int top() const { return position_ - dim_.ascent(); }
|
int top() const { return position_ - dim_.ascent(); }
|
||||||
/// The vertical position of the bottom of the paragraph
|
/// The vertical position of the bottom of the paragraph
|
||||||
|
@ -220,7 +220,10 @@ void TextMetrics::updateMetrics(pit_type const anchor_pit, int const anchor_ypos
|
|||||||
int const bv_height)
|
int const bv_height)
|
||||||
{
|
{
|
||||||
LASSERT(text_->isMainText(), return);
|
LASSERT(text_->isMainText(), return);
|
||||||
pit_type const npit = pit_type(text_->paragraphs().size());
|
|
||||||
|
// Forget existing positions
|
||||||
|
for (auto & pm_pair : par_metrics_)
|
||||||
|
pm_pair.second.resetPosition();
|
||||||
|
|
||||||
if (!contains(anchor_pit))
|
if (!contains(anchor_pit))
|
||||||
// Rebreak anchor paragraph.
|
// Rebreak anchor paragraph.
|
||||||
@ -246,6 +249,7 @@ void TextMetrics::updateMetrics(pit_type const anchor_pit, int const anchor_ypos
|
|||||||
int y2 = anchor_ypos + anchor_pm.descent();
|
int y2 = anchor_ypos + anchor_pm.descent();
|
||||||
// We are now just below the anchor paragraph.
|
// We are now just below the anchor paragraph.
|
||||||
pit_type pit2 = anchor_pit + 1;
|
pit_type pit2 = anchor_pit + 1;
|
||||||
|
pit_type const npit = pit_type(text_->paragraphs().size());
|
||||||
for (; pit2 < npit && y2 < bv_height; ++pit2) {
|
for (; pit2 < npit && y2 < bv_height; ++pit2) {
|
||||||
if (!contains(pit2))
|
if (!contains(pit2))
|
||||||
redoParagraph(pit2);
|
redoParagraph(pit2);
|
||||||
|
Loading…
Reference in New Issue
Block a user