Skip to content
Permalink
Browse files
Invisible Operators should not add space.
https://bugs.webkit.org/show_bug.cgi?id=115786

Reviewed by Chris Fleizach.

Source/WebCore:

This change adds special handling for invisible operator to ensure they really behave as empty box. We now ignore their glyph widths and do not paint them.

Test: mathml/presentation/mo-invisible.html

* rendering/mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::computePreferredLogicalWidths):
(WebCore::RenderMathMLOperator::paint):
* rendering/mathml/RenderMathMLOperator.h:

LayoutTests:

Add a reftest based on the examples of the MathML specification to verify that invisible operators do not add space.

* mathml/presentation/mo-invisible-expected.html: Added.
* mathml/presentation/mo-invisible.html: Added.

Canonical link: https://commits.webkit.org/148076@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@165464 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
fred-wang committed Mar 12, 2014
1 parent 767ec3e commit 5038cfb3b23eb6e5895fa6e8b8b3396e2ebe36ad
Showing 7 changed files with 154 additions and 3 deletions.
@@ -1,3 +1,15 @@
2014-03-12 Frédéric Wang <fred.wang@free.fr>

Invisible Operators should not add space.
https://bugs.webkit.org/show_bug.cgi?id=115786

Reviewed by Chris Fleizach.

Add a reftest based on the examples of the MathML specification to verify that invisible operators do not add space.

* mathml/presentation/mo-invisible-expected.html: Added.
* mathml/presentation/mo-invisible.html: Added.

2014-03-11 Frédéric Wang <fred.wang@free.fr>

Implement MathML spacing around operators .
@@ -0,0 +1,56 @@
<!doctype html>
<html>
<head>
<title>invisible operators</title>
<meta charset="utf-8"/>
</head>
<body>

<math>
<mrow>
<mi>f</mi>
<mo lspace="0em" rspace="0em"></mo>
<mrow>
<mo>(</mo>
<mi>x</mi>
<mo>)</mo>
</mrow>
</mrow>
</math>
<math>
<mrow>
<mi>sin</mi>
<mo lspace="0em" rspace="0em"></mo>
<mi>x</mi>
</mrow>
</math>
<math>
<mrow>
<mi>x</mi>
<mo lspace="0em" rspace="0em"></mo>
<mi>y</mi>
</mrow>
</math>
<math>
<msub>
<mi>m</mi>
<mrow>
<mn>1</mn>
<mo lspace="0em" rspace="0em"></mo>
<mn>2</mn>
</mrow>
</msub>
</math>
<math>
<mrow>
<mn>2</mn>
<mo lspace="0em" rspace="0em"></mo>
<mfrac>
<mn>3</mn>
<mn>4</mn>
</mfrac>
</mrow>
</math>

</body>
</html>
@@ -0,0 +1,58 @@
<!doctype html>
<html>
<head>
<title>invisible operators</title>
<meta charset="utf-8"/>
</head>
<body>

<!-- These examples are taken from http://www.w3.org/TR/MathML/chapter3.html#presm.invisibleops.
The invisible operator glyphs should render as empty box and, per the operator dictionary, should not have space around them. -->
<math>
<mrow>
<mi>f</mi>
<mo>&#x2061;<!--FUNCTION APPLICATION--></mo>
<mrow>
<mo>(</mo>
<mi>x</mi>
<mo>)</mo>
</mrow>
</mrow>
</math>
<math>
<mrow>
<mi>sin</mi>
<mo>&#x2061;<!--FUNCTION APPLICATION--></mo>
<mi>x</mi>
</mrow>
</math>
<math>
<mrow>
<mi>x</mi>
<mo>&#x2062;<!--INVISIBLE TIMES--></mo>
<mi>y</mi>
</mrow>
</math>
<math>
<msub>
<mi>m</mi>
<mrow>
<mn>1</mn>
<mo>&#x2063;<!--INVISIBLE SEPARATOR--></mo>
<mn>2</mn>
</mrow>
</msub>
</math>
<math>
<mrow>
<mn>2</mn>
<mo>&#x2064;<!-- INVISIBLE PLUS --></mo>
<mfrac>
<mn>3</mn>
<mn>4</mn>
</mfrac>
</mrow>
</math>

</body>
</html>
@@ -1,3 +1,19 @@
2014-03-12 Frédéric Wang <fred.wang@free.fr>

Invisible Operators should not add space.
https://bugs.webkit.org/show_bug.cgi?id=115786

Reviewed by Chris Fleizach.

This change adds special handling for invisible operator to ensure they really behave as empty box. We now ignore their glyph widths and do not paint them.

Test: mathml/presentation/mo-invisible.html

* rendering/mathml/RenderMathMLOperator.cpp:
(WebCore::RenderMathMLOperator::computePreferredLogicalWidths):
(WebCore::RenderMathMLOperator::paint):
* rendering/mathml/RenderMathMLOperator.h:

2014-03-11 Frédéric Wang <fred.wang@free.fr>

Implement MathML spacing around operators .
@@ -1302,6 +1302,13 @@ void RenderMathMLOperator::computePreferredLogicalWidths()
bool allowStretching = shouldAllowStretching(stretchedCharacter);
if (!allowStretching) {
RenderMathMLToken::computePreferredLogicalWidths();
if (isInvisibleOperator()) {
// In some fonts, glyphs for invisible operators have nonzero width. Consequently, we subtract that width here to avoid wide gaps.
float glyphWidth = advanceForCharacter(m_operator);
ASSERT(glyphWidth <= m_minPreferredLogicalWidth);
m_minPreferredLogicalWidth -= glyphWidth;
m_maxPreferredLogicalWidth -= glyphWidth;
}
return;
}

@@ -1529,7 +1536,8 @@ void RenderMathMLOperator::fillWithExtensionGlyph(PaintInfo& info, const LayoutP

void RenderMathMLOperator::paint(PaintInfo& info, const LayoutPoint& paintOffset)
{
if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE)
// We skip painting for invisible operators too to avoid some "missing character" glyph to appear if appropriate math fonts are not available.
if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE || isInvisibleOperator())
return;

if (!m_isStretched && !m_stretchyCharacter) {
@@ -87,6 +87,8 @@ class RenderMathMLOperator final : public RenderMathMLToken {
virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override;
virtual bool isRenderMathMLOperator() const override { return true; }
bool isFencedOperator() { return isAnonymous(); }
// The following operators are invisible: U+2061 FUNCTION APPLICATION, U+2062 INVISIBLE TIMES, U+2063 INVISIBLE SEPARATOR, U+2064 INVISIBLE PLUS.
bool isInvisibleOperator() const { return 0x2061 <= m_operator && m_operator <= 0x2064; }
virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
virtual void computePreferredLogicalWidths() override;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override;
@@ -59,8 +59,7 @@ void RenderMathMLRow::updateOperatorProperties()
{
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isRenderMathMLBlock()) {
auto renderOperator = toRenderMathMLBlock(child)->unembellishedOperator();
if (renderOperator)
if (auto renderOperator = toRenderMathMLBlock(child)->unembellishedOperator())
renderOperator->updateOperatorProperties();
}
}

0 comments on commit 5038cfb

Please sign in to comment.