Re: empty blocks vs. zero-length runs

Subject: Re: empty blocks vs. zero-length runs
From: Paul Rohr (
Date: Tue Jun 06 2000 - 16:11:02 CDT

At 02:01 PM 6/5/00 -0700, Paul Cubbage wrote:
>> Paul> Could we prevent all this trouble by guaranteeing that *no*
>> Paul> level of the layout hierarchy is ever totally empty?
>What then? Phony data in levels?


Take a look at the formatting algorithms and how the layout containment
works. Assume for a moment that the following two invariants are

  A. Every paragraph has a single NZL run for the backwards P symbol.
      This run renders at the *end* of the paragraph.

  B. Likewise, assume that every time you introduce a forced (line /
      column / page) break, there's also a NZL run. These runs are
      rendered in the container immediately *before* the break.

My assertion is that if you maintain these two invariants, most or all of
the following screw cases should be impossible:

1. A totally empty paragraph.
False for both "empty" and content paragraphs by invariant A.

2. A totally empty block.
Logical paragraphs can be split into a chain of blocks when they cross
page/column boundaries in one of two ways:

2a. Forced break. In the worst case -- inserting a forced break inside an
otherwise empty paragraph -- we still have one NZL before the break
(invariant B) and one after (invariant A).

2b. Implicit break. The formatter should only do this if there's content
to put in both containers. The one possible screw case I can think of here
is widow/orphan control. (If so, see #5b below.)

3. A totally empty line.
This can happen for one of two reasons.

3a. Totally empty paragraphs. (See #1 above.)

3b. After a forced line break. (Analogous argument to #2a above.)

4. A totally empty column.
This actually breaks down into two separate cases:

4a. Column exists, but is empty. AFAIK, this only happens when a forced
break creates a new column without any content except for the NZL at the end
of that paragraph.

4b. Column doesn't exist. Say you have a n-column section with only m
columns worth of content, where m < n. Here we'll need to adapt the
hit-testing to warp to an earlier column. Someone should play with the
semantics to decide where in the "rightmost" column we should wind up.
Defensible choices include:

  - at the "bottom" (you're past the end of that content)
  - to the "right" of the appropriate line (you're in the right margin)

5. A totally empty page.
Again, there are two separate cases here.

5a. Page exists, but is empty. Again, this only happens after a forced
break, so the same invariant A argument applies. You should be able to
hit-test and wind up on this page, so that you can insert content after that
forced page break.

5b. This page intentionally blank. The only time this should happen is if
the page is totally skipped due to even/odd pagination (which we currently
don't support), in which case, hit-tests should probably map to the previous
page, no?

bottom line
AFAIK, all of the preceding screw cases (with the possible exception of 4b
and 5b) should cause bugs now in some or all of the following code:

  - cursor motion
  - hit-testing
  - selection behaviors

To fix this, all I'm advocating is a single change -- maintain a special NZL
run at the end of each and every paragraph. This is needed for proper
selection semantics as well as a full implementation of Show Paragraphs.
Otherwise, the rest of the existing layout hierarchy should remain intact.

I haven't formalized the above argument into a proof, but it should be
fairly clear that the proposed change should greatly reduce, or even
eliminate, brittleness in any portions of the code which assume that the
layout hierarchy is fully populated all the way down to the run level.

Again, if anyone can think of specific counter-examples which still need to
be addressed, by all means speak up.


This archive was generated by hypermail 2b25 : Tue Jun 06 2000 - 16:05:25 CDT