summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/mathml
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/mathml
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/mathml')
-rw-r--r--Source/WebCore/mathml/MathMLElement.cpp92
-rw-r--r--Source/WebCore/mathml/MathMLElement.h52
-rw-r--r--Source/WebCore/mathml/MathMLInlineContainerElement.cpp87
-rw-r--r--Source/WebCore/mathml/MathMLInlineContainerElement.h49
-rw-r--r--Source/WebCore/mathml/MathMLMathElement.cpp54
-rw-r--r--Source/WebCore/mathml/MathMLMathElement.h48
-rw-r--r--Source/WebCore/mathml/MathMLTextElement.cpp60
-rw-r--r--Source/WebCore/mathml/MathMLTextElement.h48
-rw-r--r--Source/WebCore/mathml/RenderMathMLBlock.cpp119
-rw-r--r--Source/WebCore/mathml/RenderMathMLBlock.h111
-rw-r--r--Source/WebCore/mathml/RenderMathMLFenced.cpp147
-rw-r--r--Source/WebCore/mathml/RenderMathMLFenced.h53
-rw-r--r--Source/WebCore/mathml/RenderMathMLFraction.cpp186
-rw-r--r--Source/WebCore/mathml/RenderMathMLFraction.h53
-rw-r--r--Source/WebCore/mathml/RenderMathMLMath.cpp46
-rw-r--r--Source/WebCore/mathml/RenderMathMLMath.h45
-rw-r--r--Source/WebCore/mathml/RenderMathMLOperator.cpp344
-rw-r--r--Source/WebCore/mathml/RenderMathMLOperator.h81
-rw-r--r--Source/WebCore/mathml/RenderMathMLRoot.cpp258
-rw-r--r--Source/WebCore/mathml/RenderMathMLRoot.h48
-rw-r--r--Source/WebCore/mathml/RenderMathMLRow.cpp136
-rw-r--r--Source/WebCore/mathml/RenderMathMLRow.h50
-rw-r--r--Source/WebCore/mathml/RenderMathMLSquareRoot.cpp197
-rw-r--r--Source/WebCore/mathml/RenderMathMLSquareRoot.h50
-rw-r--r--Source/WebCore/mathml/RenderMathMLSubSup.cpp212
-rw-r--r--Source/WebCore/mathml/RenderMathMLSubSup.h60
-rw-r--r--Source/WebCore/mathml/RenderMathMLUnderOver.cpp299
-rw-r--r--Source/WebCore/mathml/RenderMathMLUnderOver.h54
-rw-r--r--Source/WebCore/mathml/mathattrs.in23
-rw-r--r--Source/WebCore/mathml/mathtags.in27
30 files changed, 3089 insertions, 0 deletions
diff --git a/Source/WebCore/mathml/MathMLElement.cpp b/Source/WebCore/mathml/MathMLElement.cpp
new file mode 100644
index 0000000..6088810
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLElement.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "MathMLElement.h"
+
+#include "MathMLNames.h"
+#include "RenderObject.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+MathMLElement::MathMLElement(const QualifiedName& tagName, Document* document)
+ : StyledElement(tagName, document, CreateStyledElement)
+{
+}
+
+PassRefPtr<MathMLElement> MathMLElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new MathMLElement(tagName, document));
+}
+
+bool MathMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
+{
+ if (attrName == mathcolorAttr || attrName == mathbackgroundAttr
+ || attrName == colorAttr || attrName == backgroundAttr
+ || attrName == fontsizeAttr || attrName == fontstyleAttr
+ || attrName == fontweightAttr || attrName == fontfamilyAttr) {
+ result = eMathML;
+ return false;
+ }
+ return StyledElement::mapToEntry(attrName, result);
+}
+
+void MathMLElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == mathbackgroundAttr)
+ addCSSProperty(attr, CSSPropertyBackgroundColor, attr->value());
+ else if (attr->name() == mathsizeAttr) {
+ // The following three values of mathsize are handled in WebCore/css/mathml.css
+ if (attr->value() != "normal" && attr->value() != "small" && attr->value() != "big")
+ addCSSProperty(attr, CSSPropertyFontSize, attr->value());
+ } else if (attr->name() == mathcolorAttr)
+ addCSSProperty(attr, CSSPropertyColor, attr->value());
+ // FIXME: deprecated attributes that should loose in a conflict with a non deprecated attribute
+ else if (attr->name() == fontsizeAttr)
+ addCSSProperty(attr, CSSPropertyFontSize, attr->value());
+ else if (attr->name() == backgroundAttr)
+ addCSSProperty(attr, CSSPropertyBackgroundColor, attr->value());
+ else if (attr->name() == colorAttr)
+ addCSSProperty(attr, CSSPropertyColor, attr->value());
+ else if (attr->name() == fontstyleAttr)
+ addCSSProperty(attr, CSSPropertyFontStyle, attr->value());
+ else if (attr->name() == fontweightAttr)
+ addCSSProperty(attr, CSSPropertyFontWeight, attr->value());
+ else if (attr->name() == fontfamilyAttr)
+ addCSSProperty(attr, CSSPropertyFontFamily, attr->value());
+ else
+ StyledElement::parseMappedAttribute(attr);
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/MathMLElement.h b/Source/WebCore/mathml/MathMLElement.h
new file mode 100644
index 0000000..7678f26
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MathMLElement_h
+#define MathMLElement_h
+
+#if ENABLE(MATHML)
+#include "StyledElement.h"
+
+namespace WebCore {
+
+class MathMLElement : public StyledElement {
+public:
+ static PassRefPtr<MathMLElement> create(const QualifiedName& tagName, Document*);
+
+protected:
+ MathMLElement(const QualifiedName& tagName, Document*);
+
+private:
+ virtual bool isMathMLElement() const { return true; }
+ virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
+ virtual void parseMappedAttribute(Attribute*);
+};
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // MathMLElement_h
diff --git a/Source/WebCore/mathml/MathMLInlineContainerElement.cpp b/Source/WebCore/mathml/MathMLInlineContainerElement.cpp
new file mode 100644
index 0000000..eb579d2
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLInlineContainerElement.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "MathMLInlineContainerElement.h"
+
+#include "MathMLNames.h"
+#include "RenderMathMLBlock.h"
+#include "RenderMathMLFenced.h"
+#include "RenderMathMLFraction.h"
+#include "RenderMathMLRoot.h"
+#include "RenderMathMLRow.h"
+#include "RenderMathMLSquareRoot.h"
+#include "RenderMathMLSubSup.h"
+#include "RenderMathMLUnderOver.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+MathMLInlineContainerElement::MathMLInlineContainerElement(const QualifiedName& tagName, Document* document)
+ : MathMLElement(tagName, document)
+{
+}
+
+PassRefPtr<MathMLInlineContainerElement> MathMLInlineContainerElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new MathMLInlineContainerElement(tagName, document));
+}
+
+RenderObject* MathMLInlineContainerElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ if (hasLocalName(mrowTag))
+ return new (arena) RenderMathMLRow(this);
+ if (hasLocalName(msubTag))
+ return new (arena) RenderMathMLSubSup(this);
+ if (hasLocalName(msupTag))
+ return new (arena) RenderMathMLSubSup(this);
+ if (hasLocalName(msubsupTag))
+ return new (arena) RenderMathMLSubSup(this);
+ if (hasLocalName(moverTag))
+ return new (arena) RenderMathMLUnderOver(this);
+ if (hasLocalName(munderTag))
+ return new (arena) RenderMathMLUnderOver(this);
+ if (hasLocalName(munderoverTag))
+ return new (arena) RenderMathMLUnderOver(this);
+ if (hasLocalName(mfracTag))
+ return new (arena) RenderMathMLFraction(this);
+ if (hasLocalName(msqrtTag))
+ return new (arena) RenderMathMLSquareRoot(this);
+ if (hasLocalName(mrootTag))
+ return new (arena) RenderMathMLRoot(this);
+ if (hasLocalName(mfencedTag))
+ return new (arena) RenderMathMLFenced(this);
+
+ return new (arena) RenderMathMLBlock(this);
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/MathMLInlineContainerElement.h b/Source/WebCore/mathml/MathMLInlineContainerElement.h
new file mode 100644
index 0000000..4e80e36
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLInlineContainerElement.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MathMLInlineContainerElement_h
+#define MathMLInlineContainerElement_h
+
+#if ENABLE(MATHML)
+#include "MathMLElement.h"
+
+namespace WebCore {
+
+class MathMLInlineContainerElement : public MathMLElement {
+public:
+ static PassRefPtr<MathMLInlineContainerElement> create(const QualifiedName& tagName, Document*);
+
+protected:
+ MathMLInlineContainerElement(const QualifiedName& tagName, Document*);
+
+private:
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // MathMLInlineContainerElement_h
diff --git a/Source/WebCore/mathml/MathMLMathElement.cpp b/Source/WebCore/mathml/MathMLMathElement.cpp
new file mode 100644
index 0000000..6c5c3c6
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLMathElement.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "MathMLMathElement.h"
+
+#include "RenderMathMLMath.h"
+
+namespace WebCore {
+
+inline MathMLMathElement::MathMLMathElement(const QualifiedName& tagName, Document* document)
+ : MathMLInlineContainerElement(tagName, document)
+{
+}
+
+PassRefPtr<MathMLMathElement> MathMLMathElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new MathMLMathElement(tagName, document));
+}
+
+RenderObject* MathMLMathElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMathMLMath(this);
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/MathMLMathElement.h b/Source/WebCore/mathml/MathMLMathElement.h
new file mode 100644
index 0000000..d31d548
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLMathElement.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MathMLMathElement_h
+#define MathMLMathElement_h
+
+#if ENABLE(MATHML)
+#include "MathMLInlineContainerElement.h"
+
+namespace WebCore {
+
+class MathMLMathElement : public MathMLInlineContainerElement {
+public:
+ static PassRefPtr<MathMLMathElement> create(const QualifiedName& tagName, Document*);
+
+private:
+ MathMLMathElement(const QualifiedName& tagName, Document*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // MathMLMathElement_h
diff --git a/Source/WebCore/mathml/MathMLTextElement.cpp b/Source/WebCore/mathml/MathMLTextElement.cpp
new file mode 100644
index 0000000..8f830cb
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLTextElement.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "MathMLTextElement.h"
+
+#include "MathMLNames.h"
+#include "RenderMathMLOperator.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+inline MathMLTextElement::MathMLTextElement(const QualifiedName& tagName, Document* document)
+ : MathMLElement(tagName, document)
+{
+}
+
+PassRefPtr<MathMLTextElement> MathMLTextElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new MathMLTextElement(tagName, document));
+}
+
+RenderObject* MathMLTextElement::createRenderer(RenderArena* arena, RenderStyle* style)
+{
+ if (hasLocalName(MathMLNames::moTag))
+ return new (arena) RenderMathMLOperator(this);
+
+ return MathMLElement::createRenderer(arena, style);
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/MathMLTextElement.h b/Source/WebCore/mathml/MathMLTextElement.h
new file mode 100644
index 0000000..3af93d5
--- /dev/null
+++ b/Source/WebCore/mathml/MathMLTextElement.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MathMLTextElement_h
+#define MathMLTextElement_h
+
+#if ENABLE(MATHML)
+#include "MathMLElement.h"
+
+namespace WebCore {
+
+class MathMLTextElement : public MathMLElement {
+public:
+ static PassRefPtr<MathMLTextElement> create(const QualifiedName& tagName, Document*);
+
+private:
+ MathMLTextElement(const QualifiedName& tagName, Document*);
+
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+};
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // MathMLTextElement_h
diff --git a/Source/WebCore/mathml/RenderMathMLBlock.cpp b/Source/WebCore/mathml/RenderMathMLBlock.cpp
new file mode 100644
index 0000000..14e7656
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLBlock.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+#include "FontSelector.h"
+#include "GraphicsContext.h"
+#include "MathMLNames.h"
+#include "RenderInline.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+RenderMathMLBlock::RenderMathMLBlock(Node* container)
+ : RenderBlock(container)
+{
+}
+
+bool RenderMathMLBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->node() && child->node()->nodeType() == Node::ELEMENT_NODE;
+}
+
+PassRefPtr<RenderStyle> RenderMathMLBlock::makeBlockStyle()
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+ return newStyle;
+}
+
+int RenderMathMLBlock::nonOperatorHeight() const
+{
+ if (!isRenderMathMLOperator())
+ return offsetHeight();
+
+ return 0;
+}
+
+void RenderMathMLBlock::stretchToHeight(int height)
+{
+ for (RenderObject* current = firstChild(); current; current = current->nextSibling())
+ if (current->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(current);
+ block->stretchToHeight(height);
+ }
+}
+
+#if ENABLE(DEBUG_MATH_LAYOUT)
+void RenderMathMLBlock::paint(PaintInfo& info, int tx, int ty)
+{
+ RenderBlock::paint(info, tx, ty);
+
+ if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground)
+ return;
+
+ tx += x();
+ ty += y();
+
+ info.context->save();
+
+ info.context->setStrokeThickness(1.0f);
+ info.context->setStrokeStyle(SolidStroke);
+ info.context->setStrokeColor(Color(0, 0, 255), ColorSpaceSRGB);
+
+ info.context->drawLine(IntPoint(tx, ty), IntPoint(tx + offsetWidth(), ty));
+ info.context->drawLine(IntPoint(tx + offsetWidth(), ty), IntPoint(tx + offsetWidth(), ty + offsetHeight()));
+ info.context->drawLine(IntPoint(tx, ty + offsetHeight()), IntPoint(tx + offsetWidth(), ty + offsetHeight()));
+ info.context->drawLine(IntPoint(tx, ty), IntPoint(tx, ty + offsetHeight()));
+
+ int topStart = paddingTop();
+
+ info.context->setStrokeColor(Color(0, 255, 0), ColorSpaceSRGB);
+
+ info.context->drawLine(IntPoint(tx, ty + topStart), IntPoint(tx + offsetWidth(), ty + topStart));
+
+ int baseline = baselinePosition(AlphabeticBaseline, true, HorizontalLine);
+
+ info.context->setStrokeColor(Color(255, 0, 0), ColorSpaceSRGB);
+
+ info.context->drawLine(IntPoint(tx, ty + baseline), IntPoint(tx + offsetWidth(), ty + baseline));
+
+ info.context->restore();
+
+}
+#endif // ENABLE(DEBUG_MATH_LAYOUT)
+
+
+}
+
+#endif
diff --git a/Source/WebCore/mathml/RenderMathMLBlock.h b/Source/WebCore/mathml/RenderMathMLBlock.h
new file mode 100644
index 0000000..f05122a
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLBlock.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLBlock_h
+#define RenderMathMLBlock_h
+
+#if ENABLE(MATHML)
+
+#include "RenderBlock.h"
+
+#define ENABLE_DEBUG_MATH_LAYOUT 0
+
+namespace WebCore {
+
+class RenderMathMLBlock : public RenderBlock {
+public:
+ RenderMathMLBlock(Node* container);
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+
+ virtual bool isRenderMathMLBlock() const { return true; }
+ virtual bool isRenderMathMLOperator() const { return false; }
+ virtual bool isRenderMathMLRow() const { return false; }
+ virtual bool isRenderMathMLMath() const { return false; }
+ virtual bool hasBase() const { return false; }
+ virtual int nonOperatorHeight() const;
+ virtual void stretchToHeight(int height);
+
+#if ENABLE(DEBUG_MATH_LAYOUT)
+ virtual void paint(PaintInfo&, int tx, int ty);
+#endif
+
+protected:
+ int getBoxModelObjectHeight(RenderObject* object)
+ {
+ if (object && object->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(object);
+ return box->offsetHeight();
+ }
+
+ return 0;
+ }
+ int getBoxModelObjectHeight(const RenderObject* object)
+ {
+ if (object && object->isBoxModelObject()) {
+ const RenderBoxModelObject* box = toRenderBoxModelObject(object);
+ return box->offsetHeight();
+ }
+
+ return 0;
+ }
+ int getBoxModelObjectWidth(RenderObject* object)
+ {
+ if (object && object->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(object);
+ return box->offsetWidth();
+ }
+
+ return 0;
+ }
+ int getBoxModelObjectWidth(const RenderObject* object)
+ {
+ if (object && object->isBoxModelObject()) {
+ const RenderBoxModelObject* box = toRenderBoxModelObject(object);
+ return box->offsetWidth();
+ }
+
+ return 0;
+ }
+ virtual PassRefPtr<RenderStyle> makeBlockStyle();
+
+};
+
+inline RenderMathMLBlock* toRenderMathMLBlock(RenderObject* object)
+{
+ ASSERT(!object || object->isRenderMathMLBlock());
+ return static_cast<RenderMathMLBlock*>(object);
+}
+
+inline const RenderMathMLBlock* toRenderMathMLBlock(const RenderObject* object)
+{
+ ASSERT(!object || object->isRenderMathMLBlock());
+ return static_cast<const RenderMathMLBlock*>(object);
+}
+
+}
+
+
+#endif // ENABLE(MATHML)
+#endif // RenderMathMLBlock_h
diff --git a/Source/WebCore/mathml/RenderMathMLFenced.cpp b/Source/WebCore/mathml/RenderMathMLFenced.cpp
new file mode 100644
index 0000000..f7bbf71
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLFenced.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLFenced.h"
+
+#include "FontSelector.h"
+#include "MathMLNames.h"
+#include "RenderInline.h"
+#include "RenderMathMLOperator.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+enum Braces { OpeningBraceChar = 0x28, ClosingBraceChar = 0x29 };
+
+static const float gOperatorPadding = 0.1f;
+
+RenderMathMLFenced::RenderMathMLFenced(Node* fenced)
+ : RenderMathMLRow(fenced)
+ , m_open(OpeningBraceChar)
+ , m_close(ClosingBraceChar)
+{
+}
+
+void RenderMathMLFenced::updateFromElement()
+{
+ Element* fenced = static_cast<Element*>(node());
+
+ // FIXME: Handle open/close values with more than one character (they should be treated like text).
+ AtomicString openValue = fenced->getAttribute(MathMLNames::openAttr);
+ if (openValue.length() > 0)
+ m_open = openValue[0];
+ AtomicString closeValue = fenced->getAttribute(MathMLNames::closeAttr);
+ if (closeValue.length() > 0)
+ m_close = closeValue[0];
+
+ AtomicString separators = static_cast<Element*>(fenced)->getAttribute(MathMLNames::separatorsAttr);
+ if (!separators.isNull()) {
+ Vector<UChar> characters;
+ for (unsigned int i = 0; i < separators.length(); i++) {
+ if (!isSpaceOrNewline(separators[i]))
+ characters.append(separators[i]);
+ }
+ m_separators = !characters.size() ? 0 : StringImpl::create(characters.data() , characters.size());
+ } else {
+ // The separator defaults to a single comma.
+ m_separators = StringImpl::create(",");
+ }
+
+ if (isEmpty())
+ makeFences();
+}
+
+RefPtr<RenderStyle> RenderMathMLFenced::makeOperatorStyle()
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(INLINE_BLOCK);
+ newStyle->setPaddingRight(Length(static_cast<int>(gOperatorPadding * style()->fontSize()), Fixed));
+ return newStyle;
+}
+
+void RenderMathMLFenced::makeFences()
+{
+ RenderObject* openFence = new (renderArena()) RenderMathMLOperator(node(), m_open);
+ openFence->setStyle(makeOperatorStyle().release());
+ RenderBlock::addChild(openFence, firstChild());
+ RenderObject* closeFence = new (renderArena()) RenderMathMLOperator(node(), m_close);
+ closeFence->setStyle(makeOperatorStyle().release());
+ RenderBlock::addChild(closeFence);
+}
+
+void RenderMathMLFenced::addChild(RenderObject* child, RenderObject*)
+{
+ // make the fences if the render object is empty
+ if (isEmpty())
+ updateFromElement();
+
+ if (m_separators.get()) {
+ unsigned int count = 0;
+ for (Node* position = child->node(); position; position = position->previousSibling()) {
+ if (position->nodeType() == Node::ELEMENT_NODE)
+ count++;
+ }
+
+ if (count > 1) {
+ UChar separator;
+
+ // Use the last separator if we've run out of specified separators.
+ if ((count - 1) >= m_separators.get()->length())
+ separator = (*m_separators.get())[m_separators.get()->length() - 1];
+ else
+ separator = (*m_separators.get())[count - 1];
+
+ RenderObject* separatorObj = new (renderArena()) RenderMathMLOperator(node(), separator);
+ separatorObj->setStyle(makeOperatorStyle().release());
+ RenderBlock::addChild(separatorObj, lastChild());
+ }
+ }
+
+ // If we have a block, we'll wrap it in an inline-block.
+ if (child->isBlockFlow() && child->style()->display() != INLINE_BLOCK) {
+ // Block objects wrapper.
+
+ RenderBlock* block = new (renderArena()) RenderBlock(node());
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(INLINE_BLOCK);
+ block->setStyle(newStyle.release());
+
+ RenderBlock::addChild(block, lastChild());
+ block->addChild(child);
+ } else
+ RenderBlock::addChild(child, lastChild());
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/mathml/RenderMathMLFenced.h b/Source/WebCore/mathml/RenderMathMLFenced.h
new file mode 100644
index 0000000..64e4d90
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLFenced.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLFenced_h
+#define RenderMathMLFenced_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLRow.h"
+
+namespace WebCore {
+
+class RenderMathMLFenced : public RenderMathMLRow {
+public:
+ RenderMathMLFenced(Node *fraction);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void updateFromElement();
+
+private:
+ void makeFences();
+ RefPtr<RenderStyle> makeOperatorStyle();
+ UChar m_open;
+ UChar m_close;
+ RefPtr<StringImpl> m_separators;
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLFenced_h
diff --git a/Source/WebCore/mathml/RenderMathMLFraction.cpp b/Source/WebCore/mathml/RenderMathMLFraction.cpp
new file mode 100644
index 0000000..1435be7
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLFraction.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLFraction.h"
+
+#include "GraphicsContext.h"
+#include "MathMLNames.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+static const double gHorizontalPad = 0.2;
+static const int gLineThin = 1;
+static const int gLineMedium = 3;
+static const int gLineThick = 5;
+static const double gFractionAlignment = 0.25;
+static const double gFractionBarWidth = 0.05;
+static const double gDenominatorPad = 0.1;
+
+RenderMathMLFraction::RenderMathMLFraction(Element* fraction)
+ : RenderMathMLBlock(fraction)
+ , m_lineThickness(gLineThin)
+{
+ setChildrenInline(false);
+}
+
+void RenderMathMLFraction::updateFromElement()
+{
+ // FIXME: mfrac where bevelled=true will need to reorganize the descendants
+ if (isEmpty())
+ return;
+
+ Element* fraction = static_cast<Element*>(node());
+
+ RenderObject* numerator = firstChild();
+ String nalign = fraction->getAttribute(MathMLNames::numalignAttr);
+ if (equalIgnoringCase(nalign, "left"))
+ numerator->style()->setTextAlign(LEFT);
+ else if (equalIgnoringCase(nalign, "right"))
+ numerator->style()->setTextAlign(RIGHT);
+ else
+ numerator->style()->setTextAlign(CENTER);
+
+ RenderObject* denominator = numerator->nextSibling();
+ if (!denominator)
+ return;
+
+ String dalign = fraction->getAttribute(MathMLNames::denomalignAttr);
+ if (equalIgnoringCase(dalign, "left"))
+ denominator->style()->setTextAlign(LEFT);
+ else if (equalIgnoringCase(dalign, "right"))
+ denominator->style()->setTextAlign(RIGHT);
+ else
+ denominator->style()->setTextAlign(CENTER);
+
+ // FIXME: parse units
+ String thickness = fraction->getAttribute(MathMLNames::linethicknessAttr);
+ m_lineThickness = gLineThin;
+ if (equalIgnoringCase(thickness, "thin"))
+ m_lineThickness = gLineThin;
+ else if (equalIgnoringCase(thickness, "medium"))
+ m_lineThickness = gLineMedium;
+ else if (equalIgnoringCase(thickness, "thick"))
+ m_lineThickness = gLineThick;
+ else if (equalIgnoringCase(thickness, "0"))
+ m_lineThickness = 0;
+
+ // Update the style for the padding of the denominator for the line thickness
+ lastChild()->style()->setPaddingTop(Length(static_cast<int>(m_lineThickness + style()->fontSize() * gDenominatorPad), Fixed));
+}
+
+void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ RenderBlock* row = new (renderArena()) RenderMathMLBlock(node());
+ RefPtr<RenderStyle> rowStyle = makeBlockStyle();
+
+ rowStyle->setTextAlign(CENTER);
+ Length pad(static_cast<int>(rowStyle->fontSize() * gHorizontalPad), Fixed);
+ rowStyle->setPaddingLeft(pad);
+ rowStyle->setPaddingRight(pad);
+
+ // Only add padding for rows as denominators
+ bool isNumerator = isEmpty();
+ if (!isNumerator)
+ rowStyle->setPaddingTop(Length(2, Fixed));
+
+ row->setStyle(rowStyle.release());
+ RenderBlock::addChild(row, beforeChild);
+ row->addChild(child);
+ updateFromElement();
+}
+
+void RenderMathMLFraction::layout()
+{
+ updateFromElement();
+
+ // Adjust the fraction line thickness for the zoom
+ if (lastChild() && lastChild()->isRenderBlock())
+ m_lineThickness = static_cast<int>(m_lineThickness * ceil(gFractionBarWidth * style()->fontSize()));
+
+ RenderBlock::layout();
+
+}
+
+void RenderMathMLFraction::paint(PaintInfo& info, int tx, int ty)
+{
+ RenderMathMLBlock::paint(info, tx, ty);
+ if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground)
+ return;
+
+ if (!firstChild() ||!m_lineThickness)
+ return;
+
+ int verticalOffset = 0;
+ // The children are always RenderMathMLBlock instances
+ if (firstChild()->isRenderMathMLBlock()) {
+ int adjustForThickness = m_lineThickness > 1 ? m_lineThickness / 2 : 1;
+ if (m_lineThickness % 2 == 1)
+ adjustForThickness++;
+ RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
+ if (numerator->isRenderMathMLRow())
+ verticalOffset = numerator->offsetHeight() + adjustForThickness;
+ else
+ verticalOffset = numerator->offsetHeight();
+ }
+
+ tx += x();
+ ty += y() + verticalOffset;
+
+ info.context->save();
+
+ info.context->setStrokeThickness(static_cast<float>(m_lineThickness));
+ info.context->setStrokeStyle(SolidStroke);
+ info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceSRGB);
+
+ info.context->drawLine(IntPoint(tx, ty), IntPoint(tx + offsetWidth(), ty));
+
+ info.context->restore();
+}
+
+int RenderMathMLFraction::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+{
+ if (firstChild() && firstChild()->isRenderMathMLBlock()) {
+ RenderMathMLBlock* numerator = toRenderMathMLBlock(firstChild());
+ // FIXME: the baseline should adjust so the fraction line aligns
+ // relative certain operators (e.g. aligns with the horizontal
+ // stroke of the plus). 1/3 of the current font size is just
+ // a good guess.
+ return numerator->offsetHeight() + style()->fontSize() / 3;
+ }
+ return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
+}
+
+}
+
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/RenderMathMLFraction.h b/Source/WebCore/mathml/RenderMathMLFraction.h
new file mode 100644
index 0000000..8a3a9ed
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLFraction.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLFraction_h
+#define RenderMathMLFraction_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLFraction : public RenderMathMLBlock {
+public:
+ RenderMathMLFraction(Element* fraction);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void updateFromElement();
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual void paint(PaintInfo&, int tx, int ty);
+protected:
+ virtual void layout();
+private:
+ int m_lineThickness;
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLFraction_h
diff --git a/Source/WebCore/mathml/RenderMathMLMath.cpp b/Source/WebCore/mathml/RenderMathMLMath.cpp
new file mode 100644
index 0000000..2b65f69
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLMath.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLMath.h"
+
+#include "MathMLNames.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+RenderMathMLMath::RenderMathMLMath(Node* math)
+ : RenderMathMLRow(math)
+{
+}
+
+}
+
+#endif // ENABLE(MATHML)
+
diff --git a/Source/WebCore/mathml/RenderMathMLMath.h b/Source/WebCore/mathml/RenderMathMLMath.h
new file mode 100644
index 0000000..26f2093
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLMath.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLMath_h
+#define RenderMathMLMath_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLRow.h"
+
+namespace WebCore {
+
+class RenderMathMLMath : public RenderMathMLRow {
+public:
+ RenderMathMLMath(Node* container);
+ virtual bool isRenderMathMLMath() const { return true; }
+};
+
+}
+
+
+#endif // ENABLE(MATHML)
+#endif // RenderMathMLMath_h
diff --git a/Source/WebCore/mathml/RenderMathMLOperator.cpp b/Source/WebCore/mathml/RenderMathMLOperator.cpp
new file mode 100644
index 0000000..7f039b9
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLOperator.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLOperator.h"
+
+#include "FontSelector.h"
+#include "MathMLNames.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+RenderMathMLOperator::RenderMathMLOperator(Node* container)
+ : RenderMathMLBlock(container)
+ , m_stretchHeight(0)
+ , m_operator(0)
+{
+}
+
+RenderMathMLOperator::RenderMathMLOperator(Node* container, UChar operatorChar)
+ : RenderMathMLBlock(container)
+ , m_stretchHeight(0)
+ , m_operator(convertHyphenMinusToMinusSign(operatorChar))
+{
+}
+
+bool RenderMathMLOperator::isChildAllowed(RenderObject*, RenderStyle*) const
+{
+ return false;
+}
+
+static const float gOperatorSpacer = 0.1f;
+static const float gOperatorExpansion = 1.2f;
+
+void RenderMathMLOperator::stretchToHeight(int height)
+{
+ if (height == m_stretchHeight)
+ return;
+ m_stretchHeight = static_cast<int>(height * gOperatorExpansion);
+
+ updateBoxModelInfoFromStyle();
+ setNeedsLayout(true);
+}
+
+void RenderMathMLOperator::layout()
+{
+ // FIXME: This probably shouldn't be called here but when the operator
+ // isn't stretched (e.g. outside of a mrow), it needs to be called somehow
+ updateFromElement();
+ RenderBlock::layout();
+}
+
+// This is a table of stretchy characters.
+// FIXME: Should this be read from the unicode characteristics somehow?
+// table: stretchy operator, top char, extension char, bottom char, middle char
+static struct StretchyCharacter {
+ UChar character;
+ UChar topGlyph;
+ UChar extensionGlyph;
+ UChar bottomGlyph;
+ UChar middleGlyph;
+} stretchyCharacters[13] = {
+ { 0x28 , 0x239b, 0x239c, 0x239d, 0x0 }, // left parenthesis
+ { 0x29 , 0x239e, 0x239f, 0x23a0, 0x0 }, // right parenthesis
+ { 0x5b , 0x23a1, 0x23a2, 0x23a3, 0x0 }, // left square bracket
+ { 0x2308, 0x23a1, 0x23a2, 0x23a2, 0x0 }, // left ceiling
+ { 0x230a, 0x23a2, 0x23a2, 0x23a3, 0x0 }, // left floor
+ { 0x5d , 0x23a4, 0x23a5, 0x23a6, 0x0 }, // right square bracket
+ { 0x2309, 0x23a4, 0x23a5, 0x23a5, 0x0 }, // right ceiling
+ { 0x230b, 0x23a5, 0x23a5, 0x23a6, 0x0 }, // right floor
+ { 0x7b , 0x23a7, 0x23aa, 0x23a9, 0x23a8 }, // left curly bracket
+ { 0x7c , 0x23d0, 0x23d0, 0x23d0, 0x0 }, // vertical bar
+ { 0x2016, 0x2016, 0x2016, 0x2016, 0x0 }, // double vertical line
+ { 0x7d , 0x23ab, 0x23aa, 0x23ad, 0x23ac }, // right curly bracket
+ { 0x222b, 0x2320, 0x23ae, 0x2321, 0x0 } // integral sign
+};
+
+// We stack glyphs using a 14px height with a displayed glyph height
+// of 10px. The line height is set to less than the 14px so that there
+// are no blank spaces between the stacked glyphs.
+//
+// Certain glyphs (e.g. middle and bottom) need to be adjusted upwards
+// in the stack so that there isn't a gap.
+//
+// All of these settings are represented in the constants below.
+
+// FIXME: use fractions of style()->fontSize() for proper zooming/resizing.
+static const int gGlyphFontSize = 14;
+static const int gGlyphLineHeight = 11;
+static const int gMinimumStretchHeight = 24;
+static const int gGlyphHeight = 10;
+static const int gTopGlyphTopAdjust = 1;
+static const int gMiddleGlyphTopAdjust = -1;
+static const int gBottomGlyphTopAdjust = -3;
+static const float gMinimumRatioForStretch = 0.10f;
+
+void RenderMathMLOperator::updateFromElement()
+{
+ // Destroy our current children
+ children()->destroyLeftoverChildren();
+
+ // Since we share a node with our children, destroying our children will set our node's
+ // renderer to 0, so we need to re-set it back to this.
+ node()->setRenderer(this);
+
+ // If the operator is fixed, it will be contained in m_operator
+ UChar firstChar = m_operator;
+
+ // This boolean indicates whether stretching is disabled via the markup.
+ bool stretchDisabled = false;
+
+ // We made need the element later if we can't stretch.
+ if (node()->nodeType() == Node::ELEMENT_NODE) {
+ if (Element* mo = static_cast<Element*>(node())) {
+ AtomicString stretchyAttr = mo->getAttribute(MathMLNames::stretchyAttr);
+ stretchDisabled = equalIgnoringCase(stretchyAttr, "false");
+
+ // If stretching isn't disabled, get the character from the text content.
+ if (!stretchDisabled && !firstChar) {
+ String opText = mo->textContent();
+ for (unsigned int i = 0; !firstChar && i < opText.length(); i++) {
+ if (!isSpaceOrNewline(opText[i]))
+ firstChar = opText[i];
+ }
+ }
+ }
+ }
+
+ // The 'index' holds the stretchable character's glyph information
+ int index = -1;
+
+ // isStretchy indicates whether the character is streatchable via a number of factors.
+ bool isStretchy = false;
+
+ // Check for a stretchable character.
+ if (!stretchDisabled && firstChar) {
+ const int maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters);
+ for (index++; index < maxIndex; index++) {
+ if (stretchyCharacters[index].character == firstChar) {
+ isStretchy = true;
+ break;
+ }
+ }
+ }
+
+ // We only stretch character if the stretch height is larger than a minimum size (e.g. 24px).
+ bool shouldStretch = isStretchy && m_stretchHeight>gMinimumStretchHeight;
+
+ // Either stretch is disabled or we don't have a stretchable character over the minimum height
+ if (stretchDisabled || !shouldStretch) {
+ m_isStacked = false;
+ RenderBlock* container = new (renderArena()) RenderMathMLBlock(node());
+
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(INLINE_BLOCK);
+ newStyle->setVerticalAlign(BASELINE);
+
+ // Check for a stretchable character that is under the minimum height and use the
+ // font size to adjust the glyph size.
+ int currentFontSize = style()->fontSize();
+ if (!stretchDisabled && isStretchy && m_stretchHeight > 0 && m_stretchHeight <= gMinimumStretchHeight && m_stretchHeight > currentFontSize) {
+ FontDescription desc;
+ desc.setIsAbsoluteSize(true);
+ desc.setSpecifiedSize(m_stretchHeight);
+ desc.setComputedSize(m_stretchHeight);
+ newStyle->setFontDescription(desc);
+ newStyle->font().update(newStyle->font().fontSelector());
+ }
+
+ container->setStyle(newStyle.release());
+ addChild(container);
+
+ // Build the text of the operator.
+ RenderText* text = 0;
+ if (m_operator)
+ text = new (renderArena()) RenderText(node(), StringImpl::create(&m_operator, 1));
+ else if (node()->nodeType() == Node::ELEMENT_NODE)
+ if (Element* mo = static_cast<Element*>(node()))
+ text = new (renderArena()) RenderText(node(), mo->textContent().replace(hyphenMinus, minusSign).impl());
+ // If we can't figure out the text, leave it blank.
+ if (text) {
+ RefPtr<RenderStyle> textStyle = RenderStyle::create();
+ textStyle->inheritFrom(container->style());
+ text->setStyle(textStyle.release());
+ container->addChild(text);
+ }
+ } else {
+ // Build stretchable characters as a stack of glyphs.
+ m_isStacked = true;
+
+ if (stretchyCharacters[index].middleGlyph) {
+ // We have a middle glyph (e.g. a curly bracket) that requires special processing.
+ int half = (m_stretchHeight - gGlyphHeight) / 2;
+ if (half <= gGlyphHeight) {
+ // We only have enough space for a single middle glyph.
+ createGlyph(stretchyCharacters[index].topGlyph, half, gTopGlyphTopAdjust);
+ createGlyph(stretchyCharacters[index].middleGlyph, gGlyphHeight, gMiddleGlyphTopAdjust);
+ createGlyph(stretchyCharacters[index].bottomGlyph, 0, gBottomGlyphTopAdjust);
+ } else {
+ // We have to extend both the top and bottom to the middle.
+ createGlyph(stretchyCharacters[index].topGlyph, gGlyphHeight, gTopGlyphTopAdjust);
+ int remaining = half - gGlyphHeight;
+ while (remaining > 0) {
+ if (remaining < gGlyphHeight) {
+ createGlyph(stretchyCharacters[index].extensionGlyph, remaining);
+ remaining = 0;
+ } else {
+ createGlyph(stretchyCharacters[index].extensionGlyph, gGlyphHeight);
+ remaining -= gGlyphHeight;
+ }
+ }
+
+ // The middle glyph in the stack.
+ createGlyph(stretchyCharacters[index].middleGlyph, gGlyphHeight, gMiddleGlyphTopAdjust);
+
+ // The remaining is the top half minus the middle glyph height.
+ remaining = half - gGlyphHeight;
+ // We need to make sure we have the full height in case the height is odd.
+ if (m_stretchHeight % 2 == 1)
+ remaining++;
+
+ // Extend to the bottom glyph.
+ while (remaining > 0) {
+ if (remaining < gGlyphHeight) {
+ createGlyph(stretchyCharacters[index].extensionGlyph, remaining);
+ remaining = 0;
+ } else {
+ createGlyph(stretchyCharacters[index].extensionGlyph, gGlyphHeight);
+ remaining -= gGlyphHeight;
+ }
+ }
+
+ // The bottom glyph in the stack.
+ createGlyph(stretchyCharacters[index].bottomGlyph, 0, gBottomGlyphTopAdjust);
+ }
+ } else {
+ // We do not have a middle glyph and so we just extend from the top to the bottom glyph.
+ int remaining = m_stretchHeight - 2 * gGlyphHeight;
+ createGlyph(stretchyCharacters[index].topGlyph, gGlyphHeight, gTopGlyphTopAdjust);
+ while (remaining > 0) {
+ if (remaining < gGlyphHeight) {
+ createGlyph(stretchyCharacters[index].extensionGlyph, remaining);
+ remaining = 0;
+ } else {
+ createGlyph(stretchyCharacters[index].extensionGlyph, gGlyphHeight);
+ remaining -= gGlyphHeight;
+ }
+ }
+ createGlyph(stretchyCharacters[index].bottomGlyph, 0, gBottomGlyphTopAdjust);
+ }
+ }
+}
+
+RefPtr<RenderStyle> RenderMathMLOperator::createStackableStyle(int size, int topRelative)
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+
+ FontDescription desc;
+ desc.setIsAbsoluteSize(true);
+ desc.setSpecifiedSize(gGlyphFontSize);
+ desc.setComputedSize(gGlyphFontSize);
+ newStyle->setFontDescription(desc);
+ newStyle->font().update(newStyle->font().fontSelector());
+ newStyle->setLineHeight(Length(gGlyphLineHeight, Fixed));
+ newStyle->setVerticalAlign(TOP);
+
+ if (size > 0)
+ newStyle->setMaxHeight(Length(size, Fixed));
+
+ newStyle->setOverflowY(OHIDDEN);
+ newStyle->setOverflowX(OHIDDEN);
+ if (topRelative) {
+ newStyle->setTop(Length(topRelative, Fixed));
+ newStyle->setPosition(RelativePosition);
+ }
+
+ return newStyle;
+}
+
+RenderBlock* RenderMathMLOperator::createGlyph(UChar glyph, int size, int charRelative, int topRelative)
+{
+ RenderBlock* container = new (renderArena()) RenderMathMLBlock(node());
+ container->setStyle(createStackableStyle(size, topRelative).release());
+ addChild(container);
+ RenderBlock* parent = container;
+ if (charRelative) {
+ RenderBlock* charBlock = new (renderArena()) RenderBlock(node());
+ RefPtr<RenderStyle> charStyle = RenderStyle::create();
+ charStyle->inheritFrom(container->style());
+ charStyle->setDisplay(INLINE_BLOCK);
+ charStyle->setTop(Length(charRelative, Fixed));
+ charStyle->setPosition(RelativePosition);
+ charBlock->setStyle(charStyle);
+ parent->addChild(charBlock);
+ parent = charBlock;
+ }
+
+ RenderText* text = new (renderArena()) RenderText(node(), StringImpl::create(&glyph, 1));
+ text->setStyle(container->style());
+ parent->addChild(text);
+ return container;
+}
+
+int RenderMathMLOperator::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
+{
+ if (m_isStacked)
+ return m_stretchHeight * 2 / 3 - (m_stretchHeight - static_cast<int>(m_stretchHeight / gOperatorExpansion)) / 2;
+ return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/mathml/RenderMathMLOperator.h b/Source/WebCore/mathml/RenderMathMLOperator.h
new file mode 100644
index 0000000..6501494
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLOperator.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLOperator_h
+#define RenderMathMLOperator_h
+
+#if ENABLE(MATHML)
+
+#include "CharacterNames.h"
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLOperator : public RenderMathMLBlock {
+public:
+ RenderMathMLOperator(Node* container);
+ RenderMathMLOperator(Node* container, UChar operatorChar);
+ virtual bool isRenderMathMLOperator() const { return true; }
+ virtual void stretchToHeight(int pixelHeight);
+ virtual void updateFromElement();
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+
+protected:
+ virtual void layout();
+ virtual RefPtr<RenderStyle> createStackableStyle(int size, int topRelative);
+ virtual RenderBlock* createGlyph(UChar glyph, int size = 0, int charRelative = 0, int topRelative = 0);
+
+private:
+ int m_stretchHeight;
+ bool m_isStacked;
+ UChar m_operator;
+};
+
+inline RenderMathMLOperator* toRenderMathMLOperator(RenderMathMLBlock* block)
+{
+ ASSERT(!block || block->isRenderMathMLOperator());
+ return static_cast<RenderMathMLOperator*>(block);
+}
+
+inline const RenderMathMLOperator* toRenderMathMLOperator(const RenderMathMLBlock* block)
+{
+ ASSERT(!block || block->isRenderMathMLOperator());
+ return static_cast<const RenderMathMLOperator*>(block);
+}
+
+inline UChar convertHyphenMinusToMinusSign(UChar glyph)
+{
+ // When rendered as a mathematical operator, minus glyph should be larger.
+ if (glyph == hyphenMinus)
+ return minusSign;
+
+ return glyph;
+}
+
+}
+
+#endif // ENABLE(MATHML)
+#endif // RenderMathMLOperator_h
diff --git a/Source/WebCore/mathml/RenderMathMLRoot.cpp b/Source/WebCore/mathml/RenderMathMLRoot.cpp
new file mode 100644
index 0000000..f0a7abb
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLRoot.cpp
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLRoot.h"
+
+#include "GraphicsContext.h"
+#include "MathMLNames.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+// Left margin of the radical (px)
+const int gRadicalLeftMargin = 3;
+// Bottom padding of the radical (px)
+const int gRadicalBasePad = 3;
+// Threshold above which the radical shape is modified to look nice with big bases (%)
+const float gThresholdBaseHeight = 1.5f;
+// Radical width (%)
+const float gRadicalWidth = 0.75f;
+// Horizontal position of the bottom point of the radical (%)
+const float gRadicalBottomPointXPos= 0.5f;
+// Horizontal position of the top left point of the radical (%)
+const float gRadicalTopLeftPointXPos = 0.8f;
+// Vertical position of the top left point of the radical (%)
+const float gRadicalTopLeftPointYPos = 0.625f;
+// Vertical shift of the left end point of the radical (%)
+const float gRadicalLeftEndYShift = 0.05f;
+// Root padding around the base (%)
+const float gRootPadding = 0.2f;
+// Additional bottom root padding (%)
+const float gRootBottomPadding = 0.2f;
+
+// Radical line thickness (%)
+const float gRadicalLineThickness = 0.02f;
+// Radical thick line thickness (%)
+const float gRadicalThickLineThickness = 0.1f;
+
+RenderMathMLRoot::RenderMathMLRoot(Node *expression)
+: RenderMathMLBlock(expression)
+{
+}
+
+void RenderMathMLRoot::addChild(RenderObject* child, RenderObject* )
+{
+ if (isEmpty()) {
+ // Add a block for the index
+ RenderBlock* block = new (renderArena()) RenderBlock(node());
+ RefPtr<RenderStyle> indexStyle = makeBlockStyle();
+ indexStyle->setDisplay(INLINE_BLOCK);
+ block->setStyle(indexStyle.release());
+ RenderBlock::addChild(block);
+
+ // FIXME: the wrapping does not seem to be needed anymore.
+ // this is the base, so wrap it so we can pad it
+ block = new (renderArena()) RenderBlock(node());
+ RefPtr<RenderStyle> baseStyle = makeBlockStyle();
+ baseStyle->setDisplay(INLINE_BLOCK);
+ baseStyle->setPaddingLeft(Length(5 * gRadicalWidth , Percent));
+ block->setStyle(baseStyle.release());
+ RenderBlock::addChild(block);
+ block->addChild(child);
+ } else {
+ // always add to the index
+ firstChild()->addChild(child);
+ }
+}
+
+void RenderMathMLRoot::paint(PaintInfo& info, int tx, int ty)
+{
+ RenderMathMLBlock::paint(info , tx , ty);
+
+ if (info.context->paintingDisabled())
+ return;
+
+ if (!firstChild() || !lastChild())
+ return;
+
+ tx += x();
+ ty += y();
+
+ RenderBoxModelObject* indexBox = toRenderBoxModelObject(lastChild());
+
+ int maxHeight = indexBox->offsetHeight();
+ // default to the font size in pixels if we're empty
+ if (!maxHeight)
+ maxHeight = style()->fontSize();
+ int width = indexBox->offsetWidth();
+
+ int indexWidth = 0;
+ RenderObject* current = firstChild();
+ while (current != lastChild()) {
+ if (current->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(current);
+ indexWidth += box->offsetWidth();
+ }
+ current = current->nextSibling();
+ }
+
+ int frontWidth = static_cast<int>(style()->fontSize() * gRadicalWidth);
+ int topStartShift = 0;
+ // Base height above which the shape of the root changes
+ int thresholdHeight = static_cast<int>(gThresholdBaseHeight * style()->fontSize());
+
+ if (maxHeight > thresholdHeight && thresholdHeight) {
+ float shift = (maxHeight - thresholdHeight) / static_cast<float>(thresholdHeight);
+ if (shift > 1.)
+ shift = 1.0f;
+ topStartShift = static_cast<int>(gRadicalBottomPointXPos * frontWidth * shift);
+ }
+
+ width += topStartShift;
+
+ int rootPad = static_cast<int>(gRootPadding * style()->fontSize());
+ int start = tx + indexWidth + gRadicalLeftMargin + style()->paddingLeft().value() - rootPad;
+ ty += style()->paddingTop().value() - rootPad;
+
+ FloatPoint topStart(start - topStartShift, ty);
+ FloatPoint bottomLeft(start - gRadicalBottomPointXPos * frontWidth , ty + maxHeight + gRadicalBasePad);
+ FloatPoint topLeft(start - gRadicalTopLeftPointXPos * frontWidth , ty + gRadicalTopLeftPointYPos * maxHeight);
+ FloatPoint leftEnd(start - frontWidth , topLeft.y() + gRadicalLeftEndYShift * style()->fontSize());
+
+ info.context->save();
+
+ info.context->setStrokeThickness(gRadicalLineThickness * style()->fontSize());
+ info.context->setStrokeStyle(SolidStroke);
+ info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
+ info.context->setLineJoin(MiterJoin);
+ info.context->setMiterLimit(style()->fontSize());
+
+ Path root;
+
+ root.moveTo(FloatPoint(topStart.x() + width, ty));
+ // draw top
+ root.addLineTo(topStart);
+ // draw from top left corner to bottom point of radical
+ root.addLineTo(bottomLeft);
+ // draw from bottom point to top of left part of radical base "pocket"
+ root.addLineTo(topLeft);
+ // draw to end
+ root.addLineTo(leftEnd);
+
+ info.context->strokePath(root);
+
+ info.context->save();
+
+ // Build a mask to draw the thick part of the root.
+ Path mask;
+
+ mask.moveTo(topStart);
+ mask.addLineTo(bottomLeft);
+ mask.addLineTo(topLeft);
+ mask.addLineTo(FloatPoint(2 * topLeft.x() - leftEnd.x(), 2 * topLeft.y() - leftEnd.y()));
+
+ info.context->clip(mask);
+
+ // Draw the thick part of the root.
+ info.context->setStrokeThickness(gRadicalThickLineThickness * style()->fontSize());
+ info.context->setLineCap(SquareCap);
+
+ Path line;
+ line.moveTo(bottomLeft);
+ line.addLineTo(topLeft);
+
+ info.context->strokePath(line);
+
+ info.context->restore();
+
+ info.context->restore();
+
+}
+
+void RenderMathMLRoot::layout()
+{
+ RenderBlock::layout();
+
+ if (!firstChild() || !lastChild())
+ return;
+
+ int maxHeight = toRenderBoxModelObject(lastChild())->offsetHeight();
+
+ RenderObject* current = lastChild()->firstChild();
+ if (current)
+ current->style()->setVerticalAlign(BASELINE);
+
+ if (!maxHeight)
+ maxHeight = style()->fontSize();
+
+ // Base height above which the shape of the root changes
+ int thresholdHeight = static_cast<int>(gThresholdBaseHeight * style()->fontSize());
+ int topStartShift = 0;
+
+ if (maxHeight > thresholdHeight && thresholdHeight) {
+ float shift = (maxHeight - thresholdHeight) / static_cast<float>(thresholdHeight);
+ if (shift > 1.)
+ shift = 1.0f;
+ int frontWidth = static_cast<int>(style()->fontSize() * gRadicalWidth);
+ topStartShift = static_cast<int>(gRadicalBottomPointXPos * frontWidth * shift);
+
+ style()->setPaddingBottom(Length(static_cast<int>(gRootBottomPadding * style()->fontSize()), Fixed));
+ }
+
+ // Positioning of the index
+ RenderBoxModelObject* indexBox = toRenderBoxModelObject(firstChild()->firstChild());
+ if (!indexBox)
+ return;
+
+ int indexShift = indexBox->offsetWidth() + topStartShift;
+ int radicalHeight = static_cast<int>((1 - gRadicalTopLeftPointYPos) * maxHeight);
+ int rootMarginTop = radicalHeight + style()->paddingBottom().value() + indexBox->offsetHeight() - (maxHeight + static_cast<int>(gRootPadding * style()->fontSize()));
+
+ style()->setPaddingLeft(Length(indexShift, Fixed));
+ if (rootMarginTop > 0)
+ style()->setPaddingTop(Length(rootMarginTop + static_cast<int>(gRootPadding * style()->fontSize()), Fixed));
+
+ setNeedsLayout(true);
+ setPreferredLogicalWidthsDirty(true, false);
+ RenderBlock::layout();
+
+ indexBox->style()->setBottom(Length(radicalHeight + style()->paddingBottom().value(), Fixed));
+
+ // Now that we've potentially changed its position, we need layout the index again.
+ indexBox->setNeedsLayout(true);
+ indexBox->layout();
+}
+
+}
+
+#endif // ENABLE(MATHML)
+
+
diff --git a/Source/WebCore/mathml/RenderMathMLRoot.h b/Source/WebCore/mathml/RenderMathMLRoot.h
new file mode 100644
index 0000000..80f56ac
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLRoot.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLRoot_h
+#define RenderMathMLRoot_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLRoot : public RenderMathMLBlock {
+public:
+ RenderMathMLRoot(Node* fraction);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void paint(PaintInfo&, int tx, int ty);
+protected:
+ virtual void layout();
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLRoot_h
diff --git a/Source/WebCore/mathml/RenderMathMLRow.cpp b/Source/WebCore/mathml/RenderMathMLRow.cpp
new file mode 100644
index 0000000..ad54846
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLRow.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLRow.h"
+
+#include "MathMLNames.h"
+#include "RenderMathMLOperator.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+RenderMathMLRow::RenderMathMLRow(Node* row)
+ : RenderMathMLBlock(row)
+{
+}
+
+int RenderMathMLRow::nonOperatorHeight() const
+{
+ int maxHeight = 0;
+ for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+ if (current->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(current);
+ int blockHeight = block->nonOperatorHeight();
+ // Check to see if this box has a larger height
+ if (blockHeight > maxHeight)
+ maxHeight = blockHeight;
+ } else if (current->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(current);
+ // Check to see if this box has a larger height
+ if (box->offsetHeight() > maxHeight)
+ maxHeight = box->offsetHeight();
+ }
+
+ }
+ return maxHeight;
+}
+
+void RenderMathMLRow::layout()
+{
+ RenderBlock::layout();
+
+ int maxHeight = 0;
+ int childCount = 0;
+ int operatorCount = 0;
+
+ // Calculate the non-operator max height of the row.
+ int operatorHeight = 0;
+ for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+ childCount++;
+ if (current->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(current);
+ // Check to see if the non-operator block has a greater height.
+ if (!block->hasBase() && !block->isRenderMathMLOperator() && block->offsetHeight() > maxHeight)
+ maxHeight = block->offsetHeight();
+ if (block->hasBase() && block->nonOperatorHeight() > maxHeight)
+ maxHeight = block->nonOperatorHeight();
+ // If the block is an operator, capture the maximum height and increment the count.
+ if (block->isRenderMathMLOperator()) {
+ if (block->offsetHeight() > operatorHeight)
+ operatorHeight = block->offsetHeight();
+ operatorCount++;
+ }
+ } else if (current->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(current);
+ // Check to see if this box has a larger height.
+ if (box->offsetHeight() > maxHeight)
+ maxHeight = box->offsetHeight();
+ }
+ }
+
+ if (childCount > 0 && childCount == operatorCount) {
+ // We have only operators and so set the max height to the operator height.
+ maxHeight = operatorHeight;
+ }
+
+ // Stretch everything to the same height (blocks can ignore the request).
+ if (maxHeight > 0) {
+ bool didStretch = false;
+ for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+ if (current->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(current);
+ block->stretchToHeight(maxHeight);
+ didStretch = true;
+ }
+ }
+ if (didStretch) {
+ setNeedsLayout(true);
+ setPreferredLogicalWidthsDirty(true, false);
+ RenderBlock::layout();
+ }
+ }
+
+}
+
+int RenderMathMLRow::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+{
+ if (firstChild() && firstChild()->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
+ if (block->isRenderMathMLOperator())
+ return block->y() + block->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
+ }
+
+ return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
+}
+
+}
+
+#endif // ENABLE(MATHML)
+
diff --git a/Source/WebCore/mathml/RenderMathMLRow.h b/Source/WebCore/mathml/RenderMathMLRow.h
new file mode 100644
index 0000000..62a0d09
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLRow.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLRow_h
+#define RenderMathMLRow_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLRow : public RenderMathMLBlock {
+public:
+ RenderMathMLRow(Node* container);
+ virtual bool isRenderMathMLRow() const { return true; }
+ virtual int nonOperatorHeight() const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual void stretchToHeight(int) {}
+protected:
+ virtual void layout();
+};
+
+}
+
+
+#endif // ENABLE(MATHML)
+#endif // RenderMathMLRow_h
diff --git a/Source/WebCore/mathml/RenderMathMLSquareRoot.cpp b/Source/WebCore/mathml/RenderMathMLSquareRoot.cpp
new file mode 100644
index 0000000..1285acd
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLSquareRoot.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ * Copyright (C) 2010 François Sausset (sausset@gmail.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLSquareRoot.h"
+
+#include "GraphicsContext.h"
+#include "MathMLNames.h"
+#include "Path.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+// Bottom padding of the radical (px)
+const int gRadicalBasePad = 3;
+// Threshold above which the radical shape is modified to look nice with big bases (%)
+const float gThresholdBaseHeight = 1.5f;
+// Radical width (%)
+const float gRadicalWidth = 0.75f;
+// Horizontal position of the bottom point of the radical (%)
+const float gRadicalBottomPointXPos= 0.5f;
+// Horizontal position of the top left point of the radical (%)
+const float gRadicalTopLeftPointXPos = 0.2f;
+// Vertical position of the top left point of the radical (%)
+const float gRadicalTopLeftPointYPos = 0.5f;
+// Vertical shift of the left end point of the radical (%)
+const float gRadicalLeftEndYShift = 0.05f;
+// Additional bottom root padding (%)
+const float gRootBottomPadding = 0.2f;
+
+// Radical line thickness (%)
+const float gRadicalLineThickness = 0.02f;
+// Radical thick line thickness (%)
+const float gRadicalThickLineThickness = 0.1f;
+
+RenderMathMLSquareRoot::RenderMathMLSquareRoot(Node *expression)
+ : RenderMathMLBlock(expression)
+{
+}
+
+void RenderMathMLSquareRoot::paint(PaintInfo& info, int tx, int ty)
+{
+ RenderMathMLBlock::paint(info, tx, ty);
+
+ if (info.context->paintingDisabled())
+ return;
+
+ tx += x();
+ ty += y();
+
+ int maxHeight = 0;
+ int width = 0;
+ RenderObject* current = firstChild();
+ while (current) {
+ if (current->isBoxModelObject()) {
+
+ RenderBoxModelObject* box = toRenderBoxModelObject(current);
+
+ // Check to see if this box has a larger height
+ if (box->offsetHeight() > maxHeight)
+ maxHeight = box->offsetHeight();
+ width += box->offsetWidth();
+ }
+ current = current->nextSibling();
+ }
+ // default to the font size in pixels if we're empty
+ if (!maxHeight)
+ maxHeight = style()->fontSize();
+
+ int frontWidth = static_cast<int>(style()->fontSize() * gRadicalWidth);
+ int topStartShift = 0;
+ // Base height above which the shape of the root changes
+ int thresholdHeight = static_cast<int>(gThresholdBaseHeight * style()->fontSize());
+
+ if (maxHeight > thresholdHeight && thresholdHeight) {
+ float shift = (maxHeight - thresholdHeight) / static_cast<float>(thresholdHeight);
+ if (shift > 1.)
+ shift = 1.0f;
+ topStartShift = static_cast<int>(gRadicalBottomPointXPos * frontWidth * shift);
+ }
+
+ width += topStartShift;
+
+ FloatPoint topStart(tx + frontWidth - topStartShift, ty);
+ FloatPoint bottomLeft(tx + frontWidth * gRadicalBottomPointXPos , ty + maxHeight + gRadicalBasePad);
+ FloatPoint topLeft(tx + frontWidth * gRadicalTopLeftPointXPos , ty + gRadicalTopLeftPointYPos * maxHeight);
+ FloatPoint leftEnd(tx , topLeft.y() + gRadicalLeftEndYShift * style()->fontSize());
+
+ info.context->save();
+
+ info.context->setStrokeThickness(gRadicalLineThickness * style()->fontSize());
+ info.context->setStrokeStyle(SolidStroke);
+ info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
+ info.context->setLineJoin(MiterJoin);
+ info.context->setMiterLimit(style()->fontSize());
+
+ Path root;
+
+ root.moveTo(FloatPoint(topStart.x() + width , ty));
+ // draw top
+ root.addLineTo(topStart);
+ // draw from top left corner to bottom point of radical
+ root.addLineTo(bottomLeft);
+ // draw from bottom point to top of left part of radical base "pocket"
+ root.addLineTo(topLeft);
+ // draw to end
+ root.addLineTo(leftEnd);
+
+ info.context->strokePath(root);
+
+ info.context->save();
+
+ // Build a mask to draw the thick part of the root.
+ Path mask;
+
+ mask.moveTo(topStart);
+ mask.addLineTo(bottomLeft);
+ mask.addLineTo(topLeft);
+ mask.addLineTo(FloatPoint(2 * topLeft.x() - leftEnd.x(), 2 * topLeft.y() - leftEnd.y()));
+
+ info.context->clip(mask);
+
+ // Draw the thick part of the root.
+ info.context->setStrokeThickness(gRadicalThickLineThickness * style()->fontSize());
+ info.context->setLineCap(SquareCap);
+
+ Path line;
+ line.moveTo(bottomLeft);
+ line.addLineTo(topLeft);
+
+ info.context->strokePath(line);
+
+ info.context->restore();
+
+ info.context->restore();
+}
+
+void RenderMathMLSquareRoot::layout()
+{
+ int maxHeight = 0;
+
+ RenderObject* current = firstChild();
+ while (current) {
+ if (current->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(current);
+
+ if (box->offsetHeight() > maxHeight)
+ maxHeight = box->offsetHeight();
+
+ box->style()->setVerticalAlign(BASELINE);
+ }
+ current = current->nextSibling();
+ }
+
+ if (!maxHeight)
+ maxHeight = style()->fontSize();
+
+
+ if (maxHeight > static_cast<int>(gThresholdBaseHeight * style()->fontSize()))
+ style()->setPaddingBottom(Length(static_cast<int>(gRootBottomPadding * style()->fontSize()), Fixed));
+
+
+ RenderBlock::layout();
+}
+
+}
+
+#endif // ENABLE(MATHML)
+
+
diff --git a/Source/WebCore/mathml/RenderMathMLSquareRoot.h b/Source/WebCore/mathml/RenderMathMLSquareRoot.h
new file mode 100644
index 0000000..d40b1ba
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLSquareRoot.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderMathMLSquareRoot_h
+#define RenderMathMLSquareRoot_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLSquareRoot : public RenderMathMLBlock {
+public:
+ RenderMathMLSquareRoot(Node* fraction);
+ virtual void paint(PaintInfo&, int tx, int ty);
+protected:
+ virtual void layout();
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLSquareRoot_h
+
+
+
diff --git a/Source/WebCore/mathml/RenderMathMLSubSup.cpp b/Source/WebCore/mathml/RenderMathMLSubSup.cpp
new file mode 100644
index 0000000..0ea6667
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLSubSup.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLSubSup.h"
+
+#include "FontSelector.h"
+#include "MathMLNames.h"
+#include "RenderInline.h"
+#include "RenderTable.h"
+#include "RenderTableCell.h"
+#include "RenderTableRow.h"
+#include "RenderTableSection.h"
+#include "RenderText.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+static const int gTopAdjustDivisor = 3;
+static const int gSubsupScriptMargin = 1;
+static const float gSubSupStretch = 1.2f;
+
+RenderMathMLSubSup::RenderMathMLSubSup(Element* element)
+ : RenderMathMLBlock(element)
+ , m_scripts(0)
+{
+ // Determine what kind of under/over expression we have by element name
+ if (element->hasLocalName(MathMLNames::msubTag))
+ m_kind = Sub;
+ else if (element->hasLocalName(MathMLNames::msupTag))
+ m_kind = Sup;
+ else if (element->hasLocalName(MathMLNames::msubsupTag))
+ m_kind = SubSup;
+ else
+ m_kind = SubSup;
+}
+
+void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ if (firstChild()) {
+ // We already have a base, so this is the super/subscripts being added.
+
+ if (m_kind == SubSup) {
+ if (!m_scripts) {
+ m_scripts = new (renderArena()) RenderMathMLBlock(node());
+ RefPtr<RenderStyle> scriptsStyle = RenderStyle::create();
+ scriptsStyle->inheritFrom(style());
+ scriptsStyle->setDisplay(INLINE_BLOCK);
+ scriptsStyle->setVerticalAlign(TOP);
+ scriptsStyle->setMarginLeft(Length(gSubsupScriptMargin, Fixed));
+ scriptsStyle->setTextAlign(LEFT);
+ m_scripts->setStyle(scriptsStyle.release());
+ RenderMathMLBlock::addChild(m_scripts, beforeChild);
+ }
+
+ RenderBlock* script = new (renderArena()) RenderMathMLBlock(node());
+ RefPtr<RenderStyle> scriptStyle = RenderStyle::create();
+ scriptStyle->inheritFrom(m_scripts->style());
+ scriptStyle->setDisplay(BLOCK);
+ script->setStyle(scriptStyle.release());
+
+ m_scripts->addChild(script, m_scripts->firstChild());
+ script->addChild(child);
+ } else
+ RenderMathMLBlock::addChild(child, beforeChild);
+
+ } else {
+ RenderMathMLBlock* wrapper = new (renderArena()) RenderMathMLBlock(node());
+ RefPtr<RenderStyle> wrapperStyle = RenderStyle::create();
+ wrapperStyle->inheritFrom(style());
+ wrapperStyle->setDisplay(INLINE_BLOCK);
+ wrapperStyle->setVerticalAlign(BASELINE);
+ wrapper->setStyle(wrapperStyle.release());
+ RenderMathMLBlock::addChild(wrapper, beforeChild);
+ wrapper->addChild(child);
+
+ }
+}
+
+void RenderMathMLSubSup::stretchToHeight(int height)
+{
+ RenderObject* base = firstChild();
+ if (!base)
+ return;
+
+ if (base->firstChild()->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(base->firstChild());
+ block->stretchToHeight(static_cast<int>(gSubSupStretch * height));
+
+ // Adjust the script placement after we stretch
+ if (height > 0 && m_kind == SubSup && m_scripts) {
+ RenderObject* script = m_scripts->firstChild();
+ if (script) {
+ // Calculate the script height without the container margins.
+ RenderObject* top = script;
+ int topHeight = getBoxModelObjectHeight(top->firstChild());
+ int topAdjust = topHeight / gTopAdjustDivisor;
+ top->style()->setMarginTop(Length(-topAdjust, Fixed));
+ top->style()->setMarginBottom(Length(height - topHeight + topAdjust, Fixed));
+ if (top->isBoxModelObject()) {
+ RenderBoxModelObject* topBox = toRenderBoxModelObject(top);
+ topBox->updateBoxModelInfoFromStyle();
+ }
+ m_scripts->setNeedsLayout(true);
+ setNeedsLayout(true);
+ }
+ }
+
+ }
+}
+
+int RenderMathMLSubSup::nonOperatorHeight() const
+{
+ if (m_kind == SubSup)
+ return static_cast<int>(style()->fontSize()*gSubSupStretch);
+ return static_cast<int>(style()->fontSize());
+}
+
+void RenderMathMLSubSup::layout()
+{
+ if (firstChild())
+ firstChild()->setNeedsLayout(true);
+ if (m_scripts)
+ m_scripts->setNeedsLayout(true);
+
+ RenderBlock::layout();
+
+ if (m_kind == SubSup) {
+ if (RenderObject* base = firstChild()) {
+ int maxHeight = 0;
+ RenderObject* current = base->firstChild();
+ while (current) {
+ int height = getBoxModelObjectHeight(current);
+ if (height > maxHeight)
+ maxHeight = height;
+ current = current->nextSibling();
+ }
+ int heightDiff = m_scripts ? (m_scripts->offsetHeight() - maxHeight) / 2 : 0;
+ if (heightDiff < 0)
+ heightDiff = 0;
+ base->style()->setPaddingTop(Length(heightDiff, Fixed));
+ base->setNeedsLayout(true);
+ }
+ setNeedsLayout(true);
+ RenderBlock::layout();
+ }
+}
+
+int RenderMathMLSubSup::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+{
+ RenderObject* base = firstChild();
+ if (!base)
+ return offsetHeight();
+
+ int baseline = offsetHeight();
+ if (!base || !base->isBoxModelObject())
+ return baseline;
+
+ switch (m_kind) {
+ case SubSup:
+ base = base->firstChild();
+ if (m_scripts && base->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(base);
+
+ int topAdjust = (m_scripts->offsetHeight() - box->offsetHeight()) / 2;
+
+ // FIXME: The last bit of this calculation should be more exact. Why is the 2-3px scaled for zoom necessary?
+ // The baseline is top spacing of the base + the baseline of the base + adjusted space for zoom
+ float zoomFactor = style()->effectiveZoom();
+ return topAdjust + box->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode) + static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
+ }
+ break;
+ case Sup:
+ case Sub:
+ RenderBoxModelObject* box = toRenderBoxModelObject(base);
+ baseline = box->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
+ break;
+ }
+
+ return baseline;
+
+}
+
+}
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/RenderMathMLSubSup.h b/Source/WebCore/mathml/RenderMathMLSubSup.h
new file mode 100644
index 0000000..7a9d310
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLSubSup.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef RenderMathMLSubSup_h
+#define RenderMathMLSubSup_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+#include "RenderTable.h"
+
+namespace WebCore {
+
+class RenderMathMLSubSup : public RenderMathMLBlock {
+public:
+ RenderMathMLSubSup(Element* fraction);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual bool hasBase() const { return true; }
+ virtual int nonOperatorHeight() const;
+ virtual void stretchToHeight(int pixelHeight);
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+
+protected:
+ virtual void layout();
+
+private:
+ enum SubSupType { Sub, Sup, SubSup };
+ SubSupType m_kind;
+ RenderBlock* m_scripts;
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLSubSup_h
+
diff --git a/Source/WebCore/mathml/RenderMathMLUnderOver.cpp b/Source/WebCore/mathml/RenderMathMLUnderOver.cpp
new file mode 100644
index 0000000..a3de697
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLUnderOver.cpp
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLUnderOver.h"
+
+#include "FontSelector.h"
+#include "MathMLNames.h"
+
+namespace WebCore {
+
+using namespace MathMLNames;
+
+static const double gOverSpacingAdjustment = 0.5;
+
+RenderMathMLUnderOver::RenderMathMLUnderOver(Node* expression)
+ : RenderMathMLBlock(expression)
+{
+ Element* element = static_cast<Element*>(expression);
+ // Determine what kind of under/over expression we have by element name
+
+ if (element->hasLocalName(MathMLNames::munderTag))
+ m_kind = Under;
+ else if (element->hasLocalName(MathMLNames::moverTag))
+ m_kind = Over;
+ else if (element->hasLocalName(MathMLNames::munderoverTag))
+ m_kind = UnderOver;
+ else
+ m_kind = Under;
+
+}
+
+void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeChild)
+{
+ RenderMathMLBlock* row = new (renderArena()) RenderMathMLBlock(node());
+ RefPtr<RenderStyle> rowStyle = makeBlockStyle();
+ row->setStyle(rowStyle.release());
+
+ // look through the children for rendered elements counting the blocks so we know what child
+ // we are adding
+ int blocks = 0;
+ RenderObject* current = this->firstChild();
+ while (current) {
+ blocks++;
+ current = current->nextSibling();
+ }
+
+ switch (blocks) {
+ case 0:
+ // this is the base so just append it
+ RenderBlock::addChild(row, beforeChild);
+ break;
+ case 1:
+ // the under or over
+ // FIXME: text-align: center does not work
+ row->style()->setTextAlign(CENTER);
+ if (m_kind == Over) {
+ // add the over as first
+ RenderBlock::addChild(row, firstChild());
+ } else {
+ // add the under as last
+ RenderBlock::addChild(row, beforeChild);
+ }
+ break;
+ case 2:
+ // the under or over
+ // FIXME: text-align: center does not work
+ row->style()->setTextAlign(CENTER);
+ if (m_kind == UnderOver) {
+ // add the over as first
+ RenderBlock::addChild(row, firstChild());
+ } else {
+ // we really shouldn't get here as only munderover should have three children
+ RenderBlock::addChild(row, beforeChild);
+ }
+ break;
+ default:
+ // munderover shouldn't have more than three children. In theory we shouldn't
+ // get here if the MathML is correctly formed, but that isn't a guarantee.
+ // We will treat this as another under element and they'll get something funky.
+ RenderBlock::addChild(row, beforeChild);
+ }
+ row->addChild(child);
+}
+
+inline int getOffsetHeight(RenderObject* obj)
+{
+ if (obj->isBoxModelObject()) {
+ RenderBoxModelObject* box = toRenderBoxModelObject(obj);
+ return box->offsetHeight();
+ }
+
+ return 0;
+}
+
+void RenderMathMLUnderOver::stretchToHeight(int height)
+{
+
+ RenderObject* base = firstChild();
+ if (!base)
+ return;
+
+ // For over or underover, the base is the sibling of the first child
+ if (m_kind != Under)
+ base = base->nextSibling();
+
+ if (!base)
+ return;
+
+ // use the child of the row which is the actual base
+ base = base->firstChild();
+
+ if (base && base->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(base);
+ block->stretchToHeight(height);
+ setNeedsLayout(true);
+ }
+}
+
+void RenderMathMLUnderOver::layout()
+{
+ RenderBlock::layout();
+ RenderObject* over = 0;
+ RenderObject* base = 0;
+ switch (m_kind) {
+ case Over:
+ // We need to calculate the baseline over the over versus the start of the base and
+ // adjust the placement of the base.
+ over = firstChild();
+ if (over) {
+ // FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
+ // FIXME: bases that ascend higher than the line box intrude into the over
+ if (!over->firstChild()->isBoxModelObject())
+ break;
+
+ int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(AlphabeticBaseline, true, HorizontalLine)));
+
+ // base row wrapper
+ base = over->nextSibling();
+ if (base) {
+ if (overSpacing > 0)
+ base->style()->setMarginTop(Length(-overSpacing, Fixed));
+ else
+ base->style()->setMarginTop(Length(0, Fixed));
+ }
+
+ }
+ break;
+ case Under:
+ // FIXME: Non-ascending glyphs in the under should be moved closer to the base
+
+ // We need to calculate the baseline of the base versus the start of the under block and
+ // adjust the placement of the under block.
+
+ // base row wrapper
+ base = firstChild();
+ if (base) {
+ int baseHeight = getOffsetHeight(base);
+ // actual base
+ base = base->firstChild();
+ if (!base->isBoxModelObject())
+ break;
+
+ // FIXME: We need to look at the space between a single maximum height of
+ // the line boxes and the baseline and squeeze them together
+ int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
+
+ // adjust the base's intrusion into the under
+ RenderObject* under = lastChild();
+ if (under && underSpacing > 0)
+ under->style()->setMarginTop(Length(-underSpacing, Fixed));
+ }
+ break;
+ case UnderOver:
+ // FIXME: Non-descending glyphs in the over should be moved closer to the base
+ // FIXME: Non-ascending glyphs in the under should be moved closer to the base
+
+ // We need to calculate the baseline of the over versus the start of the base and
+ // adjust the placement of the base.
+
+ over = firstChild();
+ if (over) {
+ // FIXME: descending glyphs intrude into base (e.g. lowercase y over base)
+ // FIXME: bases that ascend higher than the line box intrude into the over
+ if (!over->firstChild()->isBoxModelObject())
+ break;
+ int overSpacing = static_cast<int>(gOverSpacingAdjustment * (getOffsetHeight(over) - toRenderBoxModelObject(over->firstChild())->baselinePosition(AlphabeticBaseline, true, HorizontalLine)));
+
+ // base row wrapper
+ base = over->nextSibling();
+
+ if (base) {
+ if (overSpacing > 0)
+ base->style()->setMarginTop(Length(-overSpacing, Fixed));
+
+ // We need to calculate the baseline of the base versus the start of the under block and
+ // adjust the placement of the under block.
+
+ int baseHeight = getOffsetHeight(base);
+ // actual base
+ base = base->firstChild();
+ if (!base->isBoxModelObject())
+ break;
+
+ // FIXME: We need to look at the space between a single maximum height of
+ // the line boxes and the baseline and squeeze them together
+ int underSpacing = baseHeight - toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
+
+ RenderObject* under = lastChild();
+ if (under && under->firstChild()->isRenderInline() && underSpacing > 0)
+ under->style()->setMarginTop(Length(-underSpacing, Fixed));
+
+ }
+ }
+ break;
+ }
+ setNeedsLayout(true);
+ RenderBlock::layout();
+}
+
+int RenderMathMLUnderOver::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
+{
+ RenderObject* current = firstChild();
+ if (!current)
+ return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
+
+ int baseline = 0;
+ switch (m_kind) {
+ case UnderOver:
+ case Over:
+ baseline += getOffsetHeight(current);
+ current = current->nextSibling();
+ if (current) {
+ // actual base
+ RenderObject* base = current->firstChild();
+ if (!base || !base->isBoxModelObject())
+ break;
+ baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, firstLine, HorizontalLine, linePositionMode);
+ // added the negative top margin
+ baseline += current->style()->marginTop().value();
+ }
+ break;
+ case Under:
+ RenderObject* base = current->firstChild();
+ if (base && base->isBoxModelObject())
+ baseline += toRenderBoxModelObject(base)->baselinePosition(AlphabeticBaseline, true, HorizontalLine);
+ }
+
+ // FIXME: Where is the extra 2-3px adjusted for zoom coming from?
+ float zoomFactor = style()->effectiveZoom();
+ baseline += static_cast<int>((zoomFactor > 1.25 ? 2 : 3) * zoomFactor);
+ return baseline;
+}
+
+
+int RenderMathMLUnderOver::nonOperatorHeight() const
+{
+ int nonOperators = 0;
+ for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
+ if (current->firstChild()->isRenderMathMLBlock()) {
+ RenderMathMLBlock* block = toRenderMathMLBlock(current->firstChild());
+ if (!block->isRenderMathMLOperator())
+ nonOperators += getOffsetHeight(current);
+ } else {
+ nonOperators += getOffsetHeight(current);
+ }
+ }
+ return nonOperators;
+}
+
+}
+
+
+#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/mathml/RenderMathMLUnderOver.h b/Source/WebCore/mathml/RenderMathMLUnderOver.h
new file mode 100644
index 0000000..fbab72a
--- /dev/null
+++ b/Source/WebCore/mathml/RenderMathMLUnderOver.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Alex Milowski (alex@milowski.com). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef RenderMathMLUnderOver_h
+#define RenderMathMLUnderOver_h
+
+#if ENABLE(MATHML)
+
+#include "RenderMathMLBlock.h"
+
+namespace WebCore {
+
+class RenderMathMLUnderOver : public RenderMathMLBlock {
+public:
+ RenderMathMLUnderOver(Node* expression);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void layout();
+ virtual bool hasBase() const { return true; }
+ virtual int nonOperatorHeight() const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual void stretchToHeight(int pixelHeight);
+private:
+ enum UnderOverType { Under, Over, UnderOver };
+ UnderOverType m_kind;
+};
+
+}
+
+#endif // ENABLE(MATHML)
+
+#endif // RenderMathMLUnderOver_h
diff --git a/Source/WebCore/mathml/mathattrs.in b/Source/WebCore/mathml/mathattrs.in
new file mode 100644
index 0000000..4fda481
--- /dev/null
+++ b/Source/WebCore/mathml/mathattrs.in
@@ -0,0 +1,23 @@
+namespace="MathML"
+namespaceURI="http://www.w3.org/1998/Math/MathML"
+guardFactoryWith="ENABLE(MATHML)"
+attrsNullNamespace
+
+background
+close
+color
+definitionURL
+denomalign
+fontfamily
+fontsize
+fontstyle
+fontweight
+linethickness
+mathbackground
+mathcolor
+mathsize
+mathvariant
+numalign
+open
+separators
+stretchy
diff --git a/Source/WebCore/mathml/mathtags.in b/Source/WebCore/mathml/mathtags.in
new file mode 100644
index 0000000..b2dcb93
--- /dev/null
+++ b/Source/WebCore/mathml/mathtags.in
@@ -0,0 +1,27 @@
+namespace="MathML"
+namespaceURI="http://www.w3.org/1998/Math/MathML"
+guardFactoryWith="ENABLE(MATHML)"
+
+math
+mfrac interfaceName=MathMLInlineContainerElement
+mfenced interfaceName=MathMLInlineContainerElement
+msubsup interfaceName=MathMLInlineContainerElement
+mrow interfaceName=MathMLInlineContainerElement
+mover interfaceName=MathMLInlineContainerElement
+munder interfaceName=MathMLInlineContainerElement
+munderover interfaceName=MathMLInlineContainerElement
+msqrt interfaceName=MathMLInlineContainerElement
+mroot interfaceName=MathMLInlineContainerElement
+mi interfaceName=MathMLTextElement
+mn interfaceName=MathMLTextElement
+mo interfaceName=MathMLTextElement
+mtext interfaceName=MathMLTextElement
+msub interfaceName=MathMLInlineContainerElement
+msup interfaceName=MathMLInlineContainerElement
+
+#if 0 // Curently only for MathMLNames used by HTMLTreeBuilder.
+ms
+mglyph
+malignmark
+annotation-xml
+#endif