Nov 2001, S.Geerken@ping.de
Last modified Sep 2003

======
DwPage
======

A widget for displaying texts. It is (currently) the main widget for
rendering HTML documents.


Signals
=======

DwPage defines the same signals as DwImage, except "image_pressed",
and with the exception that the coordinates are always -1. See
DwImage.txt for more details.


Collapsing Spaces
=================

The idea behind this is that every text box has a specific vertical
space around, and that they are combined to one space, according to
rules stated below. A rule is either a paragraph within a DwPage
widget, or a DwPage within a DwPage widget, in a single line; the
latter is used for indented boxes and list items.

The rules:

   1. If a box is following another, the space between them is the
      maximum of both box spaces:

         +---------+
         |/////////|
         |/////////|                           +---------+
         +---------+                           |/////////|
         |    A    |                           |/////////|
         +---------+                           +---------+
         |/////////|                           |    A    |
         |/////////|                           +---------+
         +---------+  are combined like this:  |/////////|
                                               |XXXXXXXXX|
         +---------+                           +---------+
         |\\\\\\\\\|                           |    B    |
         +---------+                           +---------+
         |    B    |                           |\\\\\\\\\|
         +---------+                           +---------+
         |\\\\\\\\\|
         +---------+

   2. a) If one box is the first box within another, the upper space
      of these boxes collapse. b) The analogue is the case for the
      last box:

         +---------+                       If B and C are put into A,
         |/////////|                       the result is:
         |/////////|
         +---------+        +---------+      +---------+
         |    A    | <--+-- |\\\\\\\\\|      |/////////|
         +---------+    ¦   +---------+      |XXXXXXXXX|
         |/////////|    |   |    B    |      +---------+
         |/////////|    |   +---------+      |    B    |
         +---------+    |   |\\\\\\\\\|      +---------+
                        |   +---------+      |\\\\\\\\\|
                        |                    |\\\\\\\\\|
                        |   +---------+      |\\\\\\\\\|
                        `-- |\\\\\\\\\|      +---------+
                            |\\\\\\\\\|      |    C    |
                            |\\\\\\\\\|      +---------+
                            +---------+      |\\\\\\\\\|
                            |    C    |      |XXXXXXXXX|
                            +---------+      |XXXXXXXXX|
                            |\\\\\\\\\|      +---------+
                            |\\\\\\\\\|
                            |\\\\\\\\\|
                            +---------+

For achieving this, there are some features of DwPage:

   - Consequent breaks are automatically combined, according to
     rule 1. See the code of a_Dw_page_add_break for details.

   - If a break is added as the first word of the DwPage within
     another DwPage, collapsing according to rule 2a is done
     automatically. See the code of a_Dw_page_add_break.

   - To collapse spaces according to rule 2b,
     a_Dw_page_hand_over_break must be called for the *inner*
     widget. The HTML parser does this in Html_eventually_pop_dw.


Collapsing Margins
==================

Collapsing margins, as defined in the CSS2 specification, are,
additionaly to collapsing spaces, supported. Also, spaces and margins
collaps themselves, i.e. the space between two paragraphs is maximum
of the space calculated as described in "Collapsing Spaces", and the
space calculated according to the rules for collapsing margins.

(This is an intermediate hybrid state, collapsing spaces are used in
the current version of dillo, while I implemented collapsing margins
for CSS, and integrated it already into the main trunk. For a pure
CSS-based dillo, collapsing spaces will not be needed anymore, and may
be removed for simplicity.)


Some Internals
==============

There are two lists, words and lines. The word list is quite static,
only new words may be added. A word is either text, a widget, a break
or an anchor. Anchors are stored in the text, because it may be
necessary to correct the scroller positions at rewrapping.

Lines refer to the word list (first and last), they are completely
redundant, i.e. they can be rebuild from the words. Lines can be
rewrapped either completely or partially (see "Incremental Resizing"
below), for the latter purpose, several values are accumulated in the
lines, see the file "dw_page.h" for details.


Incremental Resizing
--------------------
DwPage makes use of incremental resizing as described in Dw.txt,
section "Resizing". The parent_ref is, for children of a DwPage,
simply the number of the line.

Generally, there are three cases which may change the size of the
widget:

   1. The available size of the widget has changed, e.g. because the
      user has changed the size of the browser window. In this case,
      it is necessary to rewrap all the lines.

   2. A child widget has changed its size. In this case, only a rewrap
      down from the line where this widget is in is necessary.

      (This case is very important for tables: tables are quite at the
      bottom, so that a partial rewrap is relevant, otherwise, tables
      change their size quite often, so that this is necessary for a
      fast, non-blocking rendering)

   3. A word (or widget, break etc.) is added to the page. This makes
      it possible to reuse the old size by simply adjusting the
      current width and height, so no rewrapping is necessary.

The state of the size calculation is stored in wrap_ref within DwPage,
which has the value -1, if no rewrapping of lines necessary, or
otherwise the line from which a rewrap is necessary.
