/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "Minikin"

#include <algorithm>
#include <fstream>
#include <iostream>  // for debugging
#include <math.h>
#include <string>
#include <unicode/ubidi.h>
#include <unicode/utf16.h>
#include <vector>

#include <log/log.h>
#include <utils/JenkinsHash.h>
#include <utils/LruCache.h>
#include <utils/Singleton.h>
#include <utils/String16.h>

#include <hb-icu.h>
#include <hb-ot.h>

#include "FontLanguage.h"
#include "FontLanguageListCache.h"
#include "HbFontCache.h"
#include "LayoutUtils.h"
#include "MinikinInternal.h"
#include <minikin/Emoji.h>
#include <minikin/Layout.h>

using std::string;
using std::vector;

namespace minikin {

const int kDirection_Mask = 0x1;

struct LayoutContext {
    MinikinPaint paint;
    FontStyle style;
    std::vector<hb_font_t*> hbFonts;  // parallel to mFaces

    void clearHbFonts() {
        for (size_t i = 0; i < hbFonts.size(); i++) {
            hb_font_set_funcs(hbFonts[i], nullptr, nullptr, nullptr);
            hb_font_destroy(hbFonts[i]);
        }
        hbFonts.clear();
    }
};

// Layout cache datatypes

class LayoutCacheKey {
public:
    LayoutCacheKey(const std::shared_ptr<FontCollection>& collection, const MinikinPaint& paint,
            FontStyle style, const uint16_t* chars, size_t start, size_t count, size_t nchars,
            bool dir)
            : mChars(chars), mNchars(nchars),
            mStart(start), mCount(count), mId(collection->getId()), mStyle(style),
            mSize(paint.size), mScaleX(paint.scaleX), mSkewX(paint.skewX),
            mLetterSpacing(paint.letterSpacing),
            mPaintFlags(paint.paintFlags), mHyphenEdit(paint.hyphenEdit), mIsRtl(dir),
            mHash(computeHash()) {
    }
    bool operator==(const LayoutCacheKey &other) const;

    android::hash_t hash() const {
        return mHash;
    }

    void copyText() {
        uint16_t* charsCopy = new uint16_t[mNchars];
        memcpy(charsCopy, mChars, mNchars * sizeof(uint16_t));
        mChars = charsCopy;
    }
    void freeText() {
        delete[] mChars;
        mChars = NULL;
    }

    void doLayout(Layout* layout, LayoutContext* ctx,
            const std::shared_ptr<FontCollection>& collection) const {
        layout->mAdvances.resize(mCount, 0);
        ctx->clearHbFonts();
        layout->doLayoutRun(mChars, mStart, mCount, mNchars, mIsRtl, ctx, collection);
    }

private:
    const uint16_t* mChars;
    size_t mNchars;
    size_t mStart;
    size_t mCount;
    uint32_t mId;  // for the font collection
    FontStyle mStyle;
    float mSize;
    float mScaleX;
    float mSkewX;
    float mLetterSpacing;
    int32_t mPaintFlags;
    HyphenEdit mHyphenEdit;
    bool mIsRtl;
    // Note: any fields added to MinikinPaint must also be reflected here.
    // TODO: language matching (possibly integrate into style)
    android::hash_t mHash;

    android::hash_t computeHash() const;
};

class LayoutCache : private android::OnEntryRemoved<LayoutCacheKey, Layout*> {
public:
    LayoutCache() : mCache(kMaxEntries) {
        mCache.setOnEntryRemovedListener(this);
    }

    void clear() {
        mCache.clear();
    }

    Layout* get(LayoutCacheKey& key, LayoutContext* ctx,
            const std::shared_ptr<FontCollection>& collection) {
        Layout* layout = mCache.get(key);
        if (layout == NULL) {
            key.copyText();
            layout = new Layout();
            key.doLayout(layout, ctx, collection);
            mCache.put(key, layout);
        }
        return layout;
    }

private:
    // callback for OnEntryRemoved
    void operator()(LayoutCacheKey& key, Layout*& value) {
        key.freeText();
        delete value;
    }

    android::LruCache<LayoutCacheKey, Layout*> mCache;

    //static const size_t kMaxEntries = LruCache<LayoutCacheKey, Layout*>::kUnlimitedCapacity;

    // TODO: eviction based on memory footprint; for now, we just use a constant
    // number of strings
    static const size_t kMaxEntries = 5000;
};

static unsigned int disabledDecomposeCompatibility(hb_unicode_funcs_t*, hb_codepoint_t,
                                                   hb_codepoint_t*, void*) {
    return 0;
}

class LayoutEngine : public ::android::Singleton<LayoutEngine> {
public:
    LayoutEngine() {
        unicodeFunctions = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
        /* Disable the function used for compatibility decomposition */
        hb_unicode_funcs_set_decompose_compatibility_func(
                unicodeFunctions, disabledDecomposeCompatibility, NULL, NULL);
        hbBuffer = hb_buffer_create();
        hb_buffer_set_unicode_funcs(hbBuffer, unicodeFunctions);
    }

    hb_buffer_t* hbBuffer;
    hb_unicode_funcs_t* unicodeFunctions;
    LayoutCache layoutCache;
};

bool LayoutCacheKey::operator==(const LayoutCacheKey& other) const {
    return mId == other.mId
            && mStart == other.mStart
            && mCount == other.mCount
            && mStyle == other.mStyle
            && mSize == other.mSize
            && mScaleX == other.mScaleX
            && mSkewX == other.mSkewX
            && mLetterSpacing == other.mLetterSpacing
            && mPaintFlags == other.mPaintFlags
            && mHyphenEdit == other.mHyphenEdit
            && mIsRtl == other.mIsRtl
            && mNchars == other.mNchars
            && !memcmp(mChars, other.mChars, mNchars * sizeof(uint16_t));
}

android::hash_t LayoutCacheKey::computeHash() const {
    uint32_t hash = android::JenkinsHashMix(0, mId);
    hash = android::JenkinsHashMix(hash, mStart);
    hash = android::JenkinsHashMix(hash, mCount);
    hash = android::JenkinsHashMix(hash, hash_type(mStyle));
    hash = android::JenkinsHashMix(hash, hash_type(mSize));
    hash = android::JenkinsHashMix(hash, hash_type(mScaleX));
    hash = android::JenkinsHashMix(hash, hash_type(mSkewX));
    hash = android::JenkinsHashMix(hash, hash_type(mLetterSpacing));
    hash = android::JenkinsHashMix(hash, hash_type(mPaintFlags));
    hash = android::JenkinsHashMix(hash, hash_type(mHyphenEdit.getHyphen()));
    hash = android::JenkinsHashMix(hash, hash_type(mIsRtl));
    hash = android::JenkinsHashMixShorts(hash, mChars, mNchars);
    return android::JenkinsHashWhiten(hash);
}

android::hash_t hash_type(const LayoutCacheKey& key) {
    return key.hash();
}

void MinikinRect::join(const MinikinRect& r) {
    if (isEmpty()) {
        set(r);
    } else if (!r.isEmpty()) {
        mLeft = std::min(mLeft, r.mLeft);
        mTop = std::min(mTop, r.mTop);
        mRight = std::max(mRight, r.mRight);
        mBottom = std::max(mBottom, r.mBottom);
    }
}

void Layout::reset() {
    mGlyphs.clear();
    mFaces.clear();
    mBounds.setEmpty();
    mAdvances.clear();
    mAdvance = 0;
}

static hb_position_t harfbuzzGetGlyphHorizontalAdvance(hb_font_t* /* hbFont */, void* fontData,
        hb_codepoint_t glyph, void* /* userData */) {
    MinikinPaint* paint = reinterpret_cast<MinikinPaint*>(fontData);
    float advance = paint->font->GetHorizontalAdvance(glyph, *paint);
    return 256 * advance + 0.5;
}

static hb_bool_t harfbuzzGetGlyphHorizontalOrigin(hb_font_t* /* hbFont */, void* /* fontData */,
        hb_codepoint_t /* glyph */, hb_position_t* /* x */, hb_position_t* /* y */,
        void* /* userData */) {
    // Just return true, following the way that Harfbuzz-FreeType
    // implementation does.
    return true;
}

hb_font_funcs_t* getHbFontFuncs(bool forColorBitmapFont) {
    assertMinikinLocked();

    static hb_font_funcs_t* hbFuncs = nullptr;
    static hb_font_funcs_t* hbFuncsForColorBitmap = nullptr;

    hb_font_funcs_t** funcs = forColorBitmapFont ? &hbFuncs : &hbFuncsForColorBitmap;
    if (*funcs == nullptr) {
        *funcs = hb_font_funcs_create();
        if (forColorBitmapFont) {
            // Don't override the h_advance function since we use HarfBuzz's implementation for
            // emoji for performance reasons.
            // Note that it is technically possible for a TrueType font to have outline and embedded
            // bitmap at the same time. We ignore modified advances of hinted outline glyphs in that
            // case.
        } else {
            // Override the h_advance function since we can't use HarfBuzz's implemenation. It may
            // return the wrong value if the font uses hinting aggressively.
            hb_font_funcs_set_glyph_h_advance_func(*funcs, harfbuzzGetGlyphHorizontalAdvance, 0, 0);
        }
        hb_font_funcs_set_glyph_h_origin_func(*funcs, harfbuzzGetGlyphHorizontalOrigin, 0, 0);
        hb_font_funcs_make_immutable(*funcs);
    }
    return *funcs;
}

static bool isColorBitmapFont(hb_font_t* font) {
    hb_face_t* face = hb_font_get_face(font);
    HbBlob cbdt(hb_face_reference_table(face, HB_TAG('C', 'B', 'D', 'T')));
    return cbdt.size() > 0;
}

static float HBFixedToFloat(hb_position_t v)
{
    return scalbnf (v, -8);
}

static hb_position_t HBFloatToFixed(float v)
{
    return scalbnf (v, +8);
}

void Layout::dump() const {
    for (size_t i = 0; i < mGlyphs.size(); i++) {
        const LayoutGlyph& glyph = mGlyphs[i];
        std::cout << glyph.glyph_id << ": " << glyph.x << ", " << glyph.y << std::endl;
    }
}

int Layout::findFace(const FakedFont& face, LayoutContext* ctx) {
    unsigned int ix;
    for (ix = 0; ix < mFaces.size(); ix++) {
        if (mFaces[ix].font == face.font) {
            return ix;
        }
    }
    mFaces.push_back(face);
    // Note: ctx == NULL means we're copying from the cache, no need to create
    // corresponding hb_font object.
    if (ctx != NULL) {
        hb_font_t* font = getHbFontLocked(face.font);
        hb_font_set_funcs(font, getHbFontFuncs(isColorBitmapFont(font)), &ctx->paint, 0);
        ctx->hbFonts.push_back(font);
    }
    return ix;
}

static hb_script_t codePointToScript(hb_codepoint_t codepoint) {
    static hb_unicode_funcs_t* u = 0;
    if (!u) {
        u = LayoutEngine::getInstance().unicodeFunctions;
    }
    return hb_unicode_script(u, codepoint);
}

static hb_codepoint_t decodeUtf16(const uint16_t* chars, size_t len, ssize_t* iter) {
    const uint16_t v = chars[(*iter)++];
    // test whether v in (0xd800..0xdfff), lead or trail surrogate
    if ((v & 0xf800) == 0xd800) {
        // test whether v in (0xd800..0xdbff), lead surrogate
        if (size_t(*iter) < len && (v & 0xfc00) == 0xd800) {
            const uint16_t v2 = chars[(*iter)++];
            // test whether v2 in (0xdc00..0xdfff), trail surrogate
            if ((v2 & 0xfc00) == 0xdc00) {
                // (0xd800 0xdc00) in utf-16 maps to 0x10000 in ucs-32
                const hb_codepoint_t delta = (0xd800 << 10) + 0xdc00 - 0x10000;
                return (((hb_codepoint_t)v) << 10) + v2 - delta;
            }
            (*iter) -= 1;
            return 0xFFFDu;
        } else {
            return 0xFFFDu;
        }
    } else {
        return v;
    }
}

static hb_script_t getScriptRun(const uint16_t* chars, size_t len, ssize_t* iter) {
    if (size_t(*iter) == len) {
        return HB_SCRIPT_UNKNOWN;
    }
    uint32_t cp = decodeUtf16(chars, len, iter);
    hb_script_t current_script = codePointToScript(cp);
    for (;;) {
        if (size_t(*iter) == len)
            break;
        const ssize_t prev_iter = *iter;
        cp = decodeUtf16(chars, len, iter);
        const hb_script_t script = codePointToScript(cp);
        if (script != current_script) {
            if (current_script == HB_SCRIPT_INHERITED ||
                current_script == HB_SCRIPT_COMMON) {
                current_script = script;
            } else if (script == HB_SCRIPT_INHERITED ||
                script == HB_SCRIPT_COMMON) {
                continue;
            } else {
                *iter = prev_iter;
                break;
            }
        }
    }
    if (current_script == HB_SCRIPT_INHERITED) {
        current_script = HB_SCRIPT_COMMON;
    }

    return current_script;
}

/**
 * Disable certain scripts (mostly those with cursive connection) from having letterspacing
 * applied. See https://github.com/behdad/harfbuzz/issues/64 for more details.
 */
static bool isScriptOkForLetterspacing(hb_script_t script) {
    return !(
            script == HB_SCRIPT_ARABIC ||
            script == HB_SCRIPT_NKO ||
            script == HB_SCRIPT_PSALTER_PAHLAVI ||
            script == HB_SCRIPT_MANDAIC ||
            script == HB_SCRIPT_MONGOLIAN ||
            script == HB_SCRIPT_PHAGS_PA ||
            script == HB_SCRIPT_DEVANAGARI ||
            script == HB_SCRIPT_BENGALI ||
            script == HB_SCRIPT_GURMUKHI ||
            script == HB_SCRIPT_MODI ||
            script == HB_SCRIPT_SHARADA ||
            script == HB_SCRIPT_SYLOTI_NAGRI ||
            script == HB_SCRIPT_TIRHUTA ||
            script == HB_SCRIPT_OGHAM
            );
}

class BidiText {
public:
    class Iter {
    public:
        struct RunInfo {
            int32_t mRunStart;
            int32_t mRunLength;
            bool mIsRtl;
        };

        Iter(UBiDi* bidi, size_t start, size_t end, size_t runIndex, size_t runCount, bool isRtl);

        bool operator!= (const Iter& other) const {
            return mIsEnd != other.mIsEnd || mNextRunIndex != other.mNextRunIndex
                    || mBidi != other.mBidi;
        }

        const RunInfo& operator* () const {
            return mRunInfo;
        }

        const Iter& operator++ () {
            updateRunInfo();
            return *this;
        }

    private:
        UBiDi* const mBidi;
        bool mIsEnd;
        size_t mNextRunIndex;
        const size_t mRunCount;
        const int32_t mStart;
        const int32_t mEnd;
        RunInfo mRunInfo;

        void updateRunInfo();
    };

    BidiText(const uint16_t* buf, size_t start, size_t count, size_t bufSize, int bidiFlags);

    ~BidiText() {
        if (mBidi) {
            ubidi_close(mBidi);
        }
    }

    Iter begin () const {
        return Iter(mBidi, mStart, mEnd, 0, mRunCount, mIsRtl);
    }

    Iter end() const {
        return Iter(mBidi, mStart, mEnd, mRunCount, mRunCount, mIsRtl);
    }

private:
    const size_t mStart;
    const size_t mEnd;
    const size_t mBufSize;
    UBiDi* mBidi;
    size_t mRunCount;
    bool mIsRtl;

    BidiText(const BidiText&) = delete;
    void operator=(const BidiText&) = delete;
};

BidiText::Iter::Iter(UBiDi* bidi, size_t start, size_t end, size_t runIndex, size_t runCount,
        bool isRtl)
    : mBidi(bidi), mIsEnd(runIndex == runCount), mNextRunIndex(runIndex), mRunCount(runCount),
      mStart(start), mEnd(end), mRunInfo() {
    if (mRunCount == 1) {
        mRunInfo.mRunStart = start;
        mRunInfo.mRunLength = end - start;
        mRunInfo.mIsRtl = isRtl;
        mNextRunIndex = mRunCount;
        return;
    }
    updateRunInfo();
}

void BidiText::Iter::updateRunInfo() {
    if (mNextRunIndex == mRunCount) {
        // All runs have been iterated.
        mIsEnd = true;
        return;
    }
    int32_t startRun = -1;
    int32_t lengthRun = -1;
    const UBiDiDirection runDir = ubidi_getVisualRun(mBidi, mNextRunIndex, &startRun, &lengthRun);
    mNextRunIndex++;
    if (startRun == -1 || lengthRun == -1) {
        ALOGE("invalid visual run");
        // skip the invalid run.
        updateRunInfo();
        return;
    }
    const int32_t runEnd = std::min(startRun + lengthRun, mEnd);
    mRunInfo.mRunStart = std::max(startRun, mStart);
    mRunInfo.mRunLength = runEnd - mRunInfo.mRunStart;
    if (mRunInfo.mRunLength <= 0) {
        // skip the empty run.
        updateRunInfo();
        return;
    }
    mRunInfo.mIsRtl = (runDir == UBIDI_RTL);
}

BidiText::BidiText(const uint16_t* buf, size_t start, size_t count, size_t bufSize, int bidiFlags)
    : mStart(start), mEnd(start + count), mBufSize(bufSize), mBidi(NULL), mRunCount(1),
      mIsRtl((bidiFlags & kDirection_Mask) != 0) {
    if (bidiFlags == kBidi_Force_LTR || bidiFlags == kBidi_Force_RTL) {
        // force single run.
        return;
    }
    mBidi = ubidi_open();
    if (!mBidi) {
        ALOGE("error creating bidi object");
        return;
    }
    UErrorCode status = U_ZERO_ERROR;
    // Set callbacks to override bidi classes of new emoji
    ubidi_setClassCallback(mBidi, emojiBidiOverride, nullptr, nullptr, nullptr, &status);
    if (!U_SUCCESS(status)) {
        ALOGE("error setting bidi callback function, status = %d", status);
        return;
    }

    UBiDiLevel bidiReq = bidiFlags;
    if (bidiFlags == kBidi_Default_LTR) {
        bidiReq = UBIDI_DEFAULT_LTR;
    } else if (bidiFlags == kBidi_Default_RTL) {
        bidiReq = UBIDI_DEFAULT_RTL;
    }
    ubidi_setPara(mBidi, buf, mBufSize, bidiReq, NULL, &status);
    if (!U_SUCCESS(status)) {
        ALOGE("error calling ubidi_setPara, status = %d", status);
        return;
    }
    const int paraDir = ubidi_getParaLevel(mBidi) & kDirection_Mask;
    const ssize_t rc = ubidi_countRuns(mBidi, &status);
    if (!U_SUCCESS(status) || rc < 0) {
        ALOGW("error counting bidi runs, status = %d", status);
    }
    if (!U_SUCCESS(status) || rc <= 1) {
        mIsRtl = (paraDir == kBidi_RTL);
        return;
    }
    mRunCount = rc;
}

void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
        const std::shared_ptr<FontCollection>& collection) {
    android::AutoMutex _l(gMinikinLock);

    LayoutContext ctx;
    ctx.style = style;
    ctx.paint = paint;

    reset();
    mAdvances.resize(count, 0);

    for (const BidiText::Iter::RunInfo& runInfo : BidiText(buf, start, count, bufSize, bidiFlags)) {
        doLayoutRunCached(buf, runInfo.mRunStart, runInfo.mRunLength, bufSize, runInfo.mIsRtl, &ctx,
                start, collection, this, NULL);
    }
    ctx.clearHbFonts();
}

float Layout::measureText(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        int bidiFlags, const FontStyle &style, const MinikinPaint &paint,
        const std::shared_ptr<FontCollection>& collection, float* advances) {
    android::AutoMutex _l(gMinikinLock);

    LayoutContext ctx;
    ctx.style = style;
    ctx.paint = paint;

    float advance = 0;
    for (const BidiText::Iter::RunInfo& runInfo : BidiText(buf, start, count, bufSize, bidiFlags)) {
        float* advancesForRun = advances ? advances + (runInfo.mRunStart - start) : advances;
        advance += doLayoutRunCached(buf, runInfo.mRunStart, runInfo.mRunLength, bufSize,
                runInfo.mIsRtl, &ctx, 0, collection, NULL, advancesForRun);
    }

    ctx.clearHbFonts();
    return advance;
}

float Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        bool isRtl, LayoutContext* ctx, size_t dstStart,
        const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances) {
    const uint32_t originalHyphen = ctx->paint.hyphenEdit.getHyphen();
    float advance = 0;
    if (!isRtl) {
        // left to right
        size_t wordstart =
                start == bufSize ? start : getPrevWordBreakForCache(buf, start + 1, bufSize);
        size_t wordend;
        for (size_t iter = start; iter < start + count; iter = wordend) {
            wordend = getNextWordBreakForCache(buf, iter, bufSize);
            // Only apply hyphen to the first or last word in the string.
            uint32_t hyphen = originalHyphen;
            if (iter != start) { // Not the first word
                hyphen &= ~HyphenEdit::MASK_START_OF_LINE;
            }
            if (wordend < start + count) { // Not the last word
                hyphen &= ~HyphenEdit::MASK_END_OF_LINE;
            }
            ctx->paint.hyphenEdit = hyphen;
            size_t wordcount = std::min(start + count, wordend) - iter;
            advance += doLayoutWord(buf + wordstart, iter - wordstart, wordcount,
                    wordend - wordstart, isRtl, ctx, iter - dstStart, collection, layout,
                    advances ? advances + (iter - start) : advances);
            wordstart = wordend;
        }
    } else {
        // right to left
        size_t wordstart;
        size_t end = start + count;
        size_t wordend = end == 0 ? 0 : getNextWordBreakForCache(buf, end - 1, bufSize);
        for (size_t iter = end; iter > start; iter = wordstart) {
            wordstart = getPrevWordBreakForCache(buf, iter, bufSize);
            // Only apply hyphen to the first (rightmost) or last (leftmost) word in the string.
            uint32_t hyphen = originalHyphen;
            if (wordstart > start) { // Not the first word
                hyphen &= ~HyphenEdit::MASK_START_OF_LINE;
            }
            if (iter != end) { // Not the last word
                hyphen &= ~HyphenEdit::MASK_END_OF_LINE;
            }
            ctx->paint.hyphenEdit = hyphen;
            size_t bufStart = std::max(start, wordstart);
            advance += doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart,
                    wordend - wordstart, isRtl, ctx, bufStart - dstStart, collection, layout,
                    advances ? advances + (bufStart - start) : advances);
            wordend = wordstart;
        }
    }
    return advance;
}

float Layout::doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        bool isRtl, LayoutContext* ctx, size_t bufStart,
        const std::shared_ptr<FontCollection>& collection, Layout* layout, float* advances) {
    LayoutCache& cache = LayoutEngine::getInstance().layoutCache;
    LayoutCacheKey key(collection, ctx->paint, ctx->style, buf, start, count, bufSize, isRtl);

    float wordSpacing = count == 1 && isWordSpace(buf[start]) ? ctx->paint.wordSpacing : 0;

    float advance;
    if (ctx->paint.skipCache()) {
        Layout layoutForWord;
        key.doLayout(&layoutForWord, ctx, collection);
        if (layout) {
            layout->appendLayout(&layoutForWord, bufStart, wordSpacing);
        }
        if (advances) {
            layoutForWord.getAdvances(advances);
        }
        advance = layoutForWord.getAdvance();
    } else {
        Layout* layoutForWord = cache.get(key, ctx, collection);
        if (layout) {
            layout->appendLayout(layoutForWord, bufStart, wordSpacing);
        }
        if (advances) {
            layoutForWord->getAdvances(advances);
        }
        advance = layoutForWord->getAdvance();
    }

    if (wordSpacing != 0) {
        advance += wordSpacing;
        if (advances) {
            advances[0] += wordSpacing;
        }
    }
    return advance;
}

static void addFeatures(const string &str, vector<hb_feature_t>* features) {
    if (!str.size())
        return;

    const char* start = str.c_str();
    const char* end = start + str.size();

    while (start < end) {
        static hb_feature_t feature;
        const char* p = strchr(start, ',');
        if (!p)
            p = end;
        /* We do not allow setting features on ranges.  As such, reject any
         * setting that has non-universal range. */
        if (hb_feature_from_string (start, p - start, &feature)
                && feature.start == 0 && feature.end == (unsigned int) -1)
            features->push_back(feature);
        start = p + 1;
    }
}

static const hb_codepoint_t CHAR_HYPHEN = 0x2010; /* HYPHEN */

static inline hb_codepoint_t determineHyphenChar(hb_codepoint_t preferredHyphen, hb_font_t* font) {
    hb_codepoint_t glyph;
    if (preferredHyphen == 0x058A /* ARMENIAN_HYPHEN */
                || preferredHyphen == 0x05BE /* HEBREW PUNCTUATION MAQAF */
                || preferredHyphen == 0x1400 /* CANADIAN SYLLABIC HYPHEN */) {
        if (hb_font_get_nominal_glyph(font, preferredHyphen, &glyph)) {
            return preferredHyphen;
        } else {
            // The original hyphen requested was not supported. Let's try and see if the
            // Unicode hyphen is supported.
            preferredHyphen = CHAR_HYPHEN;
        }
    }
    if (preferredHyphen == CHAR_HYPHEN) { /* HYPHEN */
        // Fallback to ASCII HYPHEN-MINUS if the font didn't have a glyph for the preferred hyphen.
        // Note that we intentionally don't do anything special if the font doesn't have a
        // HYPHEN-MINUS either, so a tofu could be shown, hinting towards something missing.
        if (!hb_font_get_nominal_glyph(font, preferredHyphen, &glyph)) {
            return 0x002D; // HYPHEN-MINUS
        }
    }
    return preferredHyphen;
}

static inline void addHyphenToHbBuffer(hb_buffer_t* buffer, hb_font_t* font, uint32_t hyphen,
        uint32_t cluster) {
    const uint32_t* hyphenStr = HyphenEdit::getHyphenString(hyphen);
    while (*hyphenStr != 0) {
        hb_codepoint_t hyphenChar = determineHyphenChar(*hyphenStr, font);
        hb_buffer_add(buffer, hyphenChar, cluster);
        hyphenStr++;
    }
}

// Returns the cluster value assigned to the first codepoint added to the buffer, which can be used
// to translate cluster values returned by HarfBuzz to input indices.
static inline uint32_t addToHbBuffer(hb_buffer_t* buffer,
        const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        ssize_t scriptRunStart, ssize_t scriptRunEnd,
        HyphenEdit hyphenEdit, hb_font_t* hbFont) {

    // Only hyphenate the very first script run for starting hyphens.
    const uint32_t startHyphen = (scriptRunStart == 0)
            ? hyphenEdit.getStart()
            : HyphenEdit::NO_EDIT;
    // Only hyphenate the very last script run for ending hyphens.
    const uint32_t endHyphen = (static_cast<size_t>(scriptRunEnd) == count)
            ? hyphenEdit.getEnd()
            : HyphenEdit::NO_EDIT;

    // In the following code, we drop the pre-context and/or post-context if there is a
    // hyphen edit at that end. This is not absolutely necessary, since HarfBuzz uses
    // contexts only for joining scripts at the moment, e.g. to determine if the first or
    // last letter of a text range to shape should take a joining form based on an
    // adjacent letter or joiner (that comes from the context).
    //
    // TODO: Revisit this for:
    // 1. Desperate breaks for joining scripts like Arabic (where it may be better to keep
    //    the context);
    // 2. Special features like start-of-word font features (not implemented in HarfBuzz
    //    yet).

    // We don't have any start-of-line replacement edit yet, so we don't need to check for
    // those.
    if (HyphenEdit::isInsertion(startHyphen)) {
        // A cluster value of zero guarantees that the inserted hyphen will be in the same
        // cluster with the next codepoint, since there is no pre-context.
        addHyphenToHbBuffer(buffer, hbFont, startHyphen, 0 /* cluster value */);
    }

    const uint16_t* hbText;
    int hbTextLength;
    unsigned int hbItemOffset;
    unsigned int hbItemLength = scriptRunEnd - scriptRunStart; // This is >= 1.

    const bool hasEndInsertion = HyphenEdit::isInsertion(endHyphen);
    const bool hasEndReplacement = HyphenEdit::isReplacement(endHyphen);
    if (hasEndReplacement) {
        // Skip the last code unit while copying the buffer for HarfBuzz if it's a replacement. We
        // don't need to worry about non-BMP characters yet since replacements are only done for
        // code units at the moment.
        hbItemLength -= 1;
    }

    if (startHyphen == HyphenEdit::NO_EDIT) {
        // No edit at the beginning. Use the whole pre-context.
        hbText = buf;
        hbItemOffset = start + scriptRunStart;
    } else {
        // There's an edit at the beginning. Drop the pre-context and start the buffer at where we
        // want to start shaping.
        hbText = buf + start + scriptRunStart;
        hbItemOffset = 0;
    }

    if (endHyphen == HyphenEdit::NO_EDIT) {
        // No edit at the end, use the whole post-context.
        hbTextLength = (buf + bufSize) - hbText;
    } else {
        // There is an edit at the end. Drop the post-context.
        hbTextLength = hbItemOffset + hbItemLength;
    }

    hb_buffer_add_utf16(buffer, hbText, hbTextLength, hbItemOffset, hbItemLength);

    unsigned int numCodepoints;
    hb_glyph_info_t* cpInfo = hb_buffer_get_glyph_infos(buffer, &numCodepoints);

    // Add the hyphen at the end, if there's any.
    if (hasEndInsertion || hasEndReplacement) {
        // When a hyphen is inserted, by assigning the added hyphen and the last
        // codepoint added to the HarfBuzz buffer to the same cluster, we can make sure
        // that they always remain in the same cluster, even if the last codepoint gets
        // merged into another cluster (for example when it's a combining mark).
        //
        // When a replacement happens instead, we want it to get the cluster value of
        // the character it's replacing, which is one "codepoint length" larger than
        // the last cluster. But since the character replaced is always just one
        // code unit, we can just add 1.
        uint32_t hyphenCluster;
        if (numCodepoints == 0) {
            // Nothing was added to the HarfBuzz buffer. This can only happen if
            // we have a replacement that is replacing a one-code unit script run.
            hyphenCluster = 0;
        } else {
            hyphenCluster = cpInfo[numCodepoints - 1].cluster + (uint32_t) hasEndReplacement;
        }
        addHyphenToHbBuffer(buffer, hbFont, endHyphen, hyphenCluster);
        // Since we have just added to the buffer, cpInfo no longer necessarily points to
        // the right place. Refresh it.
        cpInfo = hb_buffer_get_glyph_infos(buffer, nullptr /* we don't need the size */);
    }
    return cpInfo[0].cluster;
}


void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
        bool isRtl, LayoutContext* ctx, const std::shared_ptr<FontCollection>& collection) {
    hb_buffer_t* buffer = LayoutEngine::getInstance().hbBuffer;
    vector<FontCollection::Run> items;
    collection->itemize(buf + start, count, ctx->style, &items);

    vector<hb_feature_t> features;
    // Disable default-on non-required ligature features if letter-spacing
    // See http://dev.w3.org/csswg/css-text-3/#letter-spacing-property
    // "When the effective spacing between two characters is not zero (due to
    // either justification or a non-zero value of letter-spacing), user agents
    // should not apply optional ligatures."
    if (fabs(ctx->paint.letterSpacing) > 0.03)
    {
        static const hb_feature_t no_liga = { HB_TAG('l', 'i', 'g', 'a'), 0, 0, ~0u };
        static const hb_feature_t no_clig = { HB_TAG('c', 'l', 'i', 'g'), 0, 0, ~0u };
        features.push_back(no_liga);
        features.push_back(no_clig);
    }
    addFeatures(ctx->paint.fontFeatureSettings, &features);

    double size = ctx->paint.size;
    double scaleX = ctx->paint.scaleX;

    float x = mAdvance;
    float y = 0;
    for (int run_ix = isRtl ? items.size() - 1 : 0;
            isRtl ? run_ix >= 0 : run_ix < static_cast<int>(items.size());
            isRtl ? --run_ix : ++run_ix) {
        FontCollection::Run &run = items[run_ix];
        if (run.fakedFont.font == NULL) {
            ALOGE("no font for run starting u+%04x length %d", buf[run.start], run.end - run.start);
            continue;
        }
        int font_ix = findFace(run.fakedFont, ctx);
        ctx->paint.font = mFaces[font_ix].font;
        ctx->paint.fakery = mFaces[font_ix].fakery;
        hb_font_t* hbFont = ctx->hbFonts[font_ix];
#ifdef VERBOSE_DEBUG
        ALOGD("Run %zu, font %d [%d:%d]", run_ix, font_ix, run.start, run.end);
#endif

        hb_font_set_ppem(hbFont, size * scaleX, size);
        hb_font_set_scale(hbFont, HBFloatToFixed(size * scaleX), HBFloatToFixed(size));

        const bool is_color_bitmap_font = isColorBitmapFont(hbFont);

        // TODO: if there are multiple scripts within a font in an RTL run,
        // we need to reorder those runs. This is unlikely with our current
        // font stack, but should be done for correctness.

        // Note: scriptRunStart and scriptRunEnd, as well as run.start and run.end, run between 0
        // and count.
        ssize_t scriptRunEnd;
        for (ssize_t scriptRunStart = run.start;
                scriptRunStart < run.end;
                scriptRunStart = scriptRunEnd) {
            scriptRunEnd = scriptRunStart;
            hb_script_t script = getScriptRun(buf + start, run.end, &scriptRunEnd /* iterator */);
            // After the last line, scriptRunEnd is guaranteed to have increased, since the only
            // time getScriptRun does not increase its iterator is when it has already reached the
            // end of the buffer. But that can't happen, since if we have already reached the end
            // of the buffer, we should have had (scriptRunEnd == run.end), which means
            // (scriptRunStart == run.end) which is impossible due to the exit condition of the for
            // loop. So we can be sure that scriptRunEnd > scriptRunStart.

            double letterSpace = 0.0;
            double letterSpaceHalfLeft = 0.0;
            double letterSpaceHalfRight = 0.0;

            if (ctx->paint.letterSpacing != 0.0 && isScriptOkForLetterspacing(script)) {
                letterSpace = ctx->paint.letterSpacing * size * scaleX;
                if ((ctx->paint.paintFlags & LinearTextFlag) == 0) {
                    letterSpace = round(letterSpace);
                    letterSpaceHalfLeft = floor(letterSpace * 0.5);
                } else {
                    letterSpaceHalfLeft = letterSpace * 0.5;
                }
                letterSpaceHalfRight = letterSpace - letterSpaceHalfLeft;
            }

            hb_buffer_clear_contents(buffer);
            hb_buffer_set_script(buffer, script);
            hb_buffer_set_direction(buffer, isRtl? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
            const FontLanguages& langList =
                    FontLanguageListCache::getById(ctx->style.getLanguageListId());
            if (langList.size() != 0) {
                const FontLanguage* hbLanguage = &langList[0];
                for (size_t i = 0; i < langList.size(); ++i) {
                    if (langList[i].supportsHbScript(script)) {
                        hbLanguage = &langList[i];
                        break;
                    }
                }
                hb_buffer_set_language(buffer, hbLanguage->getHbLanguage());
            }

            const uint32_t clusterStart = addToHbBuffer(
                buffer,
                buf, start, count, bufSize,
                scriptRunStart, scriptRunEnd,
                ctx->paint.hyphenEdit, hbFont);

            hb_shape(hbFont, buffer, features.empty() ? NULL : &features[0], features.size());
            unsigned int numGlyphs;
            hb_glyph_info_t* info = hb_buffer_get_glyph_infos(buffer, &numGlyphs);
            hb_glyph_position_t* positions = hb_buffer_get_glyph_positions(buffer, NULL);

            // At this point in the code, the cluster values in the info buffer correspond to the
            // input characters with some shift. The cluster value clusterStart corresponds to the
            // first character passed to HarfBuzz, which is at buf[start + scriptRunStart] whose
            // advance needs to be saved into mAdvances[scriptRunStart]. So cluster values need to
            // be reduced by (clusterStart - scriptRunStart) to get converted to indices of
            // mAdvances.
            const ssize_t clusterOffset = clusterStart - scriptRunStart;

            if (numGlyphs)
            {
                mAdvances[info[0].cluster - clusterOffset] += letterSpaceHalfLeft;
                x += letterSpaceHalfLeft;
            }
            for (unsigned int i = 0; i < numGlyphs; i++) {
#ifdef VERBOSE_DEBUG
                ALOGD("%d %d %d %d",
                        positions[i].x_advance, positions[i].y_advance,
                        positions[i].x_offset, positions[i].y_offset);
                ALOGD("DoLayout %u: %f; %d, %d",
                        info[i].codepoint, HBFixedToFloat(positions[i].x_advance),
                        positions[i].x_offset, positions[i].y_offset);
#endif
                if (i > 0 && info[i - 1].cluster != info[i].cluster) {
                    mAdvances[info[i - 1].cluster - clusterOffset] += letterSpaceHalfRight;
                    mAdvances[info[i].cluster - clusterOffset] += letterSpaceHalfLeft;
                    x += letterSpace;
                }

                hb_codepoint_t glyph_ix = info[i].codepoint;
                float xoff = HBFixedToFloat(positions[i].x_offset);
                float yoff = -HBFixedToFloat(positions[i].y_offset);
                xoff += yoff * ctx->paint.skewX;
                LayoutGlyph glyph = {font_ix, glyph_ix, x + xoff, y + yoff};
                mGlyphs.push_back(glyph);
                float xAdvance = HBFixedToFloat(positions[i].x_advance);
                if ((ctx->paint.paintFlags & LinearTextFlag) == 0) {
                    xAdvance = roundf(xAdvance);
                }
                MinikinRect glyphBounds;
                hb_glyph_extents_t extents = {};
                if (is_color_bitmap_font && hb_font_get_glyph_extents(hbFont, glyph_ix, &extents)) {
                    // Note that it is technically possible for a TrueType font to have outline and
                    // embedded bitmap at the same time. We ignore modified bbox of hinted outline
                    // glyphs in that case.
                    glyphBounds.mLeft = roundf(HBFixedToFloat(extents.x_bearing));
                    glyphBounds.mTop = roundf(HBFixedToFloat(-extents.y_bearing));
                    glyphBounds.mRight = roundf(HBFixedToFloat(extents.x_bearing + extents.width));
                    glyphBounds.mBottom =
                            roundf(HBFixedToFloat(-extents.y_bearing - extents.height));
                } else {
                    ctx->paint.font->GetBounds(&glyphBounds, glyph_ix, ctx->paint);
                }
                glyphBounds.offset(x + xoff, y + yoff);
                mBounds.join(glyphBounds);
                if (static_cast<size_t>(info[i].cluster - clusterOffset) < count) {
                    mAdvances[info[i].cluster - clusterOffset] += xAdvance;
                } else {
                    ALOGE("cluster %zu (start %zu) out of bounds of count %zu",
                        info[i].cluster - clusterOffset, start, count);
                }
                x += xAdvance;
            }
            if (numGlyphs)
            {
                mAdvances[info[numGlyphs - 1].cluster - clusterOffset] += letterSpaceHalfRight;
                x += letterSpaceHalfRight;
            }
        }
    }
    mAdvance = x;
}

void Layout::appendLayout(Layout* src, size_t start, float extraAdvance) {
    int fontMapStack[16];
    int* fontMap;
    if (src->mFaces.size() < sizeof(fontMapStack) / sizeof(fontMapStack[0])) {
        fontMap = fontMapStack;
    } else {
        fontMap = new int[src->mFaces.size()];
    }
    for (size_t i = 0; i < src->mFaces.size(); i++) {
        int font_ix = findFace(src->mFaces[i], NULL);
        fontMap[i] = font_ix;
    }
    int x0 = mAdvance;
    for (size_t i = 0; i < src->mGlyphs.size(); i++) {
        LayoutGlyph& srcGlyph = src->mGlyphs[i];
        int font_ix = fontMap[srcGlyph.font_ix];
        unsigned int glyph_id = srcGlyph.glyph_id;
        float x = x0 + srcGlyph.x;
        float y = srcGlyph.y;
        LayoutGlyph glyph = {font_ix, glyph_id, x, y};
        mGlyphs.push_back(glyph);
    }
    for (size_t i = 0; i < src->mAdvances.size(); i++) {
        mAdvances[i + start] = src->mAdvances[i];
        if (i == 0)
          mAdvances[i + start] += extraAdvance;
    }
    MinikinRect srcBounds(src->mBounds);
    srcBounds.offset(x0, 0);
    mBounds.join(srcBounds);
    mAdvance += src->mAdvance + extraAdvance;

    if (fontMap != fontMapStack) {
        delete[] fontMap;
    }
}

size_t Layout::nGlyphs() const {
    return mGlyphs.size();
}

const MinikinFont* Layout::getFont(int i) const {
    const LayoutGlyph& glyph = mGlyphs[i];
    return mFaces[glyph.font_ix].font;
}

FontFakery Layout::getFakery(int i) const {
    const LayoutGlyph& glyph = mGlyphs[i];
    return mFaces[glyph.font_ix].fakery;
}

unsigned int Layout::getGlyphId(int i) const {
    const LayoutGlyph& glyph = mGlyphs[i];
    return glyph.glyph_id;
}

float Layout::getX(int i) const {
    const LayoutGlyph& glyph = mGlyphs[i];
    return glyph.x;
}

float Layout::getY(int i) const {
    const LayoutGlyph& glyph = mGlyphs[i];
    return glyph.y;
}

float Layout::getAdvance() const {
    return mAdvance;
}

void Layout::getAdvances(float* advances) {
    memcpy(advances, &mAdvances[0], mAdvances.size() * sizeof(float));
}

void Layout::getBounds(MinikinRect* bounds) const {
    bounds->set(mBounds);
}

void Layout::purgeCaches() {
    android::AutoMutex _l(gMinikinLock);
    LayoutCache& layoutCache = LayoutEngine::getInstance().layoutCache;
    layoutCache.clear();
    purgeHbFontCacheLocked();
}

}  // namespace minikin

// Unable to define the static data member outside of android.
// TODO: introduce our own Singleton to drop android namespace.
namespace android {
ANDROID_SINGLETON_STATIC_INSTANCE(minikin::LayoutEngine);
}  // namespace android

