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 fixes on-screen appearance of things like code with lines longer
than the window width.
The TeXbook makes it clear by indicating that \fontdimen3 == 0 for
these fonts.
The test that was used to avoid breaking a string that was followed
by a too long element was not correct (especially the part that
compared with total row width).
Typical example here is:
- a word with a part that has a font change like /un/breakable;
- a longish sentence after it.
Use a new test that is good enough for this particular case, although
with sortcomings. I do not want to overcomplicate and prefer to wait
for other complaints (this code is already more complicated that I
would like).
Document known shortcoming.
Fix ticket #12660.
In order to work around the Qt row breaking algorithm, which considers
multiple spaces as one at QTextLine break, we insert word_joiner unicode
characters beteween each pair of spaces.
The TextLayoutHelper class makes it easy to handle that.
Update Row::Element::rtrim() to only remove one space at row end.
Update support::countExpanders() to count all spaces, without special
handling for consecutive ones.
Fixes bug #10117.
With a string like "abc def [inset]", it should be possible to break
between the "def" and the inset. A case of interest is when "abc def "
is too long, but "abc def" is not.
To this end, tweak the test that look whether breaking was successful:
the right width to look at is nscp_width, the width without the final
space.
It is not a good idea to contruct a QChar from a char_type that is
really 32bits.
Use lyx::isSpace, which already catters for this case.
Since this code does not depend on qt anymore, move it to
support::countExpanders.
Get rid of Row::countSeparators, which is not used anymore.
Fixes bug #12519.
Typical example is a Labeling layout which label is an inline equation
larger than the screen. Before this commit, the row would not get
broken at all.
Two parts in the patch:
1/ when breaking the row in shortenIfNeeded, mark the last element as
AlwaysBreakAfter instead of BreakAfter, in case the next element is
NoBreakBefore.
2/ when nothing could be done, as last resort keep the first element
of the row only.
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.
For some reason, Qt can break strings before the first character
(although we try to prevent that). The code was not prepared to that,
now it is.
Remove a forgotten debug statement.
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 :)
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.
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.
Move declaration of RowList to Row.h
Move initialization of POD members of Row and Row::Element to declaration.
Make method isVirtual() depend on type.
Add new row element type INVALID and method isValid()
Make methods R::E::left/right_pos inline.
Add method R::E::splitAt() that returns an element containing the
remaining stuff, or an invalid element if nothing was split. breakAt
is now a simple wrapper around this function.
Add method R::push_back().
Since we intend to break the row element in two, it is not good to
truncate the string too early.
Moreover, the row element width is now set at this point, even if no
breaking occurs.
The 20px space on top and bottom of document have traditionally been
obtained by adding the to the ascent/descent of the first/last row.
This reads to annoyances like selections that are drawn in these
margins and issues with the nesting marker.
The change is to add the values to a separate member of the Row
object, and to add new Row::total(Ascent|Descent) methods that add the
effect of this padding.
Moreover, some methods are added to TextMetrics to simplify the
BufferView code.
Fixes bug #9545.
Add new RowFlags value CanBreakAfter, which says that the row can be
broken after the inset if needed. There is no CanBreakBefore yet,
because I do not know of an inset that needs it.
This makes screen closer to the actual behavior of insets.
Currently, only unprotected spaces and some special characters are
concerned. There may be more that need this handling.
Fixes bug #11621.
Add Paragraph::isChanged() and InetText::isCgchanged() which indicate
the presence of a change in the relevant object.
Sets Row::needsChangebar() when adding an inset that contains changes.
Related to bug #8645.
It is now possible to specify in the lib/language file whether screen
rows can be broken anywhere (CJK languages) or only at work boundary.
Set WordWrap to false for the CJK languages (notice that japanese-cjk
had been forgotten before).
Moreover, remove a test for separators in row element that was not
really helpful.
Fixes part of ticket #10299.
This is hardcoded for now for simplicity and to allow backporting to
2.3.
The behavior is unchanged for all languages but Chinese, Japanese or
Korean.
Fixes part of bug #10299.
Currently, our computation of row height is not completely standard:
* we ignore completely the QFontMetrics::leading() parameter
* we add arbitrarily 2 hardcoded pixels to the height.
This patch reverses these two choices, which leads to
* slightly larger spacing for MinionPro (which has a big leading).
* an additional spacing of 20% font height that depends on dpi and zoom.
Visual inspection with LibreOffice seems to imply that it disregards
the font leading but uses a interline which is 20% larger than the
font height.
This is preliminary work, this code still feels too complicated for
its own good.
Let Row::isMarginSelected return false when Row::selection() is false
(the other changes are indentation).
This allows to remove the test for selection() in
setSelectionAndMargins, so that begin/end_margin_sel are always set
correctly.
Add clearSelectionAndMargins() instead of calling directly setSelection
(which is now private) with arguments (-1, -1).
Fixes bug #10972.
The bug is the following: when selecting several paragraphs quickly
enough, some rows do not get selected.This is a consequence of the
removal of row crc, which lead to not taking into account the
selection status of the row in the decision to repaint.
The solution chosen here is to add a Row::change() helper function to
modify row members. This will set the Row changed status whenever the
value of the member changes.