X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FTextMetrics.cpp;h=f38c78d3ea7d98e6799d17a41898eafe8bba1049;hb=a550f7d91e2f945517cf96ad5f68788944539ecb;hp=843ad7762ded41079ae0150ace17cfcb26425261;hpb=e3d252cd6256b32745b93c0cb0fd5170f448f91c;p=lyx.git diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 843ad7762d..f38c78d3ea 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -26,7 +26,6 @@ #include "CoordCache.h" #include "Cursor.h" #include "CutAndPaste.h" -#include "HSpace.h" #include "InsetList.h" #include "Language.h" #include "Layout.h" @@ -421,10 +420,21 @@ bool TextMetrics::redoParagraph(pit_type const pit) parPos.pos()++; } + // If there is an end of paragraph marker, its size should be + // substracted to the available width. The logic here is + // almost the same as in breakRow, remember keep them in sync. + int eop = 0; + if (lyxrc.paragraph_markers && ii->pos + 1 == par.size() + && size_type(pit + 1) < text_->paragraphs().size()) { + Font f(text_->layoutFont(pit)); + // ¶ U+00B6 PILCROW SIGN + eop = theFontMetrics(f).width(char_type(0x00B6)); + } + // do the metric calculation Dimension dim; int const w = max_width_ - leftMargin(max_width_, pit, ii->pos) - - right_margin; + - right_margin - eop; Font const & font = ii->inset->inheritFont() ? displayFont(pit, ii->pos) : bufferfont; MacroContext mc(&buffer, parPos); @@ -480,19 +490,21 @@ bool TextMetrics::redoParagraph(pit_type const pit) // specially tailored for the main text. // 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); if (pit == 0) { - pm.rows().front().dimension().asc += 20; + pm.rows().front().dimension().asc += margin; /* coverity thinks that we should update pm.dim().asc * below, but all the rows heights are actually counted as * part of the paragraph metric descent see loop above). */ // coverity[copy_paste_error] - pm.dim().des += 20; + pm.dim().des += margin; } ParagraphList const & pars = text_->paragraphs(); if (pit + 1 == pit_type(pars.size())) { - pm.rows().back().dimension().des += 20; - pm.dim().des += 20; + pm.rows().back().dimension().des += margin; + pm.dim().des += margin; } } @@ -626,15 +638,25 @@ void TextMetrics::computeRowMetrics(Row & row, int width) const row.dimension().wid += w; } break; + case LYX_ALIGN_LEFT: + // a displayed inset that is flushed + if (Inset const * inset = par.getInset(row.pos())) + row.left_margin += inset->indent(*bv_); + break; case LYX_ALIGN_RIGHT: - row.left_margin += w; - row.dimension().wid += w; + if (Inset const * inset = par.getInset(row.pos())) { + int const new_w = max(w - inset->indent(*bv_), 0); + row.left_margin += new_w; + row.dimension().wid += new_w; + } else { + row.left_margin += w; + row.dimension().wid += w; + } break; case LYX_ALIGN_CENTER: row.dimension().wid += w / 2; row.left_margin += w / 2; break; - case LYX_ALIGN_LEFT: case LYX_ALIGN_NONE: case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: @@ -922,7 +944,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const row.finalizeLast(); row.endpos(i); - // End of paragraph marker + // End of paragraph marker. The logic here is almost the + // same as in redoParagraph, remember keep them in sync. ParagraphList const & pars = text_->paragraphs(); if (lyxrc.paragraph_markers && !need_new_row && i == end && size_type(row.pit() + 1) < pars.size()) { @@ -1094,7 +1117,7 @@ void TextMetrics::setRowHeight(Row & row) const // returns the column near the specified x-coordinate of the row // x is set to the real beginning of this column pos_type TextMetrics::getPosNearX(Row const & row, int & x, - bool & boundary, bool const select) const + bool & boundary) const { //LYXERR0("getPosNearX(" << x << ") row=" << row); /// For the main Text, it is possible that this pit is not @@ -1124,7 +1147,7 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x, for ( ; cit != cend; ++cit) { if (w <= x && w + cit->full_width() > x) { int x_offset = int(x - w); - pos = cit->x2pos(x_offset, select); + pos = cit->x2pos(x_offset); x = int(x_offset + w); break; } @@ -1330,23 +1353,19 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, } pit_type pit = getPitNearY(y); LASSERT(pit != -1, return 0); - - int yy = y; // is modified by getPitAndRowNearY - Row const & row = getPitAndRowNearY(yy, pit, assert_in_view, up); - + Row const & row = getPitAndRowNearY(y, pit, assert_in_view, up); cur.pit() = pit; // Do we cover an inset? - InsetList::InsetTable * it = checkInsetHit(pit, x, yy); + InsetList::InsetTable * it = checkInsetHit(pit, x, y); if (!it) { // No inset, set position in the text bool bound = false; // is modified by getPosNearX - int xx = x; // is modified by getPosNearX - cur.pos() = getPosNearX(row, xx, bound); + cur.pos() = getPosNearX(row, x, bound); cur.boundary(bound); cur.setCurrentFont(); - cur.setTargetX(xx); + cur.setTargetX(x); return 0; } @@ -1359,28 +1378,17 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, cur.setTargetX(x); // Try to descend recursively inside the inset. - Inset * edited = inset->editXY(cur, x, yy); - if (edited == inset && cur.pos() == it->pos) { + Inset * edited = inset->editXY(cur, x, y); + // FIXME: it is not clear that the test on position is needed + // Remove it if/when semantics of editXY is clarified + if (cur.text() == text_ && cur.pos() == it->pos) { // non-editable inset, set cursor after the inset if x is // nearer to that position (bug 9628) - // TODO: This should be replaced with an improvement of - // Cursor::moveToClosestEdge that handles rtl text. (Which could not - // be tested because of #10569.) - CoordCache::Insets const & insetCache = bv_->coordCache().getInsets(); - if (insetCache.has(inset)) { - Dimension const & dim = insetCache.dim(inset); - Point p = insetCache.xy(inset); - bool const is_rtl = text_->isRTL(text_->getPar(pit)); - if (is_rtl) { - // "in front of" == "right of" - if (abs(p.x_ - x) < abs(p.x_ + dim.wid - x)) - cur.posForward(); - } else { - // "in front of" == "left of" - if (abs(p.x_ + dim.wid - x) < abs(p.x_ - x)) - cur.posForward(); - } - } + bool bound = false; // is modified by getPosNearX + cur.pos() = getPosNearX(row, x, bound); + cur.boundary(bound); + cur.setCurrentFont(); + cur.setTargetX(x); } if (cur.top().text() == text_) @@ -1389,8 +1397,7 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y, } -void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, - int const y, bool const select) +void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, int const y) { LASSERT(text_ == cur.text(), return); pit_type const pit = getPitNearY(y); @@ -1417,7 +1424,7 @@ void TextMetrics::setCursorFromCoordinates(Cursor & cur, int const x, bool bound = false; int xx = x; - pos_type const pos = getPosNearX(row, xx, bound, select); + pos_type const pos = getPosNearX(row, xx, bound); LYXERR(Debug::DEBUG, "setting cursor pit: " << pit << " pos: " << pos); @@ -1735,32 +1742,32 @@ int TextMetrics::leftMargin(int max_width, // set the correct parindent if (pos == 0 && (layout.labeltype == LABEL_NO_LABEL - || layout.labeltype == LABEL_ABOVE - || layout.labeltype == LABEL_CENTERED - || (layout.labeltype == LABEL_STATIC - && layout.latextype == LATEX_ENVIRONMENT - && !text_->isFirstInSequence(pit))) + || layout.labeltype == LABEL_ABOVE + || layout.labeltype == LABEL_CENTERED + || (layout.labeltype == LABEL_STATIC + && layout.latextype == LATEX_ENVIRONMENT + && !text_->isFirstInSequence(pit))) && (align == LYX_ALIGN_BLOCK || align == LYX_ALIGN_LEFT) && !par.params().noindent() // in some insets, paragraphs are never indented && !text_->inset().neverIndent() // display style insets are always centered, omit indentation && !(!par.empty() - && par.isInset(pos) - && par.getInset(pos)->display()) + && par.isInset(pos) + && par.getInset(pos)->display()) && (!(tclass.isDefaultLayout(par.layout()) - || tclass.isPlainLayout(par.layout())) + || tclass.isPlainLayout(par.layout())) || buffer.params().paragraph_separation == BufferParams::ParagraphIndentSeparation)) { - // use the parindent of the layout when the - // default indentation is used otherwise use - // the indentation set in the document - // settings - if (buffer.params().getIndentation().asLyXCommand() == "default") - l_margin += bfm.signedWidth(parindent); - else - l_margin += buffer.params().getIndentation().inPixels(*bv_); - } + /* use the parindent of the layout when the default + * indentation is used otherwise use the indentation set in + * the document settings + */ + if (buffer.params().getParIndent().empty()) + l_margin += bfm.signedWidth(parindent); + else + l_margin += buffer.params().getParIndent().inPixels(max_width_, bfm.em()); + } return l_margin; }