[webkit-dev] Fwd: Ruby Text Enhancements

Eric Mader emader at apple.com
Fri Sep 24 16:56:46 PDT 2010


Sent from the wrong email alias...

Begin forwarded message:

> From: webkit-dev-owner at lists.webkit.org
> Subject: Re: [webkit-dev] Ruby Text Enhancements
> Date: September 24, 2010 1:55:19 PM HST
> To: mader_eric at apple.com
> 
> You must be subscribed in order to post to this mailing list.
> 
> 
> From: Eric Mader <mader_eric at apple.com>
> Subject: Re: [webkit-dev] Ruby Text Enhancements
> Date: September 24, 2010 1:55:15 PM HST
> To: Roland Steiner <rolandsteiner at google.com>
> Cc: David Hyatt <hyatt at apple.com>, WebKit Development <webkit-dev at lists.webkit.org>, Yasuo Kida <kida at apple.com>
> 
> 
> I have prototyped something that seems to more-or-less work. Here's what I did:
> 
> 1) Changed RenderRubyRun to subclass these methods:
>     virtual int marginTop() const;
>     virtual int marginBottom() const;
>     virtual int marginLeft() const;
>     virtual int marginRight() const;
> 
> 
> 2) added these members to RenderRubyRun:
>     mutable bool m_haveHorizontalMargins;
>     mutable int m_leftMargin;
>     mutable int m_rightMargin;
> 
> 3) Added this private method to  RenderRubyRun:
>     void getHorizontalMargins() const;
> 
> 4) Here's what marginLeft() and MarginRight() look like:
> int RenderRubyRun::marginLeft() const
> {
>     getHorizontalMargins();
>     
>     return m_leftMargin;
> }
> 
> int RenderRubyRun::marginRight() const
> {
>     getHorizontalMargins();
>     
>     return m_rightMargin;
> }
> 
> And here's getHorizontalMargins():
> void RenderRubyRun::getHorizontalMargins() const
> {
>     if (m_haveHorizontalMargins) {
>         return;
>     }
>     
>     RenderText* rubyRenderText = static_cast<RenderText*> (rubyText()->firstChild());
>     RenderText* baseRenderText = static_cast<RenderText*> (rubyBase()->firstChild());
>     int rubyLength = rubyRenderText->firstTextBox()->width();
>     int baseLength = baseRenderText->firstTextBox()->width();
>     int leftMargin = RenderBlock::marginLeft();
>     int rightMargin = RenderBlock::marginRight();
>     
>     if (baseLength < rubyLength) {
>         RenderObject* prevSibling = parent()->previousSibling();
>         RenderObject* nextSibling = parent()->nextSibling();
>         bool prevIsText = prevSibling && prevSibling->isText();
>         bool nextIsText = nextSibling && nextSibling->isText();
>         
>         // FIXME: handle odd difference?
>         if (prevIsText)
>             leftMargin += (baseLength - rubyLength) / 2;
>         
>         if (nextIsText)
>             rightMargin += (baseLength - rubyLength) / 2;
>     }
> 
>     m_leftMargin = leftMargin;
>     m_rightMargin = rightMargin;
>     m_haveHorizontalMargins = true;
> 
> }
> 
> This method makes several assumptions that I'm not 100% sure are always safe:
> * That a RenderRuby object holds only 1 RenderRubyRun object.
> * That the text for the ruby text and ruby base are always the direct child of the RenderRubyText and RenderRubyBase object.
> * That the neighboring text is always a direct sibling of the RenderRuby object.
> 
> One enhancement I know is needed is to look at successive neighboring objects to make sure that there's enough text there that the overhanging part of the ruby text doesn't overshoot the neighbor(s) as well and bump into something it can't overlap.
> 
> Does this general approach look right?
> 
> Regards,
> Eric Mader
> 
> On Sep 22, 2010, at 12:59 PM, Eric Mader wrote:
> 
>> 
>> On Sep 21, 2010, at 7:16 PM, Roland Steiner wrote:
>> 
>>> Hi Eric, 
>>> 
>>> comments inline:
>>> 
>>> On Wed, Sep 22, 2010 at 6:57 AM, Eric Mader <emader at apple.com> wrote:
>>> 
>>> On Sep 20, 2010, at 9:52 PM, Roland Steiner wrote:
>>>> Oh vey, that's ambituous! :)  There's so many corner cases I foresee on this one that I was just too happy to postpone it when we originally discussed to leave out CSS3 ruby stuff from the initial implementation, which is purely based off HTML5 - including supporting multiple base/text pairs within a single ruby, and line-breaking within the ruby.
>>> Yes, it's a bit scary. ;-) I don't think I could implement the whole thing at once, so I'm looking at doing a partial implementation. Maybe the first round would only check to be sure that the neighboring blocks aren't <ruby> blocks.
>>> 
>>> I would actually suggest cutting it down further and at first doing it only where the neighbor is plain text - this should still catch 90% of the cases where you'd want overhang and should vastly reduce the corner cases. You can verify and compute this rather easily when layouting the ruby, and you'd not need to worry about different glyph heights of neighboring inline elements, or about replaced elements interfering. Overhang would be basically be the minimum of: maximum overhang, or length of neighboring text run, or available/remaining space on the line. The latter factor may also cause you to need to break the ruby or move it to the next line altogether.
>> 
>> I'll look at this idea too. What do I need to do to find the neighboring inline elements?
>> 
>>> I'm looking at using a RenderOverflow object to implement this. Can you point me at any documentation for this class, other than what's in the code? I'm having some trouble sorting out what all the various rectangles used in conjunction with this object represent.
>>> 
>>> I have to say I'm not personally familiar with RenderOverflow, either (haven't used it with ruby). Just judging from the description it stores overflow rectangles for stuff that is actual content (layout overflow) and stuff that is pure "cosmetic rendering", such as shadows or reflections (visual overflow). For ruby overhang you'd be looking at layout overflow in principle (unless the overhang text also has shadows and stuff, which may add to the visual overflow), AFAICT. But as I said, I'm not really an expert here.
>> 
>> I've been looking at RenderOverflow, and I'm beginning to suspect that it's not the best way to proceed. Now I'm thinking that the negative margins are the way to go. My guess is that I need to set the margins on either the RenderRubyRun object or perhaps the RenderRuby object itself. To compute the correct margins, it looks to me like I'll need to access the widths of the RenderRubyText and RenderRubyBase objects. So far, I haven't been able to work out how to do that. Any clues would be greatly appreciated.
>> 
>>> Cheers,
>>> 
>>> - Roland
>> 
>> Regards,
>> Eric
>> 
> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20100924/fa42877f/attachment.html>


More information about the webkit-dev mailing list