]> git.lyx.org Git - lyx.git/blobdiff - development/PAINTING_ANALYSIS
g-brief loads babel internally. So don't load it ourselves.
[lyx.git] / development / PAINTING_ANALYSIS
index c287710ef8c34326212a3b11a507fcf97c3d4bc4..a506371965a6b9af49744526520fdca6277959de 100644 (file)
@@ -11,7 +11,7 @@ Please keep this file up to date as the code evolves!!!
 Abbreviations:
 bv: BufferView
 pm: ParagraphMetrics
-tm::TextMetrics
+tm: TextMetrics
 
 * Questions / Ideas
 
@@ -20,15 +20,9 @@ following section. Some actions are proposed.
 
 ** SinglePar update
 
-The flag Update::SinglePar is set in many places but never acted on.
-Instead, metrics update is skipped whenever the recorded height of
-current paragraph did not change and Update::Force was not specified.
-Is it better to keep that (which incurs extra work) or to condition it
-on Update::SinglePar? If the first solution is kept, the flag
-SingleParUpdate shall be removed.
-
-Moreover, I fail to see (yet) where the 'single' part of the program
-is acted on.
+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.
 
 ** Buffer::change issues
 
@@ -40,6 +34,7 @@ a good value? NoScreenUpdate?
 On a related note, what is the semantics of a call to
 Buffer::changed(false)? What does the caller mean?
 
+
 ** How to avoid redraw with FitCursor when the cursor is already OK?
 
 In this case, we invoke Buffer::change(false) with drawing disabled
@@ -60,51 +55,28 @@ cursor.
 
 * 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.
-
-** 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.
-
-** Remember rtl status in the row object
-
-This will avoid to pass a Paragraph object to methods that do not need it.
+** Set Row::changed() in a finer way
 
-** Set inset position during metrics phase
+*** singleParUpdate
 
-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.
+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.
 
-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.
+This is also true when scrolling (how to do that?)
 
-** 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?
+*** redoParagraph
 
-** Use Row for MathData
+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.
 
-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.
+** Put labels and friends in the Row as elements
 
-Will the strings display OK if drawing string-wise?
+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.
 
-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)
+** When a paragraph ends with a newline, compute correctly the height of the extra row.
 
 ** Merging bv::updateMetrics and tm::metrics
 
@@ -115,25 +87,25 @@ insets. We should re-use the bv::updateMetrics logic:
  + transfer all the logic of bv::updateMetrics to tm.
  + Main InsetText should not be special.
 
-The difficuly for a tall table cell for example, is that it may be
+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.
 
 
 * Description of current drawing mechanism
 
-** Two stage drawing
+** Three-stage drawing
 
-There are two parts to drawing the work area:
+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.
 
- + the drawing phase draws the contents and caches the inset
-   positions. Since the caching of positions is useful in itself,
-   there is a provision for drawing "without" drawing when the only
-   thing we want is to cache inset positions
-   (Painter::setDrawingEnabled).
+ + the nodraw drawing phase paints the screen (see below) with a null
+   painter. The only useful effect is to store the inset positions.
+
+ + an update() signal is sent. This in turn will trigger a paint
+   event, and the actual screen painting will happen then.
 
 The machinery is controlled via bv::processUpdateFlags. This method is
 called at the end of bv::mouseEventDispatch and in
@@ -148,29 +120,43 @@ DecorationUpdate). It triggers a recomputation of the metrics when either:
  + Update::Force has been specified
  + Update::FitCursor has been specified and there is a need to scroll
    the display.
- + the current paragraph, after rebreak, does not have the same height as in
-   existing metrics. Note that the Update::SinglePar flag is *never*
-   taken into account.
+ + Update::SinglePar has been specified and the current paragraph has
+   not 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
+this case, the effects are cumulative. processUpdateFlags executes the
+metrics-related actions, but defers the actual drawing to the next
+paint event.
 
 The screen is drawn (with appropriate update strategy), except when
 update flag is Update::None.
 
 
-** Metrics computation
+** Metrics computation (and nodraw drawing phase)
 
 This is triggered by bv::updateMetrics, which calls tm::redoParagraph for
-all visible paragraphs. Paragraphs above or below the screen (needed
+all visible paragraphs. Some 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
 all the paragraphs of the inset.
 
+Then, a single big row is created in tm::tokenizeParagraph, which is
+later broken in multiple rows by tm::breakParagraph.
+
+At the end of the function, bv::updatePosCache is called. It triggers
+a repaint of the document with a NullPainter (a painter that does
+nothing). This has the effect of caching all insets positions.
 
 ** Drawing the work area.
 
-This is done in bv::draw. This method is triggered mainly by
-Buffer::changed, which draws all the work areas that show the given buffer.
+This is done in bv::draw. This method is triggered by a paint event,
+mainly called through Buffer::changed, which draws all the work areas
+that show the given buffer.
 
 Note that, When Buffer::changed is called outside of
 bv::processUpdateFlags, it is not clear whether the update strategy
@@ -200,3 +186,6 @@ The action depends on the update strategy:
 
  + SingleParUpdate: only tries to repaint current paragraph in a way
    that is not yet very clear to me.
+
+BufferView::draw can also be called with a null painter from
+BufferView::updateMetrics().