Changeset 115895 in webkit


Ignore:
Timestamp:
May 2, 2012 3:00:04 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

After appending MathML with jquery the table renders with overlaps
https://bugs.webkit.org/show_bug.cgi?id=52444

Patch by David Barton <Dave Barton> on 2012-05-02
Reviewed by Julien Chaffraix.

Source/WebCore:

This patch also fixes bugs 72834 and 47781. The main problem is that correct preferred
logical widths are affected by operator stretching. Thus we add a call to
setNeedsLayoutAndPrefWidthsRecalc() after the stretching code in
RenderMathMLOperator.cpp, and change RenderMathMLBlock and RenderMathMLRow to make sure
that stretching of children is done before an <mrow>'s preferred logical widths are
computed.

Test: Added a test to mathml/presentation/mo-stretch.html

  • rendering/mathml/RenderMathMLBlock.cpp:

(WebCore::RenderMathMLBlock::RenderMathMLBlock):
(WebCore::RenderMathMLBlock::computePreferredLogicalWidths):
(WebCore::RenderMathMLBlock::computeChildrenPreferredLogicalHeights):
(WebCore::RenderMathMLBlock::preferredLogicalHeightAfterSizing):

  • rendering/mathml/RenderMathMLBlock.h:

(WebCore::RenderMathMLBlock::unembellishedOperator):
(WebCore::RenderMathMLBlock::isPreferredLogicalHeightDirty):
(WebCore::RenderMathMLBlock::preferredLogicalHeight):
(WebCore::RenderMathMLBlock::setPreferredLogicalHeight):

  • Add m_preferredLogicalHeight and methods to compute and return it.
  • Remove stretchToHeight() from most classes as it no longer needs to be done recursively. We just call it on the base of an embellished operator, and that calls setNeedsLayoutAndPrefWidthsRecalc() to mark itself and its container chain.
  • rendering/mathml/RenderMathMLOperator.cpp:

(WebCore::RenderMathMLOperator::stretchToHeight):

  • Don't compare an unexpanded height to an expanded one.

(WebCore::RenderMathMLOperator::computePreferredLogicalWidths):
(WebCore::RenderMathMLOperator::updateFromElement):

  • After stretching, call setNeedsLayoutAndPrefWidthsRecalc().
  • rendering/mathml/RenderMathMLOperator.h:

(RenderMathMLOperator):

  • rendering/mathml/RenderMathMLRow.cpp:

(WebCore::RenderMathMLRow::computePreferredLogicalWidths):
(WebCore::RenderMathMLRow::layout):

  • rendering/mathml/RenderMathMLRow.h:

(RenderMathMLRow):

  • Add computePreferredLogicalWidths(), using computeChildrenPreferredLogicalHeights() to compute our children's preferred logical heights if necessary, followed by operator stretching.
  • rendering/mathml/RenderMathMLSubSup.cpp:
  • rendering/mathml/RenderMathMLSubSup.h:

(RenderMathMLSubSup):

  • rendering/mathml/RenderMathMLUnderOver.cpp:
  • rendering/mathml/RenderMathMLUnderOver.h:

(RenderMathMLUnderOver):

LayoutTests:

  • mathml/presentation/mo-stretch.html:
  • platform/mac/mathml/presentation/mo-stretch-expected.png:
  • platform/mac/mathml/presentation/mo-stretch-expected.txt:
Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r115892 r115895  
     12012-05-02  David Barton  <dbarton@mathscribe.com>
     2
     3        After appending MathML with jquery the table renders with overlaps
     4        https://bugs.webkit.org/show_bug.cgi?id=52444
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        * mathml/presentation/mo-stretch.html:
     9        * platform/mac/mathml/presentation/mo-stretch-expected.png:
     10        * platform/mac/mathml/presentation/mo-stretch-expected.txt:
     11
    1122012-05-02  Gustavo Noronha Silva  <gns@gnome.org>
    213
  • trunk/LayoutTests/mathml/presentation/mo-stretch.html

    r113749 r115895  
    44<head>
    55    <title>&lt;mo&gt; Stretching Tests</title>
     6   
     7    <style>
     8        td              { border: solid }
     9    </style>
    610</head>
    711
     
    6165</math>
    6266
     67<p>Preferred logical widths and heights, with operator stretching:</p>
     68<table><td>a</table>
     69<table><td id="grow-td">x</table>
     70<script>
     71    window.addEventListener("load", function() {
     72        document.body.offsetTop;
     73       
     74        var e = document.createElement("div");
     75        e.innerHTML = "<math display='block' style='margin-bottom: 0'> <mrow>"+
     76                "<mrow> <mo>{</mo> <mi>x</mi> <mo>}</mo> </mrow> <mo>+</mo>" +
     77                "<mfenced> <mfrac> <mn>1</mn> <mi>y</mi> </mfrac> </mfenced> <mo>+</mo>" +
     78            "<mrow> <mo>[</mo> <mtable> <mtr><mtd><mn>1</mn></mtd></mtr> <mtr><mtd><mn>2</mn></mtd></mtr>" +
     79                "<mtr><mtd><mn>3</mn></mtd></mtr> </mtable> <mo>]</mo> </mrow> </mrow> </math>";
     80        var td = document.getElementById("grow-td"), t = td.firstChild;
     81        td.insertBefore(e.firstChild, t);
     82        td.removeChild(t);
     83    }, false);
     84</script>
     85
    6386</body>
    6487
  • trunk/LayoutTests/platform/mac/mathml/presentation/mo-stretch-expected.txt

    r115573 r115895  
    11layer at (0,0) size 800x600
    22  RenderView at (0,0) size 800x600
    3 layer at (0,0) size 800x206
    4   RenderBlock {HTML} at (0,0) size 800x206
    5     RenderBody {BODY} at (8,8) size 784x182
     3layer at (0,0) size 800x358
     4  RenderBlock {HTML} at (0,0) size 800x358
     5    RenderBody {BODY} at (8,8) size 784x342
    66      RenderMathMLMath {math} at (0,0) size 784x85
    77        RenderMathMLRow {mrow} at (308,0) size 168x85
     
    172172                    text run at (3,2) width 8: "y"
    173173            RenderMathMLOperator {mo} at (23,0) size 5x41
     174      RenderBlock {P} at (0,198) size 784x18
     175        RenderText {#text} at (0,0) size 387x18
     176          text run at (0,0) width 387: "Preferred logical widths and heights, with operator stretching:"
     177      RenderTable {TABLE} at (0,232) size 19x30
     178        RenderTableSection {TBODY} at (0,0) size 19x30
     179          RenderTableRow {TR} at (0,2) size 19x26
     180            RenderTableCell {TD} at (2,2) size 15x26 [border: (3px solid #000000)] [r=0 c=0 rs=1 cs=1]
     181              RenderText {#text} at (4,4) size 7x18
     182                text run at (4,4) width 7: "a"
     183      RenderTable {TABLE} at (0,262) size 119x80
     184        RenderTableSection {TBODY} at (0,0) size 119x80
     185          RenderTableRow {TR} at (0,2) size 119x76
     186            RenderTableCell {TD} at (2,2) size 115x76 [border: (3px solid #000000)] [r=0 c=0 rs=1 cs=1]
     187              RenderMathMLMath {math} at (4,4) size 107x68
     188                RenderMathMLRow {mrow} at (1,0) size 105x68
     189                  RenderMathMLRow {mrow} at (0,25) size 27x19
     190                    RenderMathMLOperator {mo} at (0,0) size 10x19
     191                      RenderMathMLBlock {mo} at (0,0) size 9x19
     192                        RenderText {mo} at (0,0) size 9x19
     193                          text run at (0,0) width 9: "{"
     194                    RenderInline {mi} at (0,0) size 7x16
     195                      RenderText {#text} at (10,2) size 7x16
     196                        text run at (10,2) width 7: "x"
     197                    RenderMathMLOperator {mo} at (17,0) size 10x19
     198                      RenderMathMLBlock {mo} at (0,0) size 9x19
     199                        RenderText {mo} at (0,0) size 9x19
     200                          text run at (0,0) width 9: "}"
     201                  RenderMathMLOperator {mo} at (27,27) size 10x16
     202                    RenderMathMLBlock {mo} at (0,0) size 9x16
     203                      RenderText {mo} at (0,0) size 9x16
     204                        text run at (0,0) width 9: "+"
     205                  RenderMathMLFenced {mfenced} at (37,15) size 28x41
     206                    RenderMathMLOperator {mfenced} at (1,0) size 6x41
     207                    RenderMathMLFraction {mfrac} at (7,2) size 14x34
     208                      RenderMathMLBlock {mfrac} at (0,0) size 14x16
     209                        RenderInline {mn} at (0,0) size 8x16
     210                          RenderText {#text} at (3,0) size 8x16
     211                            text run at (3,0) width 8: "1"
     212                      RenderMathMLBlock {mfrac} at (0,16) size 14x18
     213                        RenderInline {mi} at (0,0) size 8x16
     214                          RenderText {#text} at (3,2) size 8x16
     215                            text run at (3,2) width 8: "y"
     216                    RenderMathMLOperator {mfenced} at (21,0) size 6x41
     217                  RenderMathMLOperator {mo} at (65,27) size 10x16
     218                    RenderMathMLBlock {mo} at (0,0) size 9x16
     219                      RenderText {mo} at (0,0) size 9x16
     220                        text run at (0,0) width 9: "+"
     221                  RenderMathMLRow {mrow} at (75,0) size 30x68
     222                    RenderMathMLOperator {mo} at (0,0) size 6x68
     223                    RenderTable {mtable} at (6,4) size 18x56
     224                      RenderTableSection (anonymous) at (0,0) size 18x56
     225                        RenderTableRow {mtr} at (0,2) size 18x16
     226                          RenderTableCell {mtd} at (2,2) size 14x16 [r=0 c=0 rs=1 cs=1]
     227                            RenderInline {mn} at (0,0) size 8x16
     228                              RenderText {#text} at (3,0) size 8x16
     229                                text run at (3,0) width 8: "1"
     230                        RenderTableRow {mtr} at (0,20) size 18x16
     231                          RenderTableCell {mtd} at (2,20) size 14x16 [r=1 c=0 rs=1 cs=1]
     232                            RenderInline {mn} at (0,0) size 8x16
     233                              RenderText {#text} at (3,0) size 8x16
     234                                text run at (3,0) width 8: "2"
     235                        RenderTableRow {mtr} at (0,38) size 18x16
     236                          RenderTableCell {mtd} at (2,38) size 14x16 [r=2 c=0 rs=1 cs=1]
     237                            RenderInline {mn} at (0,0) size 8x16
     238                              RenderText {#text} at (3,0) size 8x16
     239                                text run at (3,0) width 8: "3"
     240                    RenderMathMLOperator {mo} at (24,0) size 6x68
    174241layer at (322,8) size 5x10 scrollHeight 14
    175242  RenderMathMLBlock {mo} at (0,0) size 5x10
     
    328395layer at (415,176) size 5x11 scrollHeight 13
    329396  RenderMathMLBlock {mo} at (0,30) size 5x11
     397layer at (53,291) size 5x10 scrollHeight 14
     398  RenderMathMLBlock {mfenced} at (0,0) size 5x10
     399layer at (53,301) size 5x10 scrollHeight 13
     400  RenderMathMLBlock {mfenced} at (0,10) size 5x10
     401    RenderText {mfenced} at (0,-1) size 5x14
     402      text run at (0,-1) width 5: "\x{239C}"
     403layer at (53,311) size 5x10 scrollHeight 13
     404  RenderMathMLBlock {mfenced} at (0,20) size 5x10
     405    RenderText {mfenced} at (0,-1) size 5x14
     406      text run at (0,-1) width 5: "\x{239C}"
     407layer at (53,321) size 5x11 scrollHeight 13
     408  RenderMathMLBlock {mfenced} at (0,30) size 5x11
     409layer at (73,291) size 5x10 scrollHeight 14
     410  RenderMathMLBlock {mfenced} at (0,0) size 5x10
     411layer at (73,301) size 5x10 scrollHeight 13
     412  RenderMathMLBlock {mfenced} at (0,10) size 5x10
     413    RenderText {mfenced} at (0,-1) size 5x14
     414      text run at (0,-1) width 5: "\x{239F}"
     415layer at (73,311) size 5x10 scrollHeight 13
     416  RenderMathMLBlock {mfenced} at (0,20) size 5x10
     417    RenderText {mfenced} at (0,-1) size 5x14
     418      text run at (0,-1) width 5: "\x{239F}"
     419layer at (73,321) size 5x11 scrollHeight 13
     420  RenderMathMLBlock {mfenced} at (0,30) size 5x11
     421layer at (90,276) size 5x10 scrollHeight 14
     422  RenderMathMLBlock {mo} at (0,0) size 5x10
     423layer at (90,286) size 5x10 scrollHeight 13
     424  RenderMathMLBlock {mo} at (0,10) size 5x10
     425    RenderText {mo} at (0,-1) size 5x14
     426      text run at (0,-1) width 5: "\x{23A2}"
     427layer at (90,296) size 5x10 scrollHeight 13
     428  RenderMathMLBlock {mo} at (0,20) size 5x10
     429    RenderText {mo} at (0,-1) size 5x14
     430      text run at (0,-1) width 5: "\x{23A2}"
     431layer at (90,306) size 5x10 scrollHeight 13
     432  RenderMathMLBlock {mo} at (0,30) size 5x10
     433    RenderText {mo} at (0,-1) size 5x14
     434      text run at (0,-1) width 5: "\x{23A2}"
     435layer at (90,316) size 5x10 scrollHeight 13
     436  RenderMathMLBlock {mo} at (0,40) size 5x10
     437    RenderText {mo} at (0,-1) size 5x14
     438      text run at (0,-1) width 5: "\x{23A2}"
     439layer at (90,326) size 5x7 scrollHeight 13
     440  RenderMathMLBlock {mo} at (0,50) size 5x7
     441    RenderText {mo} at (0,-1) size 5x14
     442      text run at (0,-1) width 5: "\x{23A2}"
     443layer at (90,333) size 5x11 scrollHeight 13
     444  RenderMathMLBlock {mo} at (0,57) size 5x11
     445layer at (114,276) size 5x10 scrollHeight 14
     446  RenderMathMLBlock {mo} at (0,0) size 5x10
     447layer at (114,286) size 5x10 scrollHeight 13
     448  RenderMathMLBlock {mo} at (0,10) size 5x10
     449    RenderText {mo} at (0,-1) size 5x14
     450      text run at (0,-1) width 5: "\x{23A5}"
     451layer at (114,296) size 5x10 scrollHeight 13
     452  RenderMathMLBlock {mo} at (0,20) size 5x10
     453    RenderText {mo} at (0,-1) size 5x14
     454      text run at (0,-1) width 5: "\x{23A5}"
     455layer at (114,306) size 5x10 scrollHeight 13
     456  RenderMathMLBlock {mo} at (0,30) size 5x10
     457    RenderText {mo} at (0,-1) size 5x14
     458      text run at (0,-1) width 5: "\x{23A5}"
     459layer at (114,316) size 5x10 scrollHeight 13
     460  RenderMathMLBlock {mo} at (0,40) size 5x10
     461    RenderText {mo} at (0,-1) size 5x14
     462      text run at (0,-1) width 5: "\x{23A5}"
     463layer at (114,326) size 5x7 scrollHeight 13
     464  RenderMathMLBlock {mo} at (0,50) size 5x7
     465    RenderText {mo} at (0,-1) size 5x14
     466      text run at (0,-1) width 5: "\x{23A5}"
     467layer at (114,333) size 5x11 scrollHeight 13
     468  RenderMathMLBlock {mo} at (0,57) size 5x11
    330469layer at (322,9) size 5x11 backgroundClip at (322,8) size 5x10 clip at (322,8) size 5x10 outlineClip at (322,8) size 5x10
    331470  RenderBlock (relative positioned) {mo} at (0,0) size 5x11
     
    384523    RenderText {mo} at (0,-1) size 5x14
    385524      text run at (0,-1) width 5: "\x{23A0}"
     525layer at (53,292) size 5x11 backgroundClip at (53,291) size 5x10 clip at (53,291) size 5x10 outlineClip at (53,291) size 5x10
     526  RenderBlock (relative positioned) {mfenced} at (0,0) size 5x11
     527    RenderText {mfenced} at (0,-1) size 5x14
     528      text run at (0,-1) width 5: "\x{239B}"
     529layer at (53,318) size 5x11 backgroundClip at (53,321) size 5x11 clip at (53,321) size 5x11 outlineClip at (53,321) size 5x11
     530  RenderBlock (relative positioned) {mfenced} at (0,0) size 5x11
     531    RenderText {mfenced} at (0,-1) size 5x14
     532      text run at (0,-1) width 5: "\x{239D}"
     533layer at (73,292) size 5x11 backgroundClip at (73,291) size 5x10 clip at (73,291) size 5x10 outlineClip at (73,291) size 5x10
     534  RenderBlock (relative positioned) {mfenced} at (0,0) size 5x11
     535    RenderText {mfenced} at (0,-1) size 5x14
     536      text run at (0,-1) width 5: "\x{239E}"
     537layer at (73,318) size 5x11 backgroundClip at (73,321) size 5x11 clip at (73,321) size 5x11 outlineClip at (73,321) size 5x11
     538  RenderBlock (relative positioned) {mfenced} at (0,0) size 5x11
     539    RenderText {mfenced} at (0,-1) size 5x14
     540      text run at (0,-1) width 5: "\x{23A0}"
     541layer at (90,277) size 5x11 backgroundClip at (90,276) size 5x10 clip at (90,276) size 5x10 outlineClip at (90,276) size 5x10
     542  RenderBlock (relative positioned) {mo} at (0,0) size 5x11
     543    RenderText {mo} at (0,-1) size 5x14
     544      text run at (0,-1) width 5: "\x{23A1}"
     545layer at (90,330) size 5x11 backgroundClip at (90,333) size 5x11 clip at (90,333) size 5x11 outlineClip at (90,333) size 5x11
     546  RenderBlock (relative positioned) {mo} at (0,0) size 5x11
     547    RenderText {mo} at (0,-1) size 5x14
     548      text run at (0,-1) width 5: "\x{23A3}"
     549layer at (114,277) size 5x11 backgroundClip at (114,276) size 5x10 clip at (114,276) size 5x10 outlineClip at (114,276) size 5x10
     550  RenderBlock (relative positioned) {mo} at (0,0) size 5x11
     551    RenderText {mo} at (0,-1) size 5x14
     552      text run at (0,-1) width 5: "\x{23A4}"
     553layer at (114,330) size 5x11 backgroundClip at (114,333) size 5x11 clip at (114,333) size 5x11 outlineClip at (114,333) size 5x11
     554  RenderBlock (relative positioned) {mo} at (0,0) size 5x11
     555    RenderText {mo} at (0,-1) size 5x14
     556      text run at (0,-1) width 5: "\x{23A6}"
  • trunk/Source/WebCore/ChangeLog

    r115886 r115895  
     12012-05-02  David Barton  <dbarton@mathscribe.com>
     2
     3        After appending MathML with jquery the table renders with overlaps
     4        https://bugs.webkit.org/show_bug.cgi?id=52444
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        This patch also fixes bugs 72834 and 47781. The main problem is that correct preferred
     9        logical widths are affected by operator stretching. Thus we add a call to
     10        setNeedsLayoutAndPrefWidthsRecalc() after the stretching code in
     11        RenderMathMLOperator.cpp, and change RenderMathMLBlock and RenderMathMLRow to make sure
     12        that stretching of children is done before an <mrow>'s preferred logical widths are
     13        computed.
     14       
     15        Test: Added a test to mathml/presentation/mo-stretch.html
     16
     17        * rendering/mathml/RenderMathMLBlock.cpp:
     18        (WebCore::RenderMathMLBlock::RenderMathMLBlock):
     19        (WebCore::RenderMathMLBlock::computePreferredLogicalWidths):
     20        (WebCore::RenderMathMLBlock::computeChildrenPreferredLogicalHeights):
     21        (WebCore::RenderMathMLBlock::preferredLogicalHeightAfterSizing):
     22        * rendering/mathml/RenderMathMLBlock.h:
     23        (WebCore::RenderMathMLBlock::unembellishedOperator):
     24        (WebCore::RenderMathMLBlock::isPreferredLogicalHeightDirty):
     25        (WebCore::RenderMathMLBlock::preferredLogicalHeight):
     26        (WebCore::RenderMathMLBlock::setPreferredLogicalHeight):
     27            - Add m_preferredLogicalHeight and methods to compute and return it.
     28            - Remove stretchToHeight() from most classes as it no longer needs to be done
     29              recursively. We just call it on the base of an embellished operator, and that
     30              calls setNeedsLayoutAndPrefWidthsRecalc() to mark itself and its container
     31              chain.
     32       
     33        * rendering/mathml/RenderMathMLOperator.cpp:
     34        (WebCore::RenderMathMLOperator::stretchToHeight):
     35            - Don't compare an unexpanded height to an expanded one.
     36        (WebCore::RenderMathMLOperator::computePreferredLogicalWidths):
     37        (WebCore::RenderMathMLOperator::updateFromElement):
     38            - After stretching, call setNeedsLayoutAndPrefWidthsRecalc().
     39        * rendering/mathml/RenderMathMLOperator.h:
     40        (RenderMathMLOperator):
     41       
     42        * rendering/mathml/RenderMathMLRow.cpp:
     43        (WebCore::RenderMathMLRow::computePreferredLogicalWidths):
     44        (WebCore::RenderMathMLRow::layout):
     45        * rendering/mathml/RenderMathMLRow.h:
     46        (RenderMathMLRow):
     47            - Add computePreferredLogicalWidths(), using computeChildrenPreferredLogicalHeights()
     48              to compute our children's preferred logical heights if necessary, followed by
     49              operator stretching.
     50       
     51        * rendering/mathml/RenderMathMLSubSup.cpp:
     52        * rendering/mathml/RenderMathMLSubSup.h:
     53        (RenderMathMLSubSup):
     54        * rendering/mathml/RenderMathMLUnderOver.cpp:
     55        * rendering/mathml/RenderMathMLUnderOver.h:
     56        (RenderMathMLUnderOver):
     57
    1582012-05-02  Dana Jansens  <danakj@chromium.org>
    259
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp

    r113823 r115895  
    4747    , m_intrinsicPaddingStart(0)
    4848    , m_intrinsicPaddingEnd(0)
     49    , m_preferredLogicalHeight(preferredLogicalHeightUnset)
    4950{
    5051}
     
    137138{
    138139    return computedCSSPaddingEnd() + m_intrinsicPaddingEnd;
     140}
     141
     142void RenderMathMLBlock::computePreferredLogicalWidths()
     143{
     144    ASSERT(preferredLogicalWidthsDirty());
     145    m_preferredLogicalHeight = preferredLogicalHeightUnset;
     146    RenderBlock::computePreferredLogicalWidths();
    139147}
    140148
     
    149157}
    150158
    151 void RenderMathMLBlock::stretchToHeight(int height)
    152 {
    153     for (RenderObject* current = firstChild(); current; current = current->nextSibling())
    154        if (current->isRenderMathMLBlock()) {
    155           RenderMathMLBlock* block = toRenderMathMLBlock(current);
    156           block->stretchToHeight(height);
    157        }
     159// An arbitrary large value, like RenderBlock.cpp BLOCK_MAX_WIDTH or FixedTableLayout.cpp TABLE_MAX_WIDTH.
     160static const LayoutUnit cLargeLogicalWidth = 15000;
     161
     162void RenderMathMLBlock::computeChildrenPreferredLogicalHeights()
     163{
     164    ASSERT(needsLayout());
     165   
     166    // Ensure a full repaint will happen after layout finishes.
     167    setNeedsLayout(true, MarkOnlyThis);
     168   
     169    LayoutUnit oldAvailableLogicalWidth = availableLogicalWidth();
     170    setLogicalWidth(cLargeLogicalWidth);
     171   
     172    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     173        if (!child->isBox())
     174            continue;
     175       
     176        // Because our width changed, |child| may need layout.
     177        if (child->maxPreferredLogicalWidth() > oldAvailableLogicalWidth)
     178            child->setNeedsLayout(true, MarkOnlyThis);
     179       
     180        RenderMathMLBlock* childMathMLBlock = child->isRenderMathMLBlock() ? toRenderMathMLBlock(child) : 0;
     181        if (childMathMLBlock && !childMathMLBlock->isPreferredLogicalHeightDirty())
     182            continue;
     183        // Layout our child to compute its preferred logical height.
     184        child->layoutIfNeeded();
     185        if (childMathMLBlock)
     186            childMathMLBlock->setPreferredLogicalHeight(childMathMLBlock->logicalHeight());
     187    }
     188}
     189
     190LayoutUnit RenderMathMLBlock::preferredLogicalHeightAfterSizing(RenderObject* child)
     191{
     192    if (child->isRenderMathMLBlock())
     193        return toRenderMathMLBlock(child)->preferredLogicalHeight();
     194    if (child->isBox()) {
     195        ASSERT(!child->needsLayout());
     196        return toRenderBox(child)->logicalHeight();
     197    }
     198    return child->style()->fontSize();
    158199}
    159200
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.h

    r113823 r115895  
    5555    // https://bugs.webkit.org/show_bug.cgi?id=78617.
    5656    virtual RenderMathMLOperator* unembellishedOperator() { return 0; }
    57     virtual void stretchToHeight(int height);
    5857
    5958    virtual LayoutUnit paddingTop() const OVERRIDE;
     
    6564    virtual LayoutUnit paddingStart() const OVERRIDE;
    6665    virtual LayoutUnit paddingEnd() const OVERRIDE;
     66   
     67    // A MathML element's preferred logical widths often depend on its children's preferred heights, not just their widths.
     68    // This is due to operator stretching and other layout fine tuning. We define an element's preferred height to be its
     69    // actual height after layout inside a very wide parent.
     70    bool isPreferredLogicalHeightDirty() const { return preferredLogicalWidthsDirty() || m_preferredLogicalHeight < 0; }
     71    // The caller must ensure !isPreferredLogicalHeightDirty().
     72    LayoutUnit preferredLogicalHeight() const { ASSERT(!isPreferredLogicalHeightDirty()); return m_preferredLogicalHeight; }
     73    static const int preferredLogicalHeightUnset = -1;
     74    void setPreferredLogicalHeight(LayoutUnit logicalHeight) { m_preferredLogicalHeight = logicalHeight; }
     75    // computePreferredLogicalWidths() in derived classes must ensure m_preferredLogicalHeight is set to < 0 or its correct value.
     76    virtual void computePreferredLogicalWidths() OVERRIDE;
    6777   
    6878#if ENABLE(DEBUG_MATH_LAYOUT)
     
    98108   
    99109protected:
     110    // Set our logical width to a large value, and compute our children's preferred logical heights.
     111    void computeChildrenPreferredLogicalHeights();
     112    // This can only be called after children have been sized by computeChildrenPreferredLogicalHeights().
     113    static LayoutUnit preferredLogicalHeightAfterSizing(RenderObject* child);
     114   
    100115    int m_intrinsicPaddingBefore;
    101116    int m_intrinsicPaddingAfter;
    102117    int m_intrinsicPaddingStart;
    103118    int m_intrinsicPaddingEnd;
     119   
     120    // m_preferredLogicalHeight is dirty if it's < 0 or preferredLogicalWidthsDirty().
     121    LayoutUnit m_preferredLogicalHeight;
    104122};
    105123
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp

    r114975 r115895  
    6363void RenderMathMLOperator::stretchToHeight(int height)
    6464{
    65     if (height == m_stretchHeight)
     65    height *= gOperatorExpansion;
     66    if (m_stretchHeight == height)
    6667        return;
    67     m_stretchHeight = static_cast<int>(height * gOperatorExpansion);
    68    
    69     updateBoxModelInfoFromStyle();
    70     setNeedsLayout(true);
    71 }
    72 
    73 void RenderMathMLOperator::layout()
    74 {
    75     // FIXME: This probably shouldn't be called here but when the operator
    76     // isn't stretched (e.g. outside of a mrow), it needs to be called somehow
     68    m_stretchHeight = height;
     69   
    7770    updateFromElement();
    78     RenderBlock::layout();
     71}
     72
     73void RenderMathMLOperator::computePreferredLogicalWidths()
     74{
     75    ASSERT(preferredLogicalWidthsDirty());
     76   
     77    // Check for an uninitialized operator.
     78    if (!firstChild())
     79        updateFromElement();
     80   
     81    RenderMathMLBlock::computePreferredLogicalWidths();
    7982}
    8083
     
    313316        }
    314317    }
     318   
     319    setNeedsLayoutAndPrefWidthsRecalc();
    315320}
    316321
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h

    r114975 r115895  
    3939    RenderMathMLOperator(Node*, UChar operatorChar);
    4040    virtual bool isRenderMathMLOperator() const { return true; }
    41     virtual RenderMathMLOperator* unembellishedOperator() { return this; }
    42     virtual void stretchToHeight(int pixelHeight);
    43     virtual void updateFromElement();
     41   
    4442    virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
     43    virtual void updateFromElement() OVERRIDE;
     44   
     45    virtual RenderMathMLOperator* unembellishedOperator() OVERRIDE { return this; }
     46    void stretchToHeight(int pixelHeight);
     47   
    4548    virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
    4649       
    4750protected:
    48     virtual void layout();
    49     virtual PassRefPtr<RenderStyle> createStackableStyle(int lineHeight, int maxHeightForRenderer, int topRelative);
    50     virtual RenderBlock* createGlyph(UChar glyph, int lineHeight, int maxHeightForRenderer = 0, int charRelative = 0, int topRelative = 0);
     51    virtual void computePreferredLogicalWidths() OVERRIDE;
     52    PassRefPtr<RenderStyle> createStackableStyle(int lineHeight, int maxHeightForRenderer, int topRelative);
     53    RenderBlock* createGlyph(UChar glyph, int lineHeight, int maxHeightForRenderer = 0, int charRelative = 0, int topRelative = 0);
    5154   
    5255private:
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp

    r113749 r115895  
    5353}
    5454
    55 void RenderMathMLRow::layout()
     55void RenderMathMLRow::computePreferredLogicalWidths()
    5656{
    57     RenderBlock::layout();
     57    ASSERT(preferredLogicalWidthsDirty() && needsLayout());
    5858   
    59     int maxHeight = 0;
    60 
    61     // Calculate the non-operator max height of the row.
    62     for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
    63         if (current->isRenderMathMLBlock()) {
    64             RenderMathMLBlock* block = toRenderMathMLBlock(current);
    65             if (!block->unembellishedOperator() && block->offsetHeight() > maxHeight)
    66                 maxHeight = block->offsetHeight();
    67         } else if (current->isBoxModelObject()) {
    68             RenderBoxModelObject* box = toRenderBoxModelObject(current);
    69             // Check to see if this box has a larger height.
    70             if (box->pixelSnappedOffsetHeight() > maxHeight)
    71                 maxHeight = box->pixelSnappedOffsetHeight();
     59    computeChildrenPreferredLogicalHeights();
     60    int stretchLogicalHeight = 0;
     61    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     62        if (child->isRenderMathMLBlock()) {
     63            RenderMathMLOperator* renderMo = toRenderMathMLBlock(child)->unembellishedOperator();
     64            // FIXME: Only skip renderMo if it is stretchy.
     65            if (renderMo)
     66                continue;
     67        }
     68        stretchLogicalHeight = max<int>(stretchLogicalHeight, roundToInt(preferredLogicalHeightAfterSizing(child)));
     69    }
     70    if (!stretchLogicalHeight)
     71        stretchLogicalHeight = style()->fontSize();
     72   
     73    // Set the sizes of (possibly embellished) stretchy operator children.
     74    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     75        if (child->isRenderMathMLBlock()) {
     76            RenderMathMLOperator* renderMo = toRenderMathMLBlock(child)->unembellishedOperator();
     77            if (renderMo)
     78                renderMo->stretchToHeight(stretchLogicalHeight);
    7279        }
    7380    }
    7481   
    75     if (!maxHeight)
    76         maxHeight = style()->fontSize();
     82    RenderMathMLBlock::computePreferredLogicalWidths();
    7783   
    78     // Stretch everything to the same height (blocks can ignore the request).
    79     if (maxHeight > 0) {
    80         bool didStretch = false;
    81         for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
    82             if (current->isRenderMathMLBlock()) {
    83                 RenderMathMLBlock* block = toRenderMathMLBlock(current);
    84                 block->stretchToHeight(maxHeight);
    85                 didStretch = true;
    86             }
    87         }
    88         if (didStretch) {
    89             setNeedsLayout(true);
    90             setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
    91             RenderBlock::layout();
    92         }
    93     }
     84    // Shrink our logical width to its probable value now without triggering unnecessary relayout of our children.
     85    ASSERT(needsLayout() && logicalWidth() >= maxPreferredLogicalWidth());
     86    setLogicalWidth(maxPreferredLogicalWidth());
     87}
     88
     89void RenderMathMLRow::layout()
     90{
     91    // Our computePreferredLogicalWidths() may change our logical width and then layout our children, which
     92    // RenderBlock::layout()'s relayoutChildren logic isn't expecting.
     93    if (preferredLogicalWidthsDirty())
     94        computePreferredLogicalWidths();
    9495   
    95 }   
    96    
     96    RenderMathMLBlock::layout();
     97}
     98
    9799}
    98100
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLRow.h

    r113749 r115895  
    4040    virtual bool isRenderMathMLRow() const { return true; }
    4141   
    42     virtual void stretchToHeight(int) {}
     42protected:
     43    // This also sets our stretchy embellished operator children to their correct sizes.
     44    virtual void computePreferredLogicalWidths() OVERRIDE;
    4345   
    44 protected:
    4546    virtual void layout();
    4647
     
    4849    virtual const char* renderName() const { return isAnonymous() ? "RenderMathMLRow (anonymous)" : "RenderMathMLRow"; }
    4950};
    50    
     51
    5152}
    5253
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp

    r112425 r115895  
    118118}
    119119
    120 void RenderMathMLSubSup::stretchToHeight(int height)
    121 {
    122     RenderBoxModelObject* base = this->base();
    123     if (base && base->isRenderMathMLBlock())
    124         toRenderMathMLBlock(base)->stretchToHeight(height);
    125 }
    126 
    127120void RenderMathMLSubSup::layout()
    128121{
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h

    r111636 r115895  
    4040   
    4141    virtual RenderMathMLOperator* unembellishedOperator();
    42     virtual void stretchToHeight(int pixelHeight);
    4342
    4443protected:
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp

    r111083 r115895  
    134134}
    135135
    136 void RenderMathMLUnderOver::stretchToHeight(int height)
    137 {
    138     RenderBoxModelObject* base = this->base();
    139     if (base && base->isRenderMathMLBlock()) {
    140         RenderMathMLBlock* block = toRenderMathMLBlock(base);
    141         block->stretchToHeight(height);
    142         setNeedsLayout(true);
    143     }
    144 }
    145 
    146136void RenderMathMLUnderOver::layout()
    147137{
  • trunk/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h

    r108249 r115895  
    4141    virtual void layout();
    4242    virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
    43     virtual void stretchToHeight(int pixelHeight);
    4443   
    4544private:
Note: See TracChangeset for help on using the changeset viewer.