X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTextMetrics.cpp;h=d23c09d29bfacfe1ab6ef7533c3a8e24d79a3ede;hb=98621be1ba2a00a931e89020a164b4b8b54c597f;hp=d710e5f80afea656696a108d23c77ff473a294ad;hpb=9e2da4a3eac83f46ab184ea8d674f84643814017;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index d710e5f80a..d23c09d29b 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -45,6 +45,7 @@ #include "frontends/Painter.h" #include "frontends/NullPainter.h" +#include "support/convert.h" #include "support/debug.h" #include "support/lassert.h" @@ -500,7 +501,7 @@ bool TextMetrics::redoParagraph(pit_type const pit) // Top and bottom margin of the document (only at top-level) if (text_->isMainText()) { // original value was 20px, which is 0.2in at 100dpi - int const margin = Length(0.2, Length::IN).inPixels(0); + int const margin = bv_->zoomedPixels(20); if (pit == 0) { pm.rows().front().dimension().asc += margin; /* coverity thinks that we should update pm.dim().asc @@ -843,11 +844,6 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const // the width available for the row. int const width = max_width_ - row.right_margin; - if (pos >= end || row.width() > width) { - row.endpos(end); - return need_new_row; - } - #if 0 //FIXME: As long as leftMargin() is not correctly implemented for // MARGIN_RIGHT_ADDRESS_BOX, we should also not do this here. @@ -866,10 +862,7 @@ 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); - do { - // this can happen for an empty row after a newline - if (i >= end) - break; + while (i < end && (i == pos || row.width() <= width)) { char_type c = par.getChar(i); // The most special cases are handled first. if (par.isInset(i)) { @@ -951,7 +944,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const ++i; ++fi; - } while (i < end && row.width() <= width); + } row.finalizeLast(); row.endpos(i); @@ -1053,8 +1046,8 @@ int TextMetrics::parTopSpacing(pit_type const pit) const if (prev != pit_type(pars.size())) { asc += int(pars[prev].layout().parsep * dh); } else if (pit != 0) { - Paragraph const & prevpar = pars[pit - 1]; - if (prevpar.getDepth() != 0 || prevpar.layout() == layout) + Paragraph const & prevpar2 = pars[pit - 1]; + if (prevpar2.getDepth() != 0 || prevpar2.layout() == layout) asc += int(layout.parsep * dh); } @@ -1114,9 +1107,9 @@ void TextMetrics::setRowHeight(Row & row) const maxasc = max(maxasc, cit->dim.ascent()); maxdes = max(maxdes, cit->dim.descent()); } else { - FontMetrics const & fm = theFontMetrics(cit->font); - maxasc = max(maxasc, int(fm.maxAscent() * spacing_val)); - maxdes = max(maxdes, int(fm.maxDescent() * spacing_val)); + FontMetrics const & fm2 = theFontMetrics(cit->font); + maxasc = max(maxasc, int(fm2.maxAscent() * spacing_val)); + maxdes = max(maxdes, int(fm2.maxDescent() * spacing_val)); } } @@ -1302,9 +1295,9 @@ pit_type TextMetrics::getPitNearY(int y) LYXERR(Debug::DEBUG, "examining: pit: " << it->first << " y: " << it->second.position()); - ParagraphMetrics const & pm = par_metrics_[it->first]; + ParagraphMetrics const & pm2 = par_metrics_[it->first]; - if (it->first >= pit && int(it->second.position()) - int(pm.ascent()) <= y) { + if (it->first >= pit && int(it->second.position()) - int(pm2.ascent()) <= y) { pit = it->first; yy = it->second.position(); } @@ -1509,14 +1502,14 @@ int TextMetrics::cursorX(CursorSlice const & sl, int TextMetrics::cursorY(CursorSlice const & sl, bool boundary) const { //lyxerr << "TextMetrics::cursorY: boundary: " << boundary << endl; - ParagraphMetrics const & pm = par_metrics_[sl.pit()]; + ParagraphMetrics const & pm = parMetrics(sl.pit()); if (pm.rows().empty()) return 0; int h = 0; - h -= par_metrics_[0].rows()[0].ascent(); + h -= parMetrics(0).rows()[0].ascent(); for (pit_type pit = 0; pit < sl.pit(); ++pit) { - h += par_metrics_[pit].height(); + h += parMetrics(pit).height(); } int pos = sl.pos(); if (pos && boundary) @@ -1885,21 +1878,20 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const if (selection) row.setSelectionAndMargins(sel_beg_par, sel_end_par); else - row.setSelection(-1, -1); + row.clearSelectionAndMargins(); // The row knows nothing about the paragraph, so we have to check // whether this row is the first or last and update the margins. if (row.selection()) { if (row.sel_beg == 0) - row.begin_margin_sel = sel_beg.pit() < pit; + row.change(row.begin_margin_sel, sel_beg.pit() < pit); if (row.sel_end == sel_end_par.lastpos()) - row.end_margin_sel = sel_end.pit() > pit; + row.change(row.end_margin_sel, sel_end.pit() > pit); } // has row changed since last paint? bool row_has_changed = row.changed() - || bv_->hadHorizScrollOffset(text_, pit, row.pos()) - || bv_->needRepaint(text_, row); + || bv_->hadHorizScrollOffset(text_, pit, row.pos()); // Take this opportunity to spellcheck the row contents. if (row_has_changed && pi.do_spellcheck && lyxrc.spellcheck_continuously) { @@ -1925,8 +1917,16 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const LYXERR(Debug::PAINTING, "Clear rect@(" << max(row_x, 0) << ", " << y - row.ascent() << ")=" << width() << " x " << row.height()); - pi.pain.fillRectangle(max(row_x, 0), y - row.ascent(), - width(), row.height(), pi.background_color); + // FIXME: this is a hack. We know that at least this + // amount of pixels can be cleared on right and left. + // Doing so gets rid of caret ghosts when the cursor is at + // the begining/end of row. However, it will not work if + // the caret has a ridiculous width like 6. (see ticket + // #10797) + pi.pain.fillRectangle(max(row_x, 0) - Inset::TEXT_TO_INSET_OFFSET, + y - row.ascent(), + width() + 2 * Inset::TEXT_TO_INSET_OFFSET, + row.height(), pi.background_color); } // Instrumentation for testing row cache (see also @@ -1964,6 +1964,20 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const row_x + row.right_x() > bv_->workWidth()); y += row.descent(); +#if 0 + // This debug code shows on screen which rows are repainted. + // FIXME: since the updates related to caret blinking restrict + // the painter to a small rectangle, the numbers are not + // updated when this happens. Change the code in + // GuiWorkArea::Private::show/hideCaret if this is important. + static int count = 0; + ++count; + FontInfo fi(sane_font); + fi.setSize(FONT_SIZE_TINY); + fi.setColor(Color_red); + pi.pain.text(row_x, y, convert(count), fi); +#endif + // Restore full_repaint status. pi.full_repaint = tmp;