Typesetting II: Breaking paragraphs into lines
Breaking paragraphs into lines
Input:
TEXT
as a stringLINE_WIDTH
Output:
TEXT
typeset on the screenRequirement
LINE_WIDTH
Idea:
LINE_WIDTH
Details
let curLine = createLine();
for (let s of spans) {
let width = s.getBoundingClientRect().width;
if (!firstWord) { width += WORD_SEP * em; }
if (curWidth + width <= TEXT_WIDTH) {
curLine.appendChild(s);
curWidth += width; firstWord = false;
} else {
parent.appendChild(curLine);
curLine = createLine();
curLine.appendChild(s);
curWidth = width - WORD_SEP * em;}}
Aesthetic Goal. Minimize the raggedness of the paragraph.
Question. How to quantify raggedness?
Associate a penalty to each line break:
The penalty of the whole paragraph is the sum of penalties of all of the lines excluding the last line.
Find the line breaks for the paragraph that minimize the total penalty of the paragraph.
Question. Why is a penalty of $x^2$ sensible? How does penalty relate to raggedness?
Typeset a short paragraph by hand!
TODAY WE WILL TRY TRY AGAIN
TODAY WE WILL TRY TRY AGAIN
Input.
Output.
How can we find the optimal line breaks given the input parameters?
Given indices i
and j
with i < j
, what is the penalty of a line containing words w[i], w[i+1],..., w[j]
penalty(i, j)
Question. Must we compute penalty(i, j)
for all i
and j
?
Question. Suppose we know penalty[0, i]
for all i
up to j
. How could we find the minimum penalty line break for the first two lines setting words 0..j
?
Compute: array minPenalties
minPenalties[j]
stores the minimum total penalty of line breaks ending with a line break at j
.Question. Given minPenalties[0..j-1]
and penalty(i, j)
, how can we determine minPenalty[j]
?
Question. Given minPenalties[0..j-1]
and penalty(i, j)
, how can we determine minPenalty[j]
?
Observe. The minimal penalty of breaking at i
and j
is:
minPenalty[i-1] + penalty(i, j)
So. The minimum possible penalty of breaking at j
is the minimum of:
minPenalties[j-1] + penalty(j, j)
minPenalties[j-2] + penalty(j-1, j)
minPenalties[j-3] + penalty(j-2, j)
minPenalties[j-4] + penalty(j-3, j)
...
This technique for finding the optimal solution is called dynamic programming
Find the minimum penalty line breaking for typesetting TODAY WE WILL TRY TRY AGAIN
in a paragraph of line width 8.