/*
 * Copyright (C) 2003, 2006, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Holger Hans Peter Freyther
 * Copyright (C) 2014 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "platform/fonts/WidthIterator.h"

#include "platform/fonts/Character.h"
#include "platform/fonts/Font.h"
#include "platform/fonts/FontPlatformFeatures.h"
#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/Latin1TextIterator.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/text/SurrogatePairAwareTextIterator.h"
#include "wtf/MathExtras.h"

using namespace WTF;
using namespace Unicode;

namespace blink {

WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, bool accountForGlyphBounds, bool forTextEmphasis)
    : m_font(font)
    , m_run(run)
    , m_currentCharacter(0)
    , m_runWidthSoFar(0)
    , m_isAfterExpansion(!run.allowsLeadingExpansion())
    , m_fallbackFonts(fallbackFonts)
    , m_maxGlyphBoundingBoxY(std::numeric_limits<float>::min())
    , m_minGlyphBoundingBoxY(std::numeric_limits<float>::max())
    , m_firstGlyphOverflow(0)
    , m_lastGlyphOverflow(0)
    , m_accountForGlyphBounds(accountForGlyphBounds)
    , m_forTextEmphasis(forTextEmphasis)
{
    // If the padding is non-zero, count the number of spaces in the run
    // and divide that by the padding for per space addition.
    m_expansion = m_run.expansion();
    if (!m_expansion)
        m_expansionPerOpportunity = 0;
    else {
        bool isAfterExpansion = m_isAfterExpansion;
        unsigned expansionOpportunityCount = m_run.is8Bit() ? Character::expansionOpportunityCount(m_run.characters8(), m_run.length(), m_run.direction(), isAfterExpansion) : Character::expansionOpportunityCount(m_run.characters16(), m_run.length(), m_run.direction(), isAfterExpansion);
        if (isAfterExpansion && !m_run.allowsTrailingExpansion())
            expansionOpportunityCount--;

        if (!expansionOpportunityCount)
            m_expansionPerOpportunity = 0;
        else
            m_expansionPerOpportunity = m_expansion / expansionOpportunityCount;
    }
}

GlyphData WidthIterator::glyphDataForCharacter(CharacterData& charData)
{
    ASSERT(m_font);
    return m_font->glyphDataForCharacter(charData.character, m_run.rtl());
}

float WidthIterator::characterWidth(UChar32 character, const GlyphData& glyphData) const
{
    const SimpleFontData* fontData = glyphData.fontData;
    ASSERT(fontData);

    if (UNLIKELY(character == '\t' && m_run.allowTabs()))
        return m_font->tabWidth(*fontData, m_run.tabSize(), m_run.xPos() + m_runWidthSoFar);

    float width = fontData->widthForGlyph(glyphData.glyph);

    // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text.
    if (UNLIKELY(m_run.horizontalGlyphStretch() != 1))
        width *= m_run.horizontalGlyphStretch();

    return width;
}

void WidthIterator::cacheFallbackFont(UChar32 character, const SimpleFontData* fontData,
    const SimpleFontData* primaryFont)
{
    if (fontData == primaryFont)
        return;

    // FIXME: This does a little extra work that could be avoided if
    // glyphDataForCharacter() returned whether it chose to use a small caps font.
    if (m_font->fontDescription().variant() == FontVariantNormal || character == toUpper(character)) {
        m_fallbackFonts->add(fontData);
    } else {
        ASSERT(m_font->fontDescription().variant() == FontVariantSmallCaps);
        const GlyphData uppercaseGlyphData = m_font->glyphDataForCharacter(toUpper(character),
            m_run.rtl());
        if (uppercaseGlyphData.fontData != primaryFont)
            m_fallbackFonts->add(uppercaseGlyphData.fontData);
    }
}

float WidthIterator::adjustSpacing(float width, const CharacterData& charData,
    const SimpleFontData& fontData, GlyphBuffer* glyphBuffer)
{
    // Account for letter-spacing.
    if (width)
        width += m_font->fontDescription().letterSpacing();

    static bool expandAroundIdeographs = FontPlatformFeatures::canExpandAroundIdeographsInComplexText();
    bool treatAsSpace = Character::treatAsSpace(charData.character);
    if (treatAsSpace || (expandAroundIdeographs && Character::isCJKIdeographOrSymbol(charData.character))) {
        // Distribute the run's total expansion evenly over all expansion opportunities in the run.
        if (m_expansion) {
            if (!treatAsSpace && !m_isAfterExpansion) {
                // Take the expansion opportunity before this ideograph.
                m_expansion -= m_expansionPerOpportunity;
                float expansionAtThisOpportunity = m_expansionPerOpportunity;
                m_runWidthSoFar += expansionAtThisOpportunity;
                if (glyphBuffer) {
                    if (glyphBuffer->isEmpty()) {
                        if (m_forTextEmphasis)
                            glyphBuffer->add(fontData.zeroWidthSpaceGlyph(), &fontData, m_expansionPerOpportunity);
                        else
                            glyphBuffer->add(fontData.spaceGlyph(), &fontData, expansionAtThisOpportunity);
                    } else {
                        glyphBuffer->expandLastAdvance(expansionAtThisOpportunity);
                    }
                }
            }
            if (m_run.allowsTrailingExpansion()
                || (m_run.ltr() && charData.characterOffset + charData.clusterLength < static_cast<size_t>(m_run.length()))
                || (m_run.rtl() && charData.characterOffset)) {
                m_expansion -= m_expansionPerOpportunity;
                width += m_expansionPerOpportunity;
                m_isAfterExpansion = true;
            }
        } else {
            m_isAfterExpansion = false;
        }

        // Account for word spacing.
        // We apply additional space between "words" by adding width to the space character.
        if (treatAsSpace && (charData.character != '\t' || !m_run.allowTabs())
            && (charData.characterOffset || charData.character == noBreakSpace)
            && m_font->fontDescription().wordSpacing()) {
            width += m_font->fontDescription().wordSpacing();
        }
    } else {
        m_isAfterExpansion = false;
    }

    return width;
}

void WidthIterator::updateGlyphBounds(const GlyphData& glyphData, float width, bool firstCharacter)
{
    ASSERT(glyphData.fontData);
    FloatRect bounds = glyphData.fontData->boundsForGlyph(glyphData.glyph);

    if (firstCharacter)
        m_firstGlyphOverflow = std::max<float>(0, -bounds.x());
    m_lastGlyphOverflow = std::max<float>(0, bounds.maxX() - width);
    m_maxGlyphBoundingBoxY = std::max(m_maxGlyphBoundingBoxY, bounds.maxY());
    m_minGlyphBoundingBoxY = std::min(m_minGlyphBoundingBoxY, bounds.y());
}

template <typename TextIterator>
unsigned WidthIterator::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
{
    bool hasExtraSpacing = (m_font->fontDescription().letterSpacing() || m_font->fontDescription().wordSpacing() || m_expansion)
        && !m_run.spacingDisabled();

    const SimpleFontData* primaryFont = m_font->primaryFont();
    const SimpleFontData* lastFontData = primaryFont;

    CharacterData charData;
    while (textIterator.consume(charData.character, charData.clusterLength)) {
        charData.characterOffset = textIterator.currentCharacter();

        const GlyphData glyphData = glyphDataForCharacter(charData);
        Glyph glyph = glyphData.glyph;
        const SimpleFontData* fontData = glyphData.fontData;
        ASSERT(fontData);

        // Now that we have a glyph and font data, get its width.
        float width = characterWidth(charData.character, glyphData);

        if (m_fallbackFonts && lastFontData != fontData && width) {
            lastFontData = fontData;
            cacheFallbackFont(charData.character, fontData, primaryFont);
        }

        if (hasExtraSpacing)
            width = adjustSpacing(width, charData, *fontData, glyphBuffer);

        if (m_accountForGlyphBounds)
            updateGlyphBounds(glyphData, width, !charData.characterOffset);

        if (m_forTextEmphasis && !Character::canReceiveTextEmphasis(charData.character))
            glyph = 0;

        // Advance past the character we just dealt with.
        textIterator.advance(charData.clusterLength);
        m_runWidthSoFar += width;

        if (glyphBuffer)
            glyphBuffer->add(glyph, fontData, width);
    }

    unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
    m_currentCharacter = textIterator.currentCharacter();

    return consumedCharacters;
}

unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
{
    int length = m_run.length();

    if (offset > length)
        offset = length;

    if (m_currentCharacter >= static_cast<unsigned>(offset))
        return 0;

    if (m_run.is8Bit()) {
        Latin1TextIterator textIterator(m_run.data8(m_currentCharacter), m_currentCharacter, offset, length);
        return advanceInternal(textIterator, glyphBuffer);
    }

    SurrogatePairAwareTextIterator textIterator(m_run.data16(m_currentCharacter), m_currentCharacter, offset, length);
    return advanceInternal(textIterator, glyphBuffer);
}

bool WidthIterator::advanceOneCharacter(float& width)
{
    float initialWidth = m_runWidthSoFar;

    if (!advance(m_currentCharacter + 1))
        return false;

    width = m_runWidthSoFar - initialWidth;
    return true;
}

} // namespace blink
