X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FTextMetrics.cpp;h=f29202c668644dc6dada33af211f7fd25ac7435b;hb=d81fe084a633188555feea6aab191fe8597e1dc2;hp=eb71f74f1c00088fb1268eee64ce064c44022ff8;hpb=37fd7b24ba60d9357fde0c218de051b71e222f80;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index eb71f74f1c..f29202c668 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -565,15 +565,15 @@ void TextMetrics::computeRowMetrics(pit_type const pit, Paragraph const & par = text_->getPar(pit); - double const w = width - row.right_margin - row.width(); + int const w = width - row.right_margin - row.width(); // FIXME: put back this assertion when the crash on new doc is solved. //LASSERT(w >= 0, /**/); bool const is_rtl = text_->isRTL(par); if (is_rtl) - row.x = rightMargin(pit); + row.left_margin = rightMargin(pit); else - row.x = leftMargin(max_width_, pit, row.pos()); + row.left_margin = leftMargin(max_width_, pit, row.pos()); // is there a manual margin with a manual label Layout const & layout = par.layout(); @@ -600,7 +600,7 @@ void TextMetrics::computeRowMetrics(pit_type const pit, // are there any hfills in the row? if (int const nh = numberOfHfills(row, par.beginOfBody())) { if (w > 0) - hfill = w / double(nh); + hfill = double(w) / nh; // we don't have to look at the alignment if it is ALIGN_LEFT and // if the row is already larger then the permitted width as then // we force the LEFT_ALIGN'edness! @@ -615,20 +615,20 @@ void TextMetrics::computeRowMetrics(pit_type const pit, * or newline, then stretch it */ if (ns && !row.right_boundary() && row.endpos() != par.size()) { - setSeparatorWidth(row, w / ns); + setSeparatorWidth(row, double(w) / ns); row.dimension().wid = width; } else if (is_rtl) { row.dimension().wid = width; - row.x += w; + row.left_margin += w; } break; } case LYX_ALIGN_RIGHT: - row.x += w; + row.left_margin += w; break; case LYX_ALIGN_CENTER: - row.dimension().wid = width - int(w / 2); - row.x += w / 2; + row.dimension().wid = width - w / 2; + row.left_margin += w / 2; break; case LYX_ALIGN_LEFT: case LYX_ALIGN_NONE: @@ -639,21 +639,6 @@ void TextMetrics::computeRowMetrics(pit_type const pit, } } -#if 0 - if (is_rtl) { - pos_type body_pos = par.beginOfBody(); - pos_type end = row.endpos(); - - if (body_pos > 0 - && (body_pos > end || !par.isLineSeparator(body_pos - 1))) { - row.x += theFontMetrics(text_->labelFont(par)). - width(layout.labelsep); - if (body_pos <= end) - row.x += row.label_hfill; - } - } -#endif - // Finally, handle hfill insets pos_type const endpos = row.endpos(); pos_type body_pos = par.beginOfBody(); @@ -686,13 +671,13 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const Paragraph const & par = text_->getPar(pit); LBUFERR(par.beginOfBody() > 0 || par.isEnvSeparator(0)); - double w = 0; + int w = 0; Row::const_iterator cit = row.begin(); Row::const_iterator const end = row.end(); // iterate over elements before main body (except the last one, // which is extra space). while (cit!= end && cit->endpos < par.beginOfBody()) { - w += cit->width(); + w += cit->dim.wid; ++cit; } @@ -703,7 +688,7 @@ int TextMetrics::labelFill(pit_type const pit, Row const & row) const FontMetrics const & fm = theFontMetrics(text_->labelFont(par)); - return max(0, fm.width(label) - int(w)); + return max(0, fm.width(label) - w); } @@ -802,11 +787,12 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit int const width = max_width_ - right_margin; pos_type const body_pos = par.beginOfBody(); row.clear(); - row.dimension().wid = leftMargin(max_width_, pit, pos); + // This make get changed in computeRowMetrics depending on RTL + row.left_margin = leftMargin(max_width_, pit, pos); + row.dimension().wid = row.left_margin; row.right_margin = right_margin; if (pos >= end || row.width() > width) { - row.dimension().wid += right_margin; row.endpos(end); return; } @@ -849,6 +835,8 @@ void TextMetrics::breakRow(Row & row, int const right_margin, pit_type const pit // before body_pos. Instead, insert some spacing to // align text FontMetrics const & fm = theFontMetrics(text_->labelFont(par)); + // this is needed to make sure that the row width is correct + row.finalizeLast(); int const add = max(fm.width(par.layout().labelsep), labelEnd(pit) - row.width()); row.addSpace(i, add, *fi, par.lookupChange(i)); @@ -1114,29 +1102,29 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x, pos_type pos = row.pos(); boundary = false; if (row.empty()) - x = int(row.x); - else if (x <= row.x) { + x = row.left_margin; + else if (x <= row.left_margin) { pos = row.front().left_pos(); - x = int(row.x); - } else if (x >= row.width() - row.right_margin) { + x = row.left_margin; + } else if (x >= row.width()) { pos = row.back().right_pos(); - x = row.width() - row.right_margin; + x = row.width(); } else { - double w = row.x; + double w = row.left_margin; Row::const_iterator cit = row.begin(); Row::const_iterator cend = row.end(); for ( ; cit != cend; ++cit) { - if (w <= x && w + cit->width() > x) { - double x_offset = x - w; + if (w <= x && w + cit->full_width() > x) { + int x_offset = int(x - w); pos = cit->x2pos(x_offset); x = int(x_offset + w); break; } - w += cit->width(); + w += cit->full_width(); } if (cit == row.end()) { pos = row.back().right_pos(); - x = row.width() - row.right_margin; + x = row.width(); } /** This tests for the case where the cursor is placed * just before a font direction change. See comment on @@ -1481,10 +1469,10 @@ int TextMetrics::cursorX(CursorSlice const & sl, if (row.empty() || (pos == row.begin()->left_pos() && pos != row.begin()->right_pos())) - return int(row.x); + return row.left_margin; Row::const_iterator cit = row.begin(); - double x = row.x; + double x = row.left_margin; for ( ; cit != row.end() ; ++cit) { /** Look whether the cursor is inside the element's * span. Note that it is necessary to take the @@ -1497,7 +1485,7 @@ int TextMetrics::cursorX(CursorSlice const & sl, x += cit->pos2x(pos); break; } - x += cit->width(); + x += cit->full_width(); } return int(x); @@ -1815,7 +1803,7 @@ void TextMetrics::draw(PainterInfo & pi, int x, int y) const } -void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) const +void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const x, int y) const { BufferParams const & bparams = bv_->buffer().params(); ParagraphMetrics const & pm = par_metrics_[pit]; @@ -1855,14 +1843,25 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co for (size_t i = 0; i != nrows; ++i) { Row const & row = pm.rows()[i]; + int row_x = x; if (i) y += row.ascent(); + CursorSlice rowSlice(const_cast(text_->inset())); + rowSlice.pit() = pit; + rowSlice.pos() = row.pos(); + bool const inside = (y + row.descent() >= 0 && y - row.ascent() < ww); + + // Adapt to cursor row scroll offset if applicable. + if (bv_->currentRowSlice() == rowSlice) + row_x -= bv_->horizScrollOffset(); + // It is not needed to draw on screen if we are not inside. pi.pain.setDrawingEnabled(inside && original_drawing_state); - RowPainter rp(pi, *text_, pit, row, x, y); + + RowPainter rp(pi, *text_, pit, row, row_x, y); if (selection) row.setSelectionAndMargins(sel_beg_par, sel_end_par); @@ -1880,7 +1879,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co // Row signature; has row changed since last paint? row.setCrc(pm.computeRowSignature(row, bparams)); - bool row_has_changed = row.changed(); + bool row_has_changed = row.changed() + || rowSlice == bv_->lastRowSlice(); // Take this opportunity to spellcheck the row contents. if (row_has_changed && lyxrc.spellcheck_continuously) { @@ -1900,7 +1900,10 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co // Clear background of this row if paragraph background was not // already cleared because of a full repaint. if (!pi.full_repaint && row_has_changed) { - pi.pain.fillRectangle(x, y - row.ascent(), + 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); } @@ -1935,6 +1938,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) co rp.paintLast(); if (i == 0 && is_rtl) rp.paintFirst(); + rp.paintTooLargeMarks(row_x < 0, + row_x + row.width() > bv_->workWidth()); y += row.descent(); // Restore full_repaint status.