RenderMathMLBlock.cpp [plain text]
#include "config.h"
#if ENABLE(MATHML)
#include "RenderMathMLBlock.h"
#include "GraphicsContext.h"
#include "MathMLNames.h"
#if ENABLE(DEBUG_MATH_LAYOUT)
#include "PaintInfo.h"
#endif
namespace WebCore {
using namespace MathMLNames;
RenderMathMLBlock::RenderMathMLBlock(Node* container)
: RenderBlock(container)
, m_intrinsicPaddingBefore(0)
, m_intrinsicPaddingAfter(0)
, m_intrinsicPaddingStart(0)
, m_intrinsicPaddingEnd(0)
, m_preferredLogicalHeight(preferredLogicalHeightUnset)
{
}
bool RenderMathMLBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
{
return child->node() && child->node()->nodeType() == Node::ELEMENT_NODE;
}
LayoutUnit RenderMathMLBlock::paddingTop() const
{
LayoutUnit result = computedCSSPaddingTop();
switch (style()->writingMode()) {
case TopToBottomWritingMode:
return result + m_intrinsicPaddingBefore;
case BottomToTopWritingMode:
return result + m_intrinsicPaddingAfter;
case LeftToRightWritingMode:
case RightToLeftWritingMode:
return result + (style()->isLeftToRightDirection() ? m_intrinsicPaddingStart : m_intrinsicPaddingEnd);
}
ASSERT_NOT_REACHED();
return result;
}
LayoutUnit RenderMathMLBlock::paddingBottom() const
{
LayoutUnit result = computedCSSPaddingBottom();
switch (style()->writingMode()) {
case TopToBottomWritingMode:
return result + m_intrinsicPaddingAfter;
case BottomToTopWritingMode:
return result + m_intrinsicPaddingBefore;
case LeftToRightWritingMode:
case RightToLeftWritingMode:
return result + (style()->isLeftToRightDirection() ? m_intrinsicPaddingEnd : m_intrinsicPaddingStart);
}
ASSERT_NOT_REACHED();
return result;
}
LayoutUnit RenderMathMLBlock::paddingLeft() const
{
LayoutUnit result = computedCSSPaddingLeft();
switch (style()->writingMode()) {
case LeftToRightWritingMode:
return result + m_intrinsicPaddingBefore;
case RightToLeftWritingMode:
return result + m_intrinsicPaddingAfter;
case TopToBottomWritingMode:
case BottomToTopWritingMode:
return result + (style()->isLeftToRightDirection() ? m_intrinsicPaddingStart : m_intrinsicPaddingEnd);
}
ASSERT_NOT_REACHED();
return result;
}
LayoutUnit RenderMathMLBlock::paddingRight() const
{
LayoutUnit result = computedCSSPaddingRight();
switch (style()->writingMode()) {
case RightToLeftWritingMode:
return result + m_intrinsicPaddingBefore;
case LeftToRightWritingMode:
return result + m_intrinsicPaddingAfter;
case TopToBottomWritingMode:
case BottomToTopWritingMode:
return result + (style()->isLeftToRightDirection() ? m_intrinsicPaddingEnd : m_intrinsicPaddingStart);
}
ASSERT_NOT_REACHED();
return result;
}
LayoutUnit RenderMathMLBlock::paddingBefore() const
{
return computedCSSPaddingBefore() + m_intrinsicPaddingBefore;
}
LayoutUnit RenderMathMLBlock::paddingAfter() const
{
return computedCSSPaddingAfter() + m_intrinsicPaddingAfter;
}
LayoutUnit RenderMathMLBlock::paddingStart() const
{
return computedCSSPaddingStart() + m_intrinsicPaddingStart;
}
LayoutUnit RenderMathMLBlock::paddingEnd() const
{
return computedCSSPaddingEnd() + m_intrinsicPaddingEnd;
}
void RenderMathMLBlock::computePreferredLogicalWidths()
{
ASSERT(preferredLogicalWidthsDirty());
m_preferredLogicalHeight = preferredLogicalHeightUnset;
RenderBlock::computePreferredLogicalWidths();
}
RenderMathMLBlock* RenderMathMLBlock::createAlmostAnonymousBlock(EDisplay display)
{
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), display);
RenderMathMLBlock* newBlock = new (renderArena()) RenderMathMLBlock(node() );
newBlock->setStyle(newStyle.release());
return newBlock;
}
static const LayoutUnit cLargeLogicalWidth = 15000;
void RenderMathMLBlock::computeChildrenPreferredLogicalHeights()
{
ASSERT(needsLayout());
setNeedsLayout(true, MarkOnlyThis);
LayoutUnit oldAvailableLogicalWidth = availableLogicalWidth();
setLogicalWidth(cLargeLogicalWidth);
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (!child->isBox())
continue;
if (child->maxPreferredLogicalWidth() > oldAvailableLogicalWidth)
child->setNeedsLayout(true, MarkOnlyThis);
RenderMathMLBlock* childMathMLBlock = child->isRenderMathMLBlock() ? toRenderMathMLBlock(child) : 0;
if (childMathMLBlock && !childMathMLBlock->isPreferredLogicalHeightDirty())
continue;
child->layoutIfNeeded();
if (childMathMLBlock)
childMathMLBlock->setPreferredLogicalHeight(childMathMLBlock->logicalHeight());
}
}
LayoutUnit RenderMathMLBlock::preferredLogicalHeightAfterSizing(RenderObject* child)
{
if (child->isRenderMathMLBlock())
return toRenderMathMLBlock(child)->preferredLogicalHeight();
if (child->isBox()) {
ASSERT(!child->needsLayout());
return toRenderBox(child)->logicalHeight();
}
return child->style()->fontSize();
}
#if ENABLE(DEBUG_MATH_LAYOUT)
void RenderMathMLBlock::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
RenderBlock::paint(info, paintOffset);
if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground)
return;
IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
GraphicsContextStateSaver stateSaver(*info.context);
info.context->setStrokeThickness(1.0f);
info.context->setStrokeStyle(SolidStroke);
info.context->setStrokeColor(Color(0, 0, 255), ColorSpaceSRGB);
info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y()));
info.context->drawLine(IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + pixelSnappedOffsetHeight()));
int topStart = paddingTop();
info.context->setStrokeColor(Color(0, 255, 0), ColorSpaceSRGB);
info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + topStart), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + topStart));
int baseline = roundToInt(baselinePosition(AlphabeticBaseline, true, HorizontalLine));
info.context->setStrokeColor(Color(255, 0, 0), ColorSpaceSRGB);
info.context->drawLine(IntPoint(adjustedPaintOffset.x(), adjustedPaintOffset.y() + baseline), IntPoint(adjustedPaintOffset.x() + pixelSnappedOffsetWidth(), adjustedPaintOffset.y() + baseline));
}
#endif // ENABLE(DEBUG_MATH_LAYOUT)
}
#endif