WebCore/mathml/RenderMathMLRow.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    14  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    15  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    16  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    17  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    24  */
       
    25 
       
    26 #include "config.h"
       
    27 
       
    28 #if ENABLE(MATHML)
       
    29 
       
    30 #include "RenderMathMLRow.h"
       
    31 
       
    32 #include "MathMLNames.h"
       
    33 #include "RenderMathMLOperator.h"
       
    34 
       
    35 namespace WebCore {
       
    36 
       
    37 using namespace MathMLNames;
       
    38 
       
    39 RenderMathMLRow::RenderMathMLRow(Node* row)
       
    40     : RenderMathMLBlock(row)
       
    41 {
       
    42 }
       
    43 
       
    44 int RenderMathMLRow::nonOperatorHeight() const
       
    45 {
       
    46     int maxHeight = 0;
       
    47     for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
       
    48         if (current->isRenderMathMLBlock()) {
       
    49             RenderMathMLBlock* block = toRenderMathMLBlock(current);
       
    50             int blockHeight = block->nonOperatorHeight();
       
    51             // Check to see if this box has a larger height
       
    52             if (blockHeight > maxHeight)
       
    53                 maxHeight = blockHeight;
       
    54         } else if (current->isBoxModelObject()) {
       
    55             RenderBoxModelObject* box = toRenderBoxModelObject(current);
       
    56             // Check to see if this box has a larger height
       
    57             if (box->offsetHeight() > maxHeight)
       
    58                 maxHeight = box->offsetHeight();
       
    59         }
       
    60         
       
    61     }
       
    62     return maxHeight;
       
    63 }
       
    64 
       
    65 void RenderMathMLRow::layout() 
       
    66 {
       
    67     RenderBlock::layout();
       
    68     
       
    69     // Calculate the maximum height of the row without the operators.
       
    70     int maxHeight = nonOperatorHeight();
       
    71     
       
    72     // Notify contained operators they may need to re-layout their stretched operators.
       
    73     // We need to keep track of the number of children and operators because a row of
       
    74     // operators needs some special handling.
       
    75     int childCount = 0;
       
    76     int operatorCount = 0;
       
    77     for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
       
    78         childCount++;
       
    79         if (current->isRenderMathMLBlock()) {
       
    80             RenderMathMLBlock* block = toRenderMathMLBlock(current);
       
    81             block->stretchToHeight(maxHeight);
       
    82             if (block->isRenderMathMLOperator()) 
       
    83                 operatorCount++;
       
    84         }
       
    85     }
       
    86     
       
    87     // Layout the non-operators which have just been stretched.
       
    88     setNeedsLayoutAndPrefWidthsRecalc();
       
    89     markContainingBlocksForLayout();
       
    90     RenderBlock::layout();
       
    91 
       
    92     // Make a second pass with the real height of the operators.
       
    93     int operatorHeight = 0;
       
    94     for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
       
    95         if (current->isRenderMathMLBlock()) {
       
    96             RenderMathMLBlock* block = toRenderMathMLBlock(current);
       
    97             if (!block->hasBase() && !block->isRenderMathMLOperator()) {
       
    98                 // Check to see if this box has a larger height.
       
    99                 if (block->offsetHeight() > maxHeight)
       
   100                     maxHeight = block->offsetHeight();
       
   101             }
       
   102             if (block->isRenderMathMLOperator())
       
   103                 if (block->offsetHeight() > operatorHeight)
       
   104                     operatorHeight = block->offsetHeight();
       
   105         } else if (current->isBoxModelObject()) {
       
   106             RenderBoxModelObject* box = toRenderBoxModelObject(current);
       
   107             // Check to see if this box has a larger height.
       
   108             if (box->offsetHeight() > maxHeight)
       
   109                 maxHeight = box->offsetHeight();
       
   110         }
       
   111     }
       
   112     
       
   113     if (childCount > 0 && childCount == operatorCount) {
       
   114         // We have only operators and so set the max height to the operator height.
       
   115         maxHeight = operatorHeight;
       
   116     }
       
   117     
       
   118     int stretchHeight = maxHeight;
       
   119     
       
   120     // Stretch the operators again and re-calculate the row height.
       
   121     for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
       
   122         if (current->isRenderMathMLBlock()) {
       
   123             RenderMathMLBlock* block = toRenderMathMLBlock(current);
       
   124             if (block->isRenderMathMLOperator()) {
       
   125                 RenderMathMLOperator* mathop = toRenderMathMLOperator(block);
       
   126                 mathop->stretchToHeight(stretchHeight);
       
   127             } else {
       
   128                 block->stretchToHeight(stretchHeight);
       
   129                 RenderBoxModelObject* box = toRenderBoxModelObject(current);
       
   130                 // Check to see if this box has a larger height
       
   131                 if (box->offsetHeight() > maxHeight)
       
   132                     maxHeight = box->offsetHeight();
       
   133             }
       
   134         } else if (current->isBoxModelObject()) {
       
   135             RenderBoxModelObject* box = toRenderBoxModelObject(current);
       
   136             // Check to see if this box has a larger height
       
   137             if (box->offsetHeight() > maxHeight)
       
   138                 maxHeight = box->offsetHeight();
       
   139         }
       
   140     }
       
   141     
       
   142     // Mark outself as needing layout and do the final layout of the row.
       
   143     setNeedsLayoutAndPrefWidthsRecalc();
       
   144     markContainingBlocksForLayout();
       
   145     RenderBlock::layout();
       
   146 }    
       
   147 
       
   148 int RenderMathMLRow::baselinePosition(bool firstLine, bool isRootLineBox) const
       
   149 {
       
   150     if (firstChild() && firstChild()->isRenderMathMLBlock()) {
       
   151         RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
       
   152         if (block->isRenderMathMLOperator())
       
   153             return block->baselinePosition(firstLine, isRootLineBox);
       
   154     }
       
   155     
       
   156     return RenderBlock::baselinePosition(firstLine, isRootLineBox);
       
   157 }
       
   158     
       
   159 }
       
   160 
       
   161 #endif // ENABLE(MATHML)
       
   162