1/* 2 * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved. 3 * Copyright (C) 2012 David Barton (dbarton@mathscribe.com). All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28 29#if ENABLE(MATHML) 30 31#include "RenderMathMLBlock.h" 32 33#include "GraphicsContext.h" 34#include "MathMLNames.h" 35#include "RenderView.h" 36 37#if ENABLE(DEBUG_MATH_LAYOUT) 38#include "PaintInfo.h" 39#endif 40 41namespace WebCore { 42 43using namespace MathMLNames; 44 45RenderMathMLBlock::RenderMathMLBlock(Element* container) 46 : RenderFlexibleBox(container) 47 , m_ignoreInAccessibilityTree(false) 48{ 49} 50 51bool RenderMathMLBlock::isChildAllowed(RenderObject* child, RenderStyle*) const 52{ 53 return child->node() && child->node()->nodeType() == Node::ELEMENT_NODE; 54} 55 56RenderMathMLBlock* RenderMathMLBlock::createAnonymousMathMLBlock(EDisplay display) 57{ 58 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), display); 59 RenderMathMLBlock* newBlock = new (renderArena()) RenderMathMLBlock(0); 60 newBlock->setDocumentForAnonymous(document()); 61 newBlock->setStyle(newStyle.release()); 62 return newBlock; 63} 64 65int RenderMathMLBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const 66{ 67 // mathml.css sets math { -webkit-line-box-contain: glyphs replaced; line-height: 0; }, so when linePositionMode == PositionOfInteriorLineBoxes we want to 68 // return 0 here to match our line-height. This matters when RootInlineBox::ascentAndDescentForBox is called on a RootInlineBox for an inline-block. 69 if (linePositionMode == PositionOfInteriorLineBoxes) 70 return 0; 71 72 LayoutUnit baseline = firstLineBoxBaseline(); // FIXME: This may be unnecessary after flex baselines are implemented (https://bugs.webkit.org/show_bug.cgi?id=96188). 73 if (baseline != -1) 74 return baseline; 75 76 return RenderFlexibleBox::baselinePosition(baselineType, firstLine, direction, linePositionMode); 77} 78 79const char* RenderMathMLBlock::renderName() const 80{ 81 EDisplay display = style()->display(); 82 if (display == FLEX) 83 return isAnonymous() ? "RenderMathMLBlock (anonymous, flex)" : "RenderMathMLBlock (flex)"; 84 if (display == INLINE_FLEX) 85 return isAnonymous() ? "RenderMathMLBlock (anonymous, inline-flex)" : "RenderMathMLBlock (inline-flex)"; 86 // |display| should be one of the above. 87 ASSERT_NOT_REACHED(); 88 return isAnonymous() ? "RenderMathMLBlock (anonymous)" : "RenderMathMLBlock"; 89} 90 91#if ENABLE(DEBUG_MATH_LAYOUT) 92void RenderMathMLBlock::paint(PaintInfo& info, const LayoutPoint& paintOffset) 93{ 94 RenderFlexibleBox::paint(info, paintOffset); 95 96 if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground) 97 return; 98 99 IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location()); 100 101 GraphicsContextStateSaver stateSaver(*info.context); 102 103 info.context->setStrokeThickness(1.0f); 104 info.context->setStrokeStyle(SolidStroke); 105 info.context->setStrokeColor(Color(0, 0, 255), ColorSpaceSRGB); 106 107 info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y())); 108 info.context->drawLine(IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight())); 109 info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight())); 110 info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight())); 111 112 int topStart = paddingTop(); 113 114 info.context->setStrokeColor(Color(0, 255, 0), ColorSpaceSRGB); 115 116 info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + topStart), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + topStart)); 117 118 int baseline = roundToInt(baselinePosition(AlphabeticBaseline, true, HorizontalLine)); 119 120 info.context->setStrokeColor(Color(255, 0, 0), ColorSpaceSRGB); 121 122 info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + baseline), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + baseline)); 123} 124#endif // ENABLE(DEBUG_MATH_LAYOUT) 125 126int RenderMathMLTable::firstLineBoxBaseline() const 127{ 128 // In legal MathML, we'll have a MathML parent. That RenderFlexibleBox parent will use our firstLineBoxBaseline() for baseline alignment, per 129 // http://dev.w3.org/csswg/css3-flexbox/#flex-baselines. We want to vertically center an <mtable>, such as a matrix. Essentially the whole <mtable> element fits on a 130 // single line, whose baseline gives this centering. This is different than RenderTable::firstLineBoxBaseline, which returns the baseline of the first row of a <table>. 131 return (logicalHeight() + style()->fontMetrics().xHeight()) / 2; 132} 133 134} 135 136#endif 137