Changes between Version 4 and Version 5 of Ruby


Ignore:
Timestamp:
Dec 17, 2014 12:26:05 PM (5 years ago)
Author:
mmaxfield@apple.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Ruby

    v4 v5  
    2525The width of a ruby run is simply the maximum width of its two children: the ruby text and the ruby base (which is true of all inline-block elements). However, it’s important to realize that if the ruby text is significantly longer than the ruby base, there is some amount of overhang where the ruby text is allowed to encroach upon the space of the elements which surround it. However, this amount of overhang is capped at a multiple of the font size. This overhang is implemented by setting negative margins on the RenderRubyRun.
    2626
     27[[Image(6.png)]]
     28
     29In this image, the red box represents the bounds of the ruby run. Note how it intersects the bounds of the text on either side of the ruby!
     30
     31[[Image(7.png)]]
     32
    2733There are two conceptual pieces to the layout of ruby runs: how its containing line treats the run as a whole, and how the ruby run treats its children. Because layout is a preorder traversal, layout of the ruby text and ruby base occurs before the layout of the line containing the ruby run, which means that the outer line layout has access to information regarding the size of the ruby base and ruby text.
    2834
     
    3137Laying out a RenderBlockFlow allows subclasses to override the text alignment for the line, and RenderRubyText does so. In general, it is overridden to be “justify” in RenderRubyText::textAlignmentForLine(). Another thing that subclasses can override is, if the line’s text-align is justify, the starting position and width of the available space to lay the line out in. This is where RenderRubyText calculates its own inset amount, relative to its parent (the RenderRubyRun). This is so that it doesn’t stretch from edge to edge if the RenderRubyRun ends up being slightly wider than the space allocated to it in its containing line (because of negative margin, see above). It does this by looking at its own maxPreferredLogicalWidth(), which is the natural width of the element, and comparing that to the line’s available width that is passed in from RenderBlockFlow::computeInlineDirectionPositionsForSegment(). RenderRubyBase does both of these things similarly.
    3238
     39[[Image(8.png)]]
     40
    3341Then we pop back up to RenderRubyRun::layout() just after it calls RenderBlockFlow::layout(), where we place the ruby text to make it match up with the ruby base.
    3442
    35 Once we’re done layout out the ruby run itself, the line containing the ruby run lays out. RenderRubyRun acts as a replaced inline element (see its constructor), which means that the constructBidiRunsForSegment() call inside layoutRunsAndFloatsInRange() will return a bidi run whose renderer() is the RenderRubyRun. Then, when computeInlineDirectionPositionsForSegment() iterates over the bidi runs, it calls RenderRubyRun::getOverhang(), and applies margins equal to the starting and ending overhang. We can calculate how much overhang there should be by looking at the size of the RootInlineBoxes inside the RenderRubyBase, and comparing that to the size of the RenderRubyRun. The RootInlineBoxes will hug the size of the actual text inside the base, while the RenderRubyRun’s logicalWidth() will grow to encompass the ruby text as well. Note that we look at the ruby base (not the ruby text) when performing this calculation. In the following diagram of the ruby's containing line, the green arrows are the InlineFlowBox child relationships, and the purple arrows are InlineBox::renderer() relationships.
     43Once we’re done layout out the ruby run itself, the line containing the ruby run lays out. RenderRubyRun acts as a replaced inline element (see its constructor), which means that the constructBidiRunsForSegment() call inside layoutRunsAndFloatsInRange() will return a bidi run whose renderer() is the RenderRubyRun. Then, when computeInlineDirectionPositionsForSegment() iterates over the bidi runs, it calls RenderRubyRun::getOverhang(), and applies margins equal to the starting and ending overhang. We can calculate how much overhang there should be by looking at the size of the RootInlineBoxes inside the RenderRubyBase, and comparing that to the size of the RenderRubyRun. The RootInlineBoxes will hug the size of the actual text inside the base, while the RenderRubyRun’s logicalWidth() will grow to encompass the ruby text as well. Note that we look at the ruby base (not the ruby text) when performing this calculation. In the following diagram of the original example's ruby's containing line, the green arrows are the InlineFlowBox child relationships, and the purple arrows are InlineBox::renderer() relationships.
    3644
    3745[[Image(5.png)]]