Re: [webkit-dev] Two Pass Layout?

2009-09-23 Thread Roland Steiner
On Sat, Sep 19, 2009 at 12:42 AM, Alex Milowski  wrote:

> On Thu, Sep 17, 2009 at 11:36 PM, Roland Steiner
>  wrote:
> > Hi Alex,
> > I'm in the process of doing ruby layout, currently under review
> (reviewers:
> > *hint, hint*), where I had several of the same issues, albeit not quite
> as
> > severe as with MathML (in effect, one could see ruby as nothing than a
> > series of / operations).
>
> Is there a patch I can take a peek at?


sure: https://bugs.webkit.org/show_bug.cgi?id=28420

Compared with MathML I'm sure it's rather simple (simplistic? ;) ), though.


> Well, to some extent the way glyph stacking works is you pick a certain
> font size in pixels.  You then stack the glyphs by determining how many
> of that size you need to fill a certain pixel height.  Then zooming/etc.
> all
> seem to work well afterwards.  Oddly, for stretchy operators, the current
> font size isn't much of a consideration because you are building a large
> glyph out of smaller glyphs.


yes, but having, e.g. matrices

( a )

and (excuse the bad ASCII art)

/   \
| a |
| a |
| a |
\   /

would probably require different font sizes for the small vs. the stacked
brackets (I presume).


>  > Also note that the DOM may be manipulated afterwards - nodes added or
> > removed, causing recalculations or even add/remove line breaks (so you
> need
> > to be careful when caching values).
> > As for calulations, adding special anonymous boxes to group stuff into
> > smaller chunks might help (not sure there is actually a need for such
> things
> > in MathML). OTOH, such boxes also adds complexity when it comes to DOM
> > manipulation.
>
> Very true.  I haven't looked into how the rendering interacts with DOM
> changes.
> I assume, as some point, layout calls will be needed again.  In this case,
> I'd need to know when the siblings change size.  Is there some event that
> gets propagated for that kind of thing that turns into a sequence of method
> calls for notification?
>

I think it should be sufficient if you simply override the addChild() and
removeChild() methods in your renderer and fire off those recalculations. No
need to explicitly call layouting on your part, AFAICT.


> > Not sure I understand the requirements correctly, but can't you just nuke
> > the line boxes with deleteLineBoxTree() and have them rebuilt?
>
> I'll have to try that and see what happens.  The part I don't get rendering
> is how nested replaced objects seem to get treated different.  That is,
> if I call layout() twice with online inline content (and so a sequence of
> regular line boxes), bad things happen.  If I call layout() twice with
> a nested mfenced (an inline-block and so replaced content), the right
> thing happens.  If I call layout() twice with a nested mtable, bad things
> happen.
>
>
Not sure, what "bad things" are, but I'd just try and call
 deleteLineBoxTree() before the 2nd call as an experiment and see whether
that improves things (unless you need those line boxes).

However, overloading layout() itself and to the 2-passes in there "by hand"
(or by calling the base version at an appropriate time in between, which I
agree is prudent*) would seem to be a cleaner solution IMHO, rather than
calling it twice. This would also give you better control when doing
horizontal stacking vs. vertical stacking.

*) calling the base version at some point is prudent insofar as that it does
*something* when the user gets fancy and, e.g., tries to float or position
your math objects (OTOH, I guess you could also completely suppress such
styles for MathML).


Cheers,

Roland
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Two Pass Layout?

2009-09-18 Thread Alex Milowski
On Thu, Sep 17, 2009 at 11:36 PM, Roland Steiner
 wrote:
> Hi Alex,
> I'm in the process of doing ruby layout, currently under review (reviewers:
> *hint, hint*), where I had several of the same issues, albeit not quite as
> severe as with MathML (in effect, one could see ruby as nothing than a
> series of / operations).

Is there a patch I can take a peek at?

> I'm not sure how far my experiences
> can help you, but let me add some comments:
> On Fri, Sep 18, 2009 at 4:45 AM, Alex Milowski  wrote:
>>
>> I'd like to re-oriented the code I have to include an RenderMathOperator
>> class
>> that can stretch operators that stretchable and do something else for ones
>> that aren't (e.g. curly brackets can be stretched but angle brackets can
>> only
>> be resized by font size to a certain maximum before they look strange).
>
> Note that for "correct" rendering, even stacking braces need to change font
> sizes from time to time, so that the overall impression of weight stays
> proportionate. That is, even if you have stacking braces, their width may
> change.

Well, to some extent the way glyph stacking works is you pick a certain
font size in pixels.  You then stack the glyphs by determining how many
of that size you need to fill a certain pixel height.  Then zooming/etc. all
seem to work well afterwards.  Oddly, for stretchy operators, the current
font size isn't much of a consideration because you are building a large
glyph out of smaller glyphs.


> Also note that the DOM may be manipulated afterwards - nodes added or
> removed, causing recalculations or even add/remove line breaks (so you need
> to be careful when caching values).
> As for calulations, adding special anonymous boxes to group stuff into
> smaller chunks might help (not sure there is actually a need for such things
> in MathML). OTOH, such boxes also adds complexity when it comes to DOM
> manipulation.

Very true.  I haven't looked into how the rendering interacts with DOM changes.
I assume, as some point, layout calls will be needed again.  In this case,
I'd need to know when the siblings change size.  Is there some event that
gets propagated for that kind of thing that turns into a sequence of method
calls for notification?


>
>>
>> The consequence of this, as I've noted before, is that I somehow need
>> to "invalidate" the line boxes for the containing inline-block for the
>> mrow/mfenced.  I've tried this a number of ways but it seems that things
>> go wrong when the mrow/mfenced contains certain kind of replaced
>> content (e.g. inline-table).
>
> Not sure I understand the requirements correctly, but can't you just nuke
> the line boxes with deleteLineBoxTree() and have them rebuilt?

I'll have to try that and see what happens.  The part I don't get rendering
is how nested replaced objects seem to get treated different.  That is,
if I call layout() twice with online inline content (and so a sequence of
regular line boxes), bad things happen.  If I call layout() twice with
a nested mfenced (an inline-block and so replaced content), the right
thing happens.  If I call layout() twice with a nested mtable, bad things
happen.

That all indicates to me that I need to either:

   * prepare for layout to be called again be somehow invalidating what
 was done before
   * use methods that are "below" layout() and not call layout twice.

I'm trying to keep what RenderBlock does to layout inline children because
it does work properly in most cases.  It is only in this two-pass case
where I need to do something special.  In fact, even in that two-pass case,
if I somehow magically knew the right size for things like the stretchy
operators a priori, it would work perfectly.

-- 
--Alex Milowski
"The excellence of grammar as a guide is proportional to the paucity of the
inflexions, i.e. to the degree of analysis effected by the language
considered."

Bertrand Russell in a footnote of Principles of Mathematics
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Two Pass Layout?

2009-09-17 Thread Roland Steiner
Hi Alex,
I'm in the process of doing ruby layout, currently under review (reviewers:
*hint, hint*), where I had several of the same issues, albeit not quite as
severe as with MathML (in effect, one could see ruby as nothing than a
series of / operations). I'm not sure how far my experiences
can help you, but let me add some comments:

On Fri, Sep 18, 2009 at 4:45 AM, Alex Milowski  wrote:

> I'd like to re-oriented the code I have to include an RenderMathOperator
> class
> that can stretch operators that stretchable and do something else for ones
> that aren't (e.g. curly brackets can be stretched but angle brackets can
> only
> be resized by font size to a certain maximum before they look strange).
>

Note that for "correct" rendering, even stacking braces need to change font
sizes from time to time, so that the overall impression of weight stays
proportionate. That is, even if you have stacking braces, their width may
change.
Also note that the DOM may be manipulated afterwards - nodes added or
removed, causing recalculations or even add/remove line breaks (so you need
to be careful when caching values).

As for calulations, adding special anonymous boxes to group stuff into
smaller chunks might help (not sure there is actually a need for such things
in MathML). OTOH, such boxes also adds complexity when it comes to DOM
manipulation.


> The consequence of this, as I've noted before, is that I somehow need
> to "invalidate" the line boxes for the containing inline-block for the
> mrow/mfenced.  I've tried this a number of ways but it seems that things
> go wrong when the mrow/mfenced contains certain kind of replaced
> content (e.g. inline-table).
>

Not sure I understand the requirements correctly, but can't you just nuke
the line boxes with deleteLineBoxTree() and have them rebuilt?


Cheers,

Roland
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


[webkit-dev] Two Pass Layout?

2009-09-17 Thread Alex Milowski
I've been thinking a bit more about stretchy operators in MathML.  The
following bits are equivalent:

   1x

   {1x}

The open and close curly bracket should be stretched to the max
vertical size of
the contained inline sequence.

Even more interesting is:

   fx=
   {
   
   1if odd
   0if even
   
   
   

where the left curly bracket vertical stretches to the hight of the mtable.

I'd like to re-oriented the code I have to include an RenderMathOperator class
that can stretch operators that stretchable and do something else for ones
that aren't (e.g. curly brackets can be stretched but angle brackets can only
be resized by font size to a certain maximum before they look strange).

Anyway, the way this needs to work is the inline sequence for the row
needs one layout pass to determine the maximum height size and then
the instances of this RenderMathOperator class are be given their
"stretch size" as calculated by their siblings.  Then a second pass
would layout the content given the stretched operator's size.

RenderMathOperation would be an inline-block so when the operator
is stretched, a stack of blocks would be used to contain the glyph stack
and otherwise the base font size would just be adjusted accordingly.

The consequence of this, as I've noted before, is that I somehow need
to "invalidate" the line boxes for the containing inline-block for the
mrow/mfenced.  I've tried this a number of ways but it seems that things
go wrong when the mrow/mfenced contains certain kind of replaced
content (e.g. inline-table).

So, a couple of questions:

1. Is there a draconian way to just say "invalid, start over" so that
in the layout method of the mrow/mfenced I can just call
layout twice?

2. When I make these kinds of changes in sample XHTML + Javascript
everything seems to reflow properly.  The javascript manipulates
the style.  Is there some kind of "style changed" sequence of method
calls that I should be using?

Right now, for (1), bad things happen if the content has no
replace content or contains things like an inline-table.  That makes
me think I'm not really invalidating everything.

My thinking on (2) is that if I can do this in handwritten javascript I should
be able replicated the cascade of layout changes via method calls if I
only knew where to start.

-- 
--Alex Milowski
"The excellence of grammar as a guide is proportional to the paucity of the
inflexions, i.e. to the degree of analysis effected by the language
considered."

Bertrand Russell in a footnote of Principles of Mathematics
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev