Initial import of Dillo
This commit is contained in:
121
devdoc/dw-interrupted-drawing.doc
Normal file
121
devdoc/dw-interrupted-drawing.doc
Normal file
@ -0,0 +1,121 @@
|
||||
/** \page dw-interrupted-drawing Interrupted drawing
|
||||
|
||||
Describing the problem
|
||||
======================
|
||||
|
||||
Without interrupting drawing (which is described below), a widget can
|
||||
define the order in which its parts (background, non-widget content,
|
||||
child widgets, etc.) are drawn, but it must be drawn as a whole. There
|
||||
are situations when this is not possible.
|
||||
|
||||
Consider the following simple HTML document:
|
||||
|
||||
<head>
|
||||
<style>
|
||||
#sc-1 { position: relative; z-index: 1; background: #ffe0e0; }
|
||||
#fl-1 { float: right; background: #b0ffb0; }
|
||||
#sc-2 { position: relative; z-index: 1; background: #f0f0ff; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sc-1">
|
||||
<div id="fl-1">
|
||||
Float, line 1/3<br/>
|
||||
Float, line 2/3<br/>
|
||||
Float, line 3/3
|
||||
</div>
|
||||
Stacking Context 1
|
||||
<div id="sc-2">Stacking Context 2</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
The rendering will look like this:
|
||||
|
||||
\image html dw-interrupted-drawing-1.png
|
||||
|
||||
Note the missing "Float, line 2/3" of element #fl-1, which is covered
|
||||
by element #sc-2.
|
||||
|
||||
As described in \ref dw-out-of-flow, it has to be distinguished
|
||||
between the *container* hierarchy (equivalent to the hierarchy of
|
||||
dw::core::Widget.) and the the *generator* hierarchy. In the following
|
||||
diagram, the former is represented by solid lines, the latter by
|
||||
dotted lines:
|
||||
|
||||
\dot
|
||||
digraph G {
|
||||
node [shape=rect, fontname=Helvetica, fontsize=10];
|
||||
edge [arrowhead="vee"];
|
||||
|
||||
"#sc-1" [fillcolor="#ffe0e0", style="filled"];
|
||||
"#fl-1" [fillcolor="#b0ffb0", style="filled"];
|
||||
"#sc-2" [fillcolor="#f0f0ff", style="filled"];
|
||||
|
||||
"body" -> "#sc-1";
|
||||
"body" -> "#fl-1";
|
||||
{ rank=same; "#sc-1" -> "#fl-1" [style=dotted]; }
|
||||
"#sc-1" -> "#sc-2";
|
||||
}
|
||||
\enddot
|
||||
|
||||
|
||||
The drawing order of the four elements (represented by widgets) is:
|
||||
|
||||
- body,
|
||||
- #sc-1,
|
||||
- #fl-1,
|
||||
- #sc-2.
|
||||
|
||||
Since
|
||||
|
||||
1. #sc-2 is a child of #sc-1, but
|
||||
2. #fl-1 is a child of the body, and
|
||||
3. a widget can only draw its descendants (not necessary children,
|
||||
but drawing siblings is not allowed),
|
||||
|
||||
#sc-1 cannot be drawn as a whole; instead drawing is **interrupted**
|
||||
by #fl-1. This means:
|
||||
|
||||
1. the background and text of #sc-1 is drawn;
|
||||
2. drawing of #sc-1 is **interrupted** by #fl-1 (see below for details),
|
||||
3. drawing of #sc-1 is **continued**, by drawing #sc-2.
|
||||
|
||||
The exact control flow is described in this sequence diagram:
|
||||
|
||||
\image html dw-interrupted-drawing-2.png
|
||||
|
||||
|
||||
When is drawing interrupted?
|
||||
============================
|
||||
|
||||
A widget out of flow is regarded as part of the stacking context (see
|
||||
\ref dw-stacking-context) of its *generator* (in the example above:
|
||||
#fl-1 is part of the stacking context stablished by #sc-1, not the one
|
||||
established by body). For this reason, a widget out of flow must, in
|
||||
some cases, drawn while the *gerator* is drawn, as an
|
||||
interruption. The exact rule:
|
||||
|
||||
A widget out of flow must be drawn as an interruption (while the
|
||||
*generator* is drawn) if the stacking context of the generator (to
|
||||
which this widget belongs) is in front of the stacking context of the
|
||||
container (the parent widget).
|
||||
|
||||
See dw::oof::OOFAwareWidget::doesWidgetOOFInterruptDrawing.
|
||||
|
||||
|
||||
How does interruption of drawing work?
|
||||
======================================
|
||||
|
||||
When a widget detects that an other widget should be drawn as
|
||||
interruption (see above), it calls dw::core::Widget::drawInterruption,
|
||||
which
|
||||
|
||||
1. draws the widget within another "context" (area and reference
|
||||
widget); for this the original drawing area
|
||||
(dw::core::DrawingContext::getToplevelArea) is used.
|
||||
2. Using dw::core::DrawingContext::addWidgetDrawnAsInterruption, and
|
||||
checking later with
|
||||
dw::core::DrawingContext::hasWidgetBeenDrawnAsInterruption prevents
|
||||
these widgets from being drawn twice.
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user