PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp

https://gitlab.com/paretje/qtwebkit
C++ | 165 lines | 119 code | 19 blank | 27 comment | 56 complexity | 56d91ea69c936b73e4edf72aee7f18a3 MD5 | raw file
  1. /*
  2. * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  16. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  17. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  18. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  19. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #if ENABLE(MATHML)
  27. #include "RenderMathMLMenclose.h"
  28. #include "GraphicsContext.h"
  29. #include "MathMLMencloseElement.h"
  30. #include "PaintInfo.h"
  31. #include "RenderMathMLSquareRoot.h"
  32. #include <wtf/MathExtras.h>
  33. namespace WebCore {
  34. using namespace MathMLNames;
  35. RenderMathMLMenclose::RenderMathMLMenclose(Element& element, Ref<RenderStyle>&& style)
  36. : RenderMathMLRow(element, WTFMove(style))
  37. {
  38. }
  39. void RenderMathMLMenclose::addChild(RenderObject* newChild, RenderObject* beforeChild)
  40. {
  41. MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
  42. // Allow an anonymous RenderMathMLSquareRoot to handle drawing the radical
  43. // notation, rather than duplicating the code needed to paint a root.
  44. if (!firstChild() && menclose->isRadical())
  45. RenderMathMLBlock::addChild(RenderMathMLSquareRoot::createAnonymousWithParentRenderer(*this).leakPtr());
  46. if (newChild) {
  47. if (firstChild() && menclose->isRadical())
  48. downcast<RenderElement>(*firstChild()).addChild(newChild, beforeChild && beforeChild->parent() == firstChild() ? beforeChild : nullptr);
  49. else
  50. RenderMathMLBlock::addChild(newChild, beforeChild);
  51. }
  52. }
  53. void RenderMathMLMenclose::computePreferredLogicalWidths()
  54. {
  55. ASSERT(preferredLogicalWidthsDirty());
  56. RenderMathMLBlock::computePreferredLogicalWidths();
  57. const int paddingTop = 6;
  58. MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
  59. const Vector<String>& notationValues = menclose->notationValues();
  60. size_t notationalValueSize = notationValues.size();
  61. for (size_t i = 0; i < notationalValueSize; i++) {
  62. if (notationValues[i] == "circle") {
  63. m_minPreferredLogicalWidth = minPreferredLogicalWidth() * sqrtOfTwoFloat;
  64. m_maxPreferredLogicalWidth = maxPreferredLogicalWidth() * sqrtOfTwoFloat;
  65. }
  66. }
  67. if (menclose->isDefaultLongDiv()) {
  68. style().setPaddingTop(Length(paddingTop, Fixed));
  69. style().setPaddingLeft(Length(menclose->longDivLeftPadding().toInt(), Fixed));
  70. }
  71. setPreferredLogicalWidthsDirty(false);
  72. }
  73. void RenderMathMLMenclose::updateLogicalHeight()
  74. {
  75. MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
  76. const Vector<String>& notationValues = menclose->notationValues();
  77. size_t notationalValueSize = notationValues.size();
  78. for (size_t i = 0; i < notationalValueSize; i++)
  79. if (notationValues[i] == "circle")
  80. setLogicalHeight(logicalHeight() * sqrtOfTwoFloat);
  81. }
  82. void RenderMathMLMenclose::paint(PaintInfo& info, const LayoutPoint& paintOffset)
  83. {
  84. RenderMathMLBlock::paint(info, paintOffset);
  85. if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE)
  86. return;
  87. MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
  88. const Vector<String>& notationValues = menclose->notationValues();
  89. size_t notationalValueSize = notationValues.size();
  90. bool isDefaultLongDiv = menclose->isDefaultLongDiv();
  91. if ((notationalValueSize && checkNotationalValuesValidity(notationValues)) || isDefaultLongDiv) {
  92. IntRect rect = absoluteBoundingBoxRect();
  93. int left = rect.x();
  94. int top = rect.y();
  95. int boxWidth = rect.width();
  96. int boxHeight = rect.height();
  97. int halfboxWidth = rect.width() / 2;
  98. int halfboxHeight = rect.height() / 2;
  99. GraphicsContextStateSaver stateSaver(info.context());
  100. info.context().setStrokeThickness(1);
  101. info.context().setStrokeStyle(SolidStroke);
  102. info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
  103. // TODO add support for notation value updiagonalarrow https://bugs.webkit.org/show_bug.cgi?id=127466
  104. for (size_t i = 0; i < notationalValueSize; i++) {
  105. if (notationValues[i] == "updiagonalstrike")
  106. info.context().drawLine(IntPoint(left, top + boxHeight), IntPoint(left + boxWidth, top));
  107. else if (notationValues[i] == "downdiagonalstrike")
  108. info.context().drawLine(IntPoint(left, top), IntPoint(left + boxWidth, top + boxHeight));
  109. else if (notationValues[i] == "verticalstrike")
  110. info.context().drawLine(IntPoint(left + halfboxWidth, top), IntPoint(left + halfboxWidth, top + boxHeight));
  111. else if (notationValues[i] == "horizontalstrike")
  112. info.context().drawLine(IntPoint(left, top + halfboxHeight), IntPoint(left + boxWidth, top + halfboxHeight));
  113. else if (notationValues[i] == "circle") {
  114. info.context().setFillColor(Color::transparent);
  115. info.context().drawEllipse(rect);
  116. } else if (notationValues[i] == "longdiv")
  117. isDefaultLongDiv = true;
  118. }
  119. if (isDefaultLongDiv) {
  120. Path root;
  121. int midxPoint = 0;
  122. root.moveTo(FloatPoint(left, top));
  123. int childLeft = firstChild() ? firstChild()->absoluteBoundingBoxRect().x() : 0;
  124. if (childLeft)
  125. midxPoint= childLeft - left;
  126. else
  127. midxPoint = style().paddingLeft().value();
  128. root.addBezierCurveTo(FloatPoint(left, top), FloatPoint(left + midxPoint, top + halfboxHeight), FloatPoint(left, top + boxHeight));
  129. info.context().strokePath(root);
  130. if (isDefaultLongDiv)
  131. info.context().drawLine(IntPoint(left, top), IntPoint(left + boxWidth + midxPoint, top));
  132. }
  133. }
  134. }
  135. bool RenderMathMLMenclose::checkNotationalValuesValidity(const Vector<String>& attr) const
  136. {
  137. size_t attrSize = attr.size();
  138. for (size_t i = 0; i < attrSize; i++) {
  139. if (attr[i] == "updiagonalstrike" || attr[i] == "downdiagonalstrike" || attr[i] == "horizontalstrike" || attr[i] == "verticalstrike"
  140. || attr[i] == "circle" || attr[i] == "longdiv")
  141. return true;
  142. }
  143. return false;
  144. }
  145. }
  146. #endif // ENABLE(MATHML)