/*
 * 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>

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;
}

#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
