/*
 * Copyright 2022 Rive
 */

#include "rive/text_engine.hpp"

#ifdef WITH_RIVE_TEXT
#include "rive/text/font_hb.hpp"

#include "rive/factory.hpp"
#include "rive/renderer_utils.hpp"
#include "rive/shapes/paint/color.hpp"

#include "hb.h"
#include "hb-ot.h"
#include <unordered_set>

// harfbuzz's own file loader is compiled out (HB_NO_OPEN/HB_NO_MMAP keep it
// out of the wasm builds), so map the file ourselves and hand harfbuzz a
// borrowed pointer. RIVE_HB_FILE_MAPPING is defined in font_hb.hpp.
#ifdef RIVE_HB_FILE_MAPPING
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

extern "C"
{
#include "SheenBidi.h"
}

// Initialized to null. Client can set this to a callback.
rive::Font::FallbackProc rive::Font::gFallbackProc;

bool rive::Font::gFallbackProcEnabled = true;

rive::rcp<rive::Font> HBFont::Decode(rive::Span<const uint8_t> span)
{
    auto blob = hb_blob_create_or_fail((const char*)span.data(),
                                       (unsigned)span.size(),
                                       HB_MEMORY_MODE_DUPLICATE,
                                       nullptr,
                                       nullptr);
    if (blob)
    {
        auto face = hb_face_create_or_fail(blob, 0);
        hb_blob_destroy(blob);
        if (face)
        {
            auto font = hb_font_create(face);
            hb_face_destroy(face);
            if (font)
            {
                return rive::rcp<rive::Font>(new HBFont(font));
            }
        }
    }
    return nullptr;
}

#ifdef RIVE_HB_FILE_MAPPING
namespace
{
struct HBFileMapping
{
    void* data;
    size_t size;
};

void destroyHBFileMapping(void* context)
{
    auto* mapping = static_cast<HBFileMapping*>(context);
    munmap(mapping->data, mapping->size);
    delete mapping;
}
} // namespace
#endif

rive::rcp<rive::Font> HBFont::DecodeFile(const char* path)
{
#ifdef RIVE_HB_FILE_MAPPING
    if (path == nullptr)
    {
        return nullptr;
    }
    int fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        return nullptr;
    }
    struct stat info;
    // hb_blob_create_or_fail rejects >= 2GB, so bail before mapping.
    if (fstat(fd, &info) == -1 || info.st_size <= 0 ||
        static_cast<uint64_t>(info.st_size) >= (1ull << 31))
    {
        close(fd);
        return nullptr;
    }
    size_t size = static_cast<size_t>(info.st_size);
    void* data = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0);
    // The mapping holds its own reference to the file.
    close(fd);
    if (data == MAP_FAILED)
    {
        return nullptr;
    }

    // READONLY_MAY_MAKE_WRITABLE: harfbuzz reads our clean, evictable file
    // pages and only copies if it ever needs to write.
    auto blob =
        hb_blob_create_or_fail(static_cast<const char*>(data),
                               static_cast<unsigned>(size),
                               HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
                               new HBFileMapping{data, size},
                               &destroyHBFileMapping);
    // On failure harfbuzz has already invoked the destroy callback.
    if (blob == nullptr)
    {
        return nullptr;
    }
    auto face = hb_face_create_or_fail(blob, 0);
    hb_blob_destroy(blob);
    if (face == nullptr)
    {
        return nullptr;
    }
    auto font = hb_font_create(face);
    hb_face_destroy(face);
    if (font == nullptr)
    {
        return nullptr;
    }
    return rive::rcp<rive::Font>(new HBFont(font));
#else
    return nullptr;
#endif
}

#if defined(RIVE_NO_CORETEXT) || !defined(__APPLE__)
rive::rcp<rive::Font> HBFont::FromSystem(void* systemFont,
                                         bool useSystemShaper,
                                         uint16_t weight,
                                         uint8_t width)
{
    return nullptr;
}
#endif

float HBFont::GetStyle(hb_font_t* font, uint32_t styleTag)
{
    return hb_style_get_value(font, (hb_style_tag_t)styleTag);
}
//////////////

constexpr int kStdScale = 2048;
constexpr float gInvScale = 1.0f / kStdScale;

extern "C"
{
    static void rpath_move_to(hb_draw_funcs_t*,
                              void* rpath,
                              hb_draw_state_t*,
                              float x,
                              float y,
                              void*)
    {
        ((rive::RawPath*)rpath)->moveTo(x * gInvScale, -y * gInvScale);
    }
    static void rpath_line_to(hb_draw_funcs_t*,
                              void* rpath,
                              hb_draw_state_t*,
                              float x1,
                              float y1,
                              void*)
    {
        ((rive::RawPath*)rpath)->lineTo(x1 * gInvScale, -y1 * gInvScale);
    }
    static void rpath_quad_to(hb_draw_funcs_t*,
                              void* rpath,
                              hb_draw_state_t*,
                              float x1,
                              float y1,
                              float x2,
                              float y2,
                              void*)
    {
        ((rive::RawPath*)rpath)
            ->quadToCubic(x1 * gInvScale,
                          -y1 * gInvScale,
                          x2 * gInvScale,
                          -y2 * gInvScale);
    }
    static void rpath_cubic_to(hb_draw_funcs_t*,
                               void* rpath,
                               hb_draw_state_t*,
                               float x1,
                               float y1,
                               float x2,
                               float y2,
                               float x3,
                               float y3,
                               void*)
    {
        ((rive::RawPath*)rpath)
            ->cubicTo(x1 * gInvScale,
                      -y1 * gInvScale,
                      x2 * gInvScale,
                      -y2 * gInvScale,
                      x3 * gInvScale,
                      -y3 * gInvScale);
    }
    static void rpath_close(hb_draw_funcs_t*,
                            void* rpath,
                            hb_draw_state_t*,
                            void*)
    {
        ((rive::RawPath*)rpath)->close();
    }
}

// Convert HarfBuzz color (BGRA byte order) to Rive ColorInt (ARGB).
static rive::ColorInt hbColorToColorInt(hb_color_t c)
{
    uint8_t b = hb_color_get_blue(c);
    uint8_t g = hb_color_get_green(c);
    uint8_t r = hb_color_get_red(c);
    uint8_t a = hb_color_get_alpha(c);
    return rive::colorARGB(a, r, g, b);
}

// ── COLRv1 paint callbacks ──────────────────────────────────────────────
// We flatten the COLRv1 paint tree into a list of (path, fill) layers.

struct PaintState
{
    hb_font_t* font;
    hb_draw_funcs_t* drawFuncs;
    std::vector<rive::Font::ColorGlyphLayer>* layers;
    rive::GlyphID clipGlyph = 0;
    bool hasClip = false;
    rive::ColorInt foreground = 0xFF000000;

    // Transform stack for gradient coordinates.
    // HarfBuzz gives gradient coords in the local space of the paint;
    // transforms map them to glyph space.
    std::vector<rive::Mat2D> transformStack;

    void pushTransform(float xx,
                       float yx,
                       float xy,
                       float yy,
                       float dx,
                       float dy)
    {
        rive::Mat2D m;
        m[0] = xx;
        m[1] = yx;
        m[2] = xy;
        m[3] = yy;
        m[4] = dx * gInvScale;
        m[5] = -dy * gInvScale;
        if (transformStack.empty())
        {
            transformStack.push_back(m);
        }
        else
        {
            transformStack.push_back(transformStack.back() * m);
        }
    }

    void popTransform()
    {
        if (!transformStack.empty())
        {
            transformStack.pop_back();
        }
    }

    rive::Vec2D mapPoint(float x, float y) const
    {
        // Scale from HB font units to Rive glyph units, and flip Y.
        float rx = x * gInvScale;
        float ry = -y * gInvScale;
        if (!transformStack.empty())
        {
            // The transform stack already incorporates gInvScale + Y flip
            // in pushTransform, so just apply raw coords.
            const auto& m = transformStack.back();
            return rive::Vec2D(m[0] * x + m[2] * y + m[4],
                               m[1] * x + m[3] * y + m[5]);
        }
        return rive::Vec2D(rx, ry);
    }

    float mapRadius(float r) const
    {
        float scaled = r * gInvScale;
        if (!transformStack.empty())
        {
            // Use the geometric mean of the scale factors.
            const auto& m = transformStack.back();
            float sx = std::sqrt(m[0] * m[0] + m[1] * m[1]);
            return r * sx; // Don't double-apply gInvScale; it's in the matrix.
        }
        return scaled;
    }

    // Helper: extract color stops from hb_color_line_t.
    static std::vector<rive::Font::GradientStop> extractStops(
        hb_color_line_t* colorLine,
        rive::ColorInt foreground)
    {
        unsigned int count = 0;
        hb_color_line_get_color_stops(colorLine, 0, &count, nullptr);
        std::vector<hb_color_stop_t> hbStops(count);
        hb_color_line_get_color_stops(colorLine, 0, &count, hbStops.data());
        std::vector<rive::Font::GradientStop> stops;
        stops.reserve(count);
        for (auto& s : hbStops)
        {
            rive::ColorInt c =
                s.is_foreground ? foreground : hbColorToColorInt(s.color);
            stops.push_back({s.offset, c});
        }
        return stops;
    }

    // Helper: emit a layer with the current clip glyph path.
    rive::Font::ColorGlyphLayer makeClipLayer() const
    {
        rive::Font::ColorGlyphLayer layer;
        hb_font_draw_glyph(font, clipGlyph, drawFuncs, &layer.path);
        return layer;
    }
};

static void paint_push_transform(hb_paint_funcs_t*,
                                 void* paint_data,
                                 float xx,
                                 float yx,
                                 float xy,
                                 float yy,
                                 float dx,
                                 float dy,
                                 void*)
{
    ((PaintState*)paint_data)->pushTransform(xx, yx, xy, yy, dx, dy);
}

static void paint_pop_transform(hb_paint_funcs_t*, void* paint_data, void*)
{
    ((PaintState*)paint_data)->popTransform();
}

static void paint_push_clip_glyph(hb_paint_funcs_t*,
                                  void* paint_data,
                                  hb_codepoint_t glyph,
                                  hb_font_t*,
                                  void*)
{
    auto* state = (PaintState*)paint_data;
    state->clipGlyph = (rive::GlyphID)glyph;
    state->hasClip = true;
}

static void paint_push_clip_rectangle(hb_paint_funcs_t*,
                                      void*,
                                      float,
                                      float,
                                      float,
                                      float,
                                      void*)
{}

static void paint_pop_clip(hb_paint_funcs_t*, void* paint_data, void*)
{
    ((PaintState*)paint_data)->hasClip = false;
}

static void paint_solid(hb_paint_funcs_t*,
                        void* paint_data,
                        hb_bool_t is_foreground,
                        hb_color_t color,
                        void*)
{
    auto* state = (PaintState*)paint_data;
    if (!state->hasClip)
        return;

    auto layer = state->makeClipLayer();
    layer.paintType = rive::Font::ColorGlyphPaintType::solid;
    if (is_foreground)
    {
        layer.useForeground = true;
        layer.color = state->foreground;
    }
    else
    {
        layer.color = hbColorToColorInt(color);
    }
    state->layers->push_back(std::move(layer));
}

static void paint_linear_gradient(hb_paint_funcs_t*,
                                  void* paint_data,
                                  hb_color_line_t* colorLine,
                                  float x0,
                                  float y0,
                                  float x1,
                                  float y1,
                                  float x2,
                                  float y2,
                                  void*)
{
    auto* state = (PaintState*)paint_data;
    if (!state->hasClip)
        return;

    auto layer = state->makeClipLayer();
    layer.paintType = rive::Font::ColorGlyphPaintType::linearGradient;
    layer.stops = PaintState::extractStops(colorLine, state->foreground);

    // OpenType linear gradient uses 3 points: p0 (start), p1 (end), p2
    // (rotation). The gradient line goes from p0 toward p1, and p2 is used
    // to rotate the direction. For Rive we need a 2-point definition.
    // The actual gradient direction is: start = p0, end = p1 projected
    // along the p0->p2 direction. For simplicity, just use p0 and p1.
    auto sp0 = state->mapPoint(x0, y0);
    auto sp1 = state->mapPoint(x1, y1);
    layer.x0 = sp0.x;
    layer.y0 = sp0.y;
    layer.x1 = sp1.x;
    layer.y1 = sp1.y;

    state->layers->push_back(std::move(layer));
}

static void paint_radial_gradient(hb_paint_funcs_t*,
                                  void* paint_data,
                                  hb_color_line_t* colorLine,
                                  float x0,
                                  float y0,
                                  float radius0,
                                  float x1,
                                  float y1,
                                  float radius1,
                                  void*)
{
    auto* state = (PaintState*)paint_data;
    if (!state->hasClip)
        return;

    auto layer = state->makeClipLayer();
    layer.paintType = rive::Font::ColorGlyphPaintType::radialGradient;
    layer.stops = PaintState::extractStops(colorLine, state->foreground);

    auto sp0 = state->mapPoint(x0, y0);
    auto sp1 = state->mapPoint(x1, y1);
    layer.x0 = sp0.x;
    layer.y0 = sp0.y;
    layer.x1 = sp1.x;
    layer.y1 = sp1.y;
    layer.r0 = state->mapRadius(radius0);
    layer.r1 = state->mapRadius(radius1);

    state->layers->push_back(std::move(layer));
}

static void paint_sweep_gradient(hb_paint_funcs_t*,
                                 void* paint_data,
                                 hb_color_line_t* colorLine,
                                 float cx,
                                 float cy,
                                 float startAngle,
                                 float endAngle,
                                 void*)
{
    auto* state = (PaintState*)paint_data;
    if (!state->hasClip)
        return;

    auto layer = state->makeClipLayer();
    layer.paintType = rive::Font::ColorGlyphPaintType::sweepGradient;
    layer.stops = PaintState::extractStops(colorLine, state->foreground);

    auto sc = state->mapPoint(cx, cy);
    layer.x0 = sc.x;
    layer.y0 = sc.y;
    layer.startAngle = startAngle;
    layer.endAngle = endAngle;

    state->layers->push_back(std::move(layer));
}

static void paint_push_group(hb_paint_funcs_t*, void*, void*) {}
static void paint_pop_group(hb_paint_funcs_t*,
                            void*,
                            hb_paint_composite_mode_t,
                            void*)
{}

static hb_bool_t paint_color_glyph(hb_paint_funcs_t*,
                                   void*,
                                   hb_codepoint_t,
                                   hb_font_t*,
                                   void*)
{
    return false;
}

static hb_bool_t paint_image(hb_paint_funcs_t*,
                             void* paint_data,
                             hb_blob_t* blob,
                             unsigned int width,
                             unsigned int height,
                             hb_tag_t format,
                             float slant,
                             hb_glyph_extents_t* extents,
                             void*)
{
    // We only support PNG images (SBIX / CBDT).
    if (format != HB_TAG('p', 'n', 'g', ' '))
    {
        return false;
    }

    unsigned int length;
    const char* data = hb_blob_get_data(blob, &length);
    if (data == nullptr || length == 0)
    {
        return false;
    }

    auto* state = (PaintState*)paint_data;

    rive::Font::ColorGlyphLayer layer;
    layer.paintType = rive::Font::ColorGlyphPaintType::image;
    layer.imageBytes.assign(reinterpret_cast<const uint8_t*>(data),
                            reinterpret_cast<const uint8_t*>(data) + length);
    layer.imageWidth = width;
    layer.imageHeight = height;
    if (extents != nullptr)
    {
        layer.imageBearingX = extents->x_bearing * gInvScale;
        layer.imageBearingY = -extents->y_bearing * gInvScale;
        layer.imageExtentX = extents->width * gInvScale;
        layer.imageExtentY = -extents->height * gInvScale;
    }

    state->layers->push_back(std::move(layer));
    return true;
}

// ────────────────────────────────────────────────────────────────────────

static rive::Font::LineMetrics make_lmx(hb_font_t* font)
{
    // premable on font...
    hb_ot_font_set_funcs(font);
    hb_font_set_scale(font, kStdScale, kStdScale);

    hb_font_extents_t extents;
    hb_font_get_h_extents(font, &extents);

    // Cap height / x-height: distances from the baseline to the top of capital
    // and lowercase letters, stored negative (up is -Y) to match ascent. We
    // measure the 'H' and 'x' glyphs directly (their top-side bearing) rather
    // than the OS/2 metrics, since the metrics API is compiled out of this
    // HarfBuzz build (HB_NO_METRICS). Each falls back to the ascent for fonts
    // without the reference glyph so vertical trim becomes a no-op at the top.
    float ascent = -extents.ascender * gInvScale;
    auto measureGlyphTop = [&](hb_codepoint_t unicode) -> float {
        hb_codepoint_t glyph = 0;
        hb_glyph_extents_t glyphExtents;
        if (hb_font_get_nominal_glyph(font, unicode, &glyph) &&
            hb_font_get_glyph_extents(font, glyph, &glyphExtents))
        {
            return -glyphExtents.y_bearing * gInvScale;
        }
        return ascent;
    };
    float capHeight = measureGlyphTop('H');
    float xHeight = measureGlyphTop('x');
    return {ascent, -extents.descender * gInvScale, capHeight, xHeight};
}

HBFont::HBFont(hb_font_t* font) : HBFont(font, {}, {}, {}) {}

HBFont::HBFont(hb_font_t* font,
               std::unordered_map<hb_tag_t, float> axisValues,
               std::unordered_map<hb_tag_t, uint32_t> featureValues,
               std::vector<hb_feature_t> features) :
    Font(make_lmx(font)),
    m_font(font),
    m_features(features),
    m_featureValues(featureValues),
    m_axisValues(axisValues)
{
    m_drawFuncs = hb_draw_funcs_create();
    hb_draw_funcs_set_move_to_func(m_drawFuncs,
                                   rpath_move_to,
                                   nullptr,
                                   nullptr);
    hb_draw_funcs_set_line_to_func(m_drawFuncs,
                                   rpath_line_to,
                                   nullptr,
                                   nullptr);
    hb_draw_funcs_set_quadratic_to_func(m_drawFuncs,
                                        rpath_quad_to,
                                        nullptr,
                                        nullptr);
    hb_draw_funcs_set_cubic_to_func(m_drawFuncs,
                                    rpath_cubic_to,
                                    nullptr,
                                    nullptr);
    hb_draw_funcs_set_close_path_func(m_drawFuncs,
                                      rpath_close,
                                      nullptr,
                                      nullptr);
    hb_draw_funcs_make_immutable(m_drawFuncs);

    // Initialize COLRv1 paint funcs.
    m_paintFuncs = hb_paint_funcs_create();
    hb_paint_funcs_set_push_transform_func(m_paintFuncs,
                                           paint_push_transform,
                                           nullptr,
                                           nullptr);
    hb_paint_funcs_set_pop_transform_func(m_paintFuncs,
                                          paint_pop_transform,
                                          nullptr,
                                          nullptr);
    hb_paint_funcs_set_push_clip_glyph_func(m_paintFuncs,
                                            paint_push_clip_glyph,
                                            nullptr,
                                            nullptr);
    hb_paint_funcs_set_push_clip_rectangle_func(m_paintFuncs,
                                                paint_push_clip_rectangle,
                                                nullptr,
                                                nullptr);
    hb_paint_funcs_set_pop_clip_func(m_paintFuncs,
                                     paint_pop_clip,
                                     nullptr,
                                     nullptr);
    hb_paint_funcs_set_color_func(m_paintFuncs, paint_solid, nullptr, nullptr);
    hb_paint_funcs_set_push_group_func(m_paintFuncs,
                                       paint_push_group,
                                       nullptr,
                                       nullptr);
    hb_paint_funcs_set_pop_group_func(m_paintFuncs,
                                      paint_pop_group,
                                      nullptr,
                                      nullptr);
    hb_paint_funcs_set_color_glyph_func(m_paintFuncs,
                                        paint_color_glyph,
                                        nullptr,
                                        nullptr);
    hb_paint_funcs_set_linear_gradient_func(m_paintFuncs,
                                            paint_linear_gradient,
                                            nullptr,
                                            nullptr);
    hb_paint_funcs_set_radial_gradient_func(m_paintFuncs,
                                            paint_radial_gradient,
                                            nullptr,
                                            nullptr);
    hb_paint_funcs_set_sweep_gradient_func(m_paintFuncs,
                                           paint_sweep_gradient,
                                           nullptr,
                                           nullptr);
    hb_paint_funcs_set_image_func(m_paintFuncs, paint_image, nullptr, nullptr);
    hb_paint_funcs_make_immutable(m_paintFuncs);

    // Initialize color glyph (COLR/CPAL/SBIX/CBDT) support.
    hb_face_t* face = hb_font_get_face(font);
    m_hasColorLayers = hb_ot_color_has_layers(face);
    m_hasColorPaint = hb_ot_color_has_paint(face);
    m_hasPNG = hb_ot_color_has_png(face);
    if (m_hasColorLayers || m_hasColorPaint)
    {
        unsigned int colorCount = 0;
        hb_ot_color_palette_get_colors(face, 0, 0, &colorCount, nullptr);
        if (colorCount > 0)
        {
            m_paletteColors.resize(colorCount);
            hb_ot_color_palette_get_colors(face,
                                           0,
                                           0,
                                           &colorCount,
                                           m_paletteColors.data());
        }
    }
}

HBFont::~HBFont()
{
    hb_draw_funcs_destroy(m_drawFuncs);
    hb_paint_funcs_destroy(m_paintFuncs);
    hb_font_destroy(m_font);
}

static void fillLanguageFeatures(hb_face_t* face,
                                 hb_tag_t tag,
                                 uint32_t scriptIndex,
                                 uint32_t languageIndex,
                                 std::unordered_set<uint32_t>& features)
{
    auto featureCount = hb_ot_layout_language_get_feature_tags(face,
                                                               tag,
                                                               scriptIndex,
                                                               languageIndex,
                                                               0,
                                                               nullptr,
                                                               nullptr);
    auto featureTags = std::vector<hb_tag_t>(featureCount);
    hb_ot_layout_language_get_feature_tags(face,
                                           tag,
                                           scriptIndex,
                                           languageIndex,
                                           0,
                                           &featureCount,
                                           featureTags.data());

    for (auto featureTag : featureTags)
    {
        features.emplace(featureTag);
    }
}

static void fillFeatures(hb_face_t* face,
                         hb_tag_t tag,
                         std::unordered_set<uint32_t>& features)
{
    auto scriptCount =
        hb_ot_layout_table_get_script_tags(face, tag, 0, nullptr, nullptr);
    auto scripts = std::vector<hb_tag_t>(scriptCount);
    hb_ot_layout_table_get_script_tags(face,
                                       tag,
                                       0,
                                       &scriptCount,
                                       scripts.data());
    for (uint32_t i = 0; i < scriptCount; ++i)
    {
        auto languageCount = hb_ot_layout_script_get_language_tags(face,
                                                                   tag,
                                                                   i,
                                                                   0,
                                                                   nullptr,
                                                                   nullptr);

        if (languageCount > 0)
        {
            auto languages = std::vector<hb_tag_t>(languageCount);
            hb_ot_layout_script_get_language_tags(face,
                                                  tag,
                                                  i,
                                                  0,
                                                  &languageCount,
                                                  languages.data());

            for (uint32_t j = 0; j < languageCount; ++j)
            {
                fillLanguageFeatures(face, tag, i, j, features);
            }
        }
        else
        {
            fillLanguageFeatures(face,
                                 tag,
                                 i,
                                 HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
                                 features);
        }
    }
}

rive::SimpleArray<uint32_t> HBFont::features() const
{
    std::unordered_set<uint32_t> features;
    auto face = hb_font_get_face(m_font);
    fillFeatures(face, HB_OT_TAG_GSUB, features);
    fillFeatures(face, HB_OT_TAG_GPOS, features);

    rive::SimpleArray<uint32_t> result(features.size());
    uint32_t index = 0;
    for (auto tag : features)
    {
        result[index++] = tag;
    }
    return result;
}

rive::Font::Axis HBFont::getAxis(uint16_t index) const
{
    auto face = hb_font_get_face(m_font);
    assert(index < hb_ot_var_get_axis_count(face));
    unsigned n = 1;
    hb_ot_var_axis_info_t info;
    hb_ot_var_get_axis_infos(face, index, &n, &info);
    assert(n == 1);
    return {info.tag, info.min_value, info.default_value, info.max_value};
}

uint16_t HBFont::getAxisCount() const
{
    auto face = hb_font_get_face(m_font);
    return (uint16_t)hb_ot_var_get_axis_count(face);
}

float HBFont::getAxisValue(uint32_t axisTag) const
{
    auto itr = m_axisValues.find(axisTag);
    if (itr != m_axisValues.end())
    {
        return itr->second;
    }
    auto face = hb_font_get_face(m_font);

    // No value specified, we're using a default.
    uint32_t axisCount = hb_ot_var_get_axis_count(face);
    for (uint32_t i = 0; i < axisCount; ++i)
    {
        hb_ot_var_axis_info_t info;
        uint32_t n = 1;
        hb_ot_var_get_axis_infos(face, i, &n, &info);
        if (info.tag == axisTag)
        {
            return info.default_value;
        }
    }
    return 0.0f;
}

uint32_t HBFont::getFeatureValue(uint32_t featureTag) const
{
    auto itr = m_featureValues.find(featureTag);
    if (itr != m_featureValues.end())
    {
        return itr->second;
    }
    return (uint32_t)-1;
}

uint16_t HBFont::getWeight() const
{
    uint32_t tag = HB_TAG('w', 'g', 'h', 't');
    float res = HBFont::GetStyle(m_font, tag);
    return static_cast<uint16_t>(res);
}

bool HBFont::isItalic() const
{
    uint32_t tag = HB_TAG('i', 't', 'a', 'l');
    float res = HBFont::GetStyle(m_font, tag);
    return res != 0.0;
}

rive::rcp<rive::Font> HBFont::withOptions(
    rive::Span<const Coord> coords,
    rive::Span<const Feature> features) const
{
    // Merges previous options with current ones.
    std::unordered_map<hb_tag_t, float> axisValues = m_axisValues;
    for (size_t i = 0; i < coords.size(); ++i)
    {
        axisValues[coords[i].axis] = coords[i].value;
    }

    AutoSTArray<16, hb_variation_t> vars(axisValues.size());
    size_t i = 0;
    for (auto itr = axisValues.begin(); itr != axisValues.end(); itr++)
    {
        vars[i++] = {itr->first, itr->second};
    }

    auto font = hb_font_create_sub_font(m_font);
    hb_font_set_variations(font, vars.data(), (unsigned int)vars.size());
    std::vector<hb_feature_t> hbFeatures;
    std::unordered_map<hb_tag_t, uint32_t> featureValues = m_featureValues;
    for (auto feature : features)
    {
        featureValues[feature.tag] = feature.value;
    }
    for (auto itr = featureValues.begin(); itr != featureValues.end(); itr++)
    {
        hbFeatures.push_back({itr->first,
                              itr->second,
                              HB_FEATURE_GLOBAL_START,
                              HB_FEATURE_GLOBAL_END});
    }

    return rive::rcp<rive::Font>(
        new HBFont(font, axisValues, featureValues, hbFeatures));
}

rive::RawPath HBFont::getPath(rive::GlyphID glyph) const
{
    rive::RawPath rpath;
    hb_font_draw_glyph(m_font, glyph, m_drawFuncs, &rpath);
    return rpath;
}

bool HBFont::hasColorGlyphs() const
{
    return m_hasColorLayers || m_hasColorPaint || m_hasPNG;
}

bool HBFont::isColorGlyph(rive::GlyphID glyph) const
{
    if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG)
    {
        return false;
    }
    hb_face_t* face = hb_font_get_face(m_font);
    // Check COLRv0 layers first.
    if (m_hasColorLayers)
    {
        unsigned int total =
            hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr);
        if (total > 0)
        {
            return true;
        }
    }
    // Check COLRv1 paint.
    if (m_hasColorPaint)
    {
        if (hb_ot_color_glyph_has_paint(face, glyph))
        {
            return true;
        }
    }
    // Check SBIX/CBDT PNG.
    if (m_hasPNG)
    {
        hb_blob_t* blob = hb_ot_color_glyph_reference_png(m_font, glyph);
        if (blob != nullptr)
        {
            bool has = hb_blob_get_length(blob) > 0;
            hb_blob_destroy(blob);
            return has;
        }
    }
    return false;
}

size_t HBFont::getColorLayers(rive::GlyphID glyph,
                              std::vector<ColorGlyphLayer>& out,
                              rive::ColorInt foreground) const
{
    if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG)
    {
        return 0;
    }

    // Check cache first.
    auto cacheIt = m_colorLayerCache.find(glyph);
    if (cacheIt != m_colorLayerCache.end())
    {
        // Copy from cache, but update foreground colors.
        for (const auto& cached : cacheIt->second)
        {
            ColorGlyphLayer layer;
            layer.paintType = cached.paintType;
            layer.path = cached.path;
            layer.useForeground = cached.useForeground;
            layer.color = cached.useForeground ? foreground : cached.color;
            // Copy gradient data if present.
            layer.stops = cached.stops;
            layer.x0 = cached.x0;
            layer.y0 = cached.y0;
            layer.x1 = cached.x1;
            layer.y1 = cached.y1;
            layer.r0 = cached.r0;
            layer.r1 = cached.r1;
            layer.startAngle = cached.startAngle;
            layer.endAngle = cached.endAngle;
            // Copy image data if present.
            layer.imageBytes = cached.imageBytes;
            layer.imageWidth = cached.imageWidth;
            layer.imageHeight = cached.imageHeight;
            layer.imageBearingX = cached.imageBearingX;
            layer.imageBearingY = cached.imageBearingY;
            layer.imageExtentX = cached.imageExtentX;
            layer.imageExtentY = cached.imageExtentY;
            out.push_back(std::move(layer));
        }
        return cacheIt->second.size();
    }

    std::vector<ColorGlyphLayer> layers;
    hb_face_t* face = hb_font_get_face(m_font);

    // Try COLRv0 first.
    if (m_hasColorLayers)
    {
        unsigned int layerCount =
            hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr);
        if (layerCount > 0)
        {
            std::vector<hb_ot_color_layer_t> hbLayers(layerCount);
            hb_ot_color_glyph_get_layers(face,
                                         glyph,
                                         0,
                                         &layerCount,
                                         hbLayers.data());

            layers.reserve(layerCount);
            for (unsigned int i = 0; i < layerCount; i++)
            {
                ColorGlyphLayer layer;
                hb_font_draw_glyph(m_font,
                                   hbLayers[i].glyph,
                                   m_drawFuncs,
                                   &layer.path);
                if (hbLayers[i].color_index == 0xFFFF)
                {
                    layer.useForeground = true;
                    layer.color = foreground;
                }
                else
                {
                    layer.useForeground = false;
                    if (hbLayers[i].color_index < m_paletteColors.size())
                    {
                        layer.color = hbColorToColorInt(
                            m_paletteColors[hbLayers[i].color_index]);
                    }
                    else
                    {
                        layer.color = 0xFF000000;
                    }
                }
                layers.push_back(std::move(layer));
            }
        }
    }

    // Fall back to COLRv1 paint if no COLRv0 layers found.
    if (layers.empty() && (m_hasColorPaint || m_hasPNG))
    {
        // hb_font_paint_glyph handles both COLRv1 and SBIX/CBDT.
        // For COLRv1 it calls paint_solid/gradient callbacks;
        // for SBIX/CBDT it calls paint_image.
        PaintState state;
        state.font = m_font;
        state.drawFuncs = m_drawFuncs;
        state.layers = &layers;
        state.foreground = foreground;

        hb_font_paint_glyph(m_font,
                            glyph,
                            m_paintFuncs,
                            &state,
                            0,                       // palette_index
                            HB_COLOR(0, 0, 0, 255)); // foreground
    }

    if (layers.empty())
    {
        return 0;
    }

    size_t count = layers.size();
    // Cache the result.
    m_colorLayerCache[glyph] = layers;
    // Move into output.
    for (auto& layer : layers)
    {
        out.push_back(std::move(layer));
    }
    return count;
}

///////////////////////////////////////////////////////////

static rive::GlyphRun shape_run(const rive::Unichar text[],
                                const rive::TextRun& tr,
                                unsigned textOffset)
{
    hb_buffer_t* buf = hb_buffer_create();
    hb_buffer_add_utf32(buf, text, tr.unicharCount, 0, tr.unicharCount);

    hb_buffer_set_direction(buf,
                            tr.level & 1 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
    hb_buffer_set_script(buf, (hb_script_t)tr.script);
    hb_buffer_set_language(buf, hb_language_get_default());

    auto hbfont = (HBFont*)tr.font.get();

    hb_shape(hbfont->m_font,
             buf,
             hbfont->m_features.data(),
             (unsigned int)hbfont->m_features.size());

    unsigned int glyph_count;
    hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
    hb_glyph_position_t* glyph_pos =
        hb_buffer_get_glyph_positions(buf, &glyph_count);

    // todo: check for missing glyphs, and perform font-substitution
    rive::GlyphRun gr(glyph_count);
    gr.font = tr.font;
    gr.size = tr.size;
    gr.lineHeight = tr.lineHeight;
    gr.letterSpacing = tr.letterSpacing;
    gr.styleId = tr.styleId;
    gr.level = tr.level;

    const float scale = tr.size / kStdScale;
    for (unsigned int i = 0; i < glyph_count; i++)
    {
        unsigned int index = tr.level & 1 ? glyph_count - 1 - i : i;
        gr.glyphs[i] = (uint16_t)glyph_info[index].codepoint;
        gr.textIndices[i] = textOffset + glyph_info[index].cluster;
        gr.advances[i] = gr.xpos[i] =
            glyph_pos[index].x_advance * scale + tr.letterSpacing;
        gr.offsets[i] = rive::Vec2D(glyph_pos[index].x_offset * scale,
                                    -glyph_pos[index].y_offset * scale);
    }
    gr.xpos[glyph_count] = 0; // so the next run can line up snug
    hb_buffer_destroy(buf);
    return gr;
}

static rive::GlyphRun extract_subset(const rive::GlyphRun& orig,
                                     size_t start,
                                     size_t end)
{
    auto count = end - start;
    rive::GlyphRun subset(
        rive::SimpleArray<rive::GlyphID>(&orig.glyphs[start], count),
        rive::SimpleArray<uint32_t>(&orig.textIndices[start], count),
        rive::SimpleArray<float>(&orig.advances[start], count),
        rive::SimpleArray<float>(&orig.xpos[start], count + 1),
        rive::SimpleArray<rive::Vec2D>(&orig.offsets[start], count));
    subset.font = std::move(orig.font);
    subset.size = orig.size;
    subset.lineHeight = orig.lineHeight;
    subset.letterSpacing = orig.letterSpacing;
    subset.level = orig.level;
    subset.xpos.back() = 0; // since we're now the end of a run
    subset.styleId = orig.styleId;

    return subset;
}

static void perform_fallback(rive::rcp<rive::Font> fallbackFont,
                             rive::SimpleArrayBuilder<rive::GlyphRun>& gruns,
                             const rive::Unichar text[],
                             const rive::GlyphRun& orig,
                             const rive::TextRun& origTextRun,
                             const uint32_t fallbackIndex)
{
    assert(orig.glyphs.size() > 0);
    const size_t count = orig.glyphs.size();
    size_t startI = 0;
    while (startI < count)
    {
        size_t endI = startI + 1;
        if (orig.glyphs[startI] == 0)
        {
            while (endI < count && orig.glyphs[endI] == 0)
            {
                ++endI;
            }

            auto textStart = orig.textIndices[startI];
            auto textCount =
                endI == count
                    ? origTextRun.unicharCount -
                          (orig.textIndices[startI] - orig.textIndices[0])
                    : orig.textIndices[endI] - textStart;

            auto tr = rive::TextRun{
                fallbackFont,
                orig.size,
                orig.lineHeight,
                origTextRun.letterSpacing,
                textCount,
                origTextRun.script,
                orig.styleId,
                orig.level,
            };

            static_cast<HBFont*>(fallbackFont.get())
                ->shapeFallbackRun(gruns,
                                   text,
                                   textStart,
                                   tr,
                                   origTextRun,
                                   fallbackIndex);
        }
        else
        {
            while (endI < count && orig.glyphs[endI] != 0)
            {
                ++endI;
            }
            gruns.add(extract_subset(orig, startI, endI));
        }
        startI = endI;
    }
}

void HBFont::shapeFallbackRun(rive::SimpleArrayBuilder<rive::GlyphRun>& gruns,
                              const rive::Unichar text[],
                              const unsigned textStart,
                              const rive::TextRun& textRun,
                              const rive::TextRun& originalTextRun,
                              const uint32_t fallbackIndex)
{
    auto gr = shape_run(&text[textStart], textRun, textStart);
    auto end = gr.glyphs.end();
    auto iter = std::find(gr.glyphs.begin(), end, 0);
    if (iter == end)
    {
        if (gr.glyphs.size() > 0)
        {
            gruns.add(std::move(gr));
        }
    }
    else
    {
        // found at least 1 zero in glyphs, so need to perform
        // font-fallback
        size_t index = iter - gr.glyphs.begin();
        rive::Unichar missing = text[gr.textIndices[index]];
        auto fallback = HBFont::gFallbackProc(missing, fallbackIndex, this);
        if (fallback && fallback.get() != this)
        {
            perform_fallback(fallback,
                             gruns,
                             text,
                             gr,
                             textRun,
                             fallbackIndex + 1);
        }
        else if (gr.glyphs.size() > 0)
        {
            gruns.add(std::move(gr));
        }
    }
}

rive::SimpleArray<rive::Paragraph> HBFont::onShapeText(
    rive::Span<const rive::Unichar> text,
    rive::Span<const rive::TextRun> truns,
    int textDirectionFlag) const
{

    rive::SimpleArrayBuilder<rive::Paragraph> paragraphs;
    SBCodepointSequence codepointSequence = {SBStringEncodingUTF32,
                                             (void*)text.data(),
                                             text.size()};

    hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_get_default();

    // Split runs by bidi types.
    uint32_t textIndex = 0;
    uint32_t runIndex = 0;
    uint32_t runStartTextIndex = 0;

    SBUInteger paragraphStart = 0;

    SBAlgorithmRef bidiAlgorithm = SBAlgorithmCreate(&codepointSequence);
    uint32_t unicharIndex = 0;
    uint32_t runTextIndex = 0;

    SBLevel defaultLevel;
    switch (textDirectionFlag)
    {
        case 0:
            defaultLevel = 0;
            break;
        case 1:
            defaultLevel = 1;
            break;
        default:
            defaultLevel = SBLevelDefaultLTR;
            break;
    }

    while (paragraphStart < text.size())
    {
        SBParagraphRef paragraph = SBAlgorithmCreateParagraph(bidiAlgorithm,
                                                              paragraphStart,
                                                              INT32_MAX,
                                                              defaultLevel);
        SBUInteger paragraphLength = SBParagraphGetLength(paragraph);
        // Next iteration reads the next paragraph (if any remain).
        paragraphStart += paragraphLength;
        const SBLevel* bidiLevels = SBParagraphGetLevelsPtr(paragraph);
        SBLevel paragraphLevel = SBParagraphGetBaseLevel(paragraph);
        uint32_t paragraphTextIndex = 0;

        std::vector<rive::TextRun> bidiRuns;
        bidiRuns.reserve(truns.size());

        while (runIndex < truns.size())
        {
            const auto& tr = truns[runIndex];
            assert(tr.unicharCount != 0);
            SBLevel lastLevel = bidiLevels[paragraphTextIndex];
            auto point = text[textIndex];
            hb_script_t lastScript = hb_unicode_script(ufuncs, point);

            rive::TextRun splitRun = {
                tr.font,
                tr.size,
                tr.lineHeight,
                tr.letterSpacing,
                tr.unicharCount - runTextIndex,
                (uint32_t)lastScript,
                tr.styleId,
                (uint8_t)lastLevel,
            };

            runStartTextIndex = textIndex;

            runTextIndex++;
            textIndex++;
            paragraphTextIndex++;
            bidiRuns.push_back(splitRun);

            while (runTextIndex < tr.unicharCount &&
                   paragraphTextIndex < paragraphLength)
            {
                auto point = text[textIndex];
                hb_script_t script =
                    hb_unicode_general_category(ufuncs, point) ==
                            HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK
                        ? HB_SCRIPT_INHERITED
                        : hb_unicode_script(ufuncs, point);

                switch (script)
                {
                    case HB_SCRIPT_COMMON:
                    case HB_SCRIPT_INHERITED:
                        // Propagate last seen "real" script value.
                        script = lastScript;
                        break;
                    default:
                        break;
                }
                if (bidiLevels[paragraphTextIndex] != lastLevel ||
                    script != lastScript)
                {
                    lastScript = script;
                    auto& back = bidiRuns.back();
                    back.unicharCount = textIndex - runStartTextIndex;
                    lastLevel = bidiLevels[paragraphTextIndex];

                    rive::TextRun backRun = {
                        back.font,
                        back.size,
                        back.lineHeight,
                        back.letterSpacing,
                        tr.unicharCount - runTextIndex,
                        (uint32_t)script,
                        back.styleId,
                        (uint8_t)lastLevel,
                    };
                    runStartTextIndex = textIndex;
                    bidiRuns.push_back(backRun);
                }
                runTextIndex++;
                textIndex++;
                paragraphTextIndex++;
            }
            // Reached the end of the run?
            if (runTextIndex == tr.unicharCount)
            {
                runIndex++;
                runTextIndex = 0;
            }
            // We consumed the whole paragraph.
            if (paragraphTextIndex == paragraphLength)
            {
                // Close off the last run.
                auto& back = bidiRuns.back();
                back.unicharCount = textIndex - runStartTextIndex;
                break;
            }
        }

        rive::SimpleArrayBuilder<rive::GlyphRun> gruns(bidiRuns.size());

        for (const auto& tr : bidiRuns)
        {
            auto gr = shape_run(&text[unicharIndex], tr, unicharIndex);
            unicharIndex += tr.unicharCount;

            // Handle dual-presentation characters (e.g. ☠ U+2620) that have a
            // text-form glyph in the current font but are followed by U+FE0F
            // (VARIATION SELECTOR-16), which requests emoji presentation.
            // The standard fallback only fires for glyph ID 0, so we explicitly
            // force such glyphs to 0 here — but only when a color emoji
            // fallback font is actually available for that codepoint, to avoid
            // regressing the rendering when no emoji font is loaded.
            if (gFallbackProc && gFallbackProcEnabled && !hasColorGlyphs())
            {
                for (size_t gi = 0; gi < gr.glyphs.size(); ++gi)
                {
                    if (gr.glyphs[gi] != 0)
                    {
                        auto textPos = gr.textIndices[gi];
                        if (textPos + 1 < text.size() &&
                            text[textPos + 1] == 0xFE0F)
                        {
                            auto emojiFont =
                                gFallbackProc(text[textPos], 0, this);
                            if (emojiFont && emojiFont->hasColorGlyphs())
                            {
                                gr.glyphs[gi] = 0;
                            }
                        }
                    }
                }
            }

            auto end = gr.glyphs.end();
            auto iter = std::find(gr.glyphs.begin(), end, 0);
            if (!gFallbackProc || iter == end || !gFallbackProcEnabled)
            {
                if (gr.glyphs.size() > 0)
                {
                    gruns.add(std::move(gr));
                }
            }
            else
            {
                // found at least 1 zero in glyphs, so need to perform
                // font-fallback
                size_t index = iter - gr.glyphs.begin();
                rive::Unichar missing = text[gr.textIndices[index]];
                // todo: consider sending more chars if that helps choose a font
                auto fallback = gFallbackProc(missing, 0, this);
                if (fallback)
                {
                    perform_fallback(fallback, gruns, text.data(), gr, tr, 1);
                }
                else if (gr.glyphs.size() > 0)
                {
                    // oh well, just keep the missing glyphs
                    gruns.add(std::move(gr));
                }
            }
        }

        // turn the advances we stored in xpos[] into actual x-positions
        // for logical order.
        float pos = 0;
        for (auto& gr : gruns)
        {
            for (auto& xp : gr.xpos)
            {
                float adv = xp;
                xp = pos;
                pos += adv;
            }
        }

        paragraphs.add({
            std::move(gruns),
            (uint8_t)paragraphLevel,
        });
        SBParagraphRelease(paragraph);
    }

    SBAlgorithmRelease(bidiAlgorithm);
    return paragraphs;
}

bool HBFont::hasGlyph(const rive::Unichar missing) const
{
    hb_codepoint_t glyph;
    return hb_font_get_nominal_glyph(m_font, missing, &glyph);
}

#endif
