diff options
Diffstat (limited to 'doc/dw-interrupted-drawing.doc')
-rw-r--r-- | doc/dw-interrupted-drawing.doc | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/doc/dw-interrupted-drawing.doc b/doc/dw-interrupted-drawing.doc new file mode 100644 index 00000000..c7037666 --- /dev/null +++ b/doc/dw-interrupted-drawing.doc @@ -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 neccessary 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. + +*/ |