/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2013 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 "core/css/resolver/FontBuilder.h"

#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/FontSize.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/TextAutosizer.h"
#include "platform/fonts/FontDescription.h"
#include "platform/text/LocaleToScriptMapping.h"

namespace blink {

// FIXME: This scoping class is a short-term fix to minimize the changes in
// Font-constructing logic.
class FontDescriptionChangeScope {
    STACK_ALLOCATED();
public:
    FontDescriptionChangeScope(FontBuilder* fontBuilder)
        : m_fontBuilder(fontBuilder)
        , m_fontDescription(fontBuilder->m_style->fontDescription())
    {
    }

    void reset() { m_fontDescription = FontDescription(); }
    void set(const FontDescription& fontDescription) { m_fontDescription = fontDescription; }
    FontDescription& fontDescription() { return m_fontDescription; }

    ~FontDescriptionChangeScope()
    {
        m_fontBuilder->didChangeFontParameters(m_fontBuilder->m_style->setFontDescription(m_fontDescription));
    }

private:
    RawPtrWillBeMember<FontBuilder> m_fontBuilder;
    FontDescription m_fontDescription;
};

FontBuilder::FontBuilder()
    : m_document(nullptr)
    , m_fontSizehasViewportUnits(false)
    , m_style(0)
    , m_fontDirty(false)
{
}

void FontBuilder::initForStyleResolve(const Document& document, RenderStyle* style)
{
    ASSERT(document.frame());
    m_document = &document;
    m_style = style;
    m_fontDirty = false;
}

inline static void setFontFamilyToStandard(FontDescription& fontDescription, const Document* document)
{
    if (!document || !document->settings())
        return;

    fontDescription.setGenericFamily(FontDescription::StandardFamily);
    const AtomicString& standardFontFamily = document->settings()->genericFontFamilySettings().standard();
    if (standardFontFamily.isEmpty())
        return;

    fontDescription.firstFamily().setFamily(standardFontFamily);
    // FIXME: Why is this needed here?
    fontDescription.firstFamily().appendFamily(nullptr);
}

void FontBuilder::setInitial(float effectiveZoom)
{
    ASSERT(m_document && m_document->settings());
    if (!m_document || !m_document->settings())
        return;

    FontDescriptionChangeScope scope(this);

    scope.reset();
    setFontFamilyToStandard(scope.fontDescription(), m_document);
    scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
    setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueMedium, NonFixedPitchFont));
}

void FontBuilder::inheritFrom(const FontDescription& fontDescription)
{
    FontDescriptionChangeScope scope(this);

    scope.set(fontDescription);
}

void FontBuilder::didChangeFontParameters(bool changed)
{
    m_fontDirty |= changed;
}

void FontBuilder::fromSystemFont(CSSValueID valueId, float effectiveZoom)
{
    FontDescriptionChangeScope scope(this);

    FontDescription fontDescription;
    RenderTheme::theme().systemFont(valueId, fontDescription);

    // Double-check and see if the theme did anything. If not, don't bother updating the font.
    if (!fontDescription.isAbsoluteSize())
        return;

    // Make sure the rendering mode and printer font settings are updated.
    const Settings* settings = m_document->settings();
    ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
    if (!settings)
        return;

    // Handle the zoom factor.
    fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, effectiveZoom, fontDescription.specifiedSize()));
    scope.set(fontDescription);
}

void FontBuilder::setFontFamilyInitial()
{
    FontDescriptionChangeScope scope(this);

    setFontFamilyToStandard(scope.fontDescription(), m_document);
}

void FontBuilder::setFontFamilyInherit(const FontDescription& parentFontDescription)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setGenericFamily(parentFontDescription.genericFamily());
    scope.fontDescription().setFamily(parentFontDescription.family());
}

// FIXME: I am not convinced FontBuilder needs to know anything about CSSValues.
void FontBuilder::setFontFamilyValue(CSSValue* value)
{
    FontDescriptionChangeScope scope(this);

    if (!value->isValueList())
        return;

    FontFamily& firstFamily = scope.fontDescription().firstFamily();
    FontFamily* currFamily = 0;

    // Before mapping in a new font-family property, we should reset the generic family.
    FixedPitchFontType oldFixedPitchFontType = scope.fontDescription().fixedPitchFontType();
    scope.fontDescription().setGenericFamily(FontDescription::NoFamily);

    for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
        CSSValue* item = i.value();
        if (!item->isPrimitiveValue())
            continue;
        CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
        AtomicString face;
        Settings* settings = m_document->settings();
        if (contentValue->isString()) {
            face = AtomicString(contentValue->getStringValue());
        } else if (settings) {
            switch (contentValue->getValueID()) {
            case CSSValueWebkitBody:
                face = settings->genericFontFamilySettings().standard();
                break;
            case CSSValueSerif:
                face = FontFamilyNames::webkit_serif;
                scope.fontDescription().setGenericFamily(FontDescription::SerifFamily);
                break;
            case CSSValueSansSerif:
                face = FontFamilyNames::webkit_sans_serif;
                scope.fontDescription().setGenericFamily(FontDescription::SansSerifFamily);
                break;
            case CSSValueCursive:
                face = FontFamilyNames::webkit_cursive;
                scope.fontDescription().setGenericFamily(FontDescription::CursiveFamily);
                break;
            case CSSValueFantasy:
                face = FontFamilyNames::webkit_fantasy;
                scope.fontDescription().setGenericFamily(FontDescription::FantasyFamily);
                break;
            case CSSValueMonospace:
                face = FontFamilyNames::webkit_monospace;
                scope.fontDescription().setGenericFamily(FontDescription::MonospaceFamily);
                break;
            case CSSValueWebkitPictograph:
                face = FontFamilyNames::webkit_pictograph;
                scope.fontDescription().setGenericFamily(FontDescription::PictographFamily);
                break;
            default:
                break;
            }
        }

        if (!face.isEmpty()) {
            if (!currFamily) {
                // Filling in the first family.
                firstFamily.setFamily(face);
                firstFamily.appendFamily(nullptr); // Remove any inherited family-fallback list.
                currFamily = &firstFamily;
            } else {
                RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create();
                newFamily->setFamily(face);
                currFamily->appendFamily(newFamily);
                currFamily = newFamily.get();
            }
        }
    }

    // We can't call useFixedDefaultSize() until all new font families have been added
    // If currFamily is non-zero then we set at least one family on this description.
    if (!currFamily)
        return;

    if (scope.fontDescription().keywordSize() && scope.fontDescription().fixedPitchFontType() != oldFixedPitchFontType) {
        scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document,
        static_cast<CSSValueID>(CSSValueXxSmall + scope.fontDescription().keywordSize() - 1), scope.fontDescription().fixedPitchFontType()));
    }
}

void FontBuilder::setFontSizeInitial()
{
    FontDescriptionChangeScope scope(this);

    float size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, scope.fontDescription().fixedPitchFontType());

    if (size < 0)
        return;

    scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
    scope.fontDescription().setSpecifiedSize(size);
}

void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription)
{
    FontDescriptionChangeScope scope(this);

    float size = parentFontDescription.specifiedSize();

    if (size < 0)
        return;

    scope.fontDescription().setKeywordSize(parentFontDescription.keywordSize());
    scope.fontDescription().setSpecifiedSize(size);
}

// FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large)
// and scale down/up to the next size level.
static float largerFontSize(float size)
{
    return size * 1.2f;
}

static float smallerFontSize(float size)
{
    return size / 1.2f;
}

// FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary.
void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle)
{
    if (!value->isPrimitiveValue())
        return;

    CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);

    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setKeywordSize(0);
    float parentSize = 0;
    bool parentIsAbsoluteSize = false;
    float size = 0;

    // FIXME: Find out when parentStyle could be 0?
    if (parentStyle) {
        parentSize = parentStyle->fontDescription().specifiedSize();
        parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize();
    }

    if (CSSValueID valueID = primitiveValue->getValueID()) {
        switch (valueID) {
        case CSSValueXxSmall:
        case CSSValueXSmall:
        case CSSValueSmall:
        case CSSValueMedium:
        case CSSValueLarge:
        case CSSValueXLarge:
        case CSSValueXxLarge:
        case CSSValueWebkitXxxLarge:
            size = FontSize::fontSizeForKeyword(m_document, valueID, scope.fontDescription().fixedPitchFontType());
            scope.fontDescription().setKeywordSize(valueID - CSSValueXxSmall + 1);
            break;
        case CSSValueLarger:
            size = largerFontSize(parentSize);
            break;
        case CSSValueSmaller:
            size = smallerFontSize(parentSize);
            break;
        default:
            return;
        }

        scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize && (valueID == CSSValueLarger || valueID == CSSValueSmaller));
    } else {
        scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength()));
        if (primitiveValue->isPercentage()) {
            size = (primitiveValue->getFloatValue() * parentSize) / 100.0f;
        } else {
            // If we have viewport units the conversion will mark the parent style as having viewport units.
            bool parentHasViewportUnits = parentStyle->hasViewportUnits();
            parentStyle->setHasViewportUnits(false);
            CSSToLengthConversionData conversionData(parentStyle, rootElementStyle, m_document->renderView(), 1.0f, true);
            if (primitiveValue->isLength())
                size = primitiveValue->computeLength<float>(conversionData);
            else if (primitiveValue->isCalculatedPercentageWithLength())
                size = primitiveValue->cssCalcValue()->toCalcValue(conversionData)->evaluate(parentSize);
            else
                ASSERT_NOT_REACHED();
            m_fontSizehasViewportUnits = parentStyle->hasViewportUnits();
            parentStyle->setHasViewportUnits(parentHasViewportUnits);
        }
    }

    if (size < 0)
        return;

    // Overly large font sizes will cause crashes on some platforms (such as Windows).
    // Cap font size here to make sure that doesn't happen.
    size = std::min(maximumAllowedFontSize, size);


    scope.fontDescription().setSpecifiedSize(size);
}

void FontBuilder::setWeight(FontWeight fontWeight)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setWeight(fontWeight);
}

void FontBuilder::setStretch(FontStretch fontStretch)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setStretch(fontStretch);
}

void FontBuilder::setScript(const String& locale)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setLocale(locale);
    scope.fontDescription().setScript(localeToScriptCodeForFontSelection(locale));
}

void FontBuilder::setStyle(FontStyle italic)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setStyle(italic);
}

void FontBuilder::setVariant(FontVariant smallCaps)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setVariant(smallCaps);
}

void FontBuilder::setVariantLigatures(const FontDescription::VariantLigatures& ligatures)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setVariantLigatures(ligatures);
}

void FontBuilder::setTextRendering(TextRenderingMode textRenderingMode)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setTextRendering(textRenderingMode);
}

void FontBuilder::setKerning(FontDescription::Kerning kerning)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setKerning(kerning);
}

void FontBuilder::setFontSmoothing(FontSmoothingMode foontSmoothingMode)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setFontSmoothing(foontSmoothingMode);
}

void FontBuilder::setFeatureSettings(PassRefPtr<FontFeatureSettings> settings)
{
    FontDescriptionChangeScope scope(this);

    scope.fontDescription().setFeatureSettings(settings);
}

void FontBuilder::setSize(FontDescription& fontDescription, float effectiveZoom, float size)
{
    fontDescription.setSpecifiedSize(size);
    fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, effectiveZoom, size));
}

float FontBuilder::getComputedSizeFromSpecifiedSize(FontDescription& fontDescription, float effectiveZoom, float specifiedSize)
{
    float zoomFactor = effectiveZoom;
    // FIXME: Why is this here!!!!?!
    if (LocalFrame* frame = m_document->frame())
        zoomFactor *= frame->textZoomFactor();

    return FontSize::getComputedSizeFromSpecifiedSize(m_document, zoomFactor, fontDescription.isAbsoluteSize(), specifiedSize);
}

static void getFontAndGlyphOrientation(const RenderStyle* style, FontOrientation& fontOrientation, NonCJKGlyphOrientation& glyphOrientation)
{
    if (style->isHorizontalWritingMode()) {
        fontOrientation = Horizontal;
        glyphOrientation = NonCJKGlyphOrientationVerticalRight;
        return;
    }

    switch (style->textOrientation()) {
    case TextOrientationVerticalRight:
        fontOrientation = Vertical;
        glyphOrientation = NonCJKGlyphOrientationVerticalRight;
        return;
    case TextOrientationUpright:
        fontOrientation = Vertical;
        glyphOrientation = NonCJKGlyphOrientationUpright;
        return;
    case TextOrientationSideways:
        if (style->writingMode() == LeftToRightWritingMode) {
            // FIXME: This should map to sideways-left, which is not supported yet.
            fontOrientation = Vertical;
            glyphOrientation = NonCJKGlyphOrientationVerticalRight;
            return;
        }
        fontOrientation = Horizontal;
        glyphOrientation = NonCJKGlyphOrientationVerticalRight;
        return;
    case TextOrientationSidewaysRight:
        fontOrientation = Horizontal;
        glyphOrientation = NonCJKGlyphOrientationVerticalRight;
        return;
    default:
        ASSERT_NOT_REACHED();
        fontOrientation = Horizontal;
        glyphOrientation = NonCJKGlyphOrientationVerticalRight;
        return;
    }
}

void FontBuilder::checkForOrientationChange(RenderStyle* style)
{
    FontOrientation fontOrientation;
    NonCJKGlyphOrientation glyphOrientation;
    getFontAndGlyphOrientation(style, fontOrientation, glyphOrientation);

    FontDescriptionChangeScope scope(this);

    if (scope.fontDescription().orientation() == fontOrientation && scope.fontDescription().nonCJKGlyphOrientation() == glyphOrientation)
        return;

    scope.fontDescription().setNonCJKGlyphOrientation(glyphOrientation);
    scope.fontDescription().setOrientation(fontOrientation);
}

void FontBuilder::checkForGenericFamilyChange(RenderStyle* style, const RenderStyle* parentStyle)
{
    FontDescriptionChangeScope scope(this);

    if (scope.fontDescription().isAbsoluteSize() || !parentStyle)
        return;

    const FontDescription& parentFontDescription = parentStyle->fontDescription();
    if (scope.fontDescription().fixedPitchFontType() == parentFontDescription.fixedPitchFontType())
        return;

    // For now, lump all families but monospace together.
    if (scope.fontDescription().genericFamily() != FontDescription::MonospaceFamily
        && parentFontDescription.genericFamily() != FontDescription::MonospaceFamily)
        return;

    // We know the parent is monospace or the child is monospace, and that font
    // size was unspecified. We want to scale our font size as appropriate.
    // If the font uses a keyword size, then we refetch from the table rather than
    // multiplying by our scale factor.
    float size;
    if (scope.fontDescription().keywordSize()) {
        size = FontSize::fontSizeForKeyword(m_document, static_cast<CSSValueID>(CSSValueXxSmall + scope.fontDescription().keywordSize() - 1), scope.fontDescription().fixedPitchFontType());
    } else {
        Settings* settings = m_document->settings();
        float fixedScaleFactor = (settings && settings->defaultFixedFontSize() && settings->defaultFontSize())
            ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize()
            : 1;
        size = parentFontDescription.fixedPitchFontType() == FixedPitchFont ?
            scope.fontDescription().specifiedSize() / fixedScaleFactor :
            scope.fontDescription().specifiedSize() * fixedScaleFactor;
    }

    setSize(scope.fontDescription(), style->effectiveZoom(), size);
}

void FontBuilder::updateComputedSize(RenderStyle* style, const RenderStyle* parentStyle)
{
    FontDescriptionChangeScope scope(this);

    float computedSize = getComputedSizeFromSpecifiedSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize());
    float multiplier = style->textAutosizingMultiplier();
    if (multiplier > 1)
        computedSize = TextAutosizer::computeAutosizedFontSize(computedSize, multiplier);

    scope.fontDescription().setComputedSize(computedSize);
}

// FIXME: style param should come first
void FontBuilder::createFont(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, const RenderStyle* parentStyle, RenderStyle* style)
{
    if (!m_fontDirty)
        return;

    updateComputedSize(style, parentStyle);
    checkForGenericFamilyChange(style, parentStyle);
    checkForOrientationChange(style);
    style->font().update(fontSelector);
    m_fontDirty = false;
}

void FontBuilder::createFontForDocument(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, RenderStyle* documentStyle)
{
    FontDescription fontDescription = FontDescription();
    fontDescription.setLocale(documentStyle->locale());
    fontDescription.setScript(localeToScriptCodeForFontSelection(documentStyle->locale()));

    setFontFamilyToStandard(fontDescription, m_document);
    fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
    int size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, NonFixedPitchFont);
    fontDescription.setSpecifiedSize(size);
    fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, documentStyle->effectiveZoom(), size));

    FontOrientation fontOrientation;
    NonCJKGlyphOrientation glyphOrientation;
    getFontAndGlyphOrientation(documentStyle, fontOrientation, glyphOrientation);
    fontDescription.setOrientation(fontOrientation);
    fontDescription.setNonCJKGlyphOrientation(glyphOrientation);
    documentStyle->setFontDescription(fontDescription);
    documentStyle->font().update(fontSelector);
}

}
