COMMIT_MESSAGE (6/6)

 1Bug 160339 - Determine operator direction in MathMLOperatorElement and reduce relayout
 2

Source/WebCore/ChangeLog

112016-07-29 Frederic Wang <fwang@igalia.com>
22
 3 Move determination of operator direction into DOM class and reduce relayout
 4 https://bugs.webkit.org/show_bug.cgi?id=160339
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 We move the determination of operator direction into MathMLOperatorElement. After that,
 9 setOperatorProperties is no longer necessary in RenderMathMLOperator and we can remove many
 10 calls to update operator properties and force relayout.
 11
 12 No new tests, already covered by existing tests.
 13
 14 * mathml/MathMLInlineContainerElement.cpp:
 15 (WebCore::MathMLInlineContainerElement::childrenChanged): No need to call
 16 updateOperatorProperties.
 17 * mathml/MathMLOperatorElement.cpp:
 18 (WebCore::MathMLOperatorElement::operatorText): Set m_operatorTextIsVertical.
 19 (WebCore::MathMLOperatorElement::isVertical): Return m_operatorTextIsVertical possibly
 20 calculating it again if the operator text is dirty.
 21 * mathml/MathMLOperatorElement.h: Define new member and accessor for operator direction.
 22 * rendering/mathml/RenderMathMLFencedOperator.cpp:
 23 (WebCore::RenderMathMLFencedOperator::updateOperatorContent): Rename rebuildTokenContent.
 24 (WebCore::RenderMathMLFencedOperator::stretchTo): Call setOperatorProperties before
 25 forwarding the call to the parent class.
 26 (WebCore::RenderMathMLFencedOperator::computePreferredLogicalWidths): Ditto.
 27 (WebCore::RenderMathMLFencedOperator::styleDidChange): Ditto.
 28 (WebCore::RenderMathMLFencedOperator::updateMathOperator): Ditto.
 29 * rendering/mathml/RenderMathMLFencedOperator.h: Override some functions to keep the call
 30 to setOperatorProperties. Also handle the operator direction here.
 31 * rendering/mathml/RenderMathMLOperator.cpp:
 32 (WebCore::RenderMathMLOperator::isVertical): Forward the call to MathMLOperatorElement.
 33 (WebCore::RenderMathMLOperator::stretchTo): Use isVertical and remove setOperatorProperties.
 34 (WebCore::RenderMathMLOperator::resetStretchSize): Use isVertical.
 35 (WebCore::RenderMathMLOperator::computePreferredLogicalWidths): Remove setOperatorProperties.
 36 (WebCore::RenderMathMLOperator::updateMathOperator): Rename rebuildTokenContent as this
 37 function really just update MathOperator. Also remove setNeedsLayoutAndPrefWidthsRecalc.
 38 (WebCore::RenderMathMLOperator::updateTokenContent): Rename rebuildTokenContent.
 39 (WebCore::RenderMathMLOperator::verticalStretchedOperatorShift): Call isVertical.
 40 (WebCore::RenderMathMLOperator::paint): Ditto.
 41 (WebCore::RenderMathMLOperator::setOperatorProperties): Deleted.
 42 (WebCore::RenderMathMLOperator::rebuildTokenContent): Deleted. Renamed updateMathOperator.
 43 (WebCore::RenderMathMLOperator::updateOperatorProperties): Deleted.
 44 (WebCore::RenderMathMLOperator::styleDidChange): Remove setOperatorProperties.
 45 * rendering/mathml/RenderMathMLOperator.h:
 46 (WebCore::RenderMathMLOperator::stretchSize): Use isVertical
 47 * rendering/mathml/RenderMathMLRow.cpp:
 48 (WebCore::RenderMathMLRow::updateOperatorProperties): Deleted.
 49 * rendering/mathml/RenderMathMLRow.h: Delete updateOperatorProperties.
 50
 512016-07-29 Frederic Wang <fwang@igalia.com>
 52
353 More cleanup of MathML operator parsing
454 https://bugs.webkit.org/show_bug.cgi?id=160336
555

Source/WebCore/mathml/MathMLInlineContainerElement.cpp

@@void MathMLInlineContainerElement::childrenChanged(const ChildChange& change)
6060 static_cast<MathMLOperatorElement*>(child)->setOperatorFormDirty();
6161 }
6262
63  // FIXME: Parsing of operator properties should be done in the element classes rather than in the renderer classes.
64  // See https://webkit.org/b/156537
65  if (renderer() && is<RenderMathMLRow>(*renderer()))
66  downcast<RenderMathMLRow>(*renderer()).updateOperatorProperties();
6763 MathMLElement::childrenChanged(change);
6864}
6965

Source/WebCore/mathml/MathMLOperatorElement.cpp

@@UChar MathMLOperatorElement::operatorText()
6565 return m_operatorText.value();
6666
6767 m_operatorText = Optional<UChar>(parseOperatorText(textContent()));
 68 m_operatorTextIsVertical = MathMLOperatorDictionary::isVertical(m_operatorText.value());
 69
6870 return m_operatorText.value();
6971}
7072
 73bool MathMLOperatorElement::isVertical()
 74{
 75 // We update m_operatorTextIsVertical if m_operatorText is dirty.
 76 if (!m_operatorText)
 77 operatorText();
 78
 79 return m_operatorTextIsVertical;
 80}
 81
7182const MathMLOperatorElement::DictionaryProperty& MathMLOperatorElement::dictionaryProperty()
7283{
7384 if (!m_dictionaryProperty.dirty)

Source/WebCore/mathml/MathMLOperatorElement.h

@@public:
3636 static Ref<MathMLOperatorElement> create(const QualifiedName& tagName, Document&);
3737 static UChar parseOperatorText(const String&);
3838 UChar operatorText();
 39 bool isVertical();
3940 void setOperatorFormDirty() { m_dictionaryProperty.dirty = true; }
4041 MathMLOperatorDictionary::Form form() { return dictionaryProperty().form; }
4142 bool hasProperty(MathMLOperatorDictionary::Flag);

@@private:
5354 void parseAttribute(const QualifiedName&, const AtomicString&) final;
5455
5556 Optional<UChar> m_operatorText;
 57 bool m_operatorTextIsVertical;
5658
5759 struct DictionaryProperty {
5860 MathMLOperatorDictionary::Form form;

Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.cpp

@@RenderMathMLFencedOperator::RenderMathMLFencedOperator(Document& document, Rende
4646void RenderMathMLFencedOperator::updateOperatorContent(const String& operatorString)
4747{
4848 m_textContent = MathMLOperatorElement::parseOperatorText(operatorString);
49  rebuildTokenContent();
 49 updateMathOperator();
5050}
5151
5252void RenderMathMLFencedOperator::setOperatorProperties()

@@void RenderMathMLFencedOperator::setOperatorProperties()
7171 }
7272}
7373
 74void RenderMathMLFencedOperator::stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline)
 75{
 76 setOperatorProperties();
 77 RenderMathMLOperator::stretchTo(heightAboveBaseline, depthBelowBaseline);
 78}
 79
 80void RenderMathMLFencedOperator::stretchTo(LayoutUnit width)
 81{
 82 setOperatorProperties();
 83 RenderMathMLOperator::stretchTo(width);
 84}
 85
 86void RenderMathMLFencedOperator::computePreferredLogicalWidths()
 87{
 88 setOperatorProperties();
 89 RenderMathMLOperator::computePreferredLogicalWidths();
 90}
 91
 92void RenderMathMLFencedOperator::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 93{
 94 setOperatorProperties();
 95 RenderMathMLOperator::styleDidChange(diff, oldStyle);
 96}
 97
 98void RenderMathMLFencedOperator::updateMathOperator()
 99{
 100 setOperatorProperties();
 101 RenderMathMLOperator::updateMathOperator();
 102}
 103
74104}
75105
76106#endif

Source/WebCore/rendering/mathml/RenderMathMLFencedOperator.h

@@public:
3939
4040private:
4141 bool isRenderMathMLFencedOperator() const final { return true; }
42  void setOperatorProperties() final;
 42 void setOperatorProperties();
 43 void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline) final;
 44 void stretchTo(LayoutUnit width) final;
 45 void computePreferredLogicalWidths() final;
 46 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
 47 void updateMathOperator() final;
 48 bool isVertical() const final { return m_isVertical; }
4349 UChar textContent() const final { return m_textContent; }
4450 LayoutUnit leadingSpace() const final { return m_leadingSpace; }
4551 LayoutUnit trailingSpace() const final { return m_trailingSpace; }

@@private:
5157 bool useMathOperator() const final { return true; }
5258
5359 UChar m_textContent { 0 };
 60 bool m_isVertical { true };
5461 LayoutUnit m_leadingSpace;
5562 LayoutUnit m_trailingSpace;
5663 LayoutUnit m_minSize;

Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp

@@LayoutUnit RenderMathMLOperator::maxSize() const
117117 return maxSize;
118118}
119119
120 void RenderMathMLOperator::setOperatorProperties()
 120bool RenderMathMLOperator::isVertical() const
121121{
122  // We determine the stretch direction (default is vertical).
123  m_isVertical = MathMLOperatorDictionary::isVertical(textContent());
 122 return element().isVertical();
124123}
125124
126125void RenderMathMLOperator::stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline)
127126{
128127 ASSERT(hasOperatorFlag(MathMLOperatorDictionary::Stretchy));
129  ASSERT(m_isVertical);
 128 ASSERT(isVertical());
130129
131  if (!m_isVertical || (heightAboveBaseline == m_stretchHeightAboveBaseline && depthBelowBaseline == m_stretchDepthBelowBaseline))
 130 if (!isVertical() || (heightAboveBaseline == m_stretchHeightAboveBaseline && depthBelowBaseline == m_stretchDepthBelowBaseline))
132131 return;
133132
134133 m_stretchHeightAboveBaseline = heightAboveBaseline;
135134 m_stretchDepthBelowBaseline = depthBelowBaseline;
136135
137  setOperatorProperties();
138136 if (hasOperatorFlag(MathMLOperatorDictionary::Symmetric)) {
139137 // We make the operator stretch symmetrically above and below the axis.
140138 LayoutUnit axis = mathAxisHeight();

@@void RenderMathMLOperator::stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit
167165void RenderMathMLOperator::stretchTo(LayoutUnit width)
168166{
169167 ASSERT(hasOperatorFlag(MathMLOperatorDictionary::Stretchy));
170  ASSERT(!m_isVertical);
 168 ASSERT(!isVertical());
171169
172  if (m_isVertical || m_stretchWidth == width)
 170 if (isVertical() || m_stretchWidth == width)
173171 return;
174172
175173 m_stretchWidth = width;
176174 m_mathOperator.stretchTo(style(), width);
177175
178  setOperatorProperties();
179 
180176 setLogicalHeight(m_mathOperator.ascent() + m_mathOperator.descent());
181177}
182178
183179void RenderMathMLOperator::resetStretchSize()
184180{
185  if (m_isVertical) {
 181 if (isVertical()) {
186182 m_stretchHeightAboveBaseline = 0;
187183 m_stretchDepthBelowBaseline = 0;
188184 } else

@@void RenderMathMLOperator::computePreferredLogicalWidths()
195191
196192 LayoutUnit preferredWidth = 0;
197193
198  setOperatorProperties();
199194 if (!useMathOperator()) {
200195 RenderMathMLToken::computePreferredLogicalWidths();
201196 preferredWidth = m_maxPreferredLogicalWidth;

@@void RenderMathMLOperator::layoutBlock(bool relayoutChildren, LayoutUnit pageLog
250245 clearNeedsLayout();
251246}
252247
253 void RenderMathMLOperator::rebuildTokenContent()
 248void RenderMathMLOperator::updateMathOperator()
254249{
255  setOperatorProperties();
256 
257  if (useMathOperator()) {
258  MathOperator::Type type;
259  if (!shouldAllowStretching())
260  type = MathOperator::Type::NormalOperator;
261  else if (isLargeOperatorInDisplayStyle())
262  type = MathOperator::Type::DisplayOperator;
263  else
264  type = m_isVertical ? MathOperator::Type::VerticalOperator : MathOperator::Type::HorizontalOperator;
265  m_mathOperator.setOperator(style(), textContent(), type);
266  }
267 
268  setNeedsLayoutAndPrefWidthsRecalc();
 250 ASSERT(useMathOperator());
 251 MathOperator::Type type;
 252 if (!shouldAllowStretching())
 253 type = MathOperator::Type::NormalOperator;
 254 else if (isLargeOperatorInDisplayStyle())
 255 type = MathOperator::Type::DisplayOperator;
 256 else
 257 type = isVertical() ? MathOperator::Type::VerticalOperator : MathOperator::Type::HorizontalOperator;
 258 m_mathOperator.setOperator(style(), textContent(), type);
269259}
270260
271261void RenderMathMLOperator::updateTokenContent()
272262{
273263 ASSERT(!isAnonymous());
274264 RenderMathMLToken::updateTokenContent();
275  rebuildTokenContent();
 265 updateMathOperator();
276266}
277267
278268void RenderMathMLOperator::updateFromElement()

@@void RenderMathMLOperator::updateFromElement()
280270 updateTokenContent();
281271}
282272
283 void RenderMathMLOperator::updateOperatorProperties()
284 {
285  setOperatorProperties();
286  setNeedsLayoutAndPrefWidthsRecalc();
287 }
288 
289273bool RenderMathMLOperator::shouldAllowStretching() const
290274{
291275 return textContent() && (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || isLargeOperatorInDisplayStyle());

@@void RenderMathMLOperator::styleDidChange(StyleDifference diff, const RenderStyl
303287{
304288 RenderMathMLBlock::styleDidChange(diff, oldStyle);
305289 m_mathOperator.reset(style());
306  updateOperatorProperties();
307290}
308291
309292LayoutUnit RenderMathMLOperator::verticalStretchedOperatorShift() const
310293{
311  if (!m_isVertical || !stretchSize())
 294 if (!isVertical() || !stretchSize())
312295 return 0;
313296
314297 return (m_stretchDepthBelowBaseline - m_stretchHeightAboveBaseline - m_mathOperator.descent() + m_mathOperator.ascent()) / 2;

@@void RenderMathMLOperator::paint(PaintInfo& info, const LayoutPoint& paintOffset
331314 operatorTopLeft.move(style().isLeftToRightDirection() ? leadingSpace() : trailingSpace(), 0);
332315
333316 // Center horizontal operators.
334  if (!m_isVertical)
 317 if (!isVertical())
335318 operatorTopLeft.move(-(m_mathOperator.width() - width()) / 2, 0);
336319
337320 m_mathOperator.paint(style(), info, operatorTopLeft);

Source/WebCore/rendering/mathml/RenderMathMLOperator.h

@@public:
4242 RenderMathMLOperator(Document&, RenderStyle&&);
4343 MathMLOperatorElement& element() const;
4444
45  void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline);
46  void stretchTo(LayoutUnit width);
47  LayoutUnit stretchSize() const { return m_isVertical ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; }
 45 virtual void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline);
 46 virtual void stretchTo(LayoutUnit width);
 47 LayoutUnit stretchSize() const { return isVertical() ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; }
4848 void resetStretchSize();
4949
5050 virtual bool hasOperatorFlag(MathMLOperatorDictionary::Flag) const;
5151 bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp) && mathMLStyle()->displayStyle(); }
5252 bool shouldMoveLimits() const { return hasOperatorFlag(MathMLOperatorDictionary::MovableLimits) && !mathMLStyle()->displayStyle(); }
53  bool isVertical() const { return m_isVertical; }
 53 virtual bool isVertical() const;
5454 LayoutUnit italicCorrection() const { return m_mathOperator.italicCorrection(); }
5555
5656 void updateTokenContent() final;
57  void updateOperatorProperties();
5857 void updateFromElement() final;
5958 virtual UChar textContent() const;
6059
6160protected:
62  void rebuildTokenContent();
63  virtual void setOperatorProperties();
 61 virtual void updateMathOperator();
 62 void computePreferredLogicalWidths() override;
 63 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
6464 virtual LayoutUnit leadingSpace() const;
6565 virtual LayoutUnit trailingSpace() const;
6666 virtual LayoutUnit minSize() const;
6767 virtual LayoutUnit maxSize() const;
6868 virtual bool useMathOperator() const;
6969
70  bool m_isVertical { true };
71 
7270private:
73  void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
74  void computePreferredLogicalWidths() final;
7571 void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) final;
7672 void paint(PaintInfo&, const LayoutPoint&) final;
7773

Source/WebCore/rendering/mathml/RenderMathMLRow.cpp

@@RenderMathMLRow::RenderMathMLRow(Element& element, RenderStyle&& style)
4444{
4545}
4646
47 void RenderMathMLRow::updateOperatorProperties()
48 {
49  for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
50  if (is<RenderMathMLBlock>(*child)) {
51  if (auto* renderOperator = downcast<RenderMathMLBlock>(*child).unembellishedOperator())
52  renderOperator->updateOperatorProperties();
53  }
54  }
55  setNeedsLayoutAndPrefWidthsRecalc();
56 }
57 
58 
5947Optional<int> RenderMathMLRow::firstLineBaseline() const
6048{
6149 auto* baselineChild = firstChildBox();

Source/WebCore/rendering/mathml/RenderMathMLRow.h

@@class RenderMathMLRow : public RenderMathMLBlock {
3636public:
3737 RenderMathMLRow(Element&, RenderStyle&&);
3838
39  void updateOperatorProperties();
40 
4139protected:
4240 void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
4341 Optional<int> firstLineBaseline() const override;