The most visible part of this commit is the move of part of
BufferView::updateMetrics to a new TextMetrics::updateMetrics. This
new method makes sure that metrics are known for all visible paragraphs
(starting from anchor), and that the positions of the paragraphs have
been recorded.
This method is called up to 3 times in BufferView::updateMetrics:
* unconditionally, to update all visible metrics,
* then, if the bottom of the document is visible and too high, after
updating the anchor ypos,
* and similarly if the top of the document is visible and too low.
This fixes for example the case where one jumps to Section 5.3 at the
end of Tutorial and 'scroll_below_document' is false.
Some now redundant code is removed from BufferView::scrollToCursor.
The anchor-setting code in BufferView::draw is not clearly useful, but
left here just in case. It generates a debug warning, though.
Part of bug #12297.
Replace flag parameter for updateMetrics() by a `force' boolean. When
it is false, the method keeps the metrics of paragraphs that are still
visible in WorkArea instead of computing everything afresh. All it has
to do is update their positions.
Add code to updateMetrics() to update the value of the anchor pit/ypos
(similar to the one in draw()).
Update processUpdateFlags() to use this when update flag is ForceDraw.
Modify scrollDocView() to just change the anchor paragraph position
when the scrolling operation would re-use some of the existing
paragraphs.
The time needed to update the metrics when scrolling with mouse in the
branch-test.lyx document is now divided by 20!
Part of bug #12297.
This can make a big difference for a very large branch that contains
lots of equations.
This is complementary to the previous patch, since instead of reducing
the number of calls to updatePosCache, we make it faster.
In the same test of scrolling with mouse wheel through the
branch-test.lyx document, one finds a 23% improvement for
BufferView::updateMetrics().
Part of bug #12297.
This is a kind of hack. This allows InsetMathHull to state that it
needs some elbow room beyond its width, in order to fit the numbering
and/or the left margin (with left alignment), which are outside of the
inset itself.
To this end, InsetMathHull::metrics() sets a value in
MetricsInfo::extrawidth and this value is added later to the width of
the row that contains the inset (when this row is tight or shorter
than the max allowed width).
Fixes bug #12320.
Some text-in-math environments such as \text, \mbox, \fbox, and
\makebox, inherit the outer text font. This commit reflects this
in the on-screen representation.
Fixes#12950.
When it turns out that breaking a STRING row element was not
sufficient in Row::shortenIfNeeded, we still remember the shortest
width that one can obtain. Later, when we try to split a previous
element of the row, we have a better idea of how much of the row
remains after it.
To this end, change the signature of Element::splitAt to use an enum:
FIT (was: force=false), FORCE (was: force= true) and BEST_EFFORT
(split at max_width, but do not return an error if the string is too
large).
Fixes bug #12660.
This is a kind of hack. This allows InsetMathHull to state that it
needs some elbow room beyond its width, in order to fit the numbering
and/or the left margin (with left alignment), which are outside of the
inset itself.
To this end, InsetMathHull::metrics() sets a value in
MetricsInfo::extrawidth and this value is recorded later in the
corresponding row element's `extra' field.
The code could be reorganized to be simpler, in particular by
computing metrics in tokenizeRow, or after tokenizeRow. However the
choice here is to produce a simple patch, fit for 2.4.0.
Fixes bug #12320.
This patch reuses the code of TextMetrics::displayFont() that handles
the label part of LABEL_MANUAL paragraphs to create a new
labelDisplayFont() method usable for things like Itemize labels.
To this end, and new magic value is used as position to force the
label case in displayFont(). The code is also factored a bit and
cleaned up.
Fixes bug #12810.
Instead of actually fixing the messiness of InsetInfo, let's just fix
the symptom and avoid the access to Paragraph::id() that was crashing
LyX every time updateBuffer/validate/metrics/draw did not happen in
the right order.
Fixes bug #12639.
Instead of asserting when there are unprocessed row elements (which,
as I understand it, should almost never happen), play safe and keep
them for later processing.
Related to bug #12617.
It is not a good idea to take into account the horizontal scrolling
that may have happened. For example, this leads to display glitches
when a Description label is larger than text width.
This explains why SingleParUpdate strategy did not work with home/end
on a long row.
The spacing of Labeling, Description and friends shall be computed
when breaking the row, not when tokenizing it. Indeed, this is the
right place to determine its correct value.
To this end add a new MARGINSPACE row element type.
This allows to remove TextMetrics::labelEnd, which is not used anymore.
When a string is broken at the margin by the Qt algorithm, the space
at which breaking occurred is automatically skipped in width
computation. However, the ending space of the string is taken into
account and is visible for example at paragraph end.
When the trailing space is followed by a displayed inset, then the
space should be skipped too, which means that the width of the last
row element has to be recomputed. For the sake of performance, the
width of the element without trailing spaces is computed in advance in
FontMetrics::breakString.
This "no space" width will be used when trimming a row element of its trailing
spaces instead of the original one.
Additionally, do not trim trailing spaces when the row is flushed.
Fixes bug #12449.
Add new row flags Flush and FlushBefore to let insets indicate whether
they cause flushing of current row (eg. newline) or of previous row
(e.g. display insets).
Replace FontMetrics::breakAt, which returned the next break point,
with FontMetrics::breakString, which returns a vector of break points.
To this end, an additional parameter gives the available width for
next rows.
Rename various variables and methods accordingly. Factor the code in
breakString_helper to be more manageable.
Adapt Row::Element::splitAt to return a bool on sucess and provide
remaining row elements in a vector. The width noted above has been
added as parameters.
Rename the helper function splitFrom to moveElements and rewrite the
code to be more efficient.
Remove type of row element INVALID, which is not needed anymore.
The code in TextMetrics::breakParagraph is now much simpler.
In Row::finalize, remove the code that computed inconditionnally the
current element size, and make sure that this width will be computed
in all code paths of Row::Element::splitAt.
In TextMetrics::breakParagraph, get rid of the fragile `pos' local
variable, which was not correctly updated. Rely on the endpos of the
last element in row instead.
Rewrite cleanupRow to rely on the endpos of last the row element to
set row endpos, instead of a `pos' parameter.
Instead of having breakParagraph decide when breaking a row is
necessary, let Row::shortenIfNeeded set the row_flag of the last
element to request a row break. This was already done in splitAt.
This is in preparation of splitAt splitting in more than two elements.
Move to Row::Element::rtrim the code in Row::shortenIfNeeded that
removes trailing spaces from last element in row, so that it can be
called when actually breaking a row.
Fixes bug found by Kornel.
In this case, the extra element returned should empty but valid. The
row flag BreakAfter is set to indicate that we have a break there
(this principle will be used more generally in a forthcoming commit).
To detect that we cut at the trailing space, it is necessary to rely
on the difference between QTextLine::horizontalAdvance() and
QTextLine::naturalTextWidth() when the flag
QTextOption::IncludeTrailingSpaces is used: the trailing space is
taken into account in the later, but not in the former.
Somme comments have been added to make code intent clearer.
Change semantics of Row::shortenIfNeeded: instead of breaking the row
and returning a boolean, it returns the list of row elements that have
been removed (or broken) from the row. The logic of the method remains
the same.
Use shortenIfNeeded in breakParagraph. This was the last missing block.
Remove Row::breakAt and the old breakRow. Only bugs remain now :)
To this end, add the helper function needsRowBreak which computes the
effect of two consecutive row flags. This function implements the
priorities described in RowFlags.h.
This function is called with the relevant flags, or NoBreak* when at
boundaries and updates need_new_row.
Some common code is factored in a new cleanupRow() helper.
Remove the code that computed the width every 30 characters (yay!).
Make sure that finalizeLast() is called after inserting a row element in
a row in breakParagraph.
Still many features missing:
- handle insets that break rows (display math, newline, ...)
- handle rows that are too long by replacing the single call to
breakAt with a call to a reworked Row::shortenIfNeeded.
- some easy things at the end of breakRow (bidi text, etc.).
Move the enum definition RowFlags in its own include file, to avoid
loading Inset.h. Document it more thoroughly.
Rename RowAfter to AlwaysBreakAfter.
Add CanBreakInside (rows that can be themselves broken). This allow to
differentiate elements before bodyPos() and allows to remove a
parameter to shortenIfNeeded().
Make the Inset::rowFlags() method return int instead of RowFlags, as
should be done for all the bitwise flags. Remove the hand-made bitwise
operators.
Set R::E::row_flags when creating elements.
* INSET elements use the inset's rowFLags();
* virtual element forbid breaking before them, and inherit the *After
flags from the previous element of the row;
* STRING elements usr CanBreakInside, except before bodyPos.
More stuff may be added later.
This contains large parts of breakRow, but creates a unique row for the paragraph.
The parts taken or not in redoParagraph are annotated.
The new method is not used yet.
Introduce a GUI-less LyXRC member bookmarks_visibility. This is
experimental and will not be documented for 2.4.0. Having the code
present will allow to (1) improve it gradually and (2) fix the many
bookmarks bugs that it exposes.
The corresponding tag is \experimental:bookmarks_visibility, which is
intentionally weird.
Three possible values:
* none: no bookmark display
* margin: display the bookmark in margin
* inline: display the bookmark at cursor position.
The default margin has been made wider so that there is room for the
bookmark. This was necessary anyway. The margin bookmark is now
displayed correctly in full screen with limited text width.
Margin display still needs some improvements when several bookmarks
are on the same row.
Mostly fixes bug #2496.
1/ fix horizontal position of the insets
This is adapted from parts of racoon's patch for bug #12131.
2/ fix height of the indicators when at the top or bottom of document,
by using the row's contents_dim() to measure is height.
3/ fix partial blinking of horizontl scrolling marks when editing table.
Fixes bug #12171.
The bookmarks are shown with circled numbers in the right margin (or
the left margin in RTL mode). A new color "bookmarks" has been added.
Currently bookmark 0 (the return position) is not displayed because it
is very disturbing in practice.
To make this work, a new method BookmarksSection::bookmarksInPar
retuns the list of bookmarks in a paragraph along with their position.
Force redraw when using bookmark-save and bookmark-clear.
Caveats:
- this solution does not show the precise position of the bookmark
(this is supposedly not a problem).
- if several bookmarks are on the same row, they will currently be
garbled. It would be easy to make sure that only one is shown ; what
would be more difficult would be to move the second bookmark lower.
- it is possible to make sure that the markers are correctly centered
in the margin, and that the margin size is large enough to hold the
marker (I did not try all fonts).
Fixes bug #2496.