Compare commits

..

No commits in common. "ecac032a940009029a21676a73599b3c7a8a15c6" and "6727022b052814b9981d3c2e18cffd99464d504f" have entirely different histories.

11 changed files with 71 additions and 75 deletions

View File

@ -1288,9 +1288,7 @@ bool Cursor::posVisToNewRow(bool movingLeft)
// if moving left in an LTR paragraph or moving right in an
// RTL one, move to previous row
if (par_is_LTR == movingLeft) {
if (row.start_boundary())
boundary(true);
else if (row.pos() == 0) { // we're at first row in paragraph
if (row.pos() == 0) { // we're at first row in paragraph
if (pit() == 0) // no previous paragraph! don't move
return false;
// move to last pos in previous par

View File

@ -105,7 +105,6 @@ public:
/// The context to resolve macros
MacroContext const & macrocontext;
/// Are we at the start of a paragraph (vertical mode)?
/// This is not used anymore, but could be useful
bool vmode;
/// if true, do not expand insets to max width artificially
bool tight_insets;

View File

@ -95,10 +95,6 @@ size_t ParagraphMetrics::getRowIndex(pos_type pos, bool boundary) const
{
LBUFERR(!rows().empty());
// This makes a difference when the first row is empty (e.g. before display math)
if (pos == 0 && boundary)
return 0;
// If boundary is set we should return the row on which
// the character before is inside.
if (pos > 0 && boundary)

View File

@ -212,10 +212,6 @@ public:
///
pos_type endpos() const { return end_; }
///
void start_boundary(bool b) { start_boundary_ = b; }
///
bool start_boundary() const { return start_boundary_; }
///
void end_boundary(bool b) { end_boundary_ = b; }
///
bool end_boundary() const { return end_boundary_; }
@ -377,8 +373,6 @@ private:
pos_type pos_ = 0;
/// one behind last pos covered by this row
pos_type end_ = 0;
// Is there a boundary at the start of the row (display inset...)
bool start_boundary_ = false;
// Is there a boundary at the end of the row (display inset...)
bool end_boundary_ = false;
// Shall the row be flushed when it is supposed to be justified?

View File

@ -27,34 +27,30 @@ enum RowFlags {
// Do not break before or after this element, except if really
// needed (between NoBreak* and CanBreak*).
Inline = 0,
// force (maybe empty) row before this element
AlwaysBreakBefore = 1 << 0,
// break row before this element if the row is not empty
BreakBefore = 1 << 1,
BreakBefore = 1 << 0,
// break row whenever needed before this element
CanBreakBefore = 1 << 2,
CanBreakBefore = 1 << 1,
// Avoid breaking row before this element
NoBreakBefore = 1 << 3,
NoBreakBefore = 1 << 2,
// flush the row before this element (useful with BreakBefore)
FlushBefore = 1 << 4,
FlushBefore = 1 << 3,
// force new (maybe empty) row after this element
AlwaysBreakAfter = 1 << 5,
AlwaysBreakAfter = 1 << 4,
// break row after this element if there are more elements
BreakAfter = 1 << 6,
BreakAfter = 1 << 5,
// break row whenever needed after this element
CanBreakAfter = 1 << 7,
CanBreakAfter = 1 << 6,
// Avoid breaking row after this element
NoBreakAfter = 1 << 8,
NoBreakAfter = 1 << 7,
// The contents of the row may be broken in two (e.g. string)
CanBreakInside = 1 << 9,
CanBreakInside = 1 << 8,
// Flush the row that ends with this element
Flush = 1 << 10,
Flush = 1 << 9,
// specify an alignment (left, right) for a display element
// (default is center)
AlignLeft = 1 << 11,
AlignRight = 1 << 12,
// Forbid boundary after this element
NoEndBoundary = 1 << 13,
AlignLeft = 1 << 10,
AlignRight = 1 << 11,
// A display element breaks row at both ends
Display = FlushBefore | BreakBefore | BreakAfter,
// Flags that concern breaking after element

View File

@ -3054,16 +3054,29 @@ bool Text::cursorBackward(Cursor & cur)
// Tell BufferView to test for FitCursor in any case!
cur.screenUpdateFlags(Update::FitCursor);
// if on right side of a row boundary (at row start), skip it,
// i.e. set boundary to true, i.e. go only logically left
if (!cur.boundary()
&& cur.textRow().pos() == cur.pos()
&& cur.textRow().start_boundary()) {
return setCursor(cur, cur.pit(), cur.pos(), true, true);
}
// not at paragraph start?
if (cur.pos() > 0) {
// if on right side of boundary (i.e. not at paragraph end, but line end)
// -> skip it, i.e. set boundary to true, i.e. go only logically left
// there are some exceptions to ignore this: lineseps, newlines, spaces
#if 0
// some effectless debug code to see the values in the debugger
bool bound = cur.boundary();
int rowpos = cur.textRow().pos();
int pos = cur.pos();
bool sep = cur.paragraph().isSeparator(cur.pos() - 1);
bool newline = cur.paragraph().isNewline(cur.pos() - 1);
bool linesep = cur.paragraph().isLineSeparator(cur.pos() - 1);
#endif
if (!cur.boundary() &&
cur.textRow().pos() == cur.pos() &&
!cur.paragraph().isLineSeparator(cur.pos() - 1) &&
!cur.paragraph().isNewline(cur.pos() - 1) &&
!cur.paragraph().isEnvSeparator(cur.pos() - 1) &&
!cur.paragraph().isSeparator(cur.pos() - 1)) {
return setCursor(cur, cur.pit(), cur.pos(), true, true);
}
// go left and try to enter inset
if (checkAndActivateInset(cur, false))
return false;
@ -3130,14 +3143,33 @@ bool Text::cursorForward(Cursor & cur)
// next position is left of boundary,
// but go to next line for special cases like space, newline, linesep
#if 0
// some effectless debug code to see the values in the debugger
int endpos = cur.textRow().endpos();
int lastpos = cur.lastpos();
int pos = cur.pos();
bool linesep = cur.paragraph().isLineSeparator(cur.pos());
bool newline = cur.paragraph().isNewline(cur.pos());
bool sep = cur.paragraph().isSeparator(cur.pos());
if (cur.pos() != cur.lastpos()) {
bool linesep2 = cur.paragraph().isLineSeparator(cur.pos()+1);
bool newline2 = cur.paragraph().isNewline(cur.pos()+1);
bool sep2 = cur.paragraph().isSeparator(cur.pos()+1);
}
#endif
if (cur.textRow().endpos() == cur.pos() + 1) {
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
cur.pos() + 1 == cur.lastpos() &&
cur.pit() != cur.lastpit()) {
// move to next paragraph
return setCursor(cur, cur.pit() + 1, 0, true, false);
} else if (cur.textRow().end_boundary())
} else if (cur.textRow().endpos() != cur.lastpos() &&
!cur.paragraph().isNewline(cur.pos()) &&
!cur.paragraph().isEnvSeparator(cur.pos()) &&
!cur.paragraph().isLineSeparator(cur.pos()) &&
!cur.paragraph().isSeparator(cur.pos())) {
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
}
}
// in front of RTL boundary? Stay on this side of the boundary because:

View File

@ -706,8 +706,7 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const
// Display-style insets should always be on a centered row
if (Inset const * inset = par.getInset(row.pos())) {
// If we are in empty row, alignment of inset does not apply (it is in next row)
if (!row.empty() && inset->rowFlags() & Display) {
if (inset->rowFlags() & Display) {
if (inset->rowFlags() & AlignLeft)
align = LYX_ALIGN_LEFT;
else if (inset->rowFlags() & AlignRight)
@ -1147,9 +1146,7 @@ void cleanupRow(Row & row, bool at_end)
if (!at_end && !row.flushed())
row.back().rtrim();
// boundary exists when there was no space at the end of row
row.end_boundary(!at_end
&& row.back().endpos == row.endpos()
&& !(row.back().row_flags & NoEndBoundary));
row.end_boundary(!at_end && row.back().endpos == row.endpos());
// make sure that the RTL elements are in reverse ordering
row.reverseRTL();
}
@ -1158,7 +1155,7 @@ void cleanupRow(Row & row, bool at_end)
// Implement the priorities described in RowFlags.h.
bool needsRowBreak(int f1, int f2)
{
if (f1 & AlwaysBreakAfter || f2 & AlwaysBreakBefore)
if (f1 & AlwaysBreakAfter /*|| f2 & AlwaysBreakBefore*/)
return true;
if (f1 & NoBreakAfter || f2 & NoBreakBefore)
return false;
@ -1186,21 +1183,13 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool const row_empty = rows.empty() || rows.back().empty();
// The row flags of previous element, if there is one.
// Otherwise we use NoBreakAfter to avoid an empty row before
// e.g. a displayed inset.
// e.g. a displayed equation.
int const f1 = row_empty ? NoBreakAfter : rows.back().back().row_flags;
// The row flags of next element, if there is one.
// Otherwise we use NoBreakBefore (see above), unless the
// paragraph has an end label (for which an empty row is OK).
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
: fcit->row_flags;
if (rows.empty() && needsRowBreak(f1, f2)) {
// Create an empty row before element
rows.push_back(newRow(*this, bigrow.pit(), 0, is_rtl));
Row & newrow = rows.back();
cleanupRow(newrow, false);
newrow.end_boundary(true);
newrow.left_margin = leftMargin(newrow.pit(), 0, true);
}
if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty()) {
// Flush row as requested by row flags
@ -1252,13 +1241,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
rows.back().needsChangeBar(true);
}
// Set start_boundary to be equal to the previous row's end boundary
bool sb = false;
for (auto & row : rows) {
row.start_boundary(sb);
sb = row.end_boundary();
}
return rows;
}
@ -1486,15 +1468,14 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x,
boundary = true;
}
if (row.empty())
boundary = row.end_boundary();
/** This tests for the case where the cursor is set at the end
* of a row which has been broken due something else than a
* separator (a display inset or a forced breaking of the
* row). We know that there is a separator when the end of the
* row is larger than the end of its last element.
*/
else if (pos == row.back().endpos && row.back().endpos == row.endpos()) {
if (!row.empty() && pos == row.back().endpos
&& row.back().endpos == row.endpos()) {
Inset const * inset = row.back().inset;
if (inset && (inset->lyxCode() == NEWLINE_CODE
|| inset->lyxCode() == SEPARATOR_CODE))
@ -1857,7 +1838,7 @@ int TextMetrics::leftMargin(pit_type pit) const
}
int TextMetrics::leftMargin(pit_type const pit, pos_type const pos, bool ignore_contents) const
int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
{
ParagraphList const & pars = text_->paragraphs();
@ -2017,8 +1998,7 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos, bool ignore_
// in some insets, paragraphs are never indented
&& !text_->inset().neverIndent()
// display style insets do not need indentation
&& !(!ignore_contents
&& !par.empty()
&& !(!par.empty()
&& par.isInset(0)
&& par.getInset(0)->rowFlags() & Display)
&& (!(tclass.isDefaultLayout(par.layout())

View File

@ -138,10 +138,8 @@ public:
* This information cannot be taken from the layout object, because
* in LaTeX the beginning of the text fits in some cases
* (for example sections) exactly the label-width.
* When \c ignore_contents is true, alignment properties related
* to insets in paragraph are not taken into account.
*/
int leftMargin(pit_type pit, pos_type pos, bool ignore_contents = false) const;
int leftMargin(pit_type pit, pos_type pos) const;
/// Return the left beginning of a row which is not the first one.
/// This is the left margin when there is no indentation.
int leftMargin(pit_type pit) const;

View File

@ -44,9 +44,9 @@ InsetNewline::InsetNewline() : Inset(nullptr)
int InsetNewline::rowFlags() const
{
if (params_.kind == InsetNewlineParams::LINEBREAK)
return AlwaysBreakAfter | NoEndBoundary;
return AlwaysBreakAfter;
else
return AlwaysBreakAfter | NoEndBoundary | Flush;
return AlwaysBreakAfter | Flush;
}

View File

@ -65,7 +65,7 @@ public:
return docstring();
}
///
int rowFlags() const override { return BreakAfter | Flush | NoEndBoundary; }
int rowFlags() const override { return BreakAfter | Flush; }
///
bool nextnoindent() const { return params_.kind == InsetSeparatorParams::PLAIN; }
private:

View File

@ -525,6 +525,9 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
*/
int const bottom_display_margin = mi.base.bv->zoomedPixels(6);
int top_display_margin = bottom_display_margin;
// at start of paragraph, add an empty line
if (mi.vmode)
top_display_margin += theFontMetrics(mi.base.font).maxHeight() + 2;
int const ind = indent(*mi.base.bv);
mi.extrawidth = ind;
@ -1026,9 +1029,9 @@ int InsetMathHull::rowFlags() const
case hullMultline:
case hullGather:
if (buffer().params().is_math_indent)
return AlwaysBreakBefore | Display | AlignLeft;
return Display | AlignLeft;
else
return AlwaysBreakBefore | Display;
return Display;
}
// avoid warning
return Display;