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!!!
** 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
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
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
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
+ 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.
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.
** Metrics computation (and nodraw drawing phase)
-This is triggered by bv::updateMetrics, which calls tm::redoParagraph for
-all visible paragraphs. Some Paragraphs above or below the screen (needed
-for page up/down) and computed as needed.
+This is done bv::updateMetrics. When the parameter 'force' of this
+method is true, that first thing that is done is to clear the metrics
+caches to start from a clean slate.
+
+Then, starting upwards then downwards from the anchor paragraph
+(anchor_pit_) and its vertical position (anchor_ypos_),
+tm::updateMetrics every visible paragraph whose metrics is not know
+(all of them when force==true) is recomputed using tm::redoParagraph.
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.
+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.
-Then, a single big row is created in tm::tokenizeParagraph, which is
-later broken in multiple rows by tm::breakParagraph.
+If it turns out that the top or bottom margin are incorrect (paragraphs
+are too high/low), tm::updateMetrics will be called again with fixed
+values of anchor_ypos_ (this does not incur much extra work).
-At the end of the function, bv::updatePosCache is called. It triggers
+At the end of bv::updateMetrics, 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.
+This way of working means that scrolling can be achieved by just
+updating anchor_ypos_ and calling bv::processUpdateFlags(Update::ForceDraw).
+
** Drawing the work area.
This is done in bv::draw. This method is triggered by a paint event,