Re: [webkit-dev] Two Pass Layout?
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?
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?
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?
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