/*
 * Copyright (c) 2012 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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 "HarfBuzzFace.h"

#include "FontPlatformData.h"
#include <hb-ot.h>
#include <hb.h>
#include <wtf/NeverDestroyed.h>

namespace WebCore {

const hb_tag_t HarfBuzzFace::vertTag = HB_TAG('v', 'e', 'r', 't');
const hb_tag_t HarfBuzzFace::vrt2Tag = HB_TAG('v', 'r', 't', '2');
const hb_tag_t HarfBuzzFace::kernTag = HB_TAG('k', 'e', 'r', 'n');

// Though we have FontCache class, which provides the cache mechanism for
// WebKit's font objects, we also need additional caching layer for HarfBuzz
// to reduce the memory consumption because hb_face_t should be associated with
// underling font data (e.g. CTFontRef, FTFace).

HarfBuzzFace::CacheEntry::CacheEntry(hb_face_t* face)
    : m_face(face)
{
    ASSERT(m_face);
}

HarfBuzzFace::CacheEntry::~CacheEntry()
{
    hb_face_destroy(m_face);
}

HarfBuzzFace::Cache& HarfBuzzFace::cache()
{
    static NeverDestroyed<Cache> s_cache;
    return s_cache;
}

HarfBuzzFace::HarfBuzzFace(FontPlatformData& platformData, uint64_t uniqueID)
    : m_platformData(platformData)
    , m_uniqueID(uniqueID)
    , m_scriptForVerticalText(HB_SCRIPT_INVALID)
{
    auto result = cache().add(m_uniqueID, nullptr);
    if (result.isNewEntry)
        result.iterator->value = CacheEntry::create(createFace());
    m_cacheEntry = result.iterator->value;
}

HarfBuzzFace::~HarfBuzzFace()
{
    auto it = cache().find(m_uniqueID);
    ASSERT(it != cache().end());
    ASSERT(it->value == m_cacheEntry);
    ASSERT(it->value->refCount() > 1);

    m_cacheEntry = nullptr;
    if (it->value->refCount() == 1)
        cache().remove(it);
}

static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face)
{
    static const unsigned maxCount = 32;

    unsigned scriptCount = maxCount;
    hb_tag_t scriptTags[maxCount];
    hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags);
    for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) {
        unsigned languageCount = maxCount;
        hb_tag_t languageTags[maxCount];
        hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags);
        for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) {
            unsigned featureIndex;
            if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vertTag, &featureIndex)
                || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vrt2Tag, &featureIndex))
                return hb_ot_tag_to_script(scriptTags[scriptIndex]);
        }
    }
    return HB_SCRIPT_INVALID;
}

void HarfBuzzFace::setScriptForVerticalGlyphSubstitution(hb_buffer_t* buffer)
{
    if (m_scriptForVerticalText == HB_SCRIPT_INVALID)
        m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_cacheEntry->face());
    hb_buffer_set_script(buffer, m_scriptForVerticalText);
}

} // namespace WebCore
