This is an old post from my previous blog; unfortunately, the content was never ported to this blog. I'm re-posting it here so I can reference it in the next post.
James Clark asks a
couple of questions about pagination in my comments:
Obviously a single paragraph has to be able to broken across
multiple pages. How do TextPanel and block-level elements interact to allow this?
Is it possible for a Table to split over multiple pages?
Short answers: In most cases, TextPanel is
responsible for the layout and visual representation of its contents. When this is
not true (as with Table),
there are optional interfaces which a class can implement in order to support breaking
across pages.
Long answer: I don’t have time right now to go into too much detail, so this
will be brief (and incomplete). If there’s interest in this area, I can go into
more detail in future entries.
Classes such as Image and DockPanel are
responsible for their layout and rendering. This works fine for a simple class such
as Image, which does not need to break across lines and cannot intelligently break
across pages.
In contrast, classes such as Bold and Italic,
are not responsible for their layout and rendering. Layout and rendering are instead
handled by the parent TextPanel (or
another element which can layout and render text content). There are a variety of
reasons for doing this, but the relevant reason is that TextPanel wants to be able
to break the contents of a Bold or Italic tag across lines. (Of course, we could hook
up the right APIs and enable these classes to perform their own layout and rendering,
but this would mean more work and less performance)
In the case of Paragraph,
breaking its content across multiple columns or pages is the responsibility of the
parent TextPanel, as Paragraph does not do its own layout and rendering. However,
this is not the case with Table, or any other element which does its own layout and
wishes to break across pages. If an element wishes to support breaking across pages,
it can implement the IDocumentFormatter and IDocumentHost interfaces,
which will enable it to be hosted in a paginated context.
Also from the comment:
The concept of "attached properties" looks like a new one.
It seems like the idea is that an object of class X occurring as a descendant of an
object of class Y can have a property P that is not understood by X but is understood
by Y and is used by Y in laying out X.
Attached properties allow any class to attach a property to any other class; it does
not have to be a descendant. You’re correct that class X (the attachee) does
not know how to interpret the property which was attached by Y.
…What if X has distinct logical and visual trees
(e.g. paragraph vs lines)? Presumably Y will be taking the visual tree produced by
laying out X and be using that visual tree in laying itself out. If so, how does it
get access to the properties attached to X's logical tree?
Because TextPanel creates the visuals for the Paragraph lines, the scenario you’ve
described doesn’t occur. In general, most layouts interact with their direct
visual children, so they would be checking only the direct children for an attached
property. (This is the case for layouts, which tend to have identical logical and
visual trees, with the notable exception of text layouts)