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 "GlyphPage.h" 32#include "MathMLElement.h" 33#include "OpenTypeMathData.h" 34#include "RenderMathMLToken.h" 35#include "SimpleFontData.h" 36 37namespace WebCore { 38 39namespace MathMLOperatorDictionary { 40 41enum Form { Infix, Prefix, Postfix }; 42enum Flag { 43 Accent = 0x1, // FIXME: This must be used to implement accentunder/accent on munderover (https://bugs.webkit.org/show_bug.cgi?id=124826). 44 Fence = 0x2, // This has no visual effect but allows to expose semantic information via the accessibility tree. 45 LargeOp = 0x4, 46 MovableLimits = 0x8, // FIXME: This must be used to implement displaystyle (https://bugs.webkit.org/show_bug.cgi?id=118737). 47 Separator = 0x10, // This has no visual effect but allows to expose semantic information via the accessibility tree. 48 Stretchy = 0x20, 49 Symmetric = 0x40 50}; 51struct Entry { 52 UChar character; 53 Form form; 54 unsigned short lspace; 55 unsigned short rspace; 56 unsigned short flags; 57}; 58 59} 60 61class RenderMathMLOperator : public RenderMathMLToken { 62public: 63 RenderMathMLOperator(MathMLElement&, PassRef<RenderStyle>); 64 RenderMathMLOperator(Document&, PassRef<RenderStyle>, const String& operatorString, MathMLOperatorDictionary::Form, unsigned short flags = 0); 65 66 virtual void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline); 67 void stretchTo(LayoutUnit width); 68 LayoutUnit stretchSize() const { return m_isVertical ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; } 69 70 bool hasOperatorFlag(MathMLOperatorDictionary::Flag flag) const { return m_operatorFlags & flag; } 71 // FIXME: The displaystyle property is not implemented (https://bugs.webkit.org/show_bug.cgi?id=118737). 72 bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp); } 73 74 void updateStyle() override final; 75 76 virtual void paint(PaintInfo&, const LayoutPoint&); 77 78 void updateTokenContent(const String& operatorString); 79 void updateTokenContent() override final; 80 void updateOperatorProperties(); 81 82protected: 83 virtual const char* renderName() const override { return isAnonymous() ? "RenderMathMLOperator (anonymous)" : "RenderMathMLOperator"; } 84 virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override; 85 virtual bool isRenderMathMLOperator() const override { return true; } 86 // The following operators are invisible: U+2061 FUNCTION APPLICATION, U+2062 INVISIBLE TIMES, U+2063 INVISIBLE SEPARATOR, U+2064 INVISIBLE PLUS. 87 bool isInvisibleOperator() const { return 0x2061 <= m_operator && m_operator <= 0x2064; } 88 virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override; 89 virtual void computePreferredLogicalWidths() override; 90 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override; 91 virtual int firstLineBaseline() const override; 92 virtual RenderMathMLOperator* unembellishedOperator() override { return this; } 93 void rebuildTokenContent(const String& operatorString); 94 void updateFromElement() override; 95 96 bool shouldAllowStretching() const; 97 98 FloatRect boundsForGlyph(const GlyphData&) const; 99 float heightForGlyph(const GlyphData&) const; 100 float advanceForGlyph(const GlyphData&) const; 101 102 enum DrawMode { 103 DrawNormal, DrawSizeVariant, DrawGlyphAssembly 104 }; 105 class StretchyData { 106 public: 107 DrawMode mode() const { return m_mode; } 108 GlyphData variant() const { return m_data[0]; } 109 GlyphData top() const { return m_data[0]; } 110 GlyphData extension() const { return m_data[1]; } 111 GlyphData bottom() const { return m_data[2]; } 112 GlyphData middle() const { return m_data[3]; } 113 GlyphData left() const { return m_data[2]; } 114 GlyphData right() const { return m_data[0]; } 115 116 void setNormalMode() 117 { 118 m_mode = DrawNormal; 119 } 120 void setSizeVariantMode(const GlyphData& variant) 121 { 122 m_mode = DrawSizeVariant; 123 m_data[0] = variant; 124 } 125 void setGlyphAssemblyMode(const GlyphData& top, const GlyphData& extension, const GlyphData& bottom, const GlyphData& middle) 126 { 127 m_mode = DrawGlyphAssembly; 128 m_data[0] = top; 129 m_data[1] = extension; 130 m_data[2] = bottom; 131 m_data[3] = middle; 132 } 133 StretchyData() 134 : m_mode(DrawNormal) { } 135 StretchyData(const StretchyData& data) 136 { 137 switch (data.m_mode) { 138 case DrawNormal: 139 setNormalMode(); 140 break; 141 case DrawSizeVariant: 142 setSizeVariantMode(data.variant()); 143 break; 144 case DrawGlyphAssembly: 145 setGlyphAssemblyMode(data.top(), data.extension(), data.bottom(), data.middle()); 146 break; 147 } 148 } 149 private: 150 DrawMode m_mode; 151 // FIXME: For OpenType fonts with a MATH table all the glyphs are from the same font, so we would only need to store the glyph indices here. 152 GlyphData m_data[4]; 153 }; 154 bool getGlyphAssemblyFallBack(Vector<OpenTypeMathData::AssemblyPart>, StretchyData&) const; 155 StretchyData getDisplayStyleLargeOperator(UChar) const; 156 StretchyData findStretchyData(UChar, float* maximumGlyphWidth); 157 158 enum GlyphPaintTrimming { 159 TrimTop, 160 TrimBottom, 161 TrimTopAndBottom, 162 TrimLeft, 163 TrimRight, 164 TrimLeftAndRight 165 }; 166 167 LayoutRect paintGlyph(PaintInfo&, const GlyphData&, const LayoutPoint& origin, GlyphPaintTrimming); 168 void fillWithVerticalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to); 169 void fillWithHorizontalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to); 170 void paintVerticalGlyphAssembly(PaintInfo&, const LayoutPoint&); 171 void paintHorizontalGlyphAssembly(PaintInfo&, const LayoutPoint&); 172 173 LayoutUnit m_stretchHeightAboveBaseline; 174 LayoutUnit m_stretchDepthBelowBaseline; 175 LayoutUnit m_stretchWidth; 176 177 UChar m_operator; 178 bool m_isVertical; 179 StretchyData m_stretchyData; 180 MathMLOperatorDictionary::Form m_operatorForm; 181 unsigned short m_operatorFlags; 182 LayoutUnit m_leadingSpace; 183 LayoutUnit m_trailingSpace; 184 LayoutUnit m_minSize; 185 LayoutUnit m_maxSize; 186 187 void setOperatorFlagFromAttribute(MathMLOperatorDictionary::Flag, const QualifiedName&); 188 void setOperatorPropertiesFromOpDictEntry(const MathMLOperatorDictionary::Entry*); 189 virtual void SetOperatorProperties(); 190}; 191 192RENDER_OBJECT_TYPE_CASTS(RenderMathMLOperator, isRenderMathMLOperator()) 193 194} 195 196#endif // ENABLE(MATHML) 197#endif // RenderMathMLOperator_h 198