| Index: Source/core/rendering/mathml/RenderMathMLOperator.cpp
|
| diff --git a/Source/core/rendering/mathml/RenderMathMLOperator.cpp b/Source/core/rendering/mathml/RenderMathMLOperator.cpp
|
| deleted file mode 100644
|
| index 84f058efd22c3703e70586846fb49516408c2861..0000000000000000000000000000000000000000
|
| --- a/Source/core/rendering/mathml/RenderMathMLOperator.cpp
|
| +++ /dev/null
|
| @@ -1,336 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
|
| - * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions
|
| - * are met:
|
| - * 1. Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * 2. Redistributions in binary form must reproduce the above copyright
|
| - * notice, this list of conditions and the following disclaimer in the
|
| - * documentation and/or other materials provided with the distribution.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "config.h"
|
| -
|
| -#if ENABLE(MATHML)
|
| -
|
| -#include "core/rendering/mathml/RenderMathMLOperator.h"
|
| -
|
| -#include "MathMLNames.h"
|
| -#include "core/platform/graphics/FontCache.h"
|
| -#include "core/platform/graphics/FontSelector.h"
|
| -#include "core/rendering/RenderText.h"
|
| -
|
| -namespace WebCore {
|
| -
|
| -using namespace MathMLNames;
|
| -
|
| -RenderMathMLOperator::RenderMathMLOperator(Element* element)
|
| - : RenderMathMLBlock(element)
|
| - , m_stretchHeight(0)
|
| - , m_operator(0)
|
| - , m_operatorType(Default)
|
| -{
|
| -}
|
| -
|
| -RenderMathMLOperator::RenderMathMLOperator(Element* element, UChar operatorChar)
|
| - : RenderMathMLBlock(element)
|
| - , m_stretchHeight(0)
|
| - , m_operator(convertHyphenMinusToMinusSign(operatorChar))
|
| - , m_operatorType(Default)
|
| -{
|
| -}
|
| -
|
| -bool RenderMathMLOperator::isChildAllowed(RenderObject*, RenderStyle*) const
|
| -{
|
| - return false;
|
| -}
|
| -
|
| -static const float gOperatorExpansion = 1.2f;
|
| -
|
| -void RenderMathMLOperator::stretchToHeight(int height)
|
| -{
|
| - height *= gOperatorExpansion;
|
| - if (m_stretchHeight == height)
|
| - return;
|
| - m_stretchHeight = height;
|
| -
|
| - updateFromElement();
|
| -}
|
| -
|
| -void RenderMathMLOperator::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
|
| -{
|
| - RenderMathMLBlock::styleDidChange(diff, oldStyle);
|
| -
|
| - if (firstChild())
|
| - updateFromElement();
|
| -}
|
| -
|
| -void RenderMathMLOperator::computePreferredLogicalWidths()
|
| -{
|
| - ASSERT(preferredLogicalWidthsDirty());
|
| -
|
| -#ifndef NDEBUG
|
| - // FIXME: Remove this once mathml stops modifying the render tree here.
|
| - SetLayoutNeededForbiddenScope layoutForbiddenScope(this, false);
|
| -#endif
|
| -
|
| - // Check for an uninitialized operator.
|
| - if (!firstChild())
|
| - updateFromElement();
|
| -
|
| - RenderMathMLBlock::computePreferredLogicalWidths();
|
| -}
|
| -
|
| -// This is a table of stretchy characters.
|
| -// FIXME: Should this be read from the unicode characteristics somehow?
|
| -// table: stretchy operator, top char, extension char, bottom char, middle char
|
| -static struct StretchyCharacter {
|
| - UChar character;
|
| - UChar topGlyph;
|
| - UChar extensionGlyph;
|
| - UChar bottomGlyph;
|
| - UChar middleGlyph;
|
| -} stretchyCharacters[13] = {
|
| - { 0x28 , 0x239b, 0x239c, 0x239d, 0x0 }, // left parenthesis
|
| - { 0x29 , 0x239e, 0x239f, 0x23a0, 0x0 }, // right parenthesis
|
| - { 0x5b , 0x23a1, 0x23a2, 0x23a3, 0x0 }, // left square bracket
|
| - { 0x2308, 0x23a1, 0x23a2, 0x23a2, 0x0 }, // left ceiling
|
| - { 0x230a, 0x23a2, 0x23a2, 0x23a3, 0x0 }, // left floor
|
| - { 0x5d , 0x23a4, 0x23a5, 0x23a6, 0x0 }, // right square bracket
|
| - { 0x2309, 0x23a4, 0x23a5, 0x23a5, 0x0 }, // right ceiling
|
| - { 0x230b, 0x23a5, 0x23a5, 0x23a6, 0x0 }, // right floor
|
| - { 0x7b , 0x23a7, 0x23aa, 0x23a9, 0x23a8 }, // left curly bracket
|
| - { 0x7c , 0x23aa, 0x23aa, 0x23aa, 0x0 }, // vertical bar
|
| - { 0x2016, 0x2016, 0x2016, 0x2016, 0x0 }, // double vertical line
|
| - { 0x7d , 0x23ab, 0x23aa, 0x23ad, 0x23ac }, // right curly bracket
|
| - { 0x222b, 0x2320, 0x23ae, 0x2321, 0x0 } // integral sign
|
| -};
|
| -
|
| -// Note glyphHeightForCharacter truncates its result to an int.
|
| -int RenderMathMLOperator::glyphHeightForCharacter(UChar character)
|
| -{
|
| - GlyphData data = style()->font().glyphDataForCharacter(character, false);
|
| - FloatRect glyphBounds = data.fontData->boundsForGlyph(data.glyph);
|
| - return glyphBounds.height();
|
| -}
|
| -
|
| -// FIXME: It's cleaner to only call updateFromElement when an attribute has changed. The body of
|
| -// this method should probably be moved to a private stretchHeightChanged or checkStretchHeight
|
| -// method. Probably at the same time, addChild/removeChild methods should be made to work for
|
| -// dynamic DOM changes.
|
| -void RenderMathMLOperator::updateFromElement()
|
| -{
|
| - RenderObject* savedRenderer = node()->renderer();
|
| -
|
| - // Destroy our current children
|
| - children()->destroyLeftoverChildren();
|
| -
|
| - // Since we share a node with our children, destroying our children may set our node's
|
| - // renderer to 0, so we need to restore it.
|
| - node()->setRenderer(savedRenderer);
|
| -
|
| - // If the operator is fixed, it will be contained in m_operator
|
| - UChar firstChar = m_operator;
|
| -
|
| - // This boolean indicates whether stretching is disabled via the markup.
|
| - bool stretchDisabled = false;
|
| -
|
| - // We may need the element later if we can't stretch.
|
| - if (node()->isElementNode()) {
|
| - if (Element* mo = toElement(node())) {
|
| - AtomicString stretchyAttr = mo->getAttribute(MathMLNames::stretchyAttr);
|
| - stretchDisabled = equalIgnoringCase(stretchyAttr, "false");
|
| -
|
| - // If stretching isn't disabled, get the character from the text content.
|
| - if (!stretchDisabled && !firstChar) {
|
| - String opText = mo->textContent();
|
| - for (unsigned int i = 0; !firstChar && i < opText.length(); i++) {
|
| - if (!isSpaceOrNewline(opText[i]))
|
| - firstChar = opText[i];
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - // The 'index' holds the stretchable character's glyph information
|
| - int index = -1;
|
| -
|
| - // isStretchy indicates whether the character is streatchable via a number of factors.
|
| - bool isStretchy = false;
|
| -
|
| - // Check for a stretchable character.
|
| - if (!stretchDisabled && firstChar) {
|
| - const int maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters);
|
| - for (index++; index < maxIndex; index++) {
|
| - if (stretchyCharacters[index].character == firstChar) {
|
| - isStretchy = true;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // We only stack glyphs if the stretch height is larger than a minimum size.
|
| - bool shouldStack = isStretchy && m_stretchHeight > style()->fontSize();
|
| - struct StretchyCharacter* partsData = 0;
|
| - int topGlyphHeight = 0;
|
| - int extensionGlyphHeight = 0;
|
| - int bottomGlyphHeight = 0;
|
| - int middleGlyphHeight = 0;
|
| - if (shouldStack) {
|
| - partsData = &stretchyCharacters[index];
|
| -
|
| - FontCachePurgePreventer fontCachePurgePreventer;
|
| -
|
| - topGlyphHeight = glyphHeightForCharacter(partsData->topGlyph);
|
| - extensionGlyphHeight = glyphHeightForCharacter(partsData->extensionGlyph) - 1;
|
| - bottomGlyphHeight = glyphHeightForCharacter(partsData->bottomGlyph);
|
| - if (partsData->middleGlyph)
|
| - middleGlyphHeight = glyphHeightForCharacter(partsData->middleGlyph) - 1;
|
| - shouldStack = m_stretchHeight >= topGlyphHeight + middleGlyphHeight + bottomGlyphHeight && extensionGlyphHeight > 0;
|
| - }
|
| -
|
| - // Either stretch is disabled or we don't have a stretchable character over the minimum height
|
| - if (stretchDisabled || !shouldStack) {
|
| - m_isStacked = false;
|
| - RenderBlock* container = new (renderArena()) RenderMathMLBlock(toElement(node()));
|
| - // This container doesn't offer any useful information to accessibility.
|
| - toRenderMathMLBlock(container)->setIgnoreInAccessibilityTree(true);
|
| -
|
| - RefPtr<RenderStyle> newStyle = RenderStyle::create();
|
| - newStyle->inheritFrom(style());
|
| - newStyle->setDisplay(FLEX);
|
| -
|
| - // Check for a stretchable character that is under the minimum height.
|
| - if (!stretchDisabled && isStretchy && m_stretchHeight > style()->fontSize()) {
|
| - FontDescription desc = style()->fontDescription();
|
| - desc.setIsAbsoluteSize(true);
|
| - desc.setSpecifiedSize(m_stretchHeight);
|
| - desc.setComputedSize(m_stretchHeight);
|
| - newStyle->setFontDescription(desc);
|
| - newStyle->font().update(style()->font().fontSelector());
|
| - }
|
| -
|
| - container->setStyle(newStyle.release());
|
| - addChild(container);
|
| -
|
| - // Build the text of the operator.
|
| - RenderText* text = 0;
|
| - if (m_operator)
|
| - text = new (renderArena()) RenderText(node(), StringImpl::create(&m_operator, 1));
|
| - else if (node()->isElementNode())
|
| - if (Element* mo = toElement(node()))
|
| - text = new (renderArena()) RenderText(node(), mo->textContent().replace(hyphenMinus, minusSign).impl());
|
| - // If we can't figure out the text, leave it blank.
|
| - if (text) {
|
| - RefPtr<RenderStyle> textStyle = RenderStyle::create();
|
| - textStyle->inheritFrom(container->style());
|
| - text->setStyle(textStyle.release());
|
| - container->addChild(text);
|
| - }
|
| - } else {
|
| - // Build stretchable characters as a stack of glyphs.
|
| - m_isStacked = true;
|
| -
|
| - // To avoid gaps, we position glyphs after the top glyph upward by 1px. We also truncate
|
| - // glyph heights to ints, and then reduce all but the top & bottom such heights by 1px.
|
| -
|
| - int remaining = m_stretchHeight - topGlyphHeight - bottomGlyphHeight;
|
| - createGlyph(partsData->topGlyph, topGlyphHeight, 0);
|
| - if (partsData->middleGlyph) {
|
| - // We have a middle glyph (e.g. a curly bracket) that requires special processing.
|
| - remaining -= middleGlyphHeight;
|
| - int half = (remaining + 1) / 2;
|
| - remaining -= half;
|
| - while (remaining > 0) {
|
| - int height = std::min<int>(remaining, extensionGlyphHeight);
|
| - createGlyph(partsData->extensionGlyph, height, -1);
|
| - remaining -= height;
|
| - }
|
| -
|
| - // The middle glyph in the stack.
|
| - createGlyph(partsData->middleGlyph, middleGlyphHeight, -1);
|
| -
|
| - remaining = half;
|
| - while (remaining > 0) {
|
| - int height = std::min<int>(remaining, extensionGlyphHeight);
|
| - createGlyph(partsData->extensionGlyph, height, -1);
|
| - remaining -= height;
|
| - }
|
| - } else {
|
| - // We do not have a middle glyph and so we just extend from the top to the bottom glyph.
|
| - while (remaining > 0) {
|
| - int height = std::min<int>(remaining, extensionGlyphHeight);
|
| - createGlyph(partsData->extensionGlyph, height, -1);
|
| - remaining -= height;
|
| - }
|
| - }
|
| - createGlyph(partsData->bottomGlyph, bottomGlyphHeight, -1);
|
| - }
|
| -
|
| - setNeedsLayoutAndPrefWidthsRecalc();
|
| -}
|
| -
|
| -PassRefPtr<RenderStyle> RenderMathMLOperator::createStackableStyle(int maxHeightForRenderer)
|
| -{
|
| - RefPtr<RenderStyle> newStyle = RenderStyle::create();
|
| - newStyle->inheritFrom(style());
|
| - newStyle->setDisplay(FLEX);
|
| -
|
| - newStyle->setMaxHeight(Length(maxHeightForRenderer, Fixed));
|
| -
|
| - newStyle->setOverflowY(OHIDDEN);
|
| - newStyle->setOverflowX(OHIDDEN);
|
| -
|
| - return newStyle.release();
|
| -}
|
| -
|
| -RenderBlock* RenderMathMLOperator::createGlyph(UChar glyph, int maxHeightForRenderer, int charRelative)
|
| -{
|
| - RenderBlock* container = new (renderArena()) RenderMathMLBlock(toElement(node()));
|
| - toRenderMathMLBlock(container)->setIgnoreInAccessibilityTree(true);
|
| - container->setStyle(createStackableStyle(maxHeightForRenderer));
|
| - addChild(container);
|
| - RenderBlock* parent = container;
|
| - if (charRelative) {
|
| - RenderBlock* charBlock = new (renderArena()) RenderBlock(node());
|
| - RefPtr<RenderStyle> charStyle = RenderStyle::create();
|
| - charStyle->inheritFrom(container->style());
|
| - charStyle->setDisplay(INLINE_BLOCK);
|
| - charStyle->setTop(Length(charRelative, Fixed));
|
| - charStyle->setPosition(RelativePosition);
|
| - charBlock->setStyle(charStyle);
|
| - parent->addChild(charBlock);
|
| - parent = charBlock;
|
| - }
|
| -
|
| - RenderText* text = new (renderArena()) RenderText(node(), StringImpl::create(&glyph, 1));
|
| - text->setStyle(container->style());
|
| - parent->addChild(text);
|
| - return container;
|
| -}
|
| -
|
| -int RenderMathMLOperator::firstLineBoxBaseline() const
|
| -{
|
| - if (m_isStacked)
|
| - return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;
|
| - return RenderMathMLBlock::firstLineBoxBaseline();
|
| -}
|
| -
|
| -}
|
| -
|
| -#endif
|
|
|