Minor refactoring in RenderMathMLOperator
[WebKit-https.git] / Source / WebCore / mathml / MathMLMencloseElement.cpp
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
26 #include "config.h"
27
28 #if ENABLE(MATHML)
29 #include "MathMLMencloseElement.h"
30
31 #include "MathMLNames.h"
32 #include "RenderElement.h"
33 #include "RenderMathMLMenclose.h"
34 #include "RenderObject.h"
35 #include "TextRun.h"
36 #include <wtf/Ref.h>
37 #include <wtf/text/StringBuilder.h>
38
39
40 namespace WebCore {
41
42 MathMLMencloseElement::MathMLMencloseElement(const QualifiedName& tagName, Document& document)
43     : MathMLInlineContainerElement(tagName, document)
44     , m_isRadicalValue(false)
45 {
46 }
47
48 Ref<MathMLMencloseElement> MathMLMencloseElement::create(const QualifiedName& tagName, Document& document)
49 {
50     return adoptRef(*new MathMLMencloseElement(tagName, document));
51 }
52
53 RenderPtr<RenderElement> MathMLMencloseElement::createElementRenderer(std::unique_ptr<RenderStyle> style, const RenderTreePosition&)
54 {    
55     return createRenderer<RenderMathMLMenclose>(*this, WTFMove(style));
56 }
57
58 bool MathMLMencloseElement::isPresentationAttribute(const QualifiedName& name) const
59 {
60     if (name == MathMLNames::notationAttr)
61         return true;
62     return MathMLElement::isPresentationAttribute(name);
63 }
64
65 void MathMLMencloseElement::finishParsingChildren()
66 {
67     MathMLInlineContainerElement::finishParsingChildren();
68     // When notation value is a radical and menclose does not have any child 
69     // then we add anonymous squareroot child to menclose so that square root
70     // symbol can be rendered.
71     if (m_isRadicalValue && !firstElementChild())
72         renderer()->addChild(nullptr, nullptr);
73 }
74
75 void MathMLMencloseElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
76 {
77     String val = value;
78     if (val.isEmpty())
79         return;
80     if (name == MathMLNames::notationAttr) {
81         val.split(' ', m_notationValues);
82         size_t notationValueSize = m_notationValues.size();
83         for (size_t i = 0; i < notationValueSize; i++) {
84             if (m_notationValues[i] == "top" || m_notationValues[i] == "longdiv") {
85                 if (m_notationValues[i] == "longdiv")
86                     addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingLeft, longDivLeftPadding());
87                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopStyle, "solid");
88                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopWidth, "thin");
89                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingTop, ".3ex");
90             } else if (m_notationValues[i] == "bottom") {
91                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomStyle, "solid");
92                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomWidth, "thin");
93                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingBottom, ".3ex");
94             } else if (m_notationValues[i] == "left") {
95                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderLeftStyle, "solid");
96                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderLeftWidth, "thin");
97                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingLeft, ".3ex");
98             } else if (m_notationValues[i] == "right") {
99                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightStyle, "solid");
100                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightWidth, "thin");
101                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingRight, ".3ex");
102             } else if (m_notationValues[i] == "box" || m_notationValues[i] == "roundedbox") {
103                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, "solid");
104                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, "thin");
105                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPadding, ".3ex");
106                 if (m_notationValues[i] == "roundedbox")
107                     addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRadius, ASCIILiteral("5px"));
108             } else if (m_notationValues[i] == "actuarial" || m_notationValues[i] == "madruwb") {
109                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightStyle, "solid");
110                 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightWidth, "thin");
111                 addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingRight, ".3ex");
112                 if (m_notationValues[i] == "actuarial") {
113                     addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopStyle, "solid");
114                     addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopWidth, "thin");
115                     addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingTop, ".3ex");
116                 } else if (m_notationValues[i] == "madruwb") {
117                     addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomStyle, "solid");
118                     addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomWidth, "thin");
119                     addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingBottom, ".3ex");
120                 }
121             } else if (m_notationValues[i] == "radical")
122                 m_isRadicalValue = true;
123         }
124     } else
125         MathMLInlineContainerElement::collectStyleForPresentationAttribute(name, value, style);
126 }
127
128
129 String MathMLMencloseElement::longDivLeftPadding() const
130 {
131     StringBuilder padding;
132     String closingBrace(")", String::ConstructFromLiteral);
133     TextRun run(closingBrace);
134     Node* node = parentNode();
135     if (node && node->renderer()) {
136         const FontCascade& font = node->renderer()->style().fontCascade();
137         padding.appendNumber(font.width(run));
138         padding.appendLiteral("px");
139     }
140     return padding.toString();
141 }
142
143 }
144 #endif // ENABLE(MATHML)