[Webkit-unassigned] [Bug 40555] New: line-height handling in rendering code on font fallbacks

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Sun Jun 13 19:09:31 PDT 2010


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

           Summary: line-height handling in rendering code on font
                    fallbacks
           Product: WebKit
           Version: 528+ (Nightly build)
          Platform: Macintosh
        OS/Version: All
            Status: UNCONFIRMED
          Severity: Normal
          Priority: P2
         Component: Layout and Rendering
        AssignedTo: webkit-unassigned at lists.webkit.org
        ReportedBy: gzjjgod at gmail.com


Created an attachment (id=58616)
 --> (https://bugs.webkit.org/attachment.cgi?id=58616)
Test case for this issue

I believe the line-height handling in WebCore/rendering/InlineFlowBox.cpp has a bug.

The InlineFlowBox::computeLogicalBoxHeights() functions calculates the maxAscent and maxDescent like this (typical code path):

1) First it will retrieve lineHeight from the stylesheet and baselinePosition from the font, then use baselinePosition as the maxAscent and (lineHeight - maxAscent) as maxDescent. It is reasonable, but has a potential problem which I am going to show later.
2) Then it will enumerate through all the inline boxes, for each box, it will try to find all the fonts used in that box, for each of these fonts, it will find out the max baseline position from the ascent and descent value specified by the font, with the following code:

                lineHeight = parentLineHeight.value();
                baseline = 0;
                for (size_t i = 0; i < usedFonts->size(); ++i) {
                    int halfLeading = (lineHeight - usedFonts->at(i)->ascent() - usedFonts->at(i)->descent()) / 2;
                    baseline = max(baseline, halfLeading + usedFonts->at(i)->ascent());
                }

3) Then it will use this baseline to calculate minDescent again: 

            curr->setY(verticalPositionForBox(curr, m_firstLine));
            int ascent = baseline - curr->y();
            int descent = lineHeight - ascent;
            if (maxAscent < ascent)
                maxAscent = ascent;
            if (maxDescent < descent)
                maxDescent = descent;

4) The resulting lineHeight will be maxAscent + maxDescent

Now let's see where is the problem. Here is an example, suppose we have a page with style:

    p {
        font-family: STSong, serif;
        font-size: 14px;
        line-height: 22px;
    }

The STSong font has ascent = 12, descent = 2, height = 14; the default serif font (Times New Roman) has ascent = 13, descent = 4, height = 17.

1. At first, we have lineHeight = 22, baseline = ascent + (lineHeight - height) / 2 = (13 + (22 - 17) / 2) = 15, then will can get maxAscent = 15, maxDescent = 22 - 15 = 7, as in step (1);
2. When we enumerating all the fallback fonts (STSong especially), we found halfLeading = (22 - 12 - 2) / 2 = 4, halfLeading + ascent = 16, it's larger than the original baseline (15), so we replace the baseline with 16, as in step (2)
3. Finally, we calculate the ascent to be 16 (assuming curr->y() = 0 at this point), descent = 22 - 16 = 6, then we found ascent > maxDescent, so we set maxAscent = 16, but maxDescent (7) is larger than descent (6), so we ignore the new descent. (step 3)
4. As a result, the lineHeight become 16 + 7 = 23, which unnecessarily exceeds the line-height specified in stylesheet. While in fact, all the fonts used in here only need maxAscent = 13, maxDescent = 4.

So, in my opinion, the correct value here is maxAscent = 16, maxDescent = 6. In short, when we increase the baseline in step 2, we need to decrease the maxDescent accordingly, otherwise the resulting lineHeight will exceeds the value originally specified.

A test case is attached.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list