/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkShaper.h"

#include "SkStream.h"
#include "SkTo.h"
#include "SkTypeface.h"

struct SkShaper::Impl {
    sk_sp<SkTypeface> fTypeface;
};

SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
    fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
}

SkShaper::~SkShaper() {}

bool SkShaper::good() const { return true; }

// This example only uses public API, so we don't use SkUTF8_NextUnichar.
unsigned utf8_lead_byte_to_count(const char* ptr) {
    uint8_t c = *(const uint8_t*)ptr;
    SkASSERT(c <= 0xF7);
    SkASSERT((c & 0xC0) != 0x80);
    return (((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1;
}

SkPoint SkShaper::shape(LineHandler* handler,
                        const SkFont& srcFont,
                        const char* utf8text,
                        size_t textBytes,
                        bool leftToRight,
                        SkPoint point,
                        SkScalar width) const {
    sk_ignore_unused_variable(leftToRight);
    sk_ignore_unused_variable(width);

    SkFont font(srcFont);
    font.setTypeface(fImpl->fTypeface);
    int glyphCount = font.countText(utf8text, textBytes, SkTextEncoding::kUTF8);
    if (glyphCount <= 0) {
        return point;
    }

    SkFontMetrics metrics;
    font.getMetrics(&metrics);
    point.fY -= metrics.fAscent;

    const auto buffer = handler->newLineBuffer(font, glyphCount, textBytes);
    SkAssertResult(font.textToGlyphs(utf8text, textBytes, SkTextEncoding::kUTF8, buffer.glyphs,
                                     glyphCount) == glyphCount);
    font.getPos(buffer.glyphs, glyphCount, buffer.positions, point);

    if (buffer.utf8text) {
        memcpy(buffer.utf8text, utf8text, textBytes);
    }

    if (buffer.clusters) {
        const char* txtPtr = utf8text;
        for (int i = 0; i < glyphCount; ++i) {
            // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
            buffer.clusters[i] = SkToU32(txtPtr - utf8text);
            txtPtr += utf8_lead_byte_to_count(txtPtr);
            SkASSERT(txtPtr <= utf8text + textBytes);
        }
    }

    return point + SkVector::Make(0, metrics.fDescent + metrics.fLeading);
}
