Okay, so here's how I plan to implement this stuff.
For starters, I'll focus just on column-count, column-width and column-gap and ignore support for the other properties. And I'll focus on getting layout #1 in my previous post working, which means supporting a <length> column-width, column-count: -moz-unlimited, and a <length> column-gap.
Step 1: Add a reset style struct holding the column properties. Call it nsStyleColumn. Support -moz-column-count, -moz-column-gap and -moz-column-width style properties.
Step 2: When one of -moz-column-count or -moz-column-width is not auto, have nsCSSFrameConstructor::ConstructBlock construct a wrapper frame
around the block, call it nsColumnSetFrame, similar to the way nsGfxScrollFrame wraps blocks (or WILL wrap blocks once I've rewritten it :-) ). nsColumnSetFrame will be the primary frame for the content (unless nsGfxScrollFrame is instead). nsColumnSetFrame draws borders, background and padding (if it's the primary frame) but suppresses it for the block. We force the contained block to have a space manager and be a margin root.
Step 3: nsColumnSetFrame::Reflow does the following
a) if our computed height is unconstrained, then ignore column properties and reflow the block normally. (Don't try to do column balancing, that's really hard). Otherwise,
b) compute the width of columns. In the first cut, it will just come from the style struct.
c) reflow the block with availableHeight set to our computed height and
availableWidth set to the column width.
d) if the block overflows, create continuation frames for it as subsequent columns. Position them appropriately before reflowing each one.
e) [future work] once we reach the maximum number of columns (column-count is not -moz-unlimited, and a column after the first does not completely fit without overflowing our computed width), the last continuation of the block gets put on the nsColumnSetFrame's overflow-list.
f) our final desired height is our computed height (as always). Our desired width is the rightmost edge of the last column. Our MEW is the width of one column.
When our direction is RTL then we start the columns at our right edge and advance them to the left. If there's no computed width then I'm stuck...
This will flush out many pagination bugs, especially in places where we assume that a constraint on available height can only happen when we're in a print or print preview context, and can't happen in the presence of DOM manipulation, forms UI, and so forth. But the overall scheme doesn't seem that hard, to me.
Here's how future work would sketch out:
-- column-rules would be easy to implement.
-- percentage column-gap likewise.
-- the combinations of column-width and column-count should be quite easy. Ditto column-width-policy and column-space distribution.
-- balancing column heights when the element height is unconstrained seems really hard. One crude way to do it:
a) do an unconstrained-height reflow of the block with the column width
b) divide the resulting height by the number of columns and reflow again with that as the height constraint for each column except for the last column, which is reflowed with unconstrained height
c) choose the maximum height of those columns as the final column height constraint and reflow one more time
-- column-span as in the CSS3 draft seems really hard, but doable. When we reflow a block, if we hit a column-spanning block child, then we stop reflowing before that child and push the child and all subsequent children to our overflow list (as if there was a page-break before it). When nsColumnSetFrame detects a column-spanner it balances up the set of block continuations up to this point, then builds a column block continuation just to handle the column-spanner and its ancestors, reflows that continuation to span the right columns, and then carries on reflowing the continuation following the spanner. Yes, I'm waving my hands at light speed here.
-- having floats float between and across columns would be super-hard. It could only really work if a float is only allowed to float to the right (or in RTL, to the left) of its column. In that case we could imagine, when reflowing a column which intersected a float from a column to its left, locating such floats and subtracting their areas from the space manager.
Rob _______________________________________________ mozilla-layout mailing list [EMAIL PROTECTED] http://mail.mozilla.org/listinfo/mozilla-layout
