Skip to content

Commit 3938797

Browse files
committed
Create documentation how multicol layouting and continuous container work
DEVSIX-7582
1 parent ff2f221 commit 3938797

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

layout/MODULE_OVERVIEW.md renamed to layout/README.md

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Layout module overview
22

3+
### Contents
4+
1. [Overview](#overview)
5+
2. [Rendering Engine](#rendering-engine)
6+
1. [Property Containers & Layout Objects](#property-containers--layout-objects)
7+
2. [Renderers](#renderers)
8+
3. [Continuous container layouting](#continuous-container-layouting)
9+
4. [Multicol layouting](#multicol-layouting)
10+
1. [MulticolContainer element](#multicolcontainer-element)
11+
2. [MulticolRenderer](#multicolrenderer)
12+
13+
### Overview
14+
315
Layout is a basic iText module that performs the operations of transforming abstract elements
416
(like Paragraph, Table, List) into low-level PDF syntax on actual document pages.
517

@@ -103,7 +115,7 @@ renderers.
103115

104116
Briefly, the layout mechanism is shown in the figure:
105117

106-
![Layout mechanism](Layout mechanism.png)
118+
![Layout mechanism](Layout%20mechanism.png)
107119

108120
The next step is to call the `Draw()` method. It uses layout-result from `Layout()` step and generates PDF syntax,
109121
written to the PDF document: drawing instructions based on the rendering result.
@@ -112,3 +124,51 @@ Specific Renderers contain the following instructions:
112124
- `TextRenderer`: text instructions to `PdfCanvas`
113125
- `ImageRenderer`: creating and adding `XObject`
114126
- `TableRenderer`: borders, etc.
127+
128+
### Continuous container layouting
129+
Property `TREAT_AS_CONTINUOUS_CONTAINER` is responsible for enabling continuous container layouting, which means that
130+
margins, padding, borders won't be applied for bottom of split renderer and top of overflow renderer to achieve "continuous"
131+
layouting between areas (e.g. pages).
132+
133+
All logic of continuous containers are placed in `ContinuousContainer` class, which used in BlockRenderer and ParagraphRenderer.
134+
135+
### Multicol layouting
136+
Multicol layouting is horizontal content layouting in fixed height, as in newspapers. To get such layouting it is
137+
necessary to use `MulticolContainer`, see paragraph below for more information.
138+
139+
#### MulticolContainer element
140+
Multicol layouting starts form `MulticolContainer` class, representing container whose child will be layouted in columns.
141+
The role of the instance of the class consists of the following:
142+
- Be an aggregator for content which should be layouted in columns.
143+
- Store multicol related properties e.g. `Property#COLUMN_COUNT` or `PROPERTY#COLUMN_WIDTH`
144+
- Define `MulticolRenderer` as a renderer.
145+
146+
There is one limitation of `MulticolContainer` which was added to simplify the layouting implementation:
147+
`MulticolContainer` instance always should have only one child, which presents all content which should be layouted in columns.
148+
149+
#### MulticolRenderer
150+
Layouting content in columns is performed by `MulticolRenderer` in the `layout` method and consists of the following main steps:
151+
1. Calculate the number of columns and their width based on available area and properties which are stored in model element of renderer (`MulticolContainer`).
152+
2. Calculate the approximate height of the columns:
153+
1. Temp layout all content in one column with infinity height.
154+
2. Divide result height by number of columns.
155+
3. Balance the columns by adjusting their height:
156+
1. Layout content in columns with height set to approximate height.
157+
2. If some content doesn't fit to columns (there is overflow renderer):
158+
1. (performed only in first time) Layout left over content in one infinity height column to get the left height.
159+
2. (performed only in first time) Divide left over height by fixed number of maximum iterations `MulticolRenderer#MAX_RELAYOUT_COUNT`
160+
3. (performed only in first time) Store this value in `additionalHeightPerIteration` field.
161+
4. Increase approximate height by `additionalHeightPerIteration`
162+
3. Repeat balancing until all content will fit into columns or the max number of iterations is exceeded.
163+
4. Create split and overflow renderer, adjust occupied area and return the result.
164+
165+
Such approach has 2 drawbacks:
166+
1. Too expensive in the performance meaning, because always at least 2-3 full layouts needed to draw all content.
167+
2. There will always be a case where number of iterations isn't enough and during the iterations too much height was added.
168+
169+
Another way is performing temp layout, go through renderer tree and try to find where column break can be placed, after
170+
that perform one more layout which will be returned as a result. But for that it is necessary in each renderer store
171+
some additional info about where element can be divided. This way is too complicated to implement.
172+
173+
`MulticolRenderer` is responsible for enabling property `TREAT_AS_CONTINUOUS_CONTAINER` to achieve continuous
174+
layouting between columns (see [Continuous container layouting](#continuous-container-layouting) paragraph).

0 commit comments

Comments
 (0)