/*
 * 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 "SkTextBlob.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;
}

SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
                         const SkPaint& srcPaint,
                         const char* utf8text,
                         size_t textBytes,
                         bool leftToRight,
                         SkPoint point) const {
    sk_ignore_unused_variable(leftToRight);

    SkPaint paint(srcPaint);
    paint.setTypeface(fImpl->fTypeface);
    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    int glyphCount = paint.countText(utf8text, textBytes);
    if (glyphCount <= 0) {
        return 0;
    }
    SkRect bounds;
    (void)paint.measureText(utf8text, textBytes, &bounds);
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    const SkTextBlobBuilder::RunBuffer& runBuffer =
        builder->allocRunTextPosH(paint, glyphCount, point.y(), textBytes, SkString(), &bounds);
    memcpy(runBuffer.utf8text, utf8text, textBytes);
    const char* txtPtr = utf8text;
    for (int i = 0; i < glyphCount; ++i) {
        // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
        runBuffer.clusters[i] = SkToU32(txtPtr - utf8text);
        txtPtr += utf8_lead_byte_to_count(txtPtr);
        SkASSERT(txtPtr <= utf8text + textBytes);
    }
    paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    (void)paint.textToGlyphs(utf8text, textBytes, runBuffer.glyphs);
    (void)paint.getTextWidths(utf8text, textBytes, runBuffer.pos);
    SkScalar x = point.x();
    for (int i = 0; i < glyphCount; ++i) {
        SkScalar w = runBuffer.pos[i];
        runBuffer.pos[i] = x;
        x += w;
    }
    return (SkScalar)x;
}
