Bug 522393 - Remove invisible operators special case in reflow. r=fredw, r=roc

This commit is contained in:
James Kitchener 2014-03-19 13:05:02 -04:00
parent a902b4a4c8
commit b4e54794ec
6 changed files with 98 additions and 51 deletions

View File

@ -30,7 +30,6 @@ nsMathMLmoFrame::~nsMathMLmoFrame()
{
}
static const char16_t kInvisibleComma = char16_t(0x200B); // a.k.a. ZERO WIDTH SPACE
static const char16_t kApplyFunction = char16_t(0x2061);
static const char16_t kInvisibleTimes = char16_t(0x2062);
static const char16_t kInvisibleSeparator = char16_t(0x2063);
@ -74,8 +73,7 @@ nsMathMLmoFrame::UseMathMLChar()
{
return (NS_MATHML_OPERATOR_GET_FORM(mFlags) &&
NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags) ||
NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags);
NS_MATHML_OPERATOR_IS_CENTERED(mFlags);
}
void
@ -123,18 +121,16 @@ nsMathMLmoFrame::ProcessTextData()
char16_t ch = (length == 0) ? char16_t('\0') : data[0];
if ((length == 1) &&
(ch == kInvisibleComma ||
ch == kApplyFunction ||
(ch == kApplyFunction ||
ch == kInvisibleSeparator ||
ch == kInvisiblePlus ||
ch == kInvisibleTimes)) {
mFlags |= NS_MATHML_OPERATOR_INVISIBLE;
}
// don't bother doing anything special if we don't have a
// single child with a visible text content
// don't bother doing anything special if we don't have a single child
nsPresContext* presContext = PresContext();
if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags) || mFrames.GetLength() != 1) {
if (mFrames.GetLength() != 1) {
data.Truncate(); // empty data to reset the char
mMathMLChar.SetData(presContext, data);
ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar, false);
@ -341,17 +337,10 @@ nsMathMLmoFrame::ProcessOperatorData()
// thickmathspace = 5/18em
float lspace = 5.0f/18.0f;
float rspace = 5.0f/18.0f;
if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
// mMathMLChar has been reset in ProcessTextData so we can not find it
// in the operator dictionary. The operator dictionary always uses
// lspace = rspace = 0 for invisible operators.
lspace = rspace = 0;
} else {
// lookup the operator dictionary
nsAutoString data;
mMathMLChar.GetData(data);
nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
}
// lookup the operator dictionary
nsAutoString data;
mMathMLChar.GetData(data);
nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
if (lspace || rspace) {
// Cache the default values of lspace and rspace.
// since these values are relative to the 'em' unit, convert to twips now
@ -749,15 +738,12 @@ nsMathMLmoFrame::Stretch(nsRenderingContext& aRenderingContext,
}
}
// Child frames of invisble operators are not reflowed
if (!NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
// Place our children using the default method
// This will allow our child text frame to get its DidReflow()
nsresult rv = Place(aRenderingContext, true, aDesiredStretchSize);
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
// Make sure the child frames get their DidReflow() calls.
DidReflowChildren(mFrames.FirstChild());
}
// Place our children using the default method
// This will allow our child text frame to get its DidReflow()
nsresult rv = Place(aRenderingContext, true, aDesiredStretchSize);
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
// Make sure the child frames get their DidReflow() calls.
DidReflowChildren(mFrames.FirstChild());
}
if (useMathMLChar) {
@ -947,22 +933,6 @@ nsMathMLmoFrame::Reflow(nsPresContext* aPresContext,
// it is safer to just process the whole lot here
ProcessOperatorData();
// play safe by not passing invisible operators to the font subsystem because
// some platforms risk selecting strange glyphs for them and give bad inter-space
if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
// return empty space for now, but this is not yet final since there
// can be lspace and rspace attributes that reclaim some room.
// These will be dealt with later in Stretch().
aDesiredSize.Width() = 0;
aDesiredSize.Height() = 0;
aDesiredSize.SetTopAscent(0);
aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
aStatus = NS_FRAME_COMPLETE;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
return nsMathMLTokenFrame::Reflow(aPresContext, aDesiredSize,
aReflowState, aStatus);
}

View File

@ -0,0 +1,27 @@
<html>
<math>
<mo>1</mo>
</math>
<p>
<math>
<mo>2</mo>
</math>
<p>
<math>
<mo>3</mo>
</math>
<p>
<math>
<mo>4</mo>
</math>
<p>
<table>
<tr>
<td style="border: 1px solid;">
<math>
<mo>x</mo>
</math>
</td>
</tr>
</table>
</html>

View File

@ -0,0 +1,41 @@
<html class="reftest-wait">
<body>
<math>
<mo id="mo1">&#x2061;<!-- FUNCTION APPLICATION --></mo>
</math>
<p>
<math>
<mo id="mo2">&#x2062;<!-- INVISIBLE TIMES --></mo>
</math>
<p>
<math>
<mo id="mo3">&#x2063;<!-- INVISIBLE SEPARATOR --></mo>
</math>
<p>
<math>
<mo id="mo4">&#x2064;<!-- INVISIBLE PLUS --></mo>
</math>
<p>
<!-- Test preferred width after dynamic change-->
<table>
<tr>
<td style="border: 1px solid;">
<math>
<mo id="mo5">&ApplyFunction;</mo>
</math>
</td>
</tr>
</table>
<script type="text/javascript">
function doTest() {
document.getElementById('mo1').firstChild.data = '1';
document.getElementById('mo2').firstChild.data = '2';
document.getElementById('mo3').firstChild.data = '3';
document.getElementById('mo4').firstChild.data = '4';
document.getElementById('mo5').firstChild.data = 'x';
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</body>
</html>

View File

@ -6,7 +6,7 @@
<mn>3</mn>
<mn>4</mn>
<mn>5</mn>
<mn>6</mn>
<mspace height="2em" width="0.1em"></mspace>
</mrow>
</math>
</html>

View File

@ -2,16 +2,24 @@
<math>
<mrow>
<mn>1</mn>
<mo>&#x200B;<!-- INVISIBLE COMMA --></mo>
<mn>2</mn>
<mo>&#x2061;<!-- FUNCTION APPLICATION --></mo>
<mn>3</mn>
<mn>2</mn>
<mo>&#x2062;<!-- INVISIBLE TIMES --></mo>
<mn>4</mn>
<mn>3</mn>
<mo>&#x2063;<!-- INVISIBLE SEPARATOR --></mo>
<mn>5</mn>
<mn>4</mn>
<mo>&#x2064;<!-- INVISIBLE PLUS --></mo>
<mn>6</mn>
<mn>5</mn>
<!-- Hack. The invisible operators may not belong to the same font as
the numbers, so they may have different heights. The mspace
compensates for this by ensuring the height of the mrow does not
depend on character height -->
<mspace height="2em" width="0.1em"></mspace>
</mrow>
</math>
<p>
<!-- Should be invisible -->
<math>
<mo style="background: red; color: blue;">&ApplyFunction;</mo>
</math>
</html>

View File

@ -142,6 +142,7 @@ skip-if(B2G) == maction-dynamic-1.html maction-dynamic-1-ref.html # bug 773482
== maction-dynamic-2.html maction-dynamic-2-ref.html
== mo-lspace-rspace.html mo-lspace-rspace-ref.html
== mo-invisibleoperators.html mo-invisibleoperators-ref.html
== mo-invisibleoperators-2.html mo-invisibleoperators-2-ref.html
skip-if(B2G) == maction-dynamic-3.html maction-dynamic-3-ref.html # bug 773482
== whitespace-trim-1.html whitespace-trim-1-ref.html
== whitespace-trim-2.html whitespace-trim-2-ref.html