-// only used for inset right now. should also be used for main text
-void Text::draw(PainterInfo & pi, int x, int y) const
-{
- paintTextInset(*this, pi, x, y);
-}
-
-
-// only used for inset right now. should also be used for main text
-void Text::drawSelection(PainterInfo & pi, int x, int) const
-{
- Cursor & cur = pi.base.bv->cursor();
- if (!cur.selection())
- return;
- if (!ptr_cmp(cur.text(), this))
- return;
-
- LYXERR(Debug::DEBUG)
- << BOOST_CURRENT_FUNCTION
- << "draw selection at " << x
- << endl;
-
- DocIterator beg = cur.selectionBegin();
- DocIterator end = cur.selectionEnd();
-
- BufferView & bv = *pi.base.bv;
-
- // the selection doesn't touch the visible screen?
- if (bv_funcs::status(&bv, beg) == bv_funcs::CUR_BELOW
- || bv_funcs::status(&bv, end) == bv_funcs::CUR_ABOVE)
- return;
-
- TextMetrics const & tm = bv.textMetrics(this);
- ParagraphMetrics const & pm1 = tm.parMetrics(beg.pit());
- ParagraphMetrics const & pm2 = tm.parMetrics(end.pit());
- Row const & row1 = pm1.getRow(beg.pos(), beg.boundary());
- Row const & row2 = pm2.getRow(end.pos(), end.boundary());
-
- // clip above
- int middleTop;
- bool const clipAbove =
- (bv_funcs::status(&bv, beg) == bv_funcs::CUR_ABOVE);
- if (clipAbove)
- middleTop = 0;
- else
- middleTop = bv_funcs::getPos(bv, beg, beg.boundary()).y_ + row1.descent();
-
- // clip below
- int middleBottom;
- bool const clipBelow =
- (bv_funcs::status(&bv, end) == bv_funcs::CUR_BELOW);
- if (clipBelow)
- middleBottom = bv.workHeight();
- else
- middleBottom = bv_funcs::getPos(bv, end, end.boundary()).y_ - row2.ascent();
-
- // start and end in the same line?
- if (!(clipAbove || clipBelow) && &row1 == &row2)
- // then only draw this row's selection
- drawRowSelection(pi, x, row1, beg, end, false, false);
- else {
- if (!clipAbove) {
- // get row end
- DocIterator begRowEnd = beg;
- begRowEnd.pos() = row1.endpos();
- begRowEnd.boundary(true);
-
- // draw upper rectangle
- drawRowSelection(pi, x, row1, beg, begRowEnd, false, true);
- }
-
- if (middleTop < middleBottom) {
- // draw middle rectangle
- pi.pain.fillRectangle(x, middleTop,
- tm.width(), middleBottom - middleTop,
- Color::selection);
- }
-
- if (!clipBelow) {
- // get row begin
- DocIterator endRowBeg = end;
- endRowBeg.pos() = row2.pos();
- endRowBeg.boundary(false);
-
- // draw low rectangle
- drawRowSelection(pi, x, row2, endRowBeg, end, true, false);
- }
- }
-}
-
-
-void Text::drawRowSelection(PainterInfo & pi, int x, Row const & row,
- DocIterator const & beg, DocIterator const & end,
- bool drawOnBegMargin, bool drawOnEndMargin) const
-{
- BufferView & bv = *pi.base.bv;
- Buffer & buffer = bv.buffer();
- TextMetrics const & tm = bv.textMetrics(this);
- DocIterator cur = beg;
- int x1 = cursorX(bv, beg.top(), beg.boundary());
- int x2 = cursorX(bv, end.top(), end.boundary());
- int y1 = bv_funcs::getPos(bv, cur, cur.boundary()).y_ - row.ascent();
- int y2 = y1 + row.height();
-
- // draw the margins
- if (drawOnBegMargin) {
- if (isRTL(buffer, beg.paragraph()))
- pi.pain.fillRectangle(x + x1, y1, tm.width() - x1, y2 - y1, Color::selection);
- else
- pi.pain.fillRectangle(x, y1, x1, y2 - y1, Color::selection);
- }
-
- if (drawOnEndMargin) {
- if (isRTL(buffer, beg.paragraph()))
- pi.pain.fillRectangle(x, y1, x2, y2 - y1, Color::selection);
- else
- pi.pain.fillRectangle(x + x2, y1, tm.width() - x2, y2 - y1, Color::selection);
- }
-
- // if we are on a boundary from the beginning, it's probably
- // a RTL boundary and we jump to the other side directly as this
- // segement is 0-size and confuses the logic below
- if (cur.boundary())
- cur.boundary(false);
-
- // go through row and draw from RTL boundary to RTL boundary
- while (cur < end) {
- bool drawNow = false;
-
- // simplified cursorRight code below which does not
- // descend into insets and which does not go into the
- // next line. Compare the logic with the original cursorRight
-
- // if left of boundary -> just jump to right side
- // but for RTL boundaries don't, because: abc|DDEEFFghi -> abcDDEEF|Fghi
- if (cur.boundary()) {
- cur.boundary(false);
- } else if (isRTLBoundary(buffer, cur.paragraph(), cur.pos() + 1)) {
- // in front of RTL boundary -> Stay on this side of the boundary because:
- // ab|cDDEEFFghi -> abc|DDEEFFghi
- ++cur.pos();
- cur.boundary(true);
- drawNow = true;
- } else {
- // move right
- ++cur.pos();
-
- // line end?
- if (cur.pos() == row.endpos())
- cur.boundary(true);
- }
-
- if (x1 == -1) {
- // the previous segment was just drawn, now the next starts
- x1 = cursorX(bv, cur.top(), cur.boundary());
- }
-
- if (!(cur < end) || drawNow) {
- x2 = cursorX(bv, cur.top(), cur.boundary());
- pi.pain.fillRectangle(x + min(x1,x2), y1, abs(x2 - x1), y2 - y1,
- Color::selection);
-
- // reset x1, so it is set again next round (which will be on the
- // right side of a boundary or at the selection end)
- x1 = -1;
- }
- }
-}
-
-
-
-bool Text::isLastRow(pit_type pit, Row const & row) const
-{
- return row.endpos() >= pars_[pit].size()
- && pit + 1 == pit_type(paragraphs().size());
-}
-
-
-bool Text::isFirstRow(pit_type pit, Row const & row) const
-{
- return row.pos() == 0 && pit == 0;
-}
-
-