+2012-05-14 David Barton <dbarton@mathscribe.com>
+
+ Unify RenderMathMLSquareRoot.cpp and RenderMathMLRoot.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=86319
+
+ Reviewed by Darin Adler.
+
+ * mathml/presentation/mroot-pref-width.html: Added.
+ * platform/mac/mathml/presentation/mroot-pref-width-expected.png: Added.
+ * platform/mac/mathml/presentation/mroot-pref-width-expected.txt: Added.
+
2012-05-14 Allan Sandfeld Jensen <allan.jensen@nokia.com>
Fixup: Two of the touch-adjustment tests are flaky
--- /dev/null
+<!DOCTYPE html>
+
+<p>The table cell border should go around the mroot, not through it:</p>
+<math>
+ <mtable>
+ <mtr>
+ <mtd style="border: solid">
+ <mroot>
+ <mi>x</mi>
+ <mn>1234567890</mn>
+ </mroot>
+ </mtd>
+ </mtr>
+ </mtable>
+</math>
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x84
+ RenderBlock {HTML} at (0,0) size 800x84
+ RenderBody {BODY} at (8,16) size 784x60
+ RenderBlock {P} at (0,0) size 784x18
+ RenderText {#text} at (0,0) size 405x18
+ text run at (0,0) width 405: "The table cell border should go around the mroot, not through it:"
+ RenderBlock (anonymous) at (0,34) size 784x26
+ RenderMathMLMath {math} at (0,0) size 87x26
+ RenderTable {mtable} at (1,0) size 85x26
+ RenderTableSection (anonymous) at (0,0) size 85x26
+ RenderTableRow {mtr} at (0,0) size 85x26
+ RenderTableCell {mtd} at (0,0) size 85x26 [border: (3px solid #000000)] [r=0 c=0 rs=1 cs=1]
+ RenderText {#text} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
+layer at (15,53) size 73x20
+ RenderMathMLRoot {mroot} at (6,3) size 73x20
+ RenderInline {mi} at (0,0) size 7x16
+ RenderText {#text} at (66,4) size 7x16
+ text run at (66,4) width 7: "x"
+layer at (15,53) size 66x14
+ RenderBlock (positioned) {mn} at (0,0) size 66x14
+ RenderText {#text} at (2,0) size 60x12
+ text run at (2,0) width 60: "1234567890"
+2012-05-14 David Barton <dbarton@mathscribe.com>
+
+ Unify RenderMathMLSquareRoot.cpp and RenderMathMLRoot.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=86319
+
+ Reviewed by Darin Adler.
+
+ Most of RenderMathMLSquareRoot.cpp is duplicated in RenderMathMLRoot.cpp and can be
+ eliminated. We also define RenderMathMLRoot::computePreferredLogicalWidths().
+
+ Test: mathml/presentation/mroot-pref-width.html
+
+ * rendering/mathml/RenderMathMLRoot.cpp:
+ (WebCore::RenderMathMLRoot::computePreferredLogicalWidths):
+ (WebCore::RenderMathMLRoot::layout):
+ (WebCore::RenderMathMLRoot::paint):
+ * rendering/mathml/RenderMathMLRoot.h:
+ * rendering/mathml/RenderMathMLSquareRoot.cpp:
+ (WebCore::RenderMathMLSquareRoot::RenderMathMLSquareRoot):
+ (WebCore::RenderMathMLSquareRoot::addChild):
+ * rendering/mathml/RenderMathMLSquareRoot.h:
+
2012-05-14 MORITA Hajime <morrita@google.com>
[Shadow DOM][Refactoring] HTMLContentSelector family should have better name
#include "RenderMathMLRoot.h"
#include "GraphicsContext.h"
-#include "MathMLNames.h"
#include "PaintInfo.h"
using namespace std;
namespace WebCore {
-using namespace MathMLNames;
-
// FIXME: This whole file should be changed to work with various writing modes. See https://bugs.webkit.org/show_bug.cgi?id=48951.
// Threshold above which the radical shape is modified to look nice with big bases (em)
const int gRadicalBottomPointLower = 3;
// Horizontal position of the top left point of the radical "dip" (* frontWidth)
const float gRadicalDipLeftPointXFront = 0.8f;
-// Vertical position of the top left point of the radical "dip" (* baseHeight)
-const float gRadicalDipLeftPointYPos = 0.625f;
+// Vertical position of the top left point of a sqrt radical "dip" (* baseHeight)
+const float gSqrtRadicalDipLeftPointYPos = 0.5f;
+// Vertical position of the top left point of an nth root radical "dip" (* baseHeight)
+const float gRootRadicalDipLeftPointYPos = 0.625f;
// Vertical shift of the left end point of the radical (em)
const float gRadicalLeftEndYShiftEms = 0.05f;
// Additional bottom root padding if baseHeight > threshold (em)
return toRenderBoxModelObject(index);
}
+void RenderMathMLRoot::computePreferredLogicalWidths()
+{
+ ASSERT(preferredLogicalWidthsDirty() && needsLayout());
+
+ computeChildrenPreferredLogicalHeights();
+
+ int baseHeight = firstChild() ? roundToInt(preferredLogicalHeightAfterSizing(firstChild())) : 0;
+
+ int frontWidth = lroundf(gFrontWidthEms * style()->fontSize());
+
+ // Base height above which the shape of the root changes
+ float thresholdHeight = gThresholdBaseHeightEms * style()->fontSize();
+ if (baseHeight > thresholdHeight && thresholdHeight) {
+ float shift = min<float>((baseHeight - thresholdHeight) / thresholdHeight, 1.0f);
+ m_overbarLeftPointShift = static_cast<int>(shift * gRadicalBottomPointXFront * frontWidth);
+ m_intrinsicPaddingAfter = lroundf(gBigRootBottomPaddingEms * style()->fontSize());
+ } else {
+ m_overbarLeftPointShift = 0;
+ m_intrinsicPaddingAfter = 0;
+ }
+
+ int rootPad = lroundf(gSpaceAboveEms * style()->fontSize());
+ m_intrinsicPaddingBefore = rootPad;
+ m_indexTop = 0;
+ if (RenderBoxModelObject* index = this->index()) {
+ m_intrinsicPaddingStart = roundToInt(index->maxPreferredLogicalWidth()) + m_overbarLeftPointShift;
+
+ int indexHeight = roundToInt(preferredLogicalHeightAfterSizing(index));
+ int partDipHeight = lroundf((1 - gRootRadicalDipLeftPointYPos) * baseHeight);
+ int rootExtraTop = partDipHeight + indexHeight - (baseHeight + rootPad);
+ if (rootExtraTop > 0)
+ m_intrinsicPaddingBefore += rootExtraTop;
+ else
+ m_indexTop = - rootExtraTop;
+ } else
+ m_intrinsicPaddingStart = frontWidth;
+
+ RenderMathMLBlock::computePreferredLogicalWidths();
+
+ // Shrink our logical width to its probable value now without triggering unnecessary relayout of our children.
+ ASSERT(needsLayout() && logicalWidth() >= maxPreferredLogicalWidth());
+ setLogicalWidth(maxPreferredLogicalWidth());
+}
+
+void RenderMathMLRoot::layout()
+{
+ // Our computePreferredLogicalWidths() may change our logical width and then layout our children, which
+ // RenderBlock::layout()'s relayoutChildren logic isn't expecting.
+ if (preferredLogicalWidthsDirty())
+ computePreferredLogicalWidths();
+
+ RenderMathMLBlock::layout();
+
+ RenderBoxModelObject* index = this->index();
+ // If |index|, it should be a RenderBlock here, unless the user has overriden its { position: absolute }.
+ if (index && index->isBox())
+ toRenderBox(index)->setLogicalTop(m_indexTop);
+}
+
void RenderMathMLRoot::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
RenderMathMLBlock::paint(info, paintOffset);
if (info.context->paintingDisabled())
return;
- if (!index())
- return;
+ IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location());
- IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + computedCSSContentBoxRect().location());
+ int startX = adjustedPaintOffset.x();
+ int frontWidth = lroundf(gFrontWidthEms * style()->fontSize());
+ int overbarWidth = roundToInt(getBoxModelObjectWidth(firstChild())) + m_overbarLeftPointShift;
int baseHeight = roundToInt(getBoxModelObjectHeight(firstChild()));
+ int rootPad = lroundf(gSpaceAboveEms * style()->fontSize());
+ adjustedPaintOffset.setY(adjustedPaintOffset.y() - rootPad);
- int overbarWidth = roundToInt(getBoxModelObjectWidth(firstChild())) + m_overbarLeftPointShift;
- int indexWidth = index()->pixelSnappedOffsetWidth();
- int frontWidth = static_cast<int>(roundf(gFrontWidthEms * style()->fontSize()));
- int startX = adjustedPaintOffset.x() + indexWidth + m_overbarLeftPointShift;
-
- int rootPad = static_cast<int>(roundf(gSpaceAboveEms * style()->fontSize()));
- adjustedPaintOffset.setY(adjustedPaintOffset.y() + m_intrinsicPaddingBefore - rootPad);
+ float radicalDipLeftPointYPos = (index() ? gRootRadicalDipLeftPointYPos : gSqrtRadicalDipLeftPointYPos) * baseHeight;
FloatPoint overbarLeftPoint(startX - m_overbarLeftPointShift, adjustedPaintOffset.y());
FloatPoint bottomPoint(startX - gRadicalBottomPointXFront * frontWidth, adjustedPaintOffset.y() + baseHeight + gRadicalBottomPointLower);
- FloatPoint dipLeftPoint(startX - gRadicalDipLeftPointXFront * frontWidth, adjustedPaintOffset.y() + gRadicalDipLeftPointYPos * baseHeight);
+ FloatPoint dipLeftPoint(startX - gRadicalDipLeftPointXFront * frontWidth, adjustedPaintOffset.y() + radicalDipLeftPointYPos);
FloatPoint leftEnd(startX - frontWidth, dipLeftPoint.y() + gRadicalLeftEndYShiftEms * style()->fontSize());
GraphicsContextStateSaver stateSaver(*info.context);
info.context->strokePath(line);
}
-void RenderMathMLRoot::layout()
-{
- RenderBlock::layout();
-
- if (!index())
- return;
-
- int baseHeight = roundToInt(getBoxModelObjectHeight(firstChild()));
-
- // Base height above which the shape of the root changes
- float thresholdHeight = gThresholdBaseHeightEms * style()->fontSize();
- if (baseHeight > thresholdHeight && thresholdHeight) {
- float shift = min<float>((baseHeight - thresholdHeight) / thresholdHeight, 1.0f);
- int frontWidth = static_cast<int>(roundf(gFrontWidthEms * style()->fontSize()));
- m_overbarLeftPointShift = static_cast<int>(shift * gRadicalBottomPointXFront * frontWidth);
- m_intrinsicPaddingAfter = static_cast<int>(roundf(gBigRootBottomPaddingEms * style()->fontSize()));
- } else {
- m_overbarLeftPointShift = 0;
- m_intrinsicPaddingAfter = 0;
- }
-
- RenderBoxModelObject* index = this->index();
-
- m_intrinsicPaddingStart = index->pixelSnappedOffsetWidth() + m_overbarLeftPointShift;
-
- int rootPad = static_cast<int>(roundf(gSpaceAboveEms * style()->fontSize()));
- int partDipHeight = static_cast<int>(roundf((1 - gRadicalDipLeftPointYPos) * baseHeight));
- int rootExtraTop = partDipHeight + index->pixelSnappedOffsetHeight() - (baseHeight + rootPad);
- m_intrinsicPaddingBefore = rootPad + max(rootExtraTop, 0);
-
- setNeedsLayout(true, MarkOnlyThis);
- setPreferredLogicalWidthsDirty(true, MarkOnlyThis); // FIXME: Can this really be right?
- // FIXME: Preferred logical widths are currently wrong the first time through, relying on layout() to set m_intrinsicPaddingStart.
- RenderBlock::layout();
-
- // |index| should be a RenderBlock here, unless the user has overriden its { position: absolute }.
- if (rootExtraTop < 0 && index->isBox())
- toRenderBox(index)->setLogicalTop(-rootExtraTop);
-}
-
}
#endif // ENABLE(MATHML)
namespace WebCore {
-// Render base^(1/index), using radical notation.
+// Render base^(1/index), or sqrt(base) via the derived class RenderMathMLSquareRoot, using radical notation.
class RenderMathMLRoot : public RenderMathMLBlock {
public:
RenderMathMLRoot(Element*);
private:
virtual const char* renderName() const { return "RenderMathMLRoot"; }
+ virtual void computePreferredLogicalWidths() OVERRIDE;
+
// This may return 0 for a non-MathML index (which won't occur in valid MathML).
RenderBoxModelObject* index() const;
int m_overbarLeftPointShift;
+ int m_indexTop;
};
}
#include "RenderMathMLSquareRoot.h"
-#include "GraphicsContext.h"
-#include "MathMLNames.h"
-#include "PaintInfo.h"
#include "RenderMathMLRow.h"
-using namespace std;
-
namespace WebCore {
-using namespace MathMLNames;
-
-// FIXME: This whole file should be changed to work with various writing modes. See https://bugs.webkit.org/show_bug.cgi?id=48951.
-
-// Threshold above which the radical shape is modified to look nice with big bases (em)
-const float gThresholdBaseHeightEms = 1.5f;
-// Normal width of the front of the radical sign, before the base & overbar (em)
-const float gFrontWidthEms = 0.75f;
-// Gap between the base and overbar (em)
-const float gSpaceAboveEms = 0.2f;
-// Horizontal position of the bottom point of the radical (* frontWidth)
-const float gRadicalBottomPointXFront = 0.5f;
-// Lower the radical sign's bottom point (px)
-const int gRadicalBottomPointLower = 3;
-// Horizontal position of the top left point of the radical "dip" (* frontWidth)
-const float gRadicalDipLeftPointXFront = 0.8f;
-// Vertical position of the top left point of the radical "dip" (* baseHeight)
-const float gRadicalDipLeftPointYPos = 0.5f;
-// Vertical shift of the left end point of the radical (em)
-const float gRadicalLeftEndYShiftEms = 0.05f;
-// Additional bottom root padding if baseHeight > threshold (em)
-const float gBigRootBottomPaddingEms = 0.2f;
-
-// Radical line thickness (em)
-const float gRadicalLineThicknessEms = 0.02f;
-// Radical thick line thickness (em)
-const float gRadicalThickLineThicknessEms = 0.1f;
-
RenderMathMLSquareRoot::RenderMathMLSquareRoot(Element* element)
- : RenderMathMLBlock(element)
+ : RenderMathMLRoot(element)
{
}
if (!firstChild()) {
RenderMathMLRow* newMRow = RenderMathMLRow::createAnonymousWithParentRenderer(this);
- RenderMathMLBlock::addChild(newMRow);
+ RenderMathMLRoot::addChild(newMRow);
// newMRow->isAnonymousBlock() is false because newMRow's display is INLINE_BLOCK,
// so we don't need to worry about removeLeftoverAnonymousBlock().
firstChild()->addChild(newChild, beforeChild);
}
-void RenderMathMLSquareRoot::computePreferredLogicalWidths()
-{
- m_intrinsicPaddingStart = static_cast<int>(roundf(gFrontWidthEms * style()->fontSize()));
-
- RenderMathMLBlock::computePreferredLogicalWidths();
-}
-
-void RenderMathMLSquareRoot::computeLogicalHeight()
-{
- int baseHeight = roundToInt(getBoxModelObjectHeight(firstChild()));
- float thresholdHeight = gThresholdBaseHeightEms * style()->fontSize();
- m_intrinsicPaddingAfter = baseHeight > thresholdHeight ? static_cast<int>(roundf(gBigRootBottomPaddingEms * style()->fontSize())) : 0;
- setLogicalHeight(baseHeight + borderAndPaddingLogicalHeight());
-
- RenderMathMLBlock::computeLogicalHeight();
-}
-
-void RenderMathMLSquareRoot::layout()
-{
- m_intrinsicPaddingBefore = static_cast<int>(roundf(gSpaceAboveEms * style()->fontSize()));
-
- RenderMathMLBlock::layout();
-}
-
-void RenderMathMLSquareRoot::paint(PaintInfo& info, const LayoutPoint& paintOffset)
-{
- RenderMathMLBlock::paint(info, paintOffset);
-
- if (info.context->paintingDisabled())
- return;
-
- IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + computedCSSContentBoxRect().location());
-
- int baseHeight = roundToInt(getBoxModelObjectHeight(firstChild()));
- int overbarWidth = roundToInt(getBoxModelObjectWidth(firstChild()));
-
- int frontWidth = m_intrinsicPaddingStart;
- int overbarLeftPointShift = 0;
- // Base height above which the shape of the root changes
- float thresholdHeight = gThresholdBaseHeightEms * style()->fontSize();
-
- if (baseHeight > thresholdHeight && thresholdHeight) {
- float shift = min<float>((baseHeight - thresholdHeight) / thresholdHeight, 1.0f);
- overbarLeftPointShift = static_cast<int>(shift * gRadicalBottomPointXFront * frontWidth);
- }
-
- overbarWidth += overbarLeftPointShift;
-
- int startX = adjustedPaintOffset.x() + frontWidth;
-
- FloatPoint overbarLeftPoint(startX - overbarLeftPointShift, adjustedPaintOffset.y());
- FloatPoint bottomPoint(startX - gRadicalBottomPointXFront * frontWidth, adjustedPaintOffset.y() + baseHeight + gRadicalBottomPointLower);
- FloatPoint dipLeftPoint(startX - gRadicalDipLeftPointXFront * frontWidth, adjustedPaintOffset.y() + gRadicalDipLeftPointYPos * baseHeight);
- FloatPoint leftEnd(startX - frontWidth, dipLeftPoint.y() + gRadicalLeftEndYShiftEms * style()->fontSize());
-
- GraphicsContextStateSaver stateSaver(*info.context);
-
- info.context->setStrokeThickness(gRadicalLineThicknessEms * style()->fontSize());
- info.context->setStrokeStyle(SolidStroke);
- info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
- info.context->setLineJoin(MiterJoin);
- info.context->setMiterLimit(style()->fontSize());
-
- Path root;
-
- root.moveTo(FloatPoint(overbarLeftPoint.x() + overbarWidth, adjustedPaintOffset.y()));
- // draw top
- root.addLineTo(overbarLeftPoint);
- // draw from top left corner to bottom point of radical
- root.addLineTo(bottomPoint);
- // draw from bottom point to top of left part of radical base "dip"
- root.addLineTo(dipLeftPoint);
- // draw to end
- root.addLineTo(leftEnd);
-
- info.context->strokePath(root);
-
- GraphicsContextStateSaver maskStateSaver(*info.context);
-
- // Build a mask to draw the thick part of the root.
- Path mask;
-
- mask.moveTo(overbarLeftPoint);
- mask.addLineTo(bottomPoint);
- mask.addLineTo(dipLeftPoint);
- mask.addLineTo(FloatPoint(2 * dipLeftPoint.x() - leftEnd.x(), 2 * dipLeftPoint.y() - leftEnd.y()));
-
- info.context->clip(mask);
-
- // Draw the thick part of the root.
- info.context->setStrokeThickness(gRadicalThickLineThicknessEms * style()->fontSize());
- info.context->setLineCap(SquareCap);
-
- Path line;
- line.moveTo(bottomPoint);
- line.addLineTo(dipLeftPoint);
-
- info.context->strokePath(line);
-}
-
}
#endif // ENABLE(MATHML)
#if ENABLE(MATHML)
-#include "RenderMathMLBlock.h"
+#include "RenderMathMLRoot.h"
namespace WebCore {
// Render sqrt(base), using radical notation.
-class RenderMathMLSquareRoot : public RenderMathMLBlock {
+class RenderMathMLSquareRoot : public RenderMathMLRoot {
public:
RenderMathMLSquareRoot(Element*);
virtual const char* renderName() const { return "RenderMathMLSquareRoot"; }
virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
-
- virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual void computeLogicalHeight() OVERRIDE;
- virtual void layout() OVERRIDE;
-
- virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
};
}