[LyX/master] Update PAINTING_ANALYSIS
commit a23522073c8bb2cd06ddc7cc564e9c78f868a86d Author: Jean-Marc Lasgouttes Date: Mon Nov 20 17:24:09 2023 +0100 Update PAINTING_ANALYSIS --- development/PAINTING_ANALYSIS | 62 +-- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index a506371965..438d7ca9c3 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -3,7 +3,7 @@ Understanding the painting process This file tries to describe the state of the metrics/painting mechanism, and identify the improvements that could be made. The first -section can be read alone, although the context for them is really +sections can be read alone, although the context for them is really given in the following ones. Please keep this file up to date as the code evolves!!! @@ -20,9 +20,10 @@ following section. Some actions are proposed. ** SinglePar update -This flag only has an effect in the current BufferView and at -top-level, but I think it is useful in other views too. Doing this -will require some work on the update pipeline, though. +This flag only has an effect in the current BufferView, but I think it +is useful in other views too. Doing this will require some work on the +update pipeline, though. + ** Buffer::change issues @@ -53,17 +54,16 @@ The global idea would be to extend FitCursor to cover also horizontal cursor. -* Clean-up of drawing code +* TODO Clean-up of drawing code ** Set Row::changed() in a finer way *** singleParUpdate When the height of the current paragraph changes, there is no need for -a full screen update. Only the rows after the current one need to have -their position recomputed. +a full screen update (at top level, at least). Only the rows after the +current one need to have their position recomputed. -This is also true when scrolling (how to do that?) *** redoParagraph @@ -71,13 +71,16 @@ It should be possible to check whether the new row is the same as the old one and keep its changed() status in this case. This would reduce a lot the amount of stuff to redraw. + ** Put labels and friends in the Row as elements It should not be necessary to access the Paragraph object to draw. Adding the static elements to Row is a lot of work, but worth it IMO. + ** When a paragraph ends with a newline, compute correctly the height of the extra row. + ** Merging bv::updateMetrics and tm::metrics While the full metrics computation tries hard to limit the number of @@ -89,6 +92,12 @@ insets. We should re-use the bv::updateMetrics logic: The difficulty for a tall table cell for example, is that it may be necessary to break the whole contents to know the width of the cell. +Also, the anchor is relative to the outer paragraph, which means that +for a very long inset it is necessary to rebreak until the contents +that needs to be shown (to compute the heights). + +All in all, this is difficult to get right. This is less important now +that SinglePar updates work in nested insets. * Description of current drawing mechanism @@ -99,10 +108,12 @@ There are three parts to drawing the work area: + the metrics phase computes the size of insets and breaks the paragraphs into rows. It stores the dimension of insets (both - normal and math) in bv::coordCache. + normal and math) in bv::coordCache and the vertical position of the + top-level paragraphs. + the nodraw drawing phase paints the screen (see below) with a null - painter. The only useful effect is to store the inset positions. + painter. The only useful effect is to store the positions of + visible insets. + an update() signal is sent. This in turn will trigger a paint event, and the actual screen painting will happen then. @@ -115,18 +126,18 @@ whether this is correct. Depending on the Update::flags passed to the method, it sets an update strategy in (NoScreenUpdate, SingleParUpdate, FullScreenUpdate, -DecorationUpdate). It triggers a recomputation of the metrics when either: +DecorationUpdate). It triggers a call to updateMetrics when either: + Update::Force has been specified + Update::FitCursor has been specified and there is a need to scroll the display. + Update::SinglePar has been specified and the current paragraph has - not changed height. + changed height. If a computation of metrics has taken place, Force is removed from the flags and ForceDraw is added instead. -It is OK to call processUpateFlags several times before an update. In +It is OK to call processUpdateFlags several times before an update. In this case, the effects are cumulative. processUpdateFlags executes the metrics-related actions, but defers the actual drawing to the next paint event. @@ -137,21 +148,32 @@ update flag is Update::None. ** Metrics computation (and nodraw drawing phase) -This is triggered by bv::updateMetrics, which calls
[LyX/master] Update PAINTING_ANALYSIS and add a new task
commit 095c390fe2d7c983ccb0228d73c09b8da58bc206 Author: Jean-Marc LasgouttesDate: Wed May 11 14:16:08 2016 +0200 Update PAINTING_ANALYSIS and add a new task diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index acb033d..78719f5 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -58,15 +58,14 @@ The global idea would be to extend FitCursor to cover also horizontal cursor. -* Proposals - - * Clean-up of drawing code The goal is to make painting with drawing disable fast enough that it can be used after every metrics computation. Then we can separate real drawing from metrics. +Other changes are only clean-ups. + ** DONE RowPainter Inset position is set in paintInset, paintOnlyInsets, and paintText. @@ -114,29 +113,14 @@ topBottomSpace parameter should be removed after that. The helper version should return a Row::Element instead of an InsetTable. -** TODO make Inset::display() more useful +** Do not make RowPainter operations update x_ -[This has been started in the features/betterbreak branch. Time will -tell whether it really helps. The question in particular is the -handling of separator insets] +It is better to make them const and update x_ separately. -Extending the DisplayType enum would allow to remove special cases -from the code. - -The enumeration could be like -: Inline = 0 -: BreakBefore = 1 // break row before this inset -: BreakAfter = 2 // break row after this inset -: CanBreakAfter = 4 // optionally break row after this inset -: AlignLeft = 8 -: AlignRight = 16 -: NoBoundary = 32 // do not allow cursor to go at the end of the row -: //before display inset -: Display = BreakBefore|BreakAfter - -A display equation would be Display, other could be Display|AlignLeft -BreakAfter can be used by Newline or separator insets -CanBreakAfter can be used by the optional hyphen InsetSpecialChar. +Then it will be possible to reorder the painting of the different +elements. In particular, if text is painted last, it will be more +visible in the presence of underlines (foreign language, change +tracking, spell check). ** Set inset position during metrics phase @@ -222,12 +206,8 @@ update flag is Update::None. ** Metrics computation This is triggered by bv::updateMetrics, which calls tm::redoParagraph for - + all visible paragraphs - + paragraph above the screen (up to one page) - + paragraphs below the screen (up to one page again) - -The paragraphs outside of the screen are required to make PageUp/Down -work. +all visible paragraphs. Paragraphs above or below the screen (needed +for page up/down) and computed as needed. tm::redoParagraph will call Inset::metrics for each inset. In the case of text insets, this will invoke recursively tm::metrics, which redoes
[LyX/master] Update PAINTING_ANALYSIS
commit 78eaf8333bacec8d735eae06c0745163d06a5122 Author: Jean-Marc LasgouttesDate: Sat Mar 5 00:09:34 2016 +0100 Update PAINTING_ANALYSIS Some things were wrong, and some new ideas are added (some are done in this branch already). diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index d1da54b..4934c5e 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -60,13 +60,75 @@ cursor. * Proposals -** set inset position during metrics phase +* Clean-up of drawing code -This implies to set inset positions relative to outer inset during -metrics phase and then in a second loop to descend into insets and -update positions correctly. +The goal is to make painting with drawing disable fast enough that it +can be used after every metrics computation. Then we can separate real +drawing from metrics. -Effect: avoid going through the painter machinery when it is not necessary. +** DONE RowPainter + +Inset position is set in paintInset, paintOnlyInsets, and paintText. +This should be done only once in paintInset + +** DONE TextMetrics::drawParagraph + +We can really simplify the code when drawing is disabled only +paintInset needs to be called. + + do right at the start when drawing is already disabled + + do it in the loop for rows that are not visible on screen. + +The only thing we want to do here is to set inset positions (for +text). The other insets still use the painter with drawing disabled. + +** Painter::text + +We cannot remove (or make private) the version that uses a +FontInfo because it is used by PainterInfo::draw. Document this and +remove unused arguments rtl and double spacing. This would become a specialized helper. +Proposed solution: keep the existing function, but private and without +optional arguments. + +Avoid to return (and thus compute) the width of strings? + + used by InsetSpecialChar (fixable) + + used by textDecoration() in text(): more difficult to fix + +Idea: add a version of text where wordspacing and textwidth (giving +the width of strings) are required parameters and remove optional +version. + +==> more versions, no optional parameters. + +** Set inset position during metrics phase + +In order to do that, a no-paint drawing will be initiated after every +redoParagraph. This code path will need to be made as fast as possible. + +Effect: avoid depending on actual drawing having taken place. In turn, +it will allow to do drawing on paint events, like any reasonable +application would do. + +** Cleanup after complete metrics + Then the following can be done: + + remove hack in InsetMathNest::drawSelection + + remove painting when not inside in drawParagraph + + remove Cursor::inCoordCache? + +** Use Row for MathData + +It may not be so difficult. Implement x2pos and pos2x from +the TM:cursorX and TM::getPosNearX, and use them for both text and +math. + +Will the strings display OK if drawing string-wise? + +Then it would be possible to streamline drawing with disabled painter. + +** Paint directly to screen + +Instead of using an intermediary pixmap. I have no idea of how +difficult it will prove. +One benefit will be that subpixel aliasing will work again (#9972) ** Merging bv::updateMetrics and tm::metrics @@ -75,16 +137,10 @@ paragraphs that are rebroken, the version that is used for inner inset does not try any such optimization. This can be very bad for very tall insets. We should re-use the bv::updateMetrics logic: + transfer all the logic of bv::updateMetrics to tm. - + Main InsetText should not be special. - -** Metrics outside of visible area - -Currently metrics are computed for current visible paet of text, the -page above and the page below. It should be possible to compute hidden -rows ony on demand, although it might be a bit slow. + + Main InsetText should not be special. -There was a proposal to always compute _all_ rows, but this may become -expensive for large files. This would though help scrolling. +The difficuly for a tall table cell for example, is that it may be +necessary to break the whole contents to know the width of the cell. * Description of current drawing mechanism
[LyX/master] Update PAINTING_ANALYSIS
commit 47c0b3cc052ece15dea5289b683bc57bb9cfc01a Author: Jean-Marc LasgouttesDate: Mon May 30 14:54:20 2016 +0200 Update PAINTING_ANALYSIS Remove all the tasks that have been performed. diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index e1b0b64..3ddfc74 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -66,62 +66,11 @@ drawing from metrics. Other changes are only clean-ups. -** DONE RowPainter - -Inset position is set in paintInset, paintOnlyInsets, and paintText. -This should be done only once in paintInset - -** DONE TextMetrics::drawParagraph - -We can really simplify the code when drawing is disabled only -paintInset needs to be called. - + do right at the start when drawing is already disabled - + do it in the loop for rows that are not visible on screen. - -The only thing we want to do here is to set inset positions (for -text). The other insets still use the painter with drawing disabled. - -** DONE Painter::text - -We cannot remove (or make private) the version that uses a -FontInfo because it is used by PainterInfo::draw. Document this and -remove unused arguments rtl and double spacing. This would become a specialized helper. -Proposed solution: keep the existing function, but private and without -optional arguments. - -Avoid to return (and thus compute) the width of strings? - + used by InsetSpecialChar (fixable) - + used by textDecoration() in text(): more difficult to fix - -Idea: add a version of text where wordspacing and textwidth (giving -the width of strings) are required parameters and remove optional -version. - -==> more versions, no optional parameters. - -** DONE When a document ends with a newline, add the bottom margin anyway - -The code that tests for a newline was added at 6bb98d07 in 2007. - ** When a paragraph ends with a newline, compute correctly the height of the extra row. ** Rewrite TextMetrics::editXY, checkInsetHit using row information (getPosNearX)? The helper version should return a Row::Element instead of an InsetTable. -** DONE Do not make RowPainter operations update x_ - -It is better to make them const and update x_ separately. - -** DONE remove pit argument to breakRow - -There are probably other places where the pit is not needed anymore: -computeRowMetrics, labelFill, setRowHeight, isLastRow, isFirstRow - -** DONE Split setRowHeight to separate the computation of space above/below paragraph - -This allows to remove the topBottomSpace parameter. The spacing is -computed in redoParagraph, where it feels more natural. - ** Remember rtl status in the row object This will avoid to pass a Paragraph object to methods that do not need it.