X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTextMetrics.cpp;h=0b3bfc1d16a79ce057eb979d2231dda30cfd9974;hb=b08a653f3549e08fffc5318c87da305651ecc197;hp=0f2ef90b9d7ae51d0c49507a7dbfd72096a7f4e5;hpb=bea482877e9c8774fad86b22bd065e213a80a3ba;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 0f2ef90b9d..0b3bfc1d16 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -30,6 +30,7 @@ #include "MetricsInfo.h" #include "ParagraphParameters.h" #include "RowPainter.h" +#include "Session.h" #include "Text.h" #include "TextClass.h" #include "VSpace.h" @@ -581,27 +582,29 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows) } // The space above and below the paragraph. - int const top = parTopSpacing(pit); - pm.rows().front().dim().asc += top; - int const bottom = parBottomSpacing(pit); - pm.rows().back().dim().des += bottom; - pm.dim().des += top + bottom; - - pm.dim().asc += pm.rows()[0].ascent(); - pm.dim().des -= pm.rows()[0].ascent(); + int top = parTopSpacing(pit); + int bottom = parBottomSpacing(pit); // Top and bottom margin of the document (only at top-level) // FIXME: It might be better to move this in another method // specially tailored for the main text. if (text_->isMainText()) { if (pit == 0) - pm.dim().asc += bv_->topMargin(); - ParagraphList const & pars = text_->paragraphs(); - if (pit + 1 == pit_type(pars.size())) { - pm.dim().des += bv_->bottomMargin(); + top += bv_->topMargin(); + if (pit + 1 == pit_type(text_->paragraphs().size())) { + bottom += bv_->bottomMargin(); } } + // Add the top/bottom space to rows and paragraph metrics + pm.rows().front().dim().asc += top; + pm.rows().back().dim().des += bottom; + pm.dim().des += top + bottom; + + // Move the pm ascent to be the same as the first row ascent + pm.dim().asc += pm.rows().front().ascent(); + pm.dim().des -= pm.rows().front().ascent(); + changed |= old_dim.height() != pm.dim().height(); return changed; @@ -877,6 +880,10 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const { LATTEST(row.empty()); Paragraph const & par = text_->getPar(row.pit()); + Buffer const & buf = text_->inset().buffer(); + BookmarksSection::BookmarkPosList bpl = + theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id()); + pos_type const end = par.size(); pos_type const pos = row.pos(); pos_type const body_pos = par.beginOfBody(); @@ -903,7 +910,24 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const // or the end of the par, then build a representation of the row. pos_type i = pos; FontIterator fi = FontIterator(*this, par, row.pit(), pos); - while (i < end && (i == pos || row.width() <= width)) { + // The real stopping condition is a few lines below. + while (true) { + // Firstly, check whether there is a bookmark here. + if (lyxrc.bookmarks_visibility == LyXRC::BMK_INLINE) + for (auto const & bp_p : bpl) + if (bp_p.second == i) { + Font f = *fi; + f.fontInfo().setColor(Color_bookmark); + // ❶ U+2776 DINGBAT NEGATIVE CIRCLED DIGIT ONE + char_type const ch = 0x2775 + bp_p.first; + row.addVirtual(i, docstring(1, ch), f, Change()); + } + + // The stopping condition is here so that the display of a + // bookmark can take place at paragraph start too. + if (i >= end || (i != pos && row.width() > width)) + break; + char_type c = par.getChar(i); // The most special cases are handled first. if (par.isInset(i)) { @@ -997,9 +1021,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const // in the paragraph. Font f(text_->layoutFont(row.pit())); f.fontInfo().setColor(Color_paragraphmarker); - BufferParams const & bparams - = text_->inset().buffer().params(); - f.setLanguage(par.getParLanguage(bparams)); + f.setLanguage(par.getParLanguage(buf.params())); // ¶ U+00B6 PILCROW SIGN row.addVirtual(end, docstring(1, char_type(0x00B6)), f, change); } @@ -1164,6 +1186,9 @@ void TextMetrics::setRowHeight(Row & row) const row.dim().asc = maxasc; row.dim().des = maxdes; + + // This is useful for selections + row.contents_dim() = row.dim(); } @@ -1330,7 +1355,7 @@ Row const & TextMetrics::getPitAndRowNearY(int & y, pit_type & pit, { ParagraphMetrics const & pm = par_metrics_[pit]; - int yy = pm.position() - pm.rows().front().ascent(); + int yy = pm.position() - pm.ascent(); LBUFERR(!pm.rows().empty()); RowList::const_iterator rit = pm.rows().begin(); RowList::const_iterator rlast = pm.rows().end(); @@ -1597,8 +1622,9 @@ void TextMetrics::deleteLineForward(Cursor & cur) int TextMetrics::leftMargin(pit_type pit) const { - // the + 1 is useful when the paragraph is empty - return leftMargin(pit, text_->paragraphs()[pit].size() + 1); + // FIXME: what is the semantics? It depends on whether the + // paragraph is empty! + return leftMargin(pit, text_->paragraphs()[pit].size()); } @@ -1611,7 +1637,7 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const Paragraph const & par = pars[pit]; LASSERT(pos >= 0, return 0); // We do not really care whether pos > par.size(), since we do not - // access the data. It can be actially useful, when querying the + // access the data. It can be actually useful, when querying the // margin without indentation (see leftMargin(pit_type). Buffer const & buffer = bv_->buffer(); @@ -1851,6 +1877,9 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const if (text_->isRTL(pit)) swap(pi.leftx, pi.rightx); + BookmarksSection::BookmarkPosList bpl = + theSession().bookmarks().bookmarksInPar(bv_->buffer().fileName(), pm.par().id()); + for (size_t i = 0; i != nrows; ++i) { Row const & row = pm.rows()[i]; @@ -1895,6 +1924,9 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const // Paint only the insets if the text itself is // unchanged. rp.paintOnlyInsets(); + rp.paintTooLargeMarks( + row_x + row.left_x() < bv_->leftMargin(), + row_x + row.right_x() > bv_->workWidth() - bv_->rightMargin()); row.changed(false); y += row.descent(); continue; @@ -1937,8 +1969,15 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const if (i == nrows - 1) rp.paintLast(); rp.paintText(); - rp.paintTooLargeMarks(row_x + row.left_x() < 0, - row_x + row.right_x() > bv_->workWidth()); + rp.paintTooLargeMarks( + row_x + row.left_x() < bv_->leftMargin(), + row_x + row.right_x() > bv_->workWidth() - bv_->rightMargin()); + // indicate bookmarks presence in margin + if (lyxrc.bookmarks_visibility == LyXRC::BMK_MARGIN) + for (auto const & bp_p : bpl) + if (bp_p.second >= row.pos() && bp_p.second < row.endpos()) + rp.paintBookmark(bp_p.first); + y += row.descent(); #if 0