mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-27 14:29:21 +00:00
Compare commits
2 Commits
6727022b05
...
ecac032a94
Author | SHA1 | Date | |
---|---|---|---|
|
ecac032a94 | ||
|
33442b17ee |
@ -1288,7 +1288,9 @@ bool Cursor::posVisToNewRow(bool movingLeft)
|
|||||||
// if moving left in an LTR paragraph or moving right in an
|
// if moving left in an LTR paragraph or moving right in an
|
||||||
// RTL one, move to previous row
|
// RTL one, move to previous row
|
||||||
if (par_is_LTR == movingLeft) {
|
if (par_is_LTR == movingLeft) {
|
||||||
if (row.pos() == 0) { // we're at first row in paragraph
|
if (row.start_boundary())
|
||||||
|
boundary(true);
|
||||||
|
else if (row.pos() == 0) { // we're at first row in paragraph
|
||||||
if (pit() == 0) // no previous paragraph! don't move
|
if (pit() == 0) // no previous paragraph! don't move
|
||||||
return false;
|
return false;
|
||||||
// move to last pos in previous par
|
// move to last pos in previous par
|
||||||
|
@ -105,6 +105,7 @@ public:
|
|||||||
/// The context to resolve macros
|
/// The context to resolve macros
|
||||||
MacroContext const & macrocontext;
|
MacroContext const & macrocontext;
|
||||||
/// Are we at the start of a paragraph (vertical mode)?
|
/// Are we at the start of a paragraph (vertical mode)?
|
||||||
|
/// This is not used anymore, but could be useful
|
||||||
bool vmode;
|
bool vmode;
|
||||||
/// if true, do not expand insets to max width artificially
|
/// if true, do not expand insets to max width artificially
|
||||||
bool tight_insets;
|
bool tight_insets;
|
||||||
|
@ -95,6 +95,10 @@ size_t ParagraphMetrics::getRowIndex(pos_type pos, bool boundary) const
|
|||||||
{
|
{
|
||||||
LBUFERR(!rows().empty());
|
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
|
// If boundary is set we should return the row on which
|
||||||
// the character before is inside.
|
// the character before is inside.
|
||||||
if (pos > 0 && boundary)
|
if (pos > 0 && boundary)
|
||||||
|
@ -212,6 +212,10 @@ public:
|
|||||||
///
|
///
|
||||||
pos_type endpos() const { return end_; }
|
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; }
|
void end_boundary(bool b) { end_boundary_ = b; }
|
||||||
///
|
///
|
||||||
bool end_boundary() const { return end_boundary_; }
|
bool end_boundary() const { return end_boundary_; }
|
||||||
@ -373,6 +377,8 @@ private:
|
|||||||
pos_type pos_ = 0;
|
pos_type pos_ = 0;
|
||||||
/// one behind last pos covered by this row
|
/// one behind last pos covered by this row
|
||||||
pos_type end_ = 0;
|
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...)
|
// Is there a boundary at the end of the row (display inset...)
|
||||||
bool end_boundary_ = false;
|
bool end_boundary_ = false;
|
||||||
// Shall the row be flushed when it is supposed to be justified?
|
// Shall the row be flushed when it is supposed to be justified?
|
||||||
|
@ -27,30 +27,34 @@ enum RowFlags {
|
|||||||
// Do not break before or after this element, except if really
|
// Do not break before or after this element, except if really
|
||||||
// needed (between NoBreak* and CanBreak*).
|
// needed (between NoBreak* and CanBreak*).
|
||||||
Inline = 0,
|
Inline = 0,
|
||||||
|
// force (maybe empty) row before this element
|
||||||
|
AlwaysBreakBefore = 1 << 0,
|
||||||
// break row before this element if the row is not empty
|
// break row before this element if the row is not empty
|
||||||
BreakBefore = 1 << 0,
|
BreakBefore = 1 << 1,
|
||||||
// break row whenever needed before this element
|
// break row whenever needed before this element
|
||||||
CanBreakBefore = 1 << 1,
|
CanBreakBefore = 1 << 2,
|
||||||
// Avoid breaking row before this element
|
// Avoid breaking row before this element
|
||||||
NoBreakBefore = 1 << 2,
|
NoBreakBefore = 1 << 3,
|
||||||
// flush the row before this element (useful with BreakBefore)
|
// flush the row before this element (useful with BreakBefore)
|
||||||
FlushBefore = 1 << 3,
|
FlushBefore = 1 << 4,
|
||||||
// force new (maybe empty) row after this element
|
// force new (maybe empty) row after this element
|
||||||
AlwaysBreakAfter = 1 << 4,
|
AlwaysBreakAfter = 1 << 5,
|
||||||
// break row after this element if there are more elements
|
// break row after this element if there are more elements
|
||||||
BreakAfter = 1 << 5,
|
BreakAfter = 1 << 6,
|
||||||
// break row whenever needed after this element
|
// break row whenever needed after this element
|
||||||
CanBreakAfter = 1 << 6,
|
CanBreakAfter = 1 << 7,
|
||||||
// Avoid breaking row after this element
|
// Avoid breaking row after this element
|
||||||
NoBreakAfter = 1 << 7,
|
NoBreakAfter = 1 << 8,
|
||||||
// The contents of the row may be broken in two (e.g. string)
|
// The contents of the row may be broken in two (e.g. string)
|
||||||
CanBreakInside = 1 << 8,
|
CanBreakInside = 1 << 9,
|
||||||
// Flush the row that ends with this element
|
// Flush the row that ends with this element
|
||||||
Flush = 1 << 9,
|
Flush = 1 << 10,
|
||||||
// specify an alignment (left, right) for a display element
|
// specify an alignment (left, right) for a display element
|
||||||
// (default is center)
|
// (default is center)
|
||||||
AlignLeft = 1 << 10,
|
AlignLeft = 1 << 11,
|
||||||
AlignRight = 1 << 11,
|
AlignRight = 1 << 12,
|
||||||
|
// Forbid boundary after this element
|
||||||
|
NoEndBoundary = 1 << 13,
|
||||||
// A display element breaks row at both ends
|
// A display element breaks row at both ends
|
||||||
Display = FlushBefore | BreakBefore | BreakAfter,
|
Display = FlushBefore | BreakBefore | BreakAfter,
|
||||||
// Flags that concern breaking after element
|
// Flags that concern breaking after element
|
||||||
|
48
src/Text.cpp
48
src/Text.cpp
@ -3054,29 +3054,16 @@ bool Text::cursorBackward(Cursor & cur)
|
|||||||
// Tell BufferView to test for FitCursor in any case!
|
// Tell BufferView to test for FitCursor in any case!
|
||||||
cur.screenUpdateFlags(Update::FitCursor);
|
cur.screenUpdateFlags(Update::FitCursor);
|
||||||
|
|
||||||
// not at paragraph start?
|
// if on right side of a row boundary (at row start), skip it,
|
||||||
if (cur.pos() > 0) {
|
// i.e. set boundary to true, i.e. go only logically left
|
||||||
// if on right side of boundary (i.e. not at paragraph end, but line end)
|
if (!cur.boundary()
|
||||||
// -> skip it, i.e. set boundary to true, i.e. go only logically left
|
&& cur.textRow().pos() == cur.pos()
|
||||||
// there are some exceptions to ignore this: lineseps, newlines, spaces
|
&& cur.textRow().start_boundary()) {
|
||||||
#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);
|
return setCursor(cur, cur.pit(), cur.pos(), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not at paragraph start?
|
||||||
|
if (cur.pos() > 0) {
|
||||||
// go left and try to enter inset
|
// go left and try to enter inset
|
||||||
if (checkAndActivateInset(cur, false))
|
if (checkAndActivateInset(cur, false))
|
||||||
return false;
|
return false;
|
||||||
@ -3143,34 +3130,15 @@ bool Text::cursorForward(Cursor & cur)
|
|||||||
|
|
||||||
// next position is left of boundary,
|
// next position is left of boundary,
|
||||||
// but go to next line for special cases like space, newline, linesep
|
// 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.textRow().endpos() == cur.pos() + 1) {
|
||||||
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
|
if (cur.paragraph().isEnvSeparator(cur.pos()) &&
|
||||||
cur.pos() + 1 == cur.lastpos() &&
|
cur.pos() + 1 == cur.lastpos() &&
|
||||||
cur.pit() != cur.lastpit()) {
|
cur.pit() != cur.lastpit()) {
|
||||||
// move to next paragraph
|
// move to next paragraph
|
||||||
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
return setCursor(cur, cur.pit() + 1, 0, true, false);
|
||||||
} else if (cur.textRow().endpos() != cur.lastpos() &&
|
} else if (cur.textRow().end_boundary())
|
||||||
!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);
|
return setCursor(cur, cur.pit(), cur.pos() + 1, true, true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// in front of RTL boundary? Stay on this side of the boundary because:
|
// in front of RTL boundary? Stay on this side of the boundary because:
|
||||||
// ab|cDDEEFFghi -> abc|DDEEFFghi
|
// ab|cDDEEFFghi -> abc|DDEEFFghi
|
||||||
|
@ -706,7 +706,8 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const
|
|||||||
|
|
||||||
// Display-style insets should always be on a centered row
|
// Display-style insets should always be on a centered row
|
||||||
if (Inset const * inset = par.getInset(row.pos())) {
|
if (Inset const * inset = par.getInset(row.pos())) {
|
||||||
if (inset->rowFlags() & Display) {
|
// 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() & AlignLeft)
|
if (inset->rowFlags() & AlignLeft)
|
||||||
align = LYX_ALIGN_LEFT;
|
align = LYX_ALIGN_LEFT;
|
||||||
else if (inset->rowFlags() & AlignRight)
|
else if (inset->rowFlags() & AlignRight)
|
||||||
@ -1146,7 +1147,9 @@ void cleanupRow(Row & row, bool at_end)
|
|||||||
if (!at_end && !row.flushed())
|
if (!at_end && !row.flushed())
|
||||||
row.back().rtrim();
|
row.back().rtrim();
|
||||||
// boundary exists when there was no space at the end of row
|
// boundary exists when there was no space at the end of row
|
||||||
row.end_boundary(!at_end && row.back().endpos == row.endpos());
|
row.end_boundary(!at_end
|
||||||
|
&& row.back().endpos == row.endpos()
|
||||||
|
&& !(row.back().row_flags & NoEndBoundary));
|
||||||
// make sure that the RTL elements are in reverse ordering
|
// make sure that the RTL elements are in reverse ordering
|
||||||
row.reverseRTL();
|
row.reverseRTL();
|
||||||
}
|
}
|
||||||
@ -1155,7 +1158,7 @@ void cleanupRow(Row & row, bool at_end)
|
|||||||
// Implement the priorities described in RowFlags.h.
|
// Implement the priorities described in RowFlags.h.
|
||||||
bool needsRowBreak(int f1, int f2)
|
bool needsRowBreak(int f1, int f2)
|
||||||
{
|
{
|
||||||
if (f1 & AlwaysBreakAfter /*|| f2 & AlwaysBreakBefore*/)
|
if (f1 & AlwaysBreakAfter || f2 & AlwaysBreakBefore)
|
||||||
return true;
|
return true;
|
||||||
if (f1 & NoBreakAfter || f2 & NoBreakBefore)
|
if (f1 & NoBreakAfter || f2 & NoBreakBefore)
|
||||||
return false;
|
return false;
|
||||||
@ -1183,13 +1186,21 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
|||||||
bool const row_empty = rows.empty() || rows.back().empty();
|
bool const row_empty = rows.empty() || rows.back().empty();
|
||||||
// The row flags of previous element, if there is one.
|
// The row flags of previous element, if there is one.
|
||||||
// Otherwise we use NoBreakAfter to avoid an empty row before
|
// Otherwise we use NoBreakAfter to avoid an empty row before
|
||||||
// e.g. a displayed equation.
|
// e.g. a displayed inset.
|
||||||
int const f1 = row_empty ? NoBreakAfter : rows.back().back().row_flags;
|
int const f1 = row_empty ? NoBreakAfter : rows.back().back().row_flags;
|
||||||
// The row flags of next element, if there is one.
|
// The row flags of next element, if there is one.
|
||||||
// Otherwise we use NoBreakBefore (see above), unless the
|
// Otherwise we use NoBreakBefore (see above), unless the
|
||||||
// paragraph has an end label (for which an empty row is OK).
|
// paragraph has an end label (for which an empty row is OK).
|
||||||
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
|
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
|
||||||
: fcit->row_flags;
|
: 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() || needsRowBreak(f1, f2)) {
|
||||||
if (!rows.empty()) {
|
if (!rows.empty()) {
|
||||||
// Flush row as requested by row flags
|
// Flush row as requested by row flags
|
||||||
@ -1241,6 +1252,13 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
|
|||||||
rows.back().needsChangeBar(true);
|
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;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1468,14 +1486,15 @@ pos_type TextMetrics::getPosNearX(Row const & row, int & x,
|
|||||||
boundary = true;
|
boundary = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (row.empty())
|
||||||
|
boundary = row.end_boundary();
|
||||||
/** This tests for the case where the cursor is set at the end
|
/** 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
|
* of a row which has been broken due something else than a
|
||||||
* separator (a display inset or a forced breaking of the
|
* separator (a display inset or a forced breaking of the
|
||||||
* row). We know that there is a separator when the end 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.
|
* row is larger than the end of its last element.
|
||||||
*/
|
*/
|
||||||
if (!row.empty() && pos == row.back().endpos
|
else if (pos == row.back().endpos && row.back().endpos == row.endpos()) {
|
||||||
&& row.back().endpos == row.endpos()) {
|
|
||||||
Inset const * inset = row.back().inset;
|
Inset const * inset = row.back().inset;
|
||||||
if (inset && (inset->lyxCode() == NEWLINE_CODE
|
if (inset && (inset->lyxCode() == NEWLINE_CODE
|
||||||
|| inset->lyxCode() == SEPARATOR_CODE))
|
|| inset->lyxCode() == SEPARATOR_CODE))
|
||||||
@ -1838,7 +1857,7 @@ int TextMetrics::leftMargin(pit_type pit) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
|
int TextMetrics::leftMargin(pit_type const pit, pos_type const pos, bool ignore_contents) const
|
||||||
{
|
{
|
||||||
ParagraphList const & pars = text_->paragraphs();
|
ParagraphList const & pars = text_->paragraphs();
|
||||||
|
|
||||||
@ -1998,7 +2017,8 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
|
|||||||
// in some insets, paragraphs are never indented
|
// in some insets, paragraphs are never indented
|
||||||
&& !text_->inset().neverIndent()
|
&& !text_->inset().neverIndent()
|
||||||
// display style insets do not need indentation
|
// display style insets do not need indentation
|
||||||
&& !(!par.empty()
|
&& !(!ignore_contents
|
||||||
|
&& !par.empty()
|
||||||
&& par.isInset(0)
|
&& par.isInset(0)
|
||||||
&& par.getInset(0)->rowFlags() & Display)
|
&& par.getInset(0)->rowFlags() & Display)
|
||||||
&& (!(tclass.isDefaultLayout(par.layout())
|
&& (!(tclass.isDefaultLayout(par.layout())
|
||||||
|
@ -138,8 +138,10 @@ public:
|
|||||||
* This information cannot be taken from the layout object, because
|
* This information cannot be taken from the layout object, because
|
||||||
* in LaTeX the beginning of the text fits in some cases
|
* in LaTeX the beginning of the text fits in some cases
|
||||||
* (for example sections) exactly the label-width.
|
* (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) const;
|
int leftMargin(pit_type pit, pos_type pos, bool ignore_contents = false) const;
|
||||||
/// Return the left beginning of a row which is not the first one.
|
/// Return the left beginning of a row which is not the first one.
|
||||||
/// This is the left margin when there is no indentation.
|
/// This is the left margin when there is no indentation.
|
||||||
int leftMargin(pit_type pit) const;
|
int leftMargin(pit_type pit) const;
|
||||||
|
@ -44,9 +44,9 @@ InsetNewline::InsetNewline() : Inset(nullptr)
|
|||||||
int InsetNewline::rowFlags() const
|
int InsetNewline::rowFlags() const
|
||||||
{
|
{
|
||||||
if (params_.kind == InsetNewlineParams::LINEBREAK)
|
if (params_.kind == InsetNewlineParams::LINEBREAK)
|
||||||
return AlwaysBreakAfter;
|
return AlwaysBreakAfter | NoEndBoundary;
|
||||||
else
|
else
|
||||||
return AlwaysBreakAfter | Flush;
|
return AlwaysBreakAfter | NoEndBoundary | Flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
return docstring();
|
return docstring();
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
int rowFlags() const override { return BreakAfter | Flush; }
|
int rowFlags() const override { return BreakAfter | Flush | NoEndBoundary; }
|
||||||
///
|
///
|
||||||
bool nextnoindent() const { return params_.kind == InsetSeparatorParams::PLAIN; }
|
bool nextnoindent() const { return params_.kind == InsetSeparatorParams::PLAIN; }
|
||||||
private:
|
private:
|
||||||
|
@ -525,9 +525,6 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
|
|||||||
*/
|
*/
|
||||||
int const bottom_display_margin = mi.base.bv->zoomedPixels(6);
|
int const bottom_display_margin = mi.base.bv->zoomedPixels(6);
|
||||||
int top_display_margin = bottom_display_margin;
|
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);
|
int const ind = indent(*mi.base.bv);
|
||||||
mi.extrawidth = ind;
|
mi.extrawidth = ind;
|
||||||
@ -1029,9 +1026,9 @@ int InsetMathHull::rowFlags() const
|
|||||||
case hullMultline:
|
case hullMultline:
|
||||||
case hullGather:
|
case hullGather:
|
||||||
if (buffer().params().is_math_indent)
|
if (buffer().params().is_math_indent)
|
||||||
return Display | AlignLeft;
|
return AlwaysBreakBefore | Display | AlignLeft;
|
||||||
else
|
else
|
||||||
return Display;
|
return AlwaysBreakBefore | Display;
|
||||||
}
|
}
|
||||||
// avoid warning
|
// avoid warning
|
||||||
return Display;
|
return Display;
|
||||||
|
Loading…
Reference in New Issue
Block a user