X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Frowpainter.C;h=f29b51e1d592023d038c0cfeefdc95d62cc2c006;hb=73ed0b5203ffefa9a4c2ad8e8cf54396a6e72a9c;hp=7c78a4e1e520973a229c68fa018d96080e413ec2;hpb=b27bb5cb53edeee088cf408eb37dd7d72586b90d;p=lyx.git diff --git a/src/rowpainter.C b/src/rowpainter.C index 7c78a4e1e5..f29b51e1d5 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -25,7 +25,6 @@ #include "LColor.h" #include "lyxrc.h" #include "lyxrow.h" -#include "lyxrow_funcs.h" #include "metricsinfo.h" #include "paragraph.h" #include "paragraph_funcs.h" @@ -33,7 +32,6 @@ #include "vspace.h" #include "frontends/FontMetrics.h" -#include "frontends/nullpainter.h" #include "frontends/Painter.h" #include "insets/insettext.h" @@ -42,15 +40,11 @@ #include -using lyx::docstring; -using lyx::frontend::Painter; -using lyx::frontend::NullPainter; -using lyx::frontend::FontMetrics; -using lyx::char_type; -using lyx::pit_type; -using lyx::pos_type; -using lyx::Point; +namespace lyx { + +using frontend::Painter; +using frontend::FontMetrics; using std::endl; using std::max; @@ -83,13 +77,13 @@ public: private: void paintForeignMark(double orig_x, LyXFont const & font, int desc = 0); - void paintHebrewComposeChar(lyx::pos_type & vpos, LyXFont const & font); - void paintArabicComposeChar(lyx::pos_type & vpos, LyXFont const & font); - void paintChars(lyx::pos_type & vpos, LyXFont font, + void paintHebrewComposeChar(pos_type & vpos, LyXFont const & font); + void paintArabicComposeChar(pos_type & vpos, LyXFont const & font); + void paintChars(pos_type & vpos, LyXFont const & font, bool hebrew, bool arabic); int paintAppendixStart(int y); - void paintFromPos(lyx::pos_type & vpos); - void paintInset(lyx::pos_type const pos, LyXFont const & font); + void paintFromPos(pos_type & vpos); + void paintInset(pos_type const pos, LyXFont const & font); /// return left margin int leftMargin() const; @@ -135,7 +129,7 @@ RowPainter::RowPainter(PainterInfo & pi, erased_(pi.erased_), xo_(x), yo_(y), width_(text_.width()) { - RowMetrics m = text_.computeRowMetrics(pit, row_); + RowMetrics m = text_.computeRowMetrics(*bv_.buffer(), pit, row_); x_ = m.x + xo_; //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl; @@ -152,13 +146,13 @@ RowPainter::RowPainter(PainterInfo & pi, LyXFont const RowPainter::getLabelFont() const { - return text_.getLabelFont(par_); + return text_.getLabelFont(*bv_.buffer(), par_); } int RowPainter::leftMargin() const { - return text_.leftMargin(pit_, row_.pos()); + return text_.leftMargin(*bv_.buffer(), pit_, row_.pos()); } @@ -209,7 +203,8 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font) if (!Encodings::isComposeChar_hebrew(c)) { if (isPrintableNonspace(c)) { int const width2 = - text_.singleWidth(par_, i, c, text_.getFont(par_, i)); + text_.singleWidth(*bv_.buffer(), par_, i, c, + text_.getFont(*bv_.buffer(), par_, i)); // FIXME UNICODE // This does not work anymore, and non-ascii // characters in source files are forbidden @@ -248,7 +243,8 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font) if (!Encodings::isComposeChar_arabic(c)) { if (isPrintableNonspace(c)) { int const width2 = - text_.singleWidth(par_, i, c, text_.getFont(par_, i)); + text_.singleWidth(*bv_.buffer(), par_, i, c, + text_.getFont(*bv_.buffer(), par_, i)); dx = (width2 - width) / 2; } break; @@ -258,23 +254,20 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font) pain_.text(int(x_) + dx, yo_, str, font); } - -void RowPainter::paintChars(pos_type & vpos, LyXFont font, +void RowPainter::paintChars(pos_type & vpos, LyXFont const & font, bool hebrew, bool arabic) { + // This method takes up 70% of time when typing pos_type pos = text_.bidi.vis2log(vpos); pos_type const end = row_.endpos(); FontSpan const font_span = par_.fontSpan(pos); Change::Type const prev_change = par_.lookupChange(pos).type; // first character -#if 0 - string str; - str += par_.getChar(pos); -#else std::vector str; + str.reserve(100); str.push_back(par_.getChar(pos)); -#endif + if (arabic) { char_type c = str[0]; str[0] = par_.transformChar(c, pos); @@ -303,26 +296,20 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font, if (arabic) c = par_.transformChar(c, pos); -#if 0 - str += c; -#else str.push_back(c); -#endif } - if (prev_change == Change::DELETED) - font.setColor(LColor::strikeout); - else if (prev_change == Change::INSERTED) - font.setColor(LColor::newtext); - - // Draw text and set the new x position - //lyxerr << "paint row: yo_ " << yo_ << "\n"; -#if 0 - int width = pain_.text(int(x_), yo_, str, font); -#else - int width = pain_.text(int(x_), yo_, &str[0], str.size(), font); -#endif - x_ += width; + if (prev_change != Change::UNCHANGED) { + LyXFont copy(font); + if (prev_change == Change::DELETED) { + copy.setColor(LColor::strikeout); + } else if (prev_change == Change::INSERTED) { + copy.setColor(LColor::newtext); + } + x_ += pain_.text(int(x_), yo_, &str[0], str.size(), copy); + } else { + x_ += pain_.text(int(x_), yo_, &str[0], str.size(), font); + } } @@ -343,7 +330,7 @@ void RowPainter::paintForeignMark(double orig_x, LyXFont const & font, int desc) void RowPainter::paintFromPos(pos_type & vpos) { pos_type const pos = text_.bidi.vis2log(vpos); - LyXFont orig_font = text_.getFont(par_, pos); + LyXFont orig_font = text_.getFont(*bv_.buffer(), par_, pos); double const orig_x = x_; @@ -413,12 +400,12 @@ void RowPainter::paintAppendix() void RowPainter::paintDepthBar() { - Paragraph::depth_type const depth = par_.getDepth(); + depth_type const depth = par_.getDepth(); if (depth <= 0) return; - Paragraph::depth_type prev_depth = 0; + depth_type prev_depth = 0; if (!text_.isFirstRow(pit_, row_)) { pit_type pit2 = pit_; if (row_.pos() == 0) @@ -426,7 +413,7 @@ void RowPainter::paintDepthBar() prev_depth = pars_[pit2].getDepth(); } - Paragraph::depth_type next_depth = 0; + depth_type next_depth = 0; if (!text_.isLastRow(pit_, row_)) { pit_type pit2 = pit_; if (row_.endpos() >= pars_[pit2].size()) @@ -434,11 +421,11 @@ void RowPainter::paintDepthBar() next_depth = pars_[pit2].getDepth(); } - for (Paragraph::depth_type i = 1; i <= depth; ++i) { + for (depth_type i = 1; i <= depth; ++i) { int const w = nestMargin() / 5; int x = int(xo_) + w * i; // only consider the changebar space if we're drawing outermost text - if (text_.isMainText()) + if (text_.isMainText(*bv_.buffer())) x += changebarMargin(); int const starty = yo_ - row_.ascent(); @@ -509,7 +496,7 @@ void RowPainter::paintFirst() } } - bool const is_rtl = text_.isRTL(par_); + bool const is_rtl = text_.isRTL(buffer, par_); bool const is_seq = isFirstInSequence(pit_, text_.paragraphs()); //lyxerr << "paintFirst: " << par_.id() << " is_seq: " << is_seq << std::endl; @@ -550,7 +537,7 @@ void RowPainter::paintFirst() pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font); } else { // FIXME UNICODE - docstring lab = lyx::from_utf8(layout->labelsep); + docstring lab = from_utf8(layout->labelsep); if (is_rtl) { x = width_ - leftMargin() + fm.width(lab); @@ -591,7 +578,7 @@ void RowPainter::paintFirst() if (layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) { if (is_rtl) x = leftMargin(); - x += (width_ - text_.rightMargin(par_) - leftMargin()) / 2; + x += (width_ - text_.rightMargin(buffer, par_) - leftMargin()) / 2; x -= fm.width(str) / 2; } else if (is_rtl) { x = width_ - leftMargin() - fm.width(str); @@ -604,7 +591,7 @@ void RowPainter::paintFirst() void RowPainter::paintLast() { - bool const is_rtl = text_.isRTL(par_); + bool const is_rtl = text_.isRTL(*bv_.buffer(), par_); int const endlabel = getEndLabel(pit_, text_.paragraphs()); // draw an endlabel @@ -630,11 +617,10 @@ void RowPainter::paintLast() case END_LABEL_STATIC: { LyXFont font = getLabelFont(); FontMetrics const & fm = theFontMetrics(font); - // FIXME UNICODE - docstring const & str = lyx::from_utf8(par_.layout()->endlabelstring()); + docstring const & str = par_.layout()->endlabelstring(); double const x = is_rtl ? x_ - fm.width(str) - : - text_.rightMargin(par_) - row_.width(); + : - text_.rightMargin(*bv_.buffer(), par_) - row_.width(); pain_.text(int(x), yo_, str, font); break; } @@ -663,6 +649,7 @@ void RowPainter::paintText() // Use font span to speed things up, see below FontSpan font_span; LyXFont font; + Buffer const & buffer = *bv_.buffer(); for (pos_type vpos = row_.pos(); vpos < end; ) { if (x_ > bv_.workWidth()) @@ -678,11 +665,11 @@ void RowPainter::paintText() // Use font span to speed things up, see above if (vpos < font_span.first || vpos > font_span.last) { font_span = par_.fontSpan(vpos); - font = text_.getFont(par_, vpos); + font = text_.getFont(buffer, par_, vpos); } - const int width_pos = - text_.singleWidth(par_, pos, par_.getChar(pos), font); + const int width_pos = text_.singleWidth(buffer, par_, pos, + par_.getChar(pos), font); if (x_ + width_pos < 0) { x_ += width_pos; @@ -715,7 +702,7 @@ void RowPainter::paintText() if (body_pos > 0 && pos == body_pos - 1) { // FIXME UNICODE int const lwidth = theFontMetrics(getLabelFont()) - .width(lyx::from_utf8(layout->labelsep)); + .width(from_utf8(layout->labelsep)); x_ += label_hfill_ + lwidth - width_pos; } @@ -728,7 +715,7 @@ void RowPainter::paintText() pain_.line(int(x_), y1, int(x_), y0, LColor::added_space); - if (hfillExpansion(par_, row_, pos)) { + if (par_.hfillExpansion(row_, pos)) { int const y2 = (y0 + y1) / 2; if (pos >= body_pos) { @@ -769,15 +756,15 @@ void RowPainter::paintText() } -lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par, +size_type calculateRowSignature(Row const & row, Paragraph const & par, int x, int y) { boost::crc_32_type crc; - for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) { - const unsigned char b[] = { par.getChar(i) }; + for (pos_type i = row.pos(); i < row.endpos(); ++i) { + char_type const b[] = { par.getChar(i) }; crc.process_bytes(b, 1); } - const unsigned char b[] = { x, y, row.width() }; + char_type const b[] = { x, y, row.width() }; crc.process_bytes(b, 3); return crc.checksum(); } @@ -788,7 +775,7 @@ bool CursorOnRow(PainterInfo & pi, pit_type const pit, { // Is there a cursor on this row (or inside inset on row) LCursor & cur = pi.base.bv->cursor(); - for (lyx::size_type d = 0; d < cur.depth(); d++) { + for (size_type d = 0; d < cur.depth(); ++d) { CursorSlice const & sl = cur[d]; if (sl.text() == &text && sl.pit() == pit @@ -808,7 +795,7 @@ bool innerCursorOnRow(PainterInfo & pi, pit_type pit, LCursor & cur = pi.base.bv->cursor(); if (rit->pos() + 1 != rit->endpos()) return false; - for (lyx::size_type d = 0; d < cur.depth(); d++) { + for (size_type d = 0; d < cur.depth(); d++) { CursorSlice const & sl = cur[d]; if (sl.text() == &text && sl.pit() == pit @@ -824,8 +811,6 @@ void paintPar bool repaintAll) { // lyxerr << " paintPar: pit: " << pit << " at y: " << y << endl; - static NullPainter nop; - static PainterInfo nullpi(pi.base.bv, nop); int const ww = pi.base.bv->workHeight(); pi.base.bv->coordCache().parPos()[&text][pit] = Point(x, y); @@ -838,7 +823,7 @@ void paintPar RowList::const_iterator const re = par.rows().end(); y -= rb->ascent(); - lyx::size_type rowno(0); + size_type rowno = 0; for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) { y += rit->ascent(); // Allow setting of refreshInside for nested insets in @@ -846,7 +831,7 @@ void paintPar bool tmp = refreshInside; // Row signature; has row changed since last paint? - lyx::size_type const row_sig = calculateRowSignature(*rit, par, x, y); + size_type const row_sig = calculateRowSignature(*rit, par, x, y); bool row_has_changed = par.rowSignature()[rowno] != row_sig; bool cursor_on_row = CursorOnRow(pi, pit, rit, text); @@ -869,10 +854,12 @@ void paintPar if (repaintAll || row_has_changed || cursor_on_row) { // Add to row signature cache par.rowSignature()[rowno] = row_sig; - + bool const inside = (y + rit->descent() >= 0 - && y - rit->ascent() < ww); - RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y); + && y - rit->ascent() < ww); + // it is not needed to draw on screen if we are not inside. + pi.pain.setDrawingEnabled(inside); + RowPainter rp(pi, text, pit, *rit, x, y); // Clear background of this row // (if paragraph background was not cleared) if (!repaintAll && @@ -888,7 +875,7 @@ void paintPar // Instrumentation for testing row cache (see also // 12 lines lower): - if (text.isMainText()) + if (text.isMainText(*pi.base.bv->buffer())) lyxerr[Debug::PAINTING] << "#"; else lyxerr[Debug::PAINTING] << "[" << @@ -907,18 +894,24 @@ void paintPar // Restore, see above refreshInside = tmp; } + // Re-enable screen drawing for future use of the painter. + pi.pain.setDrawingEnabled(true); + lyxerr[Debug::PAINTING] << "." << endl; } } // namespace anon -void paintText(BufferView & bv, ViewMetricsInfo const & vi, +void paintText(BufferView & bv, Painter & pain) { - LyXText & text = bv.buffer()->text(); + BOOST_ASSERT(bv.buffer()); + Buffer const & buffer = *bv.buffer(); + LyXText & text = buffer.text(); bool const select = bv.cursor().selection(); - + ViewMetricsInfo const & vi = bv.viewMetricsInfo(); + PainterInfo pi(const_cast(&bv), pain); // Should the whole screen, including insets, be refreshed? bool repaintAll = select || !vi.singlepar; @@ -947,13 +940,13 @@ void paintText(BufferView & bv, ViewMetricsInfo const & vi, // Try viewing the User Guide Mobius figure if (vi.p1 > 0) { - text.redoParagraph(vi.p1 - 1); + text.redoParagraph(bv, vi.p1 - 1); bv.coordCache().parPos()[&text][vi.p1 - 1] = Point(0, vi.y1 - text.getPar(vi.p1 - 1).descent()); } - if (vi.p2 < lyx::pit_type(text.paragraphs().size()) - 1) { - text.redoParagraph(vi.p2 + 1); + if (vi.p2 < pit_type(text.paragraphs().size()) - 1) { + text.redoParagraph(bv, vi.p2 + 1); bv.coordCache().parPos()[&text][vi.p2 + 1] = Point(0, vi.y2 + text.getPar(vi.p2 + 1).ascent()); } @@ -983,3 +976,6 @@ void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y) y += text.getPar(pit).descent(); } } + + +} // namespace lyx