]> git.lyx.org Git - lyx.git/blobdiff - src/TextMetrics.cpp
MathML: more consistency between DocBook and XHTML.
[lyx.git] / src / TextMetrics.cpp
index 0f2ef90b9d7ae51d0c49507a7dbfd72096a7f4e5..0b3bfc1d16a79ce057eb979d2231dda30cfd9974 100644 (file)
@@ -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