/*
 * Copyright (C) 2016 Igalia S.L. All rights reserved.
 * Copyright (C) 2016 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"
#include "MathOperator.h"

#if ENABLE(MATHML)

#include "RenderStyle.h"
#include "StyleInheritedData.h"

static const unsigned kRadicalOperator = 0x221A;
static const unsigned kMaximumExtensionCount = 128;

namespace WebCore {

static inline FloatRect boundsForGlyph(const GlyphData& data)
{
    return data.font ? data.font->boundsForGlyph(data.glyph) : FloatRect();
}

static inline float heightForGlyph(const GlyphData& data)
{
    return boundsForGlyph(data).height();
}

static inline void getAscentAndDescentForGlyph(const GlyphData& data, LayoutUnit& ascent, LayoutUnit& descent)
{
    FloatRect bounds = boundsForGlyph(data);
    ascent = -bounds.y();
    descent = bounds.maxY();
}

static inline float advanceWidthForGlyph(const GlyphData& data)
{
    return data.font ? data.font->widthForGlyph(data.glyph) : 0;
}

// FIXME: This hardcoded data can be removed when OpenType MATH font are widely available (http://wkbug/156837).
struct StretchyCharacter {
    UChar32 character;
    UChar topChar;
    UChar extensionChar;
    UChar bottomChar;
    UChar middleChar;
};
// The first leftRightPairsCount pairs correspond to left/right fences that can easily be mirrored in RTL.
static const short leftRightPairsCount = 5;
static const StretchyCharacter stretchyCharacters[14] = {
    { 0x28  , 0x239b, 0x239c, 0x239d, 0x0    }, // left parenthesis
    { 0x29  , 0x239e, 0x239f, 0x23a0, 0x0    }, // right parenthesis
    { 0x5b  , 0x23a1, 0x23a2, 0x23a3, 0x0    }, // left square bracket
    { 0x5d  , 0x23a4, 0x23a5, 0x23a6, 0x0    }, // right square bracket
    { 0x7b  , 0x23a7, 0x23aa, 0x23a9, 0x23a8 }, // left curly bracket
    { 0x7d  , 0x23ab, 0x23aa, 0x23ad, 0x23ac }, // right curly bracket
    { 0x2308, 0x23a1, 0x23a2, 0x23a2, 0x0    }, // left ceiling
    { 0x2309, 0x23a4, 0x23a5, 0x23a5, 0x0    }, // right ceiling
    { 0x230a, 0x23a2, 0x23a2, 0x23a3, 0x0    }, // left floor
    { 0x230b, 0x23a5, 0x23a5, 0x23a6, 0x0    }, // right floor
    { 0x7c  , 0x7c,   0x7c,   0x7c,   0x0    }, // vertical bar
    { 0x2016, 0x2016, 0x2016, 0x2016, 0x0    }, // double vertical line
    { 0x2225, 0x2225, 0x2225, 0x2225, 0x0    }, // parallel to
    { 0x222b, 0x2320, 0x23ae, 0x2321, 0x0    } // integral sign
};

void MathOperator::GlyphAssemblyData::initialize()
{
    topOrRightCodePoint = 0;
    topOrRightFallbackGlyph = 0;
    extensionCodePoint = 0;
    extensionFallbackGlyph = 0;
    bottomOrLeftCodePoint = 0;
    bottomOrLeftFallbackGlyph = 0;
    middleCodePoint = 0;
    middleFallbackGlyph = 0;
}
    
MathOperator::MathOperator()
{
    m_assembly.initialize();
    m_variantGlyph = 0;
}

void MathOperator::setOperator(const RenderStyle& style, UChar32 baseCharacter, Type operatorType)
{
    m_baseCharacter = baseCharacter;
    m_operatorType = operatorType;
    reset(style);
}

void MathOperator::reset(const RenderStyle& style)
{
    m_stretchType = StretchType::Unstretched;
    m_maxPreferredWidth = 0;
    m_width = 0;
    m_ascent = 0;
    m_descent = 0;
    m_italicCorrection = 0;
    m_radicalVerticalScale = 1;

    // We use the base size for the calculation of the preferred width.
    GlyphData baseGlyph;
    if (!getBaseGlyph(style, baseGlyph))
        return;
    m_maxPreferredWidth = m_width = advanceWidthForGlyph(baseGlyph);
    getAscentAndDescentForGlyph(baseGlyph, m_ascent, m_descent);

    if (m_operatorType == Type::VerticalOperator)
        calculateStretchyData(style, true); // We also take into account the width of larger sizes for the calculation of the preferred width.
    else if (m_operatorType == Type::DisplayOperator)
        calculateDisplayStyleLargeOperator(style); // We can directly select the size variant and determine the final metrics.
}

LayoutUnit MathOperator::stretchSize() const
{
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
    return m_operatorType == Type::VerticalOperator ? m_ascent + m_descent : m_width;
}

bool MathOperator::getGlyph(const RenderStyle& style, UChar32 character, GlyphData& glyph) const
{
    glyph = style.fontCascade().glyphDataForCharacter(character, !style.isLeftToRightDirection());
    return glyph.font && glyph.font == &style.fontCascade().primaryFont();
}

void MathOperator::setSizeVariant(const GlyphData& sizeVariant)
{
    ASSERT(sizeVariant.font);
    ASSERT(sizeVariant.font->mathData());
    m_stretchType = StretchType::SizeVariant;
    m_variantGlyph = sizeVariant.glyph;
    m_width = advanceWidthForGlyph(sizeVariant);
    getAscentAndDescentForGlyph(sizeVariant, m_ascent, m_descent);
}

static GlyphData glyphDataForCodePointOrFallbackGlyph(const RenderStyle& style, UChar32 codePoint, Glyph fallbackGlyph)
{
    if (codePoint)
        return style.fontCascade().glyphDataForCharacter(codePoint, false);
    
    GlyphData fallback;
    
    if (fallbackGlyph) {
        fallback.glyph = fallbackGlyph;
        fallback.font = &style.fontCascade().primaryFont();
    }
    
    return fallback;
}

void MathOperator::setGlyphAssembly(const RenderStyle& style, const GlyphAssemblyData& assemblyData)
{
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
    m_stretchType = StretchType::GlyphAssembly;
    m_assembly = assemblyData;

    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);
    auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);
    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);

    if (m_operatorType == Type::VerticalOperator) {
        m_width = 0;
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(topOrRight));
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(extension));
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(bottomOrLeft));
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(middle));
    } else {
        m_ascent = 0;
        m_descent = 0;
        LayoutUnit ascent, descent;
        getAscentAndDescentForGlyph(bottomOrLeft, ascent, descent);
        m_ascent = std::max(m_ascent, ascent);
        m_descent = std::max(m_descent, descent);
        getAscentAndDescentForGlyph(extension, ascent, descent);
        m_ascent = std::max(m_ascent, ascent);
        m_descent = std::max(m_descent, descent);
        getAscentAndDescentForGlyph(topOrRight, ascent, descent);
        m_ascent = std::max(m_ascent, ascent);
        m_descent = std::max(m_descent, descent);
        getAscentAndDescentForGlyph(middle, ascent, descent);
        m_ascent = std::max(m_ascent, ascent);
        m_descent = std::max(m_descent, descent);
    }
}

// The MathML specification recommends avoiding combining characters.
// See https://www.w3.org/TR/MathML/chapter7.html#chars.comb-chars
// However, many math fonts do not provide constructions for the non-combining equivalent.
const unsigned maxFallbackPerCharacter = 3;
static const UChar32 characterFallback[][maxFallbackPerCharacter] = {
    { 0x005E, 0x0302, 0 }, // CIRCUMFLEX ACCENT
    { 0x005F, 0x0332, 0 }, // LOW LINE
    { 0x007E, 0x0303, 0 }, // TILDE
    { 0x00AF, 0x0304, 0x0305 }, // MACRON
    { 0x02C6, 0x0302, 0 }, // MODIFIER LETTER CIRCUMFLEX ACCENT
    { 0x02C7, 0x030C, 0 } // CARON
};
const unsigned characterFallbackSize = WTF_ARRAY_LENGTH(characterFallback);

void MathOperator::getMathVariantsWithFallback(const RenderStyle& style, bool isVertical, Vector<Glyph>& sizeVariants, Vector<OpenTypeMathData::AssemblyPart>& assemblyParts)
{
    // In general, we first try and find contruction for the base glyph.
    GlyphData baseGlyph;
    if (!getBaseGlyph(style, baseGlyph) || !baseGlyph.font->mathData())
        return;
    baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, isVertical, sizeVariants, assemblyParts);
    if (!sizeVariants.isEmpty() || !assemblyParts.isEmpty())
        return;

    // Otherwise, we try and find fallback constructions using similar characters.
    for (unsigned i = 0; i < characterFallbackSize; i++) {
        unsigned j = 0;
        if (characterFallback[i][j] == m_baseCharacter) {
            for (j++; j < maxFallbackPerCharacter && characterFallback[i][j]; j++) {
                GlyphData glyphData;
                if (!getGlyph(style, characterFallback[i][j], glyphData))
                    continue;
                glyphData.font->mathData()->getMathVariants(glyphData.glyph, isVertical, sizeVariants, assemblyParts);
                if (!sizeVariants.isEmpty() || !assemblyParts.isEmpty())
                    return;
            }
            break;
        }
    }
}

void MathOperator::calculateDisplayStyleLargeOperator(const RenderStyle& style)
{
    ASSERT(m_operatorType == Type::DisplayOperator);

    GlyphData baseGlyph;
    if (!getBaseGlyph(style, baseGlyph) || !baseGlyph.font->mathData())
        return;

    // The value of displayOperatorMinHeight is sometimes too small, so we ensure that it is at least \sqrt{2} times the size of the base glyph.
    float displayOperatorMinHeight = std::max(heightForGlyph(baseGlyph) * sqrtOfTwoFloat, baseGlyph.font->mathData()->getMathConstant(*baseGlyph.font, OpenTypeMathData::DisplayOperatorMinHeight));

    Vector<Glyph> sizeVariants;
    Vector<OpenTypeMathData::AssemblyPart> assemblyParts;
    baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, true, sizeVariants, assemblyParts);

    // We choose the first size variant that is larger than the expected displayOperatorMinHeight and otherwise fallback to the largest variant.
    for (auto& sizeVariant : sizeVariants) {
        GlyphData glyphData(sizeVariant, baseGlyph.font);
        setSizeVariant(glyphData);
        m_maxPreferredWidth = m_width;
        m_italicCorrection = glyphData.font->mathData()->getItalicCorrection(*glyphData.font, glyphData.glyph);
        if (heightForGlyph(glyphData) >= displayOperatorMinHeight)
            break;
    }
}

bool MathOperator::calculateGlyphAssemblyFallback(const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const
{
    // The structure of the Open Type Math table is a bit more general than the one currently used by the MathOperator code, so we try to fallback in a reasonable way.
    // FIXME: MathOperator should support the most general format (https://bugs.webkit.org/show_bug.cgi?id=130327).
    // We use the approach of the copyComponents function in github.com/mathjax/MathJax-dev/blob/master/fonts/OpenTypeMath/fontUtil.py

    // We count the number of non extender pieces.
    int nonExtenderCount = 0;
    for (auto& part : assemblyParts) {
        if (!part.isExtender)
            nonExtenderCount++;
    }
    if (nonExtenderCount > 3)
        return false; // This is not supported: there are too many pieces.

    // We now browse the list of pieces from left to right for horizontal operators and from bottom to top for vertical operators.
    enum PartType {
        Start,
        ExtenderBetweenStartAndMiddle,
        Middle,
        ExtenderBetweenMiddleAndEnd,
        End,
        None
    };
    PartType expectedPartType = Start;
    assemblyData.extensionCodePoint = 0;
    assemblyData.extensionFallbackGlyph = 0;
    assemblyData.middleCodePoint = 0;
    assemblyData.middleFallbackGlyph = 0;
    for (auto& part : assemblyParts) {
        if (nonExtenderCount < 3) {
            // If we only have at most two non-extenders then we skip the middle glyph.
            if (expectedPartType == ExtenderBetweenStartAndMiddle)
                expectedPartType = ExtenderBetweenMiddleAndEnd;
            else if (expectedPartType == Middle)
                expectedPartType = End;
        }
        if (part.isExtender) {
            if (!assemblyData.extensionFallbackGlyph)
                assemblyData.extensionFallbackGlyph = part.glyph; // We copy the extender part.
            else if (assemblyData.extensionFallbackGlyph != part.glyph)
                return false; // This is not supported: the assembly has different extenders.

            switch (expectedPartType) {
            case Start:
                // We ignore the left/bottom part.
                expectedPartType = ExtenderBetweenStartAndMiddle;
                continue;
            case Middle:
                // We ignore the middle part.
                expectedPartType = ExtenderBetweenMiddleAndEnd;
                continue;
            case End:
            case None:
                // This is not supported: we got an unexpected extender.
                return false;
            case ExtenderBetweenStartAndMiddle:
            case ExtenderBetweenMiddleAndEnd:
                // We ignore multiple consecutive extenders.
                continue;
            }
        }

        switch (expectedPartType) {
        case Start:
            // We copy the left/bottom part.
            assemblyData.bottomOrLeftFallbackGlyph = part.glyph;
            assemblyData.bottomOrLeftCodePoint = 0;
            expectedPartType = ExtenderBetweenStartAndMiddle;
            continue;
        case ExtenderBetweenStartAndMiddle:
        case Middle:
            // We copy the middle part.
            assemblyData.middleFallbackGlyph = part.glyph;
            expectedPartType = ExtenderBetweenMiddleAndEnd;
            continue;
        case ExtenderBetweenMiddleAndEnd:
        case End:
            // We copy the right/top part.
            assemblyData.topOrRightFallbackGlyph = part.glyph;
            assemblyData.topOrRightCodePoint = 0;
            expectedPartType = None;
            continue;
        case None:
            // This is not supported: we got an unexpected non-extender part.
            return false;
        }
    }

    if (!assemblyData.hasExtension())
        return false; // This is not supported: we always assume that we have an extension glyph.

    // If we don't have top/bottom glyphs, we use the extension glyph.
    if (!assemblyData.topOrRightCodePoint && !assemblyData.topOrRightFallbackGlyph)
        assemblyData.topOrRightFallbackGlyph = assemblyData.extensionFallbackGlyph;
    if (!assemblyData.bottomOrLeftCodePoint && !assemblyData.bottomOrLeftFallbackGlyph)
        assemblyData.bottomOrLeftFallbackGlyph = assemblyData.extensionFallbackGlyph;

    return true;
}

void MathOperator::calculateStretchyData(const RenderStyle& style, bool calculateMaxPreferredWidth, LayoutUnit targetSize)
{
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
    ASSERT(!calculateMaxPreferredWidth || m_operatorType == Type::VerticalOperator);
    bool isVertical = m_operatorType == Type::VerticalOperator;

    GlyphData baseGlyph;
    if (!getBaseGlyph(style, baseGlyph))
        return;

    if (!calculateMaxPreferredWidth) {
        // We do not stretch if the base glyph is large enough.
        float baseSize = isVertical ? heightForGlyph(baseGlyph) : advanceWidthForGlyph(baseGlyph);
        if (targetSize <= baseSize)
            return;
    }

    GlyphAssemblyData assemblyData;
    if (baseGlyph.font->mathData()) {
        Vector<Glyph> sizeVariants;
        Vector<OpenTypeMathData::AssemblyPart> assemblyParts;
        getMathVariantsWithFallback(style, isVertical, sizeVariants, assemblyParts);
        // We verify the size variants.
        for (auto& sizeVariant : sizeVariants) {
            GlyphData glyphData(sizeVariant, baseGlyph.font);
            if (calculateMaxPreferredWidth)
                m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(glyphData));
            else {
                setSizeVariant(glyphData);
                LayoutUnit size = isVertical ? heightForGlyph(glyphData) : advanceWidthForGlyph(glyphData);
                if (size >= targetSize)
                    return;
            }
        }

        // We verify if there is a construction.
        if (!calculateGlyphAssemblyFallback(assemblyParts, assemblyData))
            return;
    } else {
        if (!isVertical)
            return;

        // If the font does not have a MATH table, we fallback to the Unicode-only constructions.
        const StretchyCharacter* stretchyCharacter = nullptr;
        const unsigned maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters);
        for (unsigned index = 0; index < maxIndex; ++index) {
            if (stretchyCharacters[index].character == m_baseCharacter) {
                stretchyCharacter = &stretchyCharacters[index];
                if (!style.isLeftToRightDirection() && index < leftRightPairsCount * 2) {
                    // If we are in right-to-left direction we select the mirrored form by adding -1 or +1 according to the parity of index.
                    index += index % 2 ? -1 : 1;
                }
                break;
            }
        }

        // Unicode contains U+23B7 RADICAL SYMBOL BOTTOM but it is generally not provided by fonts without a MATH table.
        // Moreover, it's not clear what the proper vertical extender or top hook would be.
        // Hence we fallback to scaling the base glyph vertically.
        if (!calculateMaxPreferredWidth && m_baseCharacter == kRadicalOperator) {
            LayoutUnit height = m_ascent + m_descent;
            if (height > 0 && height < targetSize) {
                m_radicalVerticalScale = targetSize.toFloat() / height;
                m_ascent *= m_radicalVerticalScale;
                m_descent *= m_radicalVerticalScale;
            }
            return;
        }

        // If we didn't find a stretchy character set for this character, we don't know how to stretch it.
        if (!stretchyCharacter)
            return;

        // We convert the list of Unicode characters into a list of glyph data.
        assemblyData.topOrRightCodePoint = stretchyCharacter->topChar;
        assemblyData.extensionCodePoint = stretchyCharacter->extensionChar;
        assemblyData.bottomOrLeftCodePoint = stretchyCharacter->bottomChar;
        assemblyData.middleCodePoint = stretchyCharacter->middleChar;
    }

    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.topOrRightCodePoint, assemblyData.topOrRightFallbackGlyph);
    auto extension = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.extensionCodePoint, assemblyData.extensionFallbackGlyph);
    auto middle = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.middleCodePoint, assemblyData.middleFallbackGlyph);
    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, assemblyData.bottomOrLeftCodePoint, assemblyData.bottomOrLeftFallbackGlyph);

    // If we are measuring the maximum width, verify each component.
    if (calculateMaxPreferredWidth) {
        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(topOrRight));
        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(extension));
        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(middle));
        m_maxPreferredWidth = std::max<LayoutUnit>(m_maxPreferredWidth, advanceWidthForGlyph(bottomOrLeft));
        return;
    }

    // We ensure that the size is large enough to avoid glyph overlaps.
    float minSize = isVertical ?
        heightForGlyph(topOrRight) + heightForGlyph(middle) + heightForGlyph(bottomOrLeft)
        : advanceWidthForGlyph(bottomOrLeft) + advanceWidthForGlyph(middle) + advanceWidthForGlyph(topOrRight);
    if (minSize > targetSize)
        return;

    setGlyphAssembly(style, assemblyData);
}

void MathOperator::stretchTo(const RenderStyle& style, LayoutUnit targetSize)
{
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
    calculateStretchyData(style, false, targetSize);
    if (m_stretchType == StretchType::GlyphAssembly) {
        if (m_operatorType == Type::VerticalOperator) {
            m_ascent = targetSize;
            m_descent = 0;
        } else
            m_width = targetSize;
    }
}

LayoutRect MathOperator::paintGlyph(const RenderStyle& style, PaintInfo& info, const GlyphData& data, const LayoutPoint& origin, GlyphPaintTrimming trim)
{
    FloatRect glyphBounds = boundsForGlyph(data);

    LayoutRect glyphPaintRect(origin, LayoutSize(glyphBounds.x() + glyphBounds.width(), glyphBounds.height()));
    glyphPaintRect.setY(origin.y() + glyphBounds.y());

    // In order to have glyphs fit snugly with one another we snap the connecting edges to pixel boundaries
    // and trim off one pixel. The pixel trim is to account for fonts that have edge pixels that have less
    // than full coverage. These edge pixels can introduce small seams between connected glyphs.
    FloatRect clipBounds = info.rect;
    switch (trim) {
    case TrimTop:
        glyphPaintRect.shiftYEdgeTo(glyphPaintRect.y().ceil() + 1);
        clipBounds.shiftYEdgeTo(glyphPaintRect.y());
        break;
    case TrimBottom:
        glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);
        clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());
        break;
    case TrimTopAndBottom:
        glyphPaintRect.shiftYEdgeTo(glyphPaintRect.y().ceil() + 1);
        glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);
        clipBounds.shiftYEdgeTo(glyphPaintRect.y());
        clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());
        break;
    case TrimLeft:
        glyphPaintRect.shiftXEdgeTo(glyphPaintRect.x().ceil() + 1);
        clipBounds.shiftXEdgeTo(glyphPaintRect.x());
        break;
    case TrimRight:
        glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1);
        clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX());
        break;
    case TrimLeftAndRight:
        glyphPaintRect.shiftXEdgeTo(glyphPaintRect.x().ceil() + 1);
        glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1);
        clipBounds.shiftXEdgeTo(glyphPaintRect.x());
        clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX());
    }

    // Clipping the enclosing IntRect avoids any potential issues at joined edges.
    GraphicsContextStateSaver stateSaver(info.context());
    info.context().clip(clipBounds);

    GlyphBuffer buffer;
    buffer.add(data.glyph, data.font, advanceWidthForGlyph(data));
    info.context().drawGlyphs(style.fontCascade(), *data.font, buffer, 0, 1, origin);

    return glyphPaintRect;
}

void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
{
    ASSERT(m_operatorType == Type::VerticalOperator);
    ASSERT(m_stretchType == StretchType::GlyphAssembly);

    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);

    ASSERT(extension.font);
    ASSERT(from.y() <= to.y());

    // If there is no space for the extension glyph, we don't need to do anything.
    if (from.y() == to.y())
        return;

    GraphicsContextStateSaver stateSaver(info.context());

    FloatRect glyphBounds = boundsForGlyph(extension);

    // Clipping the extender region here allows us to draw the bottom extender glyph into the
    // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.
    LayoutRect clipBounds = info.rect;
    clipBounds.shiftYEdgeTo(from.y());
    clipBounds.shiftMaxYEdgeTo(to.y());
    info.context().clip(clipBounds);

    // Trimming may remove up to two pixels from the top of the extender glyph, so we move it up by two pixels.
    float offsetToGlyphTop = glyphBounds.y() + 2;
    LayoutPoint glyphOrigin = LayoutPoint(from.x(), from.y() - offsetToGlyphTop);
    FloatRect lastPaintedGlyphRect(from, FloatSize());

    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxY() < to.y() && extensionCount < kMaximumExtensionCount; extensionCount++) {
        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimTopAndBottom);
        glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());

        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
        // with trimming. In that case we just draw nothing.
        if (lastPaintedGlyphRect.isEmpty())
            break;
    }
}

void MathOperator::fillWithHorizontalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
{
    ASSERT(m_operatorType == Type::HorizontalOperator);
    ASSERT(m_stretchType == StretchType::GlyphAssembly);

    auto extension = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.extensionCodePoint, m_assembly.extensionFallbackGlyph);

    ASSERT(extension.font);
    ASSERT(from.x() <= to.x());
    ASSERT(from.y() == to.y());

    // If there is no space for the extension glyph, we don't need to do anything.
    if (from.x() == to.x())
        return;

    GraphicsContextStateSaver stateSaver(info.context());

    // Clipping the extender region here allows us to draw the bottom extender glyph into the
    // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.
    LayoutRect clipBounds = info.rect;
    clipBounds.shiftXEdgeTo(from.x());
    clipBounds.shiftMaxXEdgeTo(to.x());
    info.context().clip(clipBounds);

    // Trimming may remove up to two pixels from the left of the extender glyph, so we move it left by two pixels.
    float offsetToGlyphLeft = -2;
    LayoutPoint glyphOrigin = LayoutPoint(from.x() + offsetToGlyphLeft, from.y());
    FloatRect lastPaintedGlyphRect(from, FloatSize());

    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxX() < to.x() && extensionCount < kMaximumExtensionCount; extensionCount++) {
        lastPaintedGlyphRect = paintGlyph(style, info, extension, glyphOrigin, TrimLeftAndRight);
        glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());

        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
        // with trimming. In that case we just draw nothing.
        if (lastPaintedGlyphRect.isEmpty())
            break;
    }
}

void MathOperator::paintVerticalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
{
    ASSERT(m_operatorType == Type::VerticalOperator);
    ASSERT(m_stretchType == StretchType::GlyphAssembly);

    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);

    ASSERT(topOrRight.font);
    ASSERT(bottomOrLeft.font);
    if (!topOrRight.font || !bottomOrLeft.font) {
        LOG_ERROR("MathML: no font can be found for Unicode code point.");
        return;
    }

    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
    LayoutPoint operatorTopLeft = paintOffset;
    FloatRect topGlyphBounds = boundsForGlyph(topOrRight);
    LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y());
    LayoutRect topGlyphPaintRect = paintGlyph(style, info, topOrRight, topGlyphOrigin, TrimBottom);

    FloatRect bottomGlyphBounds = boundsForGlyph(bottomOrLeft);
    LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + stretchSize() - (bottomGlyphBounds.height() + bottomGlyphBounds.y()));
    LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, bottomGlyphOrigin, TrimTop);

    if (m_assembly.hasMiddle()) {
        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);

        // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph.
        FloatRect middleGlyphBounds = boundsForGlyph(middle);
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y());
        middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0));
        middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0));

        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimTopAndBottom);
        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());
        fillWithVerticalExtensionGlyph(style, info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
    } else
        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
}

void MathOperator::paintHorizontalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
{
    ASSERT(m_operatorType == Type::HorizontalOperator);
    ASSERT(m_stretchType == StretchType::GlyphAssembly);

    auto topOrRight = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.topOrRightCodePoint, m_assembly.topOrRightFallbackGlyph);
    auto bottomOrLeft = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.bottomOrLeftCodePoint, m_assembly.bottomOrLeftFallbackGlyph);

    ASSERT(bottomOrLeft.font);
    ASSERT(topOrRight.font);
    if (!topOrRight.font || !bottomOrLeft.font) {
        LOG_ERROR("MathML: no font can be found for Unicode code point.");
        return;
    }

    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
    LayoutPoint operatorTopLeft = paintOffset;
    LayoutUnit baselineY = operatorTopLeft.y() + m_ascent;
    LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), baselineY);
    LayoutRect leftGlyphPaintRect = paintGlyph(style, info, bottomOrLeft, leftGlyphOrigin, TrimRight);

    FloatRect rightGlyphBounds = boundsForGlyph(topOrRight);
    LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + stretchSize() - rightGlyphBounds.width(), baselineY);
    LayoutRect rightGlyphPaintRect = paintGlyph(style, info, topOrRight, rightGlyphOrigin, TrimLeft);

    if (m_assembly.hasMiddle()) {
        auto middle = glyphDataForCodePointOrFallbackGlyph(style, m_assembly.middleCodePoint, m_assembly.middleFallbackGlyph);

        // Center the glyph origin between the start and end glyph paint extents.
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), baselineY);
        middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0));
        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, middle, middleGlyphOrigin, TrimLeftAndRight);
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(middleGlyphPaintRect.x(), baselineY));
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(middleGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
    } else
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
}

void MathOperator::paint(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
{
    if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style.visibility() != VISIBLE)
        return;

    // Make a copy of the PaintInfo because applyTransform will modify its rect.
    PaintInfo paintInfo(info);
    GraphicsContextStateSaver stateSaver(paintInfo.context());
    paintInfo.context().setFillColor(style.visitedDependentColorWithColorFilter(CSSPropertyColor));

    // For a radical character, we may need some scale transform to stretch it vertically or mirror it.
    if (m_baseCharacter == kRadicalOperator) {
        float radicalHorizontalScale = style.isLeftToRightDirection() ? 1 : -1;
        if (radicalHorizontalScale == -1 || m_radicalVerticalScale > 1) {
            LayoutPoint scaleOrigin = paintOffset;
            scaleOrigin.move(m_width / 2, 0);
            paintInfo.applyTransform(AffineTransform().translate(scaleOrigin).scale(radicalHorizontalScale, m_radicalVerticalScale).translate(-scaleOrigin));
        }
    }

    if (m_stretchType == StretchType::GlyphAssembly) {
        if (m_operatorType == Type::VerticalOperator)
            paintVerticalGlyphAssembly(style, info, paintOffset);
        else
            paintHorizontalGlyphAssembly(style, info, paintOffset);
        return;
    }

    GlyphData glyphData;
    ASSERT(m_stretchType == StretchType::Unstretched || m_stretchType == StretchType::SizeVariant);
    if (!getBaseGlyph(style, glyphData))
        return;
    if (m_stretchType == StretchType::SizeVariant)
        glyphData.glyph = m_variantGlyph;

    GlyphBuffer buffer;
    buffer.add(glyphData.glyph, glyphData.font, advanceWidthForGlyph(glyphData));
    LayoutPoint operatorTopLeft = paintOffset;
    FloatRect glyphBounds = boundsForGlyph(glyphData);
    LayoutPoint operatorOrigin(operatorTopLeft.x(), operatorTopLeft.y() - glyphBounds.y());
    paintInfo.context().drawGlyphs(style.fontCascade(), *glyphData.font, buffer, 0, 1, operatorOrigin);
}

}

#endif
