Now painting the workarea is done at paint events as should be.
Explicit painting after updating metrics has been replaced by a much
lighter procedure (updatePosCache) to update the insets positions cache.
Expected benefits:
- better performance
- proper use of subpixel aliasing
The LyXRC variable use_qimage is not needed anymore and is therefore removed.
This patch makes sure that, every time a ParagraphMetrics has its
position set, the inset positions for the insets held by this
paragraph are remembered too.
This is complementary to BufferView::updatePosCache, but I do not have
hard evidence that this is required other than to increase robustness.
It may help in some cases when scrolling the document (scrollbar,
cursor up/down, page up/down).
The trick is to remember in BufferView what has been done at the
previous draw, so that the row that contained the caret can be
repainted if needed.
To this end, add an argument paint_caret to BufferView, although
painting the caret is not the job of the BufferView (at this point).
BufferView::needRepaint will act as an interface with
TextMetrics::drawParagraph to know whether the painting of a given
row should be forced.
Currently everything is done at the top row level, so that, if the
caret is in a large table, the whole table will have to be repainted.
It is not clear yet that this is necessary.
Normally the two stages of drawing are
1/ compute metrics of insets/rows/paragraphs/mathrow...
2/ draw the elements and cache their positions
Now the three stages are
1/ metrics
2/ nodraw: do not draw the elements, but cache their position
3/ draw the elements (and store again their position; it does not
seems to hurt performance).
Revive the NullPainter: this replaces the setDrawingEnabled mechanism
with a painter that does nothing. The advantage is that updatePosCache
(renamed from setPosCache) does not need anymore to be invoked from
the frontend.
updatePosCache (the nodraw stage) is called at the end of
BufferView::updateMetrics.
This commit does a bulk fix of incorrect annotations (comments) at the
end of namespaces.
The commit was generated by initially running clang-format, and then
from the diff of the result extracting the hunks corresponding to
fixes of namespace comments. The changes being applied and all the
results have been manually reviewed. The source code successfully
builds on macOS.
Further details on the steps below, in case they're of interest to
someone else in the future.
1. Checkout a fresh and up to date version of src/
git pull && git checkout -- src && git status src
2. Ensure there's a suitable .clang-format in place, i.e. with options
to fix the comment at the end of namespaces, including:
FixNamespaceComments: true
SpacesBeforeTrailingComments: 1
and that clang-format is >= 5.0.0, by doing e.g.:
clang-format -dump-config | grep Comments:
clang-format --version
3. Apply clang-format to the source:
clang-format -i $(find src -name "*.cpp" -or -name "*.h")
4. Create and filter out hunks related to fixing the namespace
git diff -U0 src > tmp.patch
grepdiff '^} // namespace' --output-matching=hunk tmp.patch > fix_namespace.patch
5. Filter out hunks corresponding to simple fixes into to a separate patch:
pcregrep -M -e '^diff[^\n]+\nindex[^\n]+\n--- [^\n]+\n\+\+\+ [^\n]+\n' \
-e '^@@ -[0-9]+ \+[0-9]+ @@[^\n]*\n-\}[^\n]*\n\+\}[^\n]*\n' \
fix_namespace.patch > fix_namespace_simple.patch
6. Manually review the simple patch and then apply it, after first
restoring the source.
git checkout -- src
patch -p1 < fix_namespace_simple.path
7. Manually review the (simple) changes and then stage the changes
git diff src
git add src
8. Again apply clang-format and filter out hunks related to any
remaining fixes to the namespace, this time filter with more
context. There will be fewer hunks as all the simple cases have
already been handled:
clang-format -i $(find src -name "*.cpp" -or -name "*.h")
git diff src > tmp.patch
grepdiff '^} // namespace' --output-matching=hunk tmp.patch > fix_namespace2.patch
9. Manually review/edit the resulting patch file to remove hunks for files
which need to be dealt with manually, noting the file names and
line numbers. Then restore files to as before applying clang-format
and apply the patch:
git checkout src
patch -p1 < fix_namespace2.patch
10. Manually fix the files noted in the previous step. Stage files,
review changes and commit.
The test added at 359aef92 was incorrect. Actually, Inset::editXY
returns the inset when it is edited and also when it is not, which
can be confusing. So if we are unlucky and the slices positions in the
text area and in the inner inset match, the code below triggers and
many bad things can happen.
Also improve the documentation of Inset::editXY and TextMetrics::editXY.
Fixes#10691.
The test added at 359aef92 was incorrect. Actually, Inset::editXY
returns the inset when it is edited and also when it is not, which
can be confusing. So if we are unlucky and the slices positions in the
text area and in the inner inset match, the code below triggers and
many bad things can happen.
editXY() should probably have a documented way to indicate whether the
cursor has entered the inset, although the test used right now is
probably OK. The inset value is useful mainly for context menus or
tasks that need to know which inset the (x, y) coordinates
point to.
Note finally that the documentation of TextMetrics::editXY is
incorrect concerning the return value. It will return a non-null value
if the cursor is on a not editable inset.
Fixes#10691.
When an inset wants to use the whole available width, it is necessary
to take into account that some of this width may already be taken by
the end-of-paragraph (pilcrow) marker.
Fixes bug #10537.
This is done by two things:
1/ the equation returns LefAlign as display() value
2/ Inset::indent() return a value (in general 0) that should be added
on the left (or right in rtl) of the inset when it is flushed.
The code that uses these values is in TextMetrics::computeRowMetrics.
Use Length instead of HSpace for math_indentation and rename it to mathindent.
Get rid of the string version.
Rename (g|s)etMathIndentation() to (g|s)etMathIndent().
Remove the HSpace class altogether.
Some cleanups to parindent support to look like mathindent.
Instead of using complicated (and wrong) code, it is better to use
getPosNearX here.
Also simplify the code by removing temporary variables.
Fixes part of #10569.
The code that looks whether neighbor block has a different direction
should look to the left or to the right depending on the direction of
the current block.
Fixes part of bug #10569
This allows to somewhat simplify the text and avoid some uses of
Paragraph (in the long term, RowPainter should not have to access
these things).
At the same time do a small cleanup to RowPainter: rename
text_metrics_ to tm_, remove pm_ and width_.
When using Qt stuff in breakAt, it may happen that the row is broken
after an hyphen (whereas the old code would only consider spaces).
The fact that we abuse the Row::right_boundary() property to detect when
a row should be flushed broke justification when a row is cut at an
hyphen.
Fix this by introducing a new Row::flushed() property and set it as needed.
The code that tries to decide whether it is worth splitting a given
text row element had a shortcoming: it did not take into account the
left margin of the new row that would be created.
The problem is that this left margin is not the same as the left
margin of the current row, because there can be for example
indentation effects.
To fix this problem, we pass the amount of available space on the
next row as a parameter of Row::shortenIfNeeded.
Note that there is no need to care about RtL row elements at this
point, since the bidi algorithm will be applied to the row
subsequently.
This avoids some duplicate code. Note that the return value of
Paragraph::getAlign had to be changed. I suspect it was set to char to
avoid reading one header file in Paragraph.h.
1) Distinguish expanding characters from separators, to fit with Qt's notion of
expanding character which comes from the Unicode std. CountExpanders() is moved
to FontMetrics to fix a discrepancy with the duplicate implementation from
598f7e4a.
2) Make these expanders stretch on-screen proportionally to the em of the font.
If a row mixes large and small text, LyX let us see which spaces are set in the
bigger font.
3) Now that the stretch is defined in ems, add a limit such that an expander
never stretches more than 1.5em to avoid weird and hard to read justified lines.
4) Add a return boolean to setSeparatorExtraWidth for future use.
In redoParagraph, this should be done before coping with the insets,
other wise some graphic gliches may occur. This is a better fix for
Fixes bug #10163.
This code is signalled as a copy and paste error, but it is a false
positive.
According to the documentation, adding a comment starting with
// coverity[name_of_error]
should be enough to flag the false positive.
The new functions parBottomSpaging and parTopSapcing return below/above each paragraph.
This allows to remove the TopBottomSpace argument and makes the code a
bit clearer.
Now that Row has a pit() member, it is possible to use it instead of passing an extra pit_type parameter to a function which already has access to a Row.
It is actually easier to set the 20 pixels margin in redoParagraph, since it is not necessary to take newlines in account when deciding what is the real last row of the paragraph.
Moreover this solves the following bug (present in 2.1.x too): when the document ends with a newling, the bottom margin disappears.
Update PAINTING_ANALYSIS with new tasks.
The initial values for maxasc and maxdes (renamed from maxdesc) is obtained as a maximum of max ascents/descents of all row elements.
This allows to get rid of Paragraph::highestFontInRange and FontList::highestInRange.
Some auxilliary variables declarations are also moved to where they are needed.
Let breakRow return a boolean indicating whether an additional row is
required (after a newline) and use that to replace the code that added
an extra row when a paragraph ends with a newline.
There are two main cases:
* when drawing is disabled from the start, use a simplified code that only paints insets (in order to cache positions).
* when the row is not visible, do the same.
The goal of this optimization is to be able to always run a no-drawing draw after the metrics have been computed.
The old name would be confusing wrt setSelection(), which does additional checks.
This one is a pure acessor, and the more complete methods are
* setSelection(), which avoids empty selections
* clearSelection(), which resets anchor, and sets word selection and mark more to false.
Most of the code should use these two instead of selection(bool), but this is for later.
If we do not do that, it is not possible to position the cursor after
a long inset with the mouse.
To do this, it is necessary to add the pit information to the Row
object. This is a good idea in any case, and will allow to simplify
some code later on.
Fixes bug #10094.
While a one paragraph large collapsable inset (containing for example a tabular) could be very wide and trigger horizontal scrolling, the code that makes collapsable insets wide when they contain several paragraphs would actually make them narrower in this case.
Typical example is a wide tabular and a caption in a table float, where horizontal scrolling would not trigger.
There are two regressions that are fixed here:
* empty rows at the end of a paragraph (think after newline at end of
paragraph or empty line in Verbatim) do not have an end-of-par
marker. This is fixed by removing the early return in breakRow and
letting the whole function be executed. This requires to relax an
assertion in Paragraph::fontSpan. It makes sense here to query
position at the end of the paragraph.
* a newline at the end of a paragraph will be followed by and
end-of-par marker. This is fixed by skipping the end-of-par marker
when a new row has been requested.
When a row is broken by for example a display math inset, it is
possible to put the cursor at the end of the previous line using the
boundary setting of cursor.
For newline insets and separator insets, we want to force the cursor
to be before this inset. Also, in the other cases, do not force
boundary property (effectively reverts part of f29e7803).
* breakRow: remove wrong condition that would silently eat the contents of the
paragraph when the window is narrower than left margin
* breakRow: make sure that there is at least one element in each row
* breakAt: when force-breaking a row element, make sure it is not empty. Doing
so may create empty rows and therefore a endless loop.
Fixes bugs #9962 and #10001.
This is a fixup to commit cdb9f043, which fixed bug #9757.
It is necessary to make a special case for inserting an InsetCaption
in a tabular cell, because this commonly happens in longtable mode.
Fixes bug #9945.
The active/inactive status of hfills was not checked in numberOfHFills.
The code is reorganized a bit, but the important part is the change in the above function.
Part of bug #9870.
The computation of the legth of expanded hfills did not take into account their unexpanded size. This is done now by increasing the dimension (+=) instead of merely setting it.
Moreover, since the insets sizes are integer number, rounding effects have to be taken in account. To this end, the extra number of pixels is added to the last hfill in the row.
This fixes part of bug #9860.
Note not everything is fixed by this patch: the logic of ParagraphMetrics::hfillExpansion seems bogus to me. I do not see why consecutive hfills at the beginning of a row should not be all expanded. Since I do not know what are the peculiarities of hfill handling in LaTeX, I did not change it (yet).
I did not either try to investigate the label hfill part, because I do not even know what is so special about it. I think there is a lot of old logic that nobody ever tried to question.
This is done by implementing contentAlignment() for this inset.
In order to display properly 'stretch' alignment, the code for TextMetrics::getAlign is rewritten to include some code that was in computeRowMetrics.
In computeRowMetrics, the right margin of the row shall be taken in account when the text is not left-aligned. Rewrite the code in terms of the available width `w' to avoid this pitfall.
We already have a CoordCache of insets dimensions. It is not necessary
to store the same information in two places.
Give a name to CoordCache tables types to improve code readability.
Remove ParagraphMetrics::singleWidth, which is not used anymore.
Previously, if one clicked onto a large non-editable inset like the new LyX
logo inset, the cursor was always positioned in front of the inset, even if
the click was almost at the back edge. Now the cursor is positioned at the
correct edge. I tested this also with RTL contents, where from means right
and back means left, but the inset anchor position anchor point is still
at the left, and the right edge is dim.wid pixels to the right of it.
This was a regression from 2.1.x. I failed to copy the horrible hack that was present for the special case of () in Hebrew.
There is a real need for someone who understands RTL language stuff to fix this. Currently () are wrong in .lyx files IMO. We should not have to swap them for display.
New method TextMetrics::findRowElement, excerpted from CursorX.
Reimplement getSurroundingPos using Row information. This is easy when
the cursor is inside a row element. At row element edges, different
situations can occur; hopefully all these situations are taken into
account.
Rename the old getSurroundingPos to getSurroundingPosOrig and
transform getSurroundingPos into a wrapper that compares the two
methods. This will be removed when we are confident that the new
function is equivalent to the old one.
It will then be possible to remove also the Bidi class (at last!).
* GuiFontMetrics::pos2x, x2pos: add support for inter-word spacing.
* GuiPainter::text: idem
* Row::Element::countSeparators:
Row::countSeparators: new methods that count spaces in strings.
Row::setSeparatorExtraWidth: new method (code lifted from TextMetrics.cpp).
* TextMetrics::computeRowMetrics: rely on the above methods.
* RowPainter::paintMispelledMarked: pass only a Row::Element object reference
RowPainter::paintStringAndSel: idem; do not rely on values returned by
Painter::text (trailing spaces do not honor wordspacing value).
The goal of this commit is to make painting faster by reducing the
number of strings to paint. To this end, it is necessary to include
spaces in row elements.
Also importantly, this commit should fix existing problems with line
breaking in chinese text.
* TextMetrics::breakRow: do not do anything special for word separators.
* Row::add: when adding a character to a row element, keep the string
width updated. If need be, it is possible to tweak this by updating
every 10 characters, for example.
* GuiFontMetrics::breakAt (new): use QTextLayout to break text either
at word boundary or at an arbitrary width.
* Row::Element::breakAt: use the above method.
* Row::shortenIfNeeded: simplify now that because there is no need for
handling separator elements. This will be taken care of by the
improved breakAt.
Two things remain to be done:
* remove all traces of separator row element
* re-implement text justification.
In breakRow set left and right margin properly for RTL paragraphs.
Remove corresponding code from ComputeRowMetrics.
In row painter, check the use of left and right margin depending on
context. The problem in the original text is that the various
leftMargin() methods actually represent right margin for RTL
paragraphs. This should be fixed eventually.
The document iterator now skips math insets and insets like notes where spell check is disabled.
The continuous spell checking is part of the row painter drawing and the spell check disabled state
has to be passed down recursively while doing the inset painting.
* Remove the UndoKind parameter in the general interface
* move recordUndoInset to Cursor
* remove one variant of Undo::recordUndo.
* get rid of Text::recUndo.
The computation of length on screen depend in particular of the computation of the size of an em. Many places of the code used to rely on the width of the M character, which is not really correct:
http://en.wikipedia.org/wiki/Em_%28typography%29
In digital typography, the best value to use is the point size of the font.
* Implement FontMetrics::em(), which returns the value in pixels of the EM unit.
Convert code to use it.
* Introduce Length::inPixel(MetricsBase const &), which takes the textwidth and em information from the MetricsBase object. Convert code to use it.
* Fix several places where Length::inPixel is used without a proper em value.
* add mathed_font_em() helper function. It should eventually be removed like some other functions in MathSupport.
* Add dummy implementation of FontMetrics to tex2lyx for linking purposes.
There are several places in the code where a row is painted with drawing disabled in the painter. The goal is only to recompute inset positions.
Such a case happens in BufferView::checkCursorScrollOffset, as part of the horizontal scrolling patch. Note that this particular piece of code should eventually be removed, since it is a performance problem.
It makes sense to consider that only a real painting of a row should change its status. However, I would not be surprised if this change would break other things.
Fixes: #9388
There are several places in the code where a row is painted with drawing disabled in the painter. The goal is only to recompute inset positions.
Such a case happens in BufferView::checkCursorScrollOffset, as part of the horizontal scrolling patch.
It makes sens to consider that only a real painting of a row should change its status. However, I would not be surprised if this change would break other things.
Fixes: #9388
This implement horizontal scrolling of rows to allow editing insets
(math, tabular...) that are larger then the screen. The scrolling happens
as the cursor moves, in order to make sure that the cursor is always visible.
This effectively closes an 11 years old bug.
This feature is the result of the work of Hashini Senaratne as part of
Google Summer of Code 2013. The code has been cleaned-up for inclusion
and remaining bugs have been fixed.
Fixes bug: #1083.
* When doing a redraw with drawing disabled (to set inset positions properly), take horizontal scroll offset in account
* reset horizontal scroll offset when it is smaller than the left margin.
* when drawing a paragraph, do not modify x globally, only for the row that is offset.
[This commit is the output of the "horizontal scrolling" GSoC 2013
project, by Hashini Senaratne. The code has been cleaned up, some
variables have been renamed and moved from the Cursor class to
BufferView::Private. This is the base from which I (jmarc) will polish
the feature for landing on master.
Below is the original commit log of Hashini, updated to reflect the
changes that have been done.]
This feature also applicable for other insets; graphics and labels.
This implementation is capable of scrolling a single row when reaching
its content which is beyond the screen limits, using left and right
arrow keys.
The attribute 'horiz_scroll_offset_' introduced in the
BufferView::Private class plays a main role in horizontal scrolling of
the wide rows that grow beyond the screen limits. This attribute
represents by how much pixels the current row that the text cursor
lies in should be get scrolled.
The main logic that is responsible for drawing the scrolled rows is
within the BufferView class, BufferView::checkCursorScrollOffset.
* The main logic is called via BufferView::draw.
* What this does is set the horiz_scroll_offset_ attribute in in order to
show the position that the text cursor lies in.
* To make sure that BufferView::draw gets involved when Update flag is
FitCursor, necessary changes are made in BufferView::processUpdateFlags.
Basically what the logic that used to set the horiz_scroll_offset_
does is,
* The row which the text cursor lies in is identified by a
CursorSlice that points to the beginning of the row. This is the
'rowSlice' variable used in BufferView::checkCursorScrollOffset. Acessors
are added to obtain this variable. Here row objects were not used to
identify the current row, because it appears that row objects can
disappear when doing a decoration update for example. This means that
comparing row pointers is not a good idea, because they can change
without notice.
* Stop calculations of horiz_scroll_offset_ variable, if metrics have not been
computed yet. Otherwise the calls to TextMetrics::parMetrics, calls
redoParagraph and may change the row heigths. Therefore vertical scrolling
feature may get disturbed. This is avoided.
* Using BufferView::::setCurrentRowSlice resets horiz_scroll_offset_
when changing cursor row. This is done in order to prevent unwanted
scrolling that happens when changing the selected row using up and
down arrow keys.
* Recompute inset positions before checking scoll offset of the row, by
painting the row insets with drawing disabled. This is done because the
position of insets is computed within the drawing procedure.
* Current x position of the text cursor is compared with the
horiz_scroll_offset_ value and the other variables like row.width(),
bv.workWidth(). Compute the new horiz_scroll_offset_ value in order
to show where the text cursor lies in. The basics conditions that we
check before recomputing it are, if the text cursor lies rightward to
the current right screen boundary, if the text cursor lies leftward
to the current left screen boundary, if the text cursor lies within
screen boundaries but the length of the row is less than the left
boundary of the screen (this happens when we delete some content of
the row using delete key or backspace key).
* Change update strategy when scrooll offset has changed. This allows to
redraw the row when no drawing was scheduled. By doing so, it was
possible to redraw a wide row when moving to the leftmost position of the
wide row, from the leftmost position of the row below, using the left
arrow key.
In TextMetrics::drawParagraph it is checked whether the current row is
what is drawing now. If it is so, the value used to the x value of the row
for drawing is adapted according to BufferView::horizScrollOffset.
The method used to pass boundary() was fixed to get row when cursor was in
a nested inset. This matter is considered in Cursor::textRow and it is
modified accordingly.
GuiWorkArea::Private::showCursor() is modified to show the cursor position
in a scrolled row.
All the code that is run before row metrics have been computed should use int arithmetic. After metrics have been computed, we still need doubles because fully justified rows use double for Row::Element::extra.
Rename Row::x to Row::left_margin and change its type to int.
Rename Row::Element::width() to full_width(). In some places of the code, use dim.wid (the int version without the extra separator) because metrics have not been computed.
Let Row::Element::x2pos take a int& argument instead of double&
Let Row::Element::breakAt take a int argument instead of double
The problem was that some parts of the code assume that the right margin is part of the width of the row. This is not the case, only the left margin (Row::x) is counted.
The code has been fixed and documented to reflect this.
This can only be done where splitting of string is identical in row breaking and display. It will be possible to reintroduce this when row painting uses the tokenized row information.
This variable was introduced to guard against any bad consequence of the then-new right-to-left
languages support. Let's be bold and get rid of it altogether!
Now right to left support is always enabled.
This commits (tries to) reintroduce properly the code that was reverted at the beginning of this branch. This had to be done because these patches interefered with the big refactoring of TextMetrics.cpp.
This commit reintroduces the changes to TextMetrics.cpp contained in c668ebf6, c85dbfea9 and 061509bf.
Moreover, breaks row at insets when there is no suitable separator.
Also make the code of Row::shorten_if_needed somewhat simpler by using
iterators and factoring the code.
Fixes: #9120
All these problems are related to what happens at the extreme points of rows
* since VIRTUAL elements have a width but no contents, they have to
be treated specially at some places. It would have been better to
avoid testing for them explicitly, but I did not find a way.
* Improve and cleanup the code in breakRow and fix in passing a crash
when clicking on the right of an incomplete MARGIN_MANUAL
paragraph.
* improve the computation of row width in TextMetrics::computeRowMetrics.
* handle properly the case where a position if not found on the row
in both cursorX and getPosNearX (actually, this happens when
selecting).
* Some code cleanup and comments.
* fix handling of boundary situations in Row::Elements::x2pos;
* fix handling of boundary situations in TextMetrics::getColumnNearX;
* make sure to always use Font::isVisibleRightToLeft instead of Font::isRightToLeft;
* Improve debug messages.
The horizontal position of the inset was not taken in account.
The rounding is not always the same as with the old code, but this
is not really important.
Additional changes:
* improve debug output of rows
* remove Bidi& argument of the RowPainter constructor, since it is always
an empty Bifi that is passed. This means that the Bidi class is not
used at all any more in TextMetrics.cpp. The only remaining user is
RowPainter.
Break words longer than the screen width. The code is more complicated
than I would like, but I have no better idea right now.
Implement properly the notion of a row broken by a display inset. This is useful in different places.
Also fix a bug with last line of a paragraph spotted by Kornel.
Use proper font everywhere for end-of-par marker
Fix getColumnNearX for RTL text and for centered/right-justified paragraphs.
Let computeRowMetrics update the row width.
* convert cursorX to new scheme; old computation is still there for the sake of comparison.
* use Row to compute separator width in computeRowMetrics; again, the old code is retained for now.
* Get rid of rowWidth()
* Row now contains a vector of Elements
* replace Row::dump by a proper << operator
* the width is updated as elements are added
* breakRow is reimplmented to use this infrastructure
Collect properly all strings to compute string metrics
Some changes with respect to existing code
- end of paragraph font is now the one of the text
- words longer than a line are not broken anymore. I think this is not useful if we have horizontal scrollbar
Other than that, the code is still compatible with rowWidth and friends.
Do not assert if an inset separator is the only item of a List
environment. Although it is a weird thing to do, both GUI and
latex output can deal with it.
This fixes a crash in examples/fa/splash.lyx when selecting text
representing menu entries. This happens because menu names are in LTR
English, while the inset itself is in RTL.
The problem is that the current code relies on the fact that
1. getColumnNearX and checkInsetHit share the same idea about cursor
position.
2. pos and pos + 1 are in general consecutive on screen.
It seems that 1. is wrong here (for reasons I did not try to
understand); the second assumption is definitely false with
bi-directional text. This makes editXY very fragile.
The new code should be more robust in this respect. The logic is:
* if checkInsetHit finds an inset, use its position,
* otherwise, ask getColumnNearX for the cursor position.
Fixes: #9142
When deciding whether a paragraph should be indented or not, LyX
only takes into account default layouts. This is wrong, because
an environment could be nested into another one and thus a following
paragraph would not be "default". With this patch all paragraphs
after an environment are correctly indented, independently of
whether their layouts are "default" or not.
The latex output (which was modeled following the previous wrong
assumption) is also correspondingly adapted.
If a new paragraph is created just before a nested environment,
the indentation of the nested environment is not computed
correctly because the parindent of the previous layout would
also be erroneously taken into account. This would cause the
nested environment to move back and forth when something is
added to the new paragraph.
LyX fails to indent on screen a standard paragraph when it is
nested into an environment. The fix is a one-liner but the diff
is larger because it also fixes a previous wrong indentantion
in the source ;)
If a layout has NextNoIndent set to true, the following paragraph
is not indented on screen. LyX checks the previous layout for that
style parameter to decide whether to indent or not. Of course,
what matters is the latex output and the on-screen representation
should match this output. Now, when a layout has NextNoIndent==true,
the latex output is correctly not indented, while the on-screen
representation may fail to match this output. This can occur when,
for example, a standard paragraph is nested in the previous layout,
because LyX would check the property of the nested layout instead
of the container layout. Thus, LyX should check the property of a
previous layout at the same depth for correctly deciding whether
a paragraph has to be indented or not.
See also http://www.lyx.org/trac/ticket/9055#comment:12 for an
example document where the previous scenario actually occurs.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
TextMetrics::getColumnNearX (x -> pos translation) has special code to
ignore spaces at the beginning of a row, but neither the display code
nor TextMetrics::cursorX (pos->x translation) follow this logic. One
might argue that spaces should actually be ignored (like LaTeX does),
but this leads to UI issues and is probably too difficult to
implement.
An iterator is typicall incremented passed the valid data into the 'end'
state. However, if this means that other functions are called with invalid
parameter, we should fix this.
This explains why fontSpan was called with pos==size() while this was not
expected to happen.
This patch reverts partly f5ad0c128a (Jean-Marc Lasgouttes; Get rid of
annoying warning message).
each failure.
There are several places I was not sure what to do. These are marked
by comments beginning "LASSERT:" so they can be found easily. At the
moment, they are at:
Author.cpp:105: // LASSERT: What should we do here?
Author.cpp:121: // LASSERT: What should we do here?
Buffer.cpp:4525: // LASSERT: Is it safe to continue here, or should we just return?
Cursor.cpp:345: // LASSERT: Is it safe to continue here, or should we return?
Cursor.cpp:403: // LASSERT: Is it safe to continue here, or should we return?
Cursor.cpp:1143: // LASSERT: There have been several bugs around this code, that seem
CursorSlice.cpp:83: // LASSERT: This should only ever be called from an InsetMath.
CursorSlice.cpp:92: // LASSERT: This should only ever be called from an InsetMath.
LayoutFile.cpp:303: // LASSERT: Why would this fail?
Text.cpp:995: // LASSERT: Is it safe to continue here?
Fixes bug #7111: Assertion with undo and InsetBibitem
* add Paragraph::brokenBiblio(), with tells whether there is something to fix.
* rename Paragraph::checkBiblio to fixBiblio; simplify it greatly by using
InsetList methods
* In TextMetrics::redoParagraph, call recordUndo before fixBiblio (only when
there is something to fix obviously)
Special care is taken to update cursor only when it makes sense. Note
that there are cases where undo information is not recorded (current
cursor not in the slice where action happens)
While cppcheck did not turn out any suspicious error messages, using
the "performance" flag highlighted several nitpicks in three categories
* do not use it++ for iterators, ++it is better
* do not use size() to test for emptyness, empty() is here
* do not use "const T" as a function parameter, "const & T" is better
I doubt that any of these is a real performance problem, but the code is cleaner anyway.
Only user of this function is code that has been commented out, comment
out this function as well.
Signed-off-by: Lars Gullik Bjønnes <larsbj@gullik.org>
As long as leftMargin() is not correctly implemented for
MARGIN_RIGHT_ADDRESS_BOX, we should also not do this here. Otherwise, long
rows will be painted off the screen and will not be editable.
If we are in rtl text, we *need* to check whether the first character is a
space. We can't use the rtl variable for this because this is only
computed on the last row.
This bug was introduced in [0a137e31/lyxgit] to fix the computation for
freespacing paragraphs. We better can just check whether the paragraph is
freespacing or not.
tells LyX not to show BLOCK text as justified, but still keeps
the usual paragraph indentation.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40427 a592a061-630c-0410-9148-cb99ea01b6c8