1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/* 2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved. 3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Redistribution and use in source and binary forms, with or without 5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modification, are permitted provided that the following conditions 6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * are met: 7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 1. Redistributions of source code must retain the above copyright 8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * notice, this list of conditions and the following disclaimer. 9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 2. Redistributions in binary form must reproduce the above copyright 10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * notice, this list of conditions and the following disclaimer in the 11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * documentation and/or other materials provided with the distribution. 12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "config.h" 27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(MATHML) 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "RenderMathMLRow.h" 31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "MathMLNames.h" 33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "RenderMathMLOperator.h" 34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocknamespace WebCore { 36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockusing namespace MathMLNames; 38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockRenderMathMLRow::RenderMathMLRow(Node* row) 40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : RenderMathMLBlock(row) 41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockint RenderMathMLRow::nonOperatorHeight() const 45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int maxHeight = 0; 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (RenderObject* current = firstChild(); current; current = current->nextSibling()) { 48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (current->isRenderMathMLBlock()) { 49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderMathMLBlock* block = toRenderMathMLBlock(current); 50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int blockHeight = block->nonOperatorHeight(); 51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Check to see if this box has a larger height 52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (blockHeight > maxHeight) 53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block maxHeight = blockHeight; 54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (current->isBoxModelObject()) { 55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderBoxModelObject* box = toRenderBoxModelObject(current); 56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Check to see if this box has a larger height 57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (box->offsetHeight() > maxHeight) 58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block maxHeight = box->offsetHeight(); 59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return maxHeight; 63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderMathMLRow::layout() 66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderBlock::layout(); 68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 69e14391e94c850b8bd03680c23b38978db68687a8John Reck int maxHeight = 0; 70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int childCount = 0; 71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int operatorCount = 0; 72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 73e14391e94c850b8bd03680c23b38978db68687a8John Reck // Calculate the non-operator max height of the row. 74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int operatorHeight = 0; 75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (RenderObject* current = firstChild(); current; current = current->nextSibling()) { 76e14391e94c850b8bd03680c23b38978db68687a8John Reck childCount++; 77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (current->isRenderMathMLBlock()) { 78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderMathMLBlock* block = toRenderMathMLBlock(current); 79e14391e94c850b8bd03680c23b38978db68687a8John Reck // Check to see if the non-operator block has a greater height. 80e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!block->hasBase() && !block->isRenderMathMLOperator() && block->offsetHeight() > maxHeight) 81e14391e94c850b8bd03680c23b38978db68687a8John Reck maxHeight = block->offsetHeight(); 82e14391e94c850b8bd03680c23b38978db68687a8John Reck if (block->hasBase() && block->nonOperatorHeight() > maxHeight) 83e14391e94c850b8bd03680c23b38978db68687a8John Reck maxHeight = block->nonOperatorHeight(); 84e14391e94c850b8bd03680c23b38978db68687a8John Reck // If the block is an operator, capture the maximum height and increment the count. 85e14391e94c850b8bd03680c23b38978db68687a8John Reck if (block->isRenderMathMLOperator()) { 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (block->offsetHeight() > operatorHeight) 87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block operatorHeight = block->offsetHeight(); 88e14391e94c850b8bd03680c23b38978db68687a8John Reck operatorCount++; 89e14391e94c850b8bd03680c23b38978db68687a8John Reck } 90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (current->isBoxModelObject()) { 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderBoxModelObject* box = toRenderBoxModelObject(current); 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Check to see if this box has a larger height. 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (box->offsetHeight() > maxHeight) 94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block maxHeight = box->offsetHeight(); 95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (childCount > 0 && childCount == operatorCount) { 99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // We have only operators and so set the max height to the operator height. 100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block maxHeight = operatorHeight; 101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 103e14391e94c850b8bd03680c23b38978db68687a8John Reck // Stretch everything to the same height (blocks can ignore the request). 104e14391e94c850b8bd03680c23b38978db68687a8John Reck if (maxHeight > 0) { 105e14391e94c850b8bd03680c23b38978db68687a8John Reck bool didStretch = false; 106e14391e94c850b8bd03680c23b38978db68687a8John Reck for (RenderObject* current = firstChild(); current; current = current->nextSibling()) { 107e14391e94c850b8bd03680c23b38978db68687a8John Reck if (current->isRenderMathMLBlock()) { 108e14391e94c850b8bd03680c23b38978db68687a8John Reck RenderMathMLBlock* block = toRenderMathMLBlock(current); 109e14391e94c850b8bd03680c23b38978db68687a8John Reck block->stretchToHeight(maxHeight); 110e14391e94c850b8bd03680c23b38978db68687a8John Reck didStretch = true; 111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 112e14391e94c850b8bd03680c23b38978db68687a8John Reck } 113e14391e94c850b8bd03680c23b38978db68687a8John Reck if (didStretch) { 114e14391e94c850b8bd03680c23b38978db68687a8John Reck setNeedsLayout(true); 115e14391e94c850b8bd03680c23b38978db68687a8John Reck setPreferredLogicalWidthsDirty(true, false); 116e14391e94c850b8bd03680c23b38978db68687a8John Reck RenderBlock::layout(); 117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 12006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerint RenderMathMLRow::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 12306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{ 12406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (firstChild() && firstChild()->isRenderMathMLBlock()) { 12506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen RenderMathMLBlock* block = toRenderMathMLBlock(firstChild()); 12606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (block->isRenderMathMLOperator()) 1276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return block->y() + block->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode); 12806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 12906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 1306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode); 13106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} 13206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif // ENABLE(MATHML) 136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 137