1/*
2 * Copyright (C) 2010 Alex Milowski (alex@milowski.com). All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef RenderMathMLOperator_h
27#define RenderMathMLOperator_h
28
29#if ENABLE(MATHML)
30
31#include "RenderMathMLBlock.h"
32#include <wtf/unicode/CharacterNames.h>
33
34namespace WebCore {
35
36class RenderMathMLOperator : public RenderMathMLBlock {
37public:
38    RenderMathMLOperator(Element*);
39    RenderMathMLOperator(Element*, UChar operatorChar);
40
41    virtual bool isRenderMathMLOperator() const { return true; }
42
43    virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
44    virtual void updateFromElement() OVERRIDE;
45    virtual void computePreferredLogicalWidths() OVERRIDE;
46    virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
47
48    virtual RenderMathMLOperator* unembellishedOperator() OVERRIDE { return this; }
49    void stretchToHeight(int pixelHeight);
50    int stretchHeight() const { return m_stretchHeight; }
51    float expandedStretchHeight() const;
52
53    virtual int firstLineBoxBaseline() const OVERRIDE;
54
55    enum OperatorType { Default, Separator, Fence };
56    void setOperatorType(OperatorType type) { m_operatorType = type; }
57    OperatorType operatorType() const { return m_operatorType; }
58
59    void updateStyle();
60
61    void paint(PaintInfo&, const LayoutPoint&);
62
63    struct StretchyCharacter {
64        UChar character;
65        UChar topGlyph;
66        UChar extensionGlyph;
67        UChar bottomGlyph;
68        UChar middleGlyph;
69    };
70
71private:
72    virtual const char* renderName() const { return isAnonymous() ? "RenderMathMLOperator (anonymous)" : "RenderMathMLOperator"; }
73    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
74    virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) OVERRIDE;
75
76    bool shouldAllowStretching(UChar& characterForStretching);
77    StretchyCharacter* findAcceptableStretchyCharacter(UChar);
78
79    FloatRect glyphBoundsForCharacter(UChar);
80    float glyphHeightForCharacter(UChar);
81    float advanceForCharacter(UChar);
82
83    enum CharacterPaintTrimming {
84        TrimTop,
85        TrimBottom,
86        TrimTopAndBottom,
87    };
88
89    LayoutRect paintCharacter(PaintInfo&, UChar, const LayoutPoint& origin, CharacterPaintTrimming);
90    void fillWithExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to);
91
92    int m_stretchHeight;
93    bool m_isStretched;
94
95    UChar m_operator;
96    OperatorType m_operatorType;
97    StretchyCharacter* m_stretchyCharacter;
98};
99
100inline RenderMathMLOperator* toRenderMathMLOperator(RenderMathMLBlock* block)
101{
102    ASSERT_WITH_SECURITY_IMPLICATION(!block || block->isRenderMathMLOperator());
103    return static_cast<RenderMathMLOperator*>(block);
104}
105
106inline const RenderMathMLOperator* toRenderMathMLOperator(const RenderMathMLBlock* block)
107{
108    ASSERT_WITH_SECURITY_IMPLICATION(!block || block->isRenderMathMLOperator());
109    return static_cast<const RenderMathMLOperator*>(block);
110}
111
112// This will catch anyone doing an unnecessary cast.
113void toRenderMathMLOperator(const RenderMathMLOperator*);
114
115inline UChar convertHyphenMinusToMinusSign(UChar glyph)
116{
117    // When rendered as a mathematical operator, minus glyph should be larger.
118    if (glyph == hyphenMinus)
119        return minusSign;
120
121    return glyph;
122}
123
124}
125
126#endif // ENABLE(MATHML)
127#endif // RenderMathMLOperator_h
128