aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/breakpos.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design/breakpos.xml')
-rw-r--r--docs/design/breakpos.xml289
1 files changed, 0 insertions, 289 deletions
diff --git a/docs/design/breakpos.xml b/docs/design/breakpos.xml
deleted file mode 100644
index 34df68d9f..000000000
--- a/docs/design/breakpos.xml
+++ /dev/null
@@ -1,289 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-
-<!-- Overview -->
-
-<document>
- <header>
- <title>Layout Managers</title>
- <subtitle>Break Possibility Proposal</subtitle>
- <authors>
- <person name="Karen Lease" email="klease@club-internet.fr"/>
- </authors>
- </header>
-
- <body>
-<s1 title="Introduction">
-<p>
-As explained in <link href="layout.html">Layout</link>,
-the hierarchy of Layout Managers is responsible for building and placing
-areas. Each Layout Manager is responsible for creating and filling
-areas of a particular type, either inline or block. This document
-explains one potential algorithm for this process. It is based on the
-the generation of <em>break possibilities</em> (BP for short). The
-Layout Managers (LM for short), will generate one or more BP and
-choose the best one. The BP is then used to generate the corresponding
-areas.
-</p>
-</s1><s1 title="Anatomy of a Break Possibility">
-<p>A break possibility is represented by the BreakPoss class. A
-BreakPoss contains size information in the stacking direction and in
-the
-non-stacking direction (at least for inline areas, it must have both). Flags
-indicating various conditions (ISFIRST, ISLAST, CAN_BREAK_AFTER,
-FORCE_BREAK_AFTER, ANCHORS etc). A BreakPoss contains a reference to
-the top-level LayoutManager which generated it.
-</p>
-<p>A BreakPoss contains an object implementing
-the BreakPoss.Position interface. This object is specific to the layout
-manager which created the BreakPoss. It should indicate where the
-break occurs and allow the LM to
-create an area corresponding to the BP. A higher level LM Position
-must somehow reference or wrap the Position returned by its child LM in its
-BreakPoss object. The layout manager modifies the flags and dimension
-information in the BP to reflect its own requirements. For example an
-inline FO layout manager might add space-start, space-end, border and
-padding values to the stacking or non-stacking dimensions. It might also
-modify the flags based its on keep properties.</p>
-</s1>
-<s1 title="Turning Break Possibilities into Areas">
-<p>Once break possibilities have been generated, the galley-level
-layout manager selects the best one
-and passes it back to the LayoutManager which generated it to create
-the area. A LayoutManager is responsible for
-storing enough information in its Position objects to be able to
-create the corresponding areas.</p>
- </s1>
-<s1 title="A walk-through">
-<p>Layout Managers are created from the top down. First the
-page sequence creates a PageLM and a FlowLM. The PageLM will manage
-finding the right page model (with help from the PageSequenceMaster)
-and managing the balancing act between before-floats, footnotes and
-the normal text flow. The FlowLM will
-manage the normal content in the main flow. We can think of it as a
-<em>galley</em> manager.
-</p>
-<p>In general, each LM asks its child LMs to return sucessive
-break possibilities. It passes some
-information to the child in a flags object and it gets back
-a break possibility which contains the size in
-the stacking direction as well as information about such things as
-anchors, break conditions and span conditions which can change the
-reference area environment. This process continues down to the lowest
-level of the layout manager hierarchy which corresponds to atomic
-inline-level FOs such as characters or graphics.
-</p>
-<p>
-Each layout manager will repeatedly call getNextBreakPoss on its current
-child LM until the child returns a BP with the ISLAST
-flag set. Then the layout manager moves on to its next child LM (ie,
-it asks the next child FO to generate a layout manager.) Galley level
-layout managers which are Line and Flow will return to their parent
-layout managers either when they have finished their content or when
-they encounter a a BP which will fill one of their areas.
-</p>
-<p>The break possibilities are generated from the bottom up.
-All inline content must first be broken into
-lines which are then stacked into block areas. This is done by the
-LineLayoutManager, which creates line areas.
-The LineLM asks its child LM to generate a break possibility, which
-represents a place where the line can end. This
-initially means each potential line-end (primarily spaces or forced
-linefeeds and a few other potential line-end characters such as hard
-hyphens.) The text LM returns an object which stores the size in the
-stacking direction as a MinOptMax triplet
-and a <em>cost</em>, which is based on how well this break
-would satisfy the constraints. The Text LM keeps track of its position in
-the text content and returns the total size of the text area it would
-create if it were to break at a given point. The returned BP
-object also contains information about whether the break is forced
-(linefeed) or whether this is the last area which can be generated by
-the LM (ISLAST flag). If a textFO ends on a non-break character, the
-ISLAST flag is set, but the CAN_BREAK_AFTER flag isn't, since we don't
-know if there is any following text in another inline object for
-example.
-</p>
-<p>Variable size content is taken into account from
-the bottom up. Each LM returns a range of sizes in the stacking
-direction, based on property values. For text, this comes from
-variable word-space values or letter-space values. For other inline
-objects, it may include variable space-start and space-end values
-(after calculation of the entire sequence of space specifiers at a
-particular break possibility.)</p>
-<p>The main constraint for laying out
-lines is the available inline-progression-dimension (IPD) for the line
-area to be created. This
-depends on the IPD of the reference area ancestor, on the indents of the
-containing fo:block, and on any side-floats which may be intruding on
-this line.</p>
-<note>See below <link href="#getRefIPD">Getting the Reference
-IPD</link>
-for discussion of how the reference area IPD is
-transmitted to the Line LM.</note>
-<p>For now, let's assume that only the LineLM knows about the IPD
-available to it. Therefore only it can make a decision about which BP
-is the best one; the lower level inline layout managers can only
-return potential break points.</p>
-<note>There are certainly optimizations to this model which can be
-examined later.</note>
-<p>So the Line LM will ask its child LM(s) for break possibilities until
-it gets back a BP whose stacking dimension <em>could</em> fill the
-line. This means that the BP.stackdim.max >= LineIPD.min. It can look
-for further BP, perhaps one whose stackdim.opt is closer to the
-LineIPD.opt. If it isn't happy with the choice of break possibilities,
-it can go past the end of the line to the next one, and then try to
-find a hyphenation point between the last one which fits and the first
-one which doesn't. If no possibility is found whose min/max values
-enclose the available IPD, some constraint will be violated (and
-reported in the log.) The actual strategy is up to the Line LM and
-should be able to be easily replaced without changing the architecture
-(Strategy pattern).
-</p>
-<p>The definition of a good break possibility depends on the
-properties at the block and inline level which govern things such as
-wrapping behavior and justification mode. For example, if lines are
-not to be wrapped, only an explicit linefeed can serve as a BP. If
-lines are wrapped but not justified then there is no requirement to
-completely fill the IPD on each line, but a sophisticated layout
-manager will try to achieve "aesthetic rag".
-</p>
-<p>Note that no areas have actually been created yet. Once the LineLM
-has found a potential break point for the inline content, it can
-calculate the total size of the line area which would be created. The
-size in the IPD is determined by the Line LM based on the chosen BP.
-The size of the line area in the the block-progression-dimension
-depends on the size of the text (or other inline content). These
-values are set by the inline-level LM
-in their returned BP (in terms of ascender and descender heights with
-respect to the baseline). The LineLM adds spacing implied by the
-current line-stacking strategy and line-height property values. It
-stores a reference to the chosen inline BP and "wraps" that in its own
-Position object which it stores in the BP it returns to its parent LM
-(the block layout manager).
-</p><p>The block LM now has a potential break position after its
-first line. It assigns that possibility a cost, based on widow, orphan
-and keep properties. It can also calculate the total size of the block
-area it would create, were it to end the area after this line. It does
-this by adding any padding and border (taking into account
-conditionality). It also calculates space-before and space-after
-values, or contributes to building up a sequence of such values.
-With this information, the block LM creates a new BP (or
-updates the existing one). It stores a Position object in this
-BP which wraps the returned BP from its child Line LM.
-It returns the new BP to its parent and so on, back up to the
-FlowLM.</p>
-<p>Obviously there is more complicated logic involved when dealing
-with lists and tables. These cases need to be walked through in detail.</p>
-<p>The FlowLM sees if the returned stacking dimension will still
-fit in its available block-progression-dimension (BPD). It repeatedly calls
-getNextBreakPoss on its
-child LMs until it reaches the maximum BPD for the flow reference area
-or until there is no more content to lay out. If one child LM is
-finished, it moves on to the next until the last child LM has returned
-a BP with the ISLAST flag set. If any child LM returns a
-BP with a FORCE_BREAK_BEFORE or SPAN flag set, the FlowLM will
-force layout of any pending break possibilities and return to its
-parent (the PageLM) in order to handle the break or span condition.</p>
-<p>If the returned BP has any new before-float or footnote anchors in
-it (ANCHOR flag in the
-BP), the FlowLM will also return to the PageLM. The PageLM must then
-try to find space to place the floats, possibly asking the FlowLM for
-help if the body contains multiple columns.</p>
-</s1>
-<s1 title="Some issues">
-<p>Following are a few remarks on specific issues.</p>
-<s2 title="Where Line Layout Managers are created">
-<p>If the first child FO in a block FO is an inline-level FO
-such as text, the block LM creates an intermediate level LineLM
-to layout the
-sequence of inline content into Lines. Note that the whole sequence of
-inline FOs is managed by a single instance of LineLM. The LineLM
-becomes the parent to the various inline-level LM created by each
-individual inline FO.
-Since an fo:block can have both block and inline content, its LM
-may create a sequence of intermixed BlockLM and LineLM.</p>
-</s2>
-<anchor id="getRefIPD"/><s2 title="Getting the reference IPD">
-<p>When the layout process starts, with the FlowLM asking its first
-child LM for a break possibility, the IPD isn't known, since we don't
-know whether
-the first FO might be spanning, or on which page it might start. (Of
-course, if all page masters in the sequence have the same region-body IPD
-and all have only a single column, the IPD will never change
-and could already be calculated before starting layout.)
-The FlowLM gets its
-first child LM and calls its getNextBreakPoss method. That is a child LM for
-some block-level FO. For now, suppose it's an fo:block. The BlockLM
-will create its first child LM, which may be another block-level LM in
-the case of nested blocks or a LineLM as explained above. (Question:
-do we need a START flag for layout status?)
-</p>
-<p>We keep calling getNextBreakPoss on lower level layout managers until we
-get down to the inline level or to a level which cannot have break-before
-properties, such as a list-item-label. At that point, we assume we are
-going to have to layout some actual content. But we can't do that yet
-since we don't know the inline-progression-dimension. So we return a
-BP object which has 0 size in the stacking dimension, but which
-has flags set to signal to
-higher-level layout managers what needs to be done. If it has a break-before
-property or a span property, it stores these in the BP. If
-no reference IPD is yet defined, it sets a flag to get that. It then
-returns to its parent. The parent LM will inspect the BP object
-returned. In general, it "wraps" it with information about its own
-needs. If the returned BP is not actually returning any potential
-areas, the LM can still add information about its own break or span
-requirements. This return path continues back up to the PageLM. It
-will then check break and span requirements and create a new page
-if necessary using the appropriate page-master. At that point, the
-reference IPD for the main
-flow is known and is set in the flags object used for
-the next getNextBreakPoss call to the lower level LM.
-</p><p>Using this information, the BlockLM parent can now calculate
-the available IPD for its LineLM child, based on its indents.
-(If there are any
-side-floats information about the intrusion must be passed down by the
-FlowLM to lower level managers.) The LineLM can now generate a series
-of BreakPoss objects, which it passes back to its parent LM.
-</p>
-</s2>
-<s2 title="Hyphenation">
-<p>
-The LineLM is responsible for initiating hyphenation if it is allowed
-by the properties and if no satisfactory BP can be found without
-hyphenating. The hyphenation manager is passed two break
-possibilities, one whose IPD is less than the desired line area IPD
-and one whose IPD is greater. These break possibilities might have
-been generated by different inline-level layout managers (text + a
-wrapper with a color change for example), though
-frequently they represent two positions in a single text run.
-If hyphenation is successful, a new BP is
-returned. The LineLM may look for several intermediate BP
-based on the "cost" of the returned possibilities. If no intermediate
-BP is found, the line will be "short", the white-space stretch will be
-exceeded, or perhaps the content will be overflowed or clipped,
-depending on various property settings.</p>
-</s2>
-<s2 title="Optimizing">
-<p>It obviously seems inefficient to go down to the lowest level
-LM and back up to the FlowLM for every possible line-break
-decision. It seems like it would be possible to optimize by letting
-the lower level layout managers run until they had exceeded the
-current limit in
-the stacking direction. They would then return control to the "galley"
-level (LineLM or FlowLM) which would fine-tune the break decision by
-asking the lower level LM to find a previous BP which would fit. At
-the inline level, this means hyphenation as described above.</p>
-<p>Another interesting question is at what point pending break
-possibilities can be turned into areas.The idea is to wait until we
-are sure we won't have to redo the breaking. This depends on the
-sophistication of the layout strategy. For example, if a
-linebreak can be considered final if the line is full and there are no
-anchors on the line, we could create the LineArea at that point. But
-if we are willing to change a previous line-end decision to get a
-better overall composition of a whole group of lines (to prevent multiple
-hyphens for example), we might wait until the LineLM had finished
-laying out all its material and then make all the Lines at once.</p>
-</s2>
-</s1>
- </body>
-</document>
-