/*
 * Copyright (C) 2026  Behdad Esfahbod
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Author(s): Behdad Esfahbod
 */

#include "hb.hh"

#include "hb-gpu.h"
#include "hb-gpu-paint.hh"
#include "hb-draw.hh"
#include "hb-machinery.hh"
#include "hb-paint.hh"


/* ---- Paint callbacks ---- */

/* Op-type tags.  Must match the layout documented in
 * hb-gpu-paint.hh. */
enum {
  HB_GPU_PAINT_OP_LAYER_SOLID    = 0,
  HB_GPU_PAINT_OP_LAYER_GRADIENT = 1,
  HB_GPU_PAINT_OP_PUSH_GROUP     = 2,
  HB_GPU_PAINT_OP_POP_GROUP      = 3,
};

/* Encoder limits.  Hitting any of these flips paint->unsupported and
 * makes hb_gpu_paint_encode() return NULL rather than emit a blob
 * that would render incorrectly. */
#define HB_GPU_PAINT_MAX_OPS         0x7fff /* num_ops is i16 in the blob header */
#define HB_GPU_PAINT_MAX_GROUP_DEPTH 4      /* matches HB_GPU_PAINT_GROUP_DEPTH in fragment shader */
#define HB_GPU_PAINT_MAX_CLIP_DEPTH  3      /* shader can intersect up to 3 clip outlines per layer */
#define HB_GPU_PAINT_MAX_SUB_BLOBS   1024   /* bound clip-glyph rasterizations per paint walk */

/* Layer-op flag bits (LAYER_SOLID texel 0 .g, LAYER_GRADIENT
 * texel 0 .g where bits 0-7 hold the gradient subtype). */
#define HB_GPU_PAINT_FLAG_IS_FOREGROUND  0x0001
#define HB_GPU_PAINT_FLAG_HAS_CLIP2      0x0100
#define HB_GPU_PAINT_FLAG_HAS_CLIP3      0x0200

static hb_bool_t
hb_gpu_paint_custom_palette_color (hb_paint_funcs_t *funcs HB_UNUSED,
				   void             *paint_data,
				   unsigned          color_index,
				   hb_color_t       *color,
				   void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  if (likely (c->custom_palette && hb_map_has (c->custom_palette, color_index)))
  {
    *color = hb_map_get (c->custom_palette, color_index);
    return true;
  }
  return false;
}

static void
hb_gpu_paint_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
			      void             *paint_data,
			      hb_codepoint_t    glyph,
			      hb_font_t        *font,
			      void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;

  if (unlikely (c->clip_depth >= HB_GPU_PAINT_MAX_CLIP_DEPTH))
  {
    c->unsupported = true;
    c->clip_depth++;
    return;
  }
  c->clip_stack[c->clip_depth] = { glyph, font, c->cur_transform, -1, 0, 0, 0, 0 };
  c->clip_depth++;
}

static void
hb_gpu_paint_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
		       void             *paint_data,
		       void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  if (likely (c->clip_depth > 0)) c->clip_depth--;
}

/* Arbitrary-path clip: hand the caller the same hb_gpu_draw
 * funcs the encoder uses for glyph outlines, with scratch_draw
 * as the accumulator.  push_clip_path_end encodes the captured
 * geometry into a sub-blob and commits it to clip_stack just
 * like a glyph clip.  No font ref needed — the sub-blob is a
 * self-contained slug bundle. */
static hb_draw_funcs_t *
hb_gpu_paint_push_clip_path_start (hb_paint_funcs_t *funcs HB_UNUSED,
				   void             *paint_data,
				   void            **draw_data,
				   void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;

  if (unlikely (c->clip_depth >= HB_GPU_PAINT_MAX_CLIP_DEPTH))
  {
    c->unsupported = true;
    *draw_data = nullptr;
    return nullptr;
  }

  if (unlikely (!c->scratch_draw))
  {
    c->scratch_draw = hb_gpu_draw_create_or_fail ();
    if (unlikely (!c->scratch_draw))
    {
      c->unsupported = true;
      *draw_data = nullptr;
      return nullptr;
    }
  }

  hb_gpu_draw_clear (c->scratch_draw);
  hb_gpu_draw_set_scale (c->scratch_draw, c->x_scale, c->y_scale);

  c->pending_clip_path_transform = c->cur_transform;
  c->pending_clip_path = true;

  *draw_data = c->scratch_draw;
  return hb_gpu_draw_get_funcs (c->scratch_draw);
}

static void
hb_gpu_paint_push_clip_path_end (hb_paint_funcs_t *funcs HB_UNUSED,
				 void             *paint_data,
				 void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;

  if (unlikely (!c->pending_clip_path))
    return;
  c->pending_clip_path = false;

  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (c->scratch_draw, &ext);
  if (unlikely (!blob || !c->sub_blobs.push_or_fail (blob)))
  {
    hb_blob_destroy (blob);
    c->unsupported = true;
    return;
  }
  int idx = (int) (c->sub_blobs.length - 1);

  int x0 = ext.x_bearing;
  int x1 = (int) ((int64_t) ext.x_bearing + ext.width);
  int y0 = ext.y_bearing;
  int y1 = (int) ((int64_t) ext.y_bearing + ext.height);

  c->clip_stack[c->clip_depth] = {
    HB_CODEPOINT_INVALID, nullptr,
    c->pending_clip_path_transform,
    idx,
    hb_min (x0, x1), hb_min (y0, y1),
    hb_max (x0, x1), hb_max (y0, y1),
  };
  c->clip_depth++;
}

static void
hb_gpu_paint_push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
			     void             *paint_data,
			     float xx, float yx,
			     float xy, float yy,
			     float dx, float dy,
			     void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  if (unlikely (!c->transform_stack.push_or_fail (c->cur_transform)))
  {
    c->unsupported = true;
    return;
  }
  hb_transform_t<float> t (xx, yx, xy, yy, dx, dy);
  c->cur_transform.multiply (t);  /* cur = cur * t */
}

static void
hb_gpu_paint_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
			    void             *paint_data,
			    void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  if (unlikely (!c->transform_stack.length))
    return;
  c->cur_transform = c->transform_stack.arrayZ[c->transform_stack.length - 1];
  c->transform_stack.shrink (c->transform_stack.length - 1);
}

/* Emit a 1-texel control op.  Used for PUSH_GROUP / POP_GROUP. */
static void
emit_control_op (hb_gpu_paint_t *c, int16_t op_type, int16_t aux)
{
  if (unlikely (c->num_ops >= HB_GPU_PAINT_MAX_OPS))
  {
    c->unsupported = true;
    return;
  }
  if (unlikely (!c->ops.resize (c->ops.length + 4)))
  {
    c->unsupported = true;
    return;
  }
  int16_t *o = &c->ops.arrayZ[c->ops.length - 4];
  o[0] = op_type;
  o[1] = aux;
  o[2] = 0;
  o[3] = 0;
  c->num_ops++;
}

static void
hb_gpu_paint_push_group (hb_paint_funcs_t *funcs HB_UNUSED,
			 void             *paint_data,
			 void             *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  c->group_depth++;
  if (unlikely (c->group_depth > HB_GPU_PAINT_MAX_GROUP_DEPTH))
  {
    c->unsupported = true;
    return;
  }
  emit_control_op (c, HB_GPU_PAINT_OP_PUSH_GROUP, 0);
}

static void
hb_gpu_paint_pop_group (hb_paint_funcs_t    *funcs HB_UNUSED,
			void                *paint_data,
			hb_paint_composite_mode_t mode,
			void                *user_data HB_UNUSED)
{
  hb_gpu_paint_t *c = (hb_gpu_paint_t *) paint_data;
  bool was_in_range = c->group_depth <= HB_GPU_PAINT_MAX_GROUP_DEPTH;
  if (likely (c->group_depth > 0)) c->group_depth--;
  if (was_in_range)
    emit_control_op (c, HB_GPU_PAINT_OP_POP_GROUP, (int16_t) mode);
}

/* Quantize unsigned byte 0..255 to signed Q15 0..32767. */
static inline int16_t
color_to_q15 (unsigned byte_value)
{
  return (int16_t) ((byte_value * 32767u + 127u) / 255u);
}

static inline void
color_to_q15_rgba (hb_color_t color, int16_t out[4])
{
  out[0] = color_to_q15 (hb_color_get_red   (color));
  out[1] = color_to_q15 (hb_color_get_green (color));
  out[2] = color_to_q15 (hb_color_get_blue  (color));
  out[3] = color_to_q15 (hb_color_get_alpha (color));
}

static inline int16_t
clamp_i16 (float v)
{
  if (v <= -32768.f) return -32768;
  if (v >=  32767.f) return  32767;
  return (int16_t) v;
}

/* Compute the 2x2 inverse of the transform's linear part, quantize
 * each entry to i16 Q10 (multiplier 1024) and write row-major into
 * @out: (m00, m01, m10, m11) such that applying it gives
 *   (M^-1 * v).x = m00 * v.x + m01 * v.y
 *   (M^-1 * v).y = m10 * v.x + m11 * v.y
 * Range [-32, 32), precision ~0.001 -- covers typical COLRv1
 * PaintTransform values with headroom.  Callers who need to skip
 * transforms for degenerate cases can check for is_identity before
 * doing the extra work in-shader, but we always emit so the format
 * stays uniform. */
static inline void
linv_q10 (const hb_transform_t<float> &t, int16_t out[4])
{
  float det = t.xx * t.yy - t.xy * t.yx;
  float inv = fabsf (det) > 1e-12f ? 1.0f / det : 0.0f;
  out[0] = clamp_i16 ( t.yy * inv * 1024.f);
  out[1] = clamp_i16 (-t.xy * inv * 1024.f);
  out[2] = clamp_i16 (-t.yx * inv * 1024.f);
  out[3] = clamp_i16 ( t.xx * inv * 1024.f);
}

/* Transforming pen: applies an affine transform to each outline
 * point before forwarding to a downstream hb_draw_funcs_t.  The
 * downstream's inline draw-state bookkeeping runs against a
 * separate state (down_st) so transformed-space updates don't
 * pollute the caller's pre-transform state. */
struct hb_gpu_paint_pen_t
{
  hb_transform_t<float> transform;
  hb_draw_funcs_t  *dfuncs;
  void             *data;
  hb_draw_state_t   down_st;
};

static void
hb_gpu_paint_pen_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
			  void *data, hb_draw_state_t *st HB_UNUSED,
			  float to_x, float to_y,
			  void *user_data HB_UNUSED)
{
  auto *c = (hb_gpu_paint_pen_t *) data;
  c->transform.transform_point (to_x, to_y);
  c->dfuncs->move_to (c->data, c->down_st, to_x, to_y);
}

static void
hb_gpu_paint_pen_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
			  void *data, hb_draw_state_t *st HB_UNUSED,
			  float to_x, float to_y,
			  void *user_data HB_UNUSED)
{
  auto *c = (hb_gpu_paint_pen_t *) data;
  c->transform.transform_point (to_x, to_y);
  c->dfuncs->line_to (c->data, c->down_st, to_x, to_y);
}

static void
hb_gpu_paint_pen_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
			       void *data, hb_draw_state_t *st HB_UNUSED,
			       float c_x, float c_y,
			       float to_x, float to_y,
			       void *user_data HB_UNUSED)
{
  auto *c = (hb_gpu_paint_pen_t *) data;
  c->transform.transform_point (c_x, c_y);
  c->transform.transform_point (to_x, to_y);
  c->dfuncs->quadratic_to (c->data, c->down_st, c_x, c_y, to_x, to_y);
}

static void
hb_gpu_paint_pen_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
			   void *data, hb_draw_state_t *st HB_UNUSED,
			   float c1_x, float c1_y,
			   float c2_x, float c2_y,
			   float to_x, float to_y,
			   void *user_data HB_UNUSED)
{
  auto *c = (hb_gpu_paint_pen_t *) data;
  c->transform.transform_point (c1_x, c1_y);
  c->transform.transform_point (c2_x, c2_y);
  c->transform.transform_point (to_x, to_y);
  c->dfuncs->cubic_to (c->data, c->down_st, c1_x, c1_y, c2_x, c2_y, to_x, to_y);
}

static void
hb_gpu_paint_pen_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
			     void *data, hb_draw_state_t *st HB_UNUSED,
			     void *user_data HB_UNUSED)
{
  auto *c = (hb_gpu_paint_pen_t *) data;
  c->dfuncs->close_path (c->data, c->down_st);
}

static inline void free_static_gpu_paint_pen_funcs ();

static struct hb_gpu_paint_pen_funcs_lazy_loader_t
  : hb_draw_funcs_lazy_loader_t<hb_gpu_paint_pen_funcs_lazy_loader_t>
{
  static hb_draw_funcs_t *create ()
  {
    hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
    hb_draw_funcs_set_move_to_func      (funcs, hb_gpu_paint_pen_move_to,      nullptr, nullptr);
    hb_draw_funcs_set_line_to_func      (funcs, hb_gpu_paint_pen_line_to,      nullptr, nullptr);
    hb_draw_funcs_set_quadratic_to_func (funcs, hb_gpu_paint_pen_quadratic_to, nullptr, nullptr);
    hb_draw_funcs_set_cubic_to_func     (funcs, hb_gpu_paint_pen_cubic_to,     nullptr, nullptr);
    hb_draw_funcs_set_close_path_func   (funcs, hb_gpu_paint_pen_close_path,   nullptr, nullptr);
    hb_draw_funcs_make_immutable (funcs);
    hb_atexit (free_static_gpu_paint_pen_funcs);
    return funcs;
  }
} static_gpu_paint_pen_funcs;

static inline void
free_static_gpu_paint_pen_funcs ()
{
  static_gpu_paint_pen_funcs.free_instance ();
}

/* Rasterize @clip's glyph outline into a new sub-blob and
 * accumulate its extents.  Returns the sub_blob index (>= 0) on
 * success, or -1 if the outline is empty / the layer should be
 * skipped.  Sets c->unsupported on hard failure.  On the first
 * successful glyph-clip encode, memoizes the sub-blob index and
 * extents back into @clip; subsequent calls hit the cache fast
 * path.  This matters for adversarial COLR trees that emit many
 * paint layers under the same clip stack -- without memoization
 * each layer re-rasterizes every clip glyph. */
static int
emit_clip_sub_blob (hb_gpu_paint_t *c,
		    hb_gpu_paint_t::pending_clip_t &clip)
{
  /* Path clips were already encoded into sub_blobs at
   * push_clip_path_end time; glyph clips are cached here on first
   * use.  Either way: just accumulate extents and hand back the
   * recorded index. */
  if (clip.sub_blob_index >= 0)
  {
    c->ext_min_x = hb_min (c->ext_min_x, clip.ext_x0);
    c->ext_max_x = hb_max (c->ext_max_x, clip.ext_x1);
    c->ext_min_y = hb_min (c->ext_min_y, clip.ext_y0);
    c->ext_max_y = hb_max (c->ext_max_y, clip.ext_y1);
    return clip.sub_blob_index;
  }

  /* Adversarial COLR trees can drive thousands of fresh
   * push_clip_glyph / paint_color cycles within a single paint
   * walk, each demanding a fresh sub-blob.  Bound the work. */
  if (unlikely (c->sub_blobs.length >= HB_GPU_PAINT_MAX_SUB_BLOBS))
  {
    c->unsupported = true;
    return -1;
  }

  if (unlikely (!c->scratch_draw))
  {
    c->scratch_draw = hb_gpu_draw_create_or_fail ();
    if (unlikely (!c->scratch_draw))
    {
      c->unsupported = true;
      return -1;
    }
  }
  hb_gpu_draw_clear (c->scratch_draw);

  bool ok;
  if (clip.transform.is_identity ())
  {
    /* Fast path: feed the glyph outline straight into the draw
     * encoder with no adapter. */
    ok = hb_gpu_draw_glyph_or_fail (c->scratch_draw, clip.font, clip.glyph);
  }
  else
  {
    /* Transform each outline point by the transform that was
     * current at push_clip_glyph time -- NOT the innermost
     * cur_transform, which may have additional PaintTransform
     * wrappers from the paint child underneath. */
    int x_scale, y_scale;
    hb_font_get_scale (clip.font, &x_scale, &y_scale);
    hb_gpu_draw_set_scale (c->scratch_draw, x_scale, y_scale);

    hb_gpu_paint_pen_t pen = {};
    pen.transform = clip.transform;
    pen.dfuncs    = hb_gpu_draw_get_funcs (c->scratch_draw);
    pen.data      = c->scratch_draw;
    pen.down_st   = HB_DRAW_STATE_DEFAULT;
    ok = hb_font_draw_glyph_or_fail (clip.font, clip.glyph,
				     static_gpu_paint_pen_funcs.get_unconst (),
				     &pen);
    /* Close any trailing open path on the downstream state, since
     * hb_font_draw_glyph_or_fail only closes via our pen's state. */
    pen.dfuncs->close_path (pen.data, pen.down_st);
  }
  if (!ok)
    return -1;  /* Clip glyph has no outline -- skip. */

  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (c->scratch_draw, &ext);
  if (unlikely (!blob || !c->sub_blobs.push_or_fail (blob)))
  {
    hb_blob_destroy (blob);
    c->unsupported = true;
    return -1;
  }

  /* Accumulate extents: x_bearing/y_bearing are top-left, width
   * positive, height negative (growing down). */
  int x0 = ext.x_bearing;
  int x1 = (int) ((int64_t) ext.x_bearing + ext.width);
  int y0 = ext.y_bearing;
  int y1 = (int) ((int64_t) ext.y_bearing + ext.height);
  c->ext_min_x = hb_min (c->ext_min_x, hb_min (x0, x1));
  c->ext_max_x = hb_max (c->ext_max_x, hb_max (x0, x1));
  c->ext_min_y = hb_min (c->ext_min_y, hb_min (y0, y1));
  c->ext_max_y = hb_max (c->ext_max_y, hb_max (y0, y1));

  int idx = (int) (c->sub_blobs.length - 1);

  /* Memoize on the slot.  The (glyph, font, transform) tuple is
   * fixed between push_clip_glyph and pop_clip, and pop_clip's
   * subsequent push reinitializes the slot to sub_blob_index = -1,
   * so a stale cache cannot leak across pushes. */
  clip.sub_blob_index = idx;
  clip.ext_x0 = hb_min (x0, x1);
  clip.ext_y0 = hb_min (y0, y1);
  clip.ext_x1 = hb_max (x0, x1);
  clip.ext_y1 = hb_max (y0, y1);

  return idx;
}

/* Emit a sub-blob for every clip currently on the stack and return
 * their indices in @out (set to -1 for unused slots).  Returns
 * false if any clip's outline is empty (caller should skip the
 * layer entirely) or hb_gpu_draw_encode failed. */
static bool
emit_all_clip_sub_blobs (hb_gpu_paint_t *c, int out[HB_GPU_PAINT_MAX_CLIP_DEPTH])
{
  for (unsigned i = 0; i < HB_GPU_PAINT_MAX_CLIP_DEPTH; i++)
    out[i] = -1;
  for (unsigned i = 0; i < hb_min (c->clip_depth, (unsigned) HB_GPU_PAINT_MAX_CLIP_DEPTH); i++)
  {
    out[i] = emit_clip_sub_blob (c, c->clip_stack[i]);
    if (out[i] < 0)
      return false;
  }
  return true;
}

/* Emit a 3-texel LAYER_GRADIENT op header (excluding the
 * gradient-meta texel which the caller fills in).  @subtype is
 * 0 = linear, 1 = radial, 2 = sweep. */
static int16_t *
emit_gradient_op_header (hb_gpu_paint_t *c, unsigned subtype,
			 const int clip_idx[HB_GPU_PAINT_MAX_CLIP_DEPTH])
{
  if (unlikely (!c->ops.resize (c->ops.length + 12)))
  { c->unsupported = true; return nullptr; }
  int16_t *o = &c->ops.arrayZ[c->ops.length - 12];
  int16_t flags = (int16_t) subtype;
  if (clip_idx[1] >= 0) flags |= HB_GPU_PAINT_FLAG_HAS_CLIP2;
  if (clip_idx[2] >= 0) flags |= HB_GPU_PAINT_FLAG_HAS_CLIP3;
  o[0] = HB_GPU_PAINT_OP_LAYER_GRADIENT;
  o[1] = flags;
  o[2] = (int16_t) ((clip_idx[0] >> 16) & 0xffff);
  o[3] = (int16_t) (clip_idx[0] & 0xffff);
  o[4] = clip_idx[1] >= 0 ? (int16_t) ((clip_idx[1] >> 16) & 0xffff) : 0;
  o[5] = clip_idx[1] >= 0 ? (int16_t) (clip_idx[1] & 0xffff) : 0;
  o[6] = clip_idx[2] >= 0 ? (int16_t) ((clip_idx[2] >> 16) & 0xffff) : 0;
  o[7] = clip_idx[2] >= 0 ? (int16_t) (clip_idx[2] & 0xffff) : 0;
  return o + 8;  /* texel 2: gradient meta -- caller fills */
}

static void
hb_gpu_paint_emit_solid (hb_gpu_paint_t *c,
			 hb_bool_t       is_foreground,
			 hb_color_t      color)
{
  if (unlikely (c->unsupported))
    return;
  if (unlikely (c->clip_depth == 0))
    return;
  if (unlikely (c->num_ops >= HB_GPU_PAINT_MAX_OPS))
  {
    c->unsupported = true;
    return;
  }

  int clip_idx[HB_GPU_PAINT_MAX_CLIP_DEPTH];
  if (!emit_all_clip_sub_blobs (c, clip_idx))
    return;

  /* Emit LAYER_SOLID op: 3 texels (12 int16s).
   *   texel 0: op_type, flags, clip1_hi, clip1_lo
   *   texel 1: clip2_hi, clip2_lo, 0, 0  (only meaningful if HAS_CLIP2)
   *   texel 2: r_q15, g_q15, b_q15, a_q15
   * Payloads hold sub_blob indices; hb_gpu_paint_encode() patches
   * them into texel offsets at serialize time.
   * flags bit 0: use shader foreground uniform instead of the
   * baked color (so runtime foreground-color changes still work).
   * flags bit 8: a second clip outline is present in texel 1. */
  if (unlikely (!c->ops.resize (c->ops.length + 12)))
  {
    c->unsupported = true;
    return;
  }
  int16_t *o = &c->ops.arrayZ[c->ops.length - 12];
  int16_t flags = (int16_t) (is_foreground ? HB_GPU_PAINT_FLAG_IS_FOREGROUND : 0);
  if (clip_idx[1] >= 0) flags |= HB_GPU_PAINT_FLAG_HAS_CLIP2;
  if (clip_idx[2] >= 0) flags |= HB_GPU_PAINT_FLAG_HAS_CLIP3;
  o[0] = HB_GPU_PAINT_OP_LAYER_SOLID;
  o[1] = flags;
  o[2] = (int16_t) ((clip_idx[0] >> 16) & 0xffff);
  o[3] = (int16_t) (clip_idx[0] & 0xffff);
  o[4] = clip_idx[1] >= 0 ? (int16_t) ((clip_idx[1] >> 16) & 0xffff) : 0;
  o[5] = clip_idx[1] >= 0 ? (int16_t) (clip_idx[1] & 0xffff) : 0;
  o[6] = clip_idx[2] >= 0 ? (int16_t) ((clip_idx[2] >> 16) & 0xffff) : 0;
  o[7] = clip_idx[2] >= 0 ? (int16_t) (clip_idx[2] & 0xffff) : 0;
  color_to_q15_rgba (color, o + 8);
  c->num_ops++;
}

/* Append a color line (@count stops) to @grad_data in the encoded
 * stop format used by gradient ops: 2 texels per stop.
 *   texel a: (offset_q15, flags, _, _) with flags bit 0 = is_foreground
 *   texel b: (r_q15, g_q15, b_q15, a_q15)
 * Returns false on allocation failure. */
static bool
append_color_stops (hb_vector_t<int16_t> &grad_data,
		    const hb_color_stop_t *stops,
		    unsigned count)
{
  unsigned base = grad_data.length;
  if (unlikely (!grad_data.resize (base + count * 8)))
    return false;
  int16_t *p = grad_data.arrayZ + base;
  for (unsigned i = 0; i < count; i++)
  {
    float off = stops[i].offset;
    if (off < -1.f) off = -1.f;
    else if (off > 1.f) off = 1.f;
    p[0] = (int16_t) (off * 32767.f);
    p[1] = (int16_t) (stops[i].is_foreground ? 1 : 0);
    p[2] = 0;
    p[3] = 0;
    color_to_q15_rgba (stops[i].color, p + 4);
    p += 8;
  }
  return true;
}

static void
hb_gpu_paint_emit_linear (hb_gpu_paint_t  *c,
			  hb_color_line_t *color_line,
			  float x0, float y0,
			  float x1, float y1,
			  float x2, float y2)
{
  if (unlikely (c->unsupported))
    return;
  if (unlikely (c->clip_depth == 0))
    return;
  if (unlikely (c->num_ops >= HB_GPU_PAINT_MAX_OPS))
  {
    c->unsupported = true;
    return;
  }

  /* Resolve stops (triggers custom_palette_color, etc). */
  if (unlikely (!c->fetch_color_stops (color_line)))
    return;
  hb_color_stop_t *stops = c->color_stops_scratch.arrayZ;
  unsigned got = c->color_stops_scratch.length;

  hb_paint_extend_t extend = hb_color_line_get_extend (color_line);

  /* Emit clip sub-blob(s) first. */
  int clip_idx[HB_GPU_PAINT_MAX_CLIP_DEPTH];
  if (!emit_all_clip_sub_blobs (c, clip_idx)) return;

  /* Build gradient params sub-blob.
   *   texel 0: (p0_rendered_x, p0_rendered_y, d_canonical_x, d_canonical_y)
   *     i16 font units; d = p1 - p0 stored in untransformed space
   *   texel 1: L^-1 as 4 i16 Q10 (row-major)
   *   texels 2..N: color stops (2 texels each)
   * The shader computes p_canonical = L^-1 * (renderCoord - p0_rendered)
   * and evaluates t = dot(p_canonical, d) / dot(d, d) in
   * untransformed space, so affine distortions of the axis are
   * handled exactly rather than approximated. */
  hb_vector_t<int16_t> grad_data;
  if (unlikely (!grad_data.resize (8)))
  { c->unsupported = true; return; }

  float lx0, ly0, lx1, ly1;
  hb_paint_reduce_linear_anchors (x0, y0, x1, y1, x2, y2, &lx0, &ly0, &lx1, &ly1);
  /* Normalize stops to [0,1]; shift axis endpoints to compensate. */
  float mn, mx;
  hb_paint_normalize_color_line (stops, got, &mn, &mx);
  float dx = lx1 - lx0, dy = ly1 - ly0;
  float ax0 = lx0 + mn * dx, ay0 = ly0 + mn * dy;
  float ax1 = lx0 + mx * dx, ay1 = ly0 + mx * dy;
  /* p0 in rendered space; d in untransformed space. */
  float p0x_r = ax0, p0y_r = ay0;
  c->cur_transform.transform_point (p0x_r, p0y_r);
  grad_data[0] = clamp_i16 (p0x_r);
  grad_data[1] = clamp_i16 (p0y_r);
  grad_data[2] = clamp_i16 (ax1 - ax0);
  grad_data[3] = clamp_i16 (ay1 - ay0);
  int16_t Linv[4];
  linv_q10 (c->cur_transform, Linv);
  grad_data[4] = Linv[0];
  grad_data[5] = Linv[1];
  grad_data[6] = Linv[2];
  grad_data[7] = Linv[3];

  if (unlikely (!append_color_stops (grad_data, stops, got)))
  { c->unsupported = true; return; }

  unsigned grad_bytes = grad_data.length * sizeof (int16_t);
  hb_blob_t *grad_blob = hb_blob_create ((const char *) grad_data.arrayZ,
					 grad_bytes, HB_MEMORY_MODE_DUPLICATE,
					 nullptr, nullptr);
  if (unlikely (!grad_blob || !c->sub_blobs.push_or_fail (grad_blob)))
  {
    hb_blob_destroy (grad_blob);
    c->unsupported = true;
    return;
  }
  unsigned grad_idx = c->sub_blobs.length - 1;

  int16_t *meta = emit_gradient_op_header (c, 0 /* linear */, clip_idx);
  if (unlikely (!meta)) return;
  meta[0] = (int16_t) ((grad_idx >> 16) & 0xffff);
  meta[1] = (int16_t) (grad_idx & 0xffff);
  meta[2] = (int16_t) extend;
  meta[3] = (int16_t) got;
  c->num_ops++;
}

static void
hb_gpu_paint_emit_radial (hb_gpu_paint_t  *c,
			  hb_color_line_t *color_line,
			  float x0, float y0, float r0,
			  float x1, float y1, float r1)
{
  if (unlikely (c->unsupported))
    return;
  if (unlikely (c->clip_depth == 0))
    return;
  if (unlikely (c->num_ops >= HB_GPU_PAINT_MAX_OPS))
  {
    c->unsupported = true;
    return;
  }

  if (unlikely (!c->fetch_color_stops (color_line)))
    return;
  hb_color_stop_t *stops = c->color_stops_scratch.arrayZ;
  unsigned got = c->color_stops_scratch.length;

  hb_paint_extend_t extend = hb_color_line_get_extend (color_line);

  int clip_idx[HB_GPU_PAINT_MAX_CLIP_DEPTH];
  if (!emit_all_clip_sub_blobs (c, clip_idx)) return;

  /* Build gradient params sub-blob.
   *   texel 0: (c0_rendered_x, c0_rendered_y, d_canonical_x, d_canonical_y)
   *     where d = c1 - c0 in untransformed space
   *   texel 1: (r0, r1, _, _) in untransformed font units (i16)
   *   texel 2: L^-1 as 4 i16 Q10 (row-major)
   *   texels 3..N: color stops (2 texels each)
   * Shader computes p_canonical = L^-1 * (renderCoord - c0_rendered)
   * then solves |p - t*d|^2 = (r0 + t*(r1-r0))^2 in the
   * untransformed frame, so non-uniform scale / shear (which would
   * turn the circle into an ellipse in rendered space) is handled
   * exactly.
   */
  hb_vector_t<int16_t> grad_data;
  if (unlikely (!grad_data.resize (12)))
  { c->unsupported = true; return; }
  float mn, mx;
  hb_paint_normalize_color_line (stops, got, &mn, &mx);
  float dx = x1 - x0, dy = y1 - y0, dr = r1 - r0;
  float cx0 = x0 + mn * dx, cy0 = y0 + mn * dy, cr0 = r0 + mn * dr;
  float cx1 = x0 + mx * dx, cy1 = y0 + mx * dy, cr1 = r0 + mx * dr;
  /* c0 in rendered space; d (= c1 - c0) and radii in untransformed. */
  float cx0_r = cx0, cy0_r = cy0;
  c->cur_transform.transform_point (cx0_r, cy0_r);
  grad_data[0] = clamp_i16 (cx0_r);
  grad_data[1] = clamp_i16 (cy0_r);
  grad_data[2] = clamp_i16 (cx1 - cx0);
  grad_data[3] = clamp_i16 (cy1 - cy0);
  grad_data[4] = clamp_i16 (cr0);
  grad_data[5] = clamp_i16 (cr1);
  grad_data[6] = 0;
  grad_data[7] = 0;
  int16_t Linv[4];
  linv_q10 (c->cur_transform, Linv);
  grad_data[8]  = Linv[0];
  grad_data[9]  = Linv[1];
  grad_data[10] = Linv[2];
  grad_data[11] = Linv[3];

  if (unlikely (!append_color_stops (grad_data, stops, got)))
  { c->unsupported = true; return; }

  unsigned grad_bytes = grad_data.length * sizeof (int16_t);
  hb_blob_t *grad_blob = hb_blob_create ((const char *) grad_data.arrayZ,
					 grad_bytes, HB_MEMORY_MODE_DUPLICATE,
					 nullptr, nullptr);
  if (unlikely (!grad_blob || !c->sub_blobs.push_or_fail (grad_blob)))
  {
    hb_blob_destroy (grad_blob);
    c->unsupported = true;
    return;
  }
  unsigned grad_idx = c->sub_blobs.length - 1;

  int16_t *meta = emit_gradient_op_header (c, 1 /* radial */, clip_idx);
  if (unlikely (!meta)) return;
  meta[0] = (int16_t) ((grad_idx >> 16) & 0xffff);
  meta[1] = (int16_t) (grad_idx & 0xffff);
  meta[2] = (int16_t) extend;
  meta[3] = (int16_t) got;
  c->num_ops++;
}

static void
hb_gpu_paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
		    void             *paint_data,
		    hb_bool_t         is_foreground,
		    hb_color_t        color,
		    void             *user_data HB_UNUSED)
{
  hb_gpu_paint_emit_solid ((hb_gpu_paint_t *) paint_data, is_foreground, color);
}

static void
hb_gpu_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
			      void             *paint_data,
			      hb_color_line_t  *color_line,
			      float x0, float y0,
			      float x1, float y1,
			      float x2, float y2,
			      void             *user_data HB_UNUSED)
{
  hb_gpu_paint_emit_linear ((hb_gpu_paint_t *) paint_data, color_line,
			    x0, y0, x1, y1, x2, y2);
}

static void
hb_gpu_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
			      void             *paint_data,
			      hb_color_line_t  *color_line,
			      float x0, float y0, float r0,
			      float x1, float y1, float r1,
			      void             *user_data HB_UNUSED)
{
  hb_gpu_paint_emit_radial ((hb_gpu_paint_t *) paint_data, color_line,
			    x0, y0, r0, x1, y1, r1);
}

static void
hb_gpu_paint_emit_sweep (hb_gpu_paint_t  *c,
			 hb_color_line_t *color_line,
			 float cx, float cy,
			 float start_angle, float end_angle)
{
  if (unlikely (c->unsupported))
    return;
  if (unlikely (c->clip_depth == 0))
    return;
  if (unlikely (c->num_ops >= HB_GPU_PAINT_MAX_OPS))
  {
    c->unsupported = true;
    return;
  }

  unsigned count = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
  if (unlikely (!count))
    return;
  hb_color_stop_t stack_stops[16];
  hb_color_stop_t *stops = stack_stops;
  hb_color_stop_t *heap_stops = nullptr;
  if (count > 16)
  {
    heap_stops = (hb_color_stop_t *) hb_malloc (count * sizeof (hb_color_stop_t));
    if (unlikely (!heap_stops)) { c->unsupported = true; return; }
    stops = heap_stops;
  }
  unsigned got = count;
  hb_color_line_get_color_stops (color_line, 0, &got, stops);

  hb_paint_extend_t extend = hb_color_line_get_extend (color_line);

  int clip_idx[HB_GPU_PAINT_MAX_CLIP_DEPTH];
  if (!emit_all_clip_sub_blobs (c, clip_idx)) { hb_free (heap_stops); return; }

  /* Build gradient params sub-blob.
   *   texel 0: (center_rendered_x, center_rendered_y,
   *             start_q14, end_q14)
   *     angles in radians, stored as Q14 fractions of pi; start/end
   *     stay in untransformed space (no rotation baked in).
   *   texel 1: L^-1 as 4 i16 Q10 (row-major)
   *   texels 2..N: color stops (2 texels each)
   * Shader does p = L^-1 * (renderCoord - center_rendered) and
   * atan2 on p, so non-uniform scale / shear angular distortion is
   * handled exactly.
   */
  hb_vector_t<int16_t> grad_data;
  if (unlikely (!grad_data.resize (8)))
  { c->unsupported = true; hb_free (heap_stops); return; }

  float mn, mx;
  hb_paint_normalize_color_line (stops, got, &mn, &mx);
  float a_span = end_angle - start_angle;
  float a_lo = start_angle + mn * a_span;
  float a_hi = start_angle + mx * a_span;
  auto rad_to_q14_pi = [] (float rad) -> int16_t {
    float v = rad * (float) (1.0 / M_PI);  /* fraction of pi */
    if (v <= -2.f) return -32768;
    if (v >=  2.f) return  32767;
    return (int16_t) (v * 16384.f);
  };
  /* center in rendered space; angles stay canonical. */
  float tcx = cx, tcy = cy;
  c->cur_transform.transform_point (tcx, tcy);
  grad_data[0] = clamp_i16 (tcx);
  grad_data[1] = clamp_i16 (tcy);
  grad_data[2] = rad_to_q14_pi (a_lo);
  grad_data[3] = rad_to_q14_pi (a_hi);
  int16_t Linv[4];
  linv_q10 (c->cur_transform, Linv);
  grad_data[4] = Linv[0];
  grad_data[5] = Linv[1];
  grad_data[6] = Linv[2];
  grad_data[7] = Linv[3];

  if (unlikely (!append_color_stops (grad_data, stops, got)))
  { c->unsupported = true; hb_free (heap_stops); return; }
  hb_free (heap_stops);

  unsigned grad_bytes = grad_data.length * sizeof (int16_t);
  hb_blob_t *grad_blob = hb_blob_create ((const char *) grad_data.arrayZ,
					 grad_bytes, HB_MEMORY_MODE_DUPLICATE,
					 nullptr, nullptr);
  if (unlikely (!grad_blob || !c->sub_blobs.push_or_fail (grad_blob)))
  {
    hb_blob_destroy (grad_blob);
    c->unsupported = true;
    return;
  }
  unsigned grad_idx = c->sub_blobs.length - 1;

  int16_t *meta = emit_gradient_op_header (c, 2 /* sweep */, clip_idx);
  if (unlikely (!meta)) return;
  meta[0] = (int16_t) ((grad_idx >> 16) & 0xffff);
  meta[1] = (int16_t) (grad_idx & 0xffff);
  meta[2] = (int16_t) extend;
  meta[3] = (int16_t) got;
  c->num_ops++;
}

static void
hb_gpu_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
			     void             *paint_data,
			     hb_color_line_t  *color_line,
			     float cx, float cy,
			     float start_angle,
			     float end_angle,
			     void             *user_data HB_UNUSED)
{
  hb_gpu_paint_emit_sweep ((hb_gpu_paint_t *) paint_data, color_line,
			   cx, cy, start_angle, end_angle);
}

/* PaintImage isn't representable by our slug+gradient encoder; mark
 * unsupported so the caller learns the glyph won't render rather
 * than getting a partial blob.  PaintRectangleClip is intentionally
 * left to the default no-op: the encoder simply ignores the
 * rectangle (output is bigger than it should be, but renders). */
static hb_bool_t
hb_gpu_paint_image (hb_paint_funcs_t   *funcs   HB_UNUSED,
		    void               *paint_data,
		    hb_blob_t          *image   HB_UNUSED,
		    unsigned int        width   HB_UNUSED,
		    unsigned int        height  HB_UNUSED,
		    hb_tag_t            format  HB_UNUSED,
		    float               slant   HB_UNUSED,
		    hb_glyph_extents_t *extents HB_UNUSED,
		    void               *user_data HB_UNUSED)
{
  ((hb_gpu_paint_t *) paint_data)->unsupported = true;
  return false;
}

static inline void free_static_gpu_paint_funcs ();

static struct hb_gpu_paint_funcs_lazy_loader_t
  : hb_paint_funcs_lazy_loader_t<hb_gpu_paint_funcs_lazy_loader_t>
{
  static hb_paint_funcs_t *create ()
  {
    hb_paint_funcs_t *funcs = hb_paint_funcs_create ();

    hb_paint_funcs_set_push_transform_func        (funcs, hb_gpu_paint_push_transform,        nullptr, nullptr);
    hb_paint_funcs_set_pop_transform_func         (funcs, hb_gpu_paint_pop_transform,         nullptr, nullptr);
    hb_paint_funcs_set_push_clip_glyph_func       (funcs, hb_gpu_paint_push_clip_glyph,       nullptr, nullptr);
    hb_paint_funcs_set_push_clip_path_start_func  (funcs, hb_gpu_paint_push_clip_path_start,  nullptr, nullptr);
    hb_paint_funcs_set_push_clip_path_end_func    (funcs, hb_gpu_paint_push_clip_path_end,    nullptr, nullptr);
    hb_paint_funcs_set_pop_clip_func              (funcs, hb_gpu_paint_pop_clip,              nullptr, nullptr);
    hb_paint_funcs_set_push_group_func            (funcs, hb_gpu_paint_push_group,            nullptr, nullptr);
    hb_paint_funcs_set_pop_group_func             (funcs, hb_gpu_paint_pop_group,             nullptr, nullptr);
    hb_paint_funcs_set_color_func                 (funcs, hb_gpu_paint_color,                 nullptr, nullptr);
    hb_paint_funcs_set_linear_gradient_func       (funcs, hb_gpu_paint_linear_gradient,       nullptr, nullptr);
    hb_paint_funcs_set_radial_gradient_func       (funcs, hb_gpu_paint_radial_gradient,       nullptr, nullptr);
    hb_paint_funcs_set_sweep_gradient_func        (funcs, hb_gpu_paint_sweep_gradient,        nullptr, nullptr);
    hb_paint_funcs_set_custom_palette_color_func  (funcs, hb_gpu_paint_custom_palette_color,  nullptr, nullptr);
    /* PaintImage can't be represented by our slug+gradient encoder. */
    hb_paint_funcs_set_image_func                 (funcs, hb_gpu_paint_image,                 nullptr, nullptr);

    hb_paint_funcs_make_immutable (funcs);

    hb_atexit (free_static_gpu_paint_funcs);

    return funcs;
  }
} static_gpu_paint_funcs;

static inline void
free_static_gpu_paint_funcs ()
{
  static_gpu_paint_funcs.free_instance ();
}


/* ---- Public API ---- */

/**
 * hb_gpu_paint_create_or_fail:
 *
 * Creates a new GPU color-glyph paint encoder.
 *
 * Return value: (transfer full):
 * A newly allocated #hb_gpu_paint_t, or `NULL` on allocation
 * failure.
 *
 * Since: 14.2.0
 **/
hb_gpu_paint_t *
hb_gpu_paint_create_or_fail (void)
{
  return hb_object_create<hb_gpu_paint_t> ();
}

/**
 * hb_gpu_paint_reference: (skip)
 * @paint: a GPU color-glyph paint encoder
 *
 * Increases the reference count on @paint by one.
 *
 * Return value: (transfer full):
 * The referenced #hb_gpu_paint_t.
 *
 * Since: 14.2.0
 **/
hb_gpu_paint_t *
hb_gpu_paint_reference (hb_gpu_paint_t *paint)
{
  return hb_object_reference (paint);
}

/**
 * hb_gpu_paint_destroy: (skip)
 * @paint: a GPU color-glyph paint encoder
 *
 * Decreases the reference count on @paint by one.  When the
 * reference count reaches zero, the encoder is freed.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_destroy (hb_gpu_paint_t *paint)
{
  if (!hb_object_should_destroy (paint))
    return;

  hb_map_destroy (paint->custom_palette);
  for (hb_blob_t *b : paint->sub_blobs)
    hb_blob_destroy (b);
  hb_gpu_draw_destroy (paint->scratch_draw);
  hb_blob_destroy (paint->recycled_blob);

  hb_object_actually_destroy (paint);
  hb_free (paint);
}

/**
 * hb_gpu_paint_set_user_data: (skip)
 * @paint: a GPU color-glyph paint encoder
 * @key: the user-data key
 * @data: a pointer to the user data
 * @destroy: (nullable): a callback to call when @data is not needed anymore
 * @replace: whether to replace an existing data with the same key
 *
 * Attaches user data to @paint.
 *
 * Return value: `true` if success, `false` otherwise
 *
 * Since: 14.2.0
 **/
hb_bool_t
hb_gpu_paint_set_user_data (hb_gpu_paint_t     *paint,
			    hb_user_data_key_t *key,
			    void               *data,
			    hb_destroy_func_t   destroy,
			    hb_bool_t           replace)
{
  return hb_object_set_user_data (paint, key, data, destroy, replace);
}

/**
 * hb_gpu_paint_get_user_data: (skip)
 * @paint: a GPU color-glyph paint encoder
 * @key: the user-data key
 *
 * Fetches the user data associated with the specified key.
 *
 * Return value: (transfer none):
 * A pointer to the user data.
 *
 * Since: 14.2.0
 **/
void *
hb_gpu_paint_get_user_data (const hb_gpu_paint_t *paint,
			    hb_user_data_key_t   *key)
{
  return hb_object_get_user_data (paint, key);
}

/**
 * hb_gpu_paint_get_funcs:
 * @paint: a GPU paint context.
 *
 * Fetches the #hb_paint_funcs_t that feeds paint data into
 * @paint.  Pass @paint as the @paint_data argument when
 * calling the paint functions.
 *
 * Return value: (transfer none):
 * The GPU paint functions
 *
 * Since: 14.2.0
 **/
hb_paint_funcs_t *
hb_gpu_paint_get_funcs (const hb_gpu_paint_t *paint HB_UNUSED)
{
  return static_gpu_paint_funcs.get_unconst ();
}

/**
 * hb_gpu_paint_set_palette:
 * @paint: a GPU color-glyph paint encoder
 * @palette: palette index
 *
 * Selects which font palette is used when paint callbacks look up
 * indexed colors.  Default is palette 0.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_set_palette (hb_gpu_paint_t *paint,
			  unsigned        palette)
{
  paint->palette = palette;
}

/**
 * hb_gpu_paint_get_palette:
 * @paint: a GPU color-glyph paint encoder
 *
 * Returns the palette index previously set on @paint, or 0 if none
 * was set.
 *
 * Return value: the palette index.
 *
 * Since: 14.2.0
 **/
unsigned
hb_gpu_paint_get_palette (const hb_gpu_paint_t *paint)
{
  return paint->palette;
}

/**
 * hb_gpu_paint_clear_custom_palette_colors:
 * @paint: a GPU color-glyph paint encoder
 *
 * Clears all custom palette color overrides previously set on @paint.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_clear_custom_palette_colors (hb_gpu_paint_t *paint)
{
  if (paint->custom_palette)
    hb_map_clear (paint->custom_palette);
}

/**
 * hb_gpu_paint_set_custom_palette_color:
 * @paint: a GPU color-glyph paint encoder
 * @color_index: palette index to override
 * @color: replacement color
 *
 * Overrides one font palette color entry.  Overrides are keyed by
 * @color_index and persist on @paint until cleared (or replaced for
 * the same index).
 *
 * Return value: `true` if the override was set; `false` on allocation failure.
 *
 * Since: 14.2.0
 **/
hb_bool_t
hb_gpu_paint_set_custom_palette_color (hb_gpu_paint_t *paint,
				       unsigned int    color_index,
				       hb_color_t      color)
{
  if (unlikely (!paint->custom_palette))
  {
    paint->custom_palette = hb_map_create ();
    if (unlikely (!paint->custom_palette))
      return false;
  }
  hb_map_set (paint->custom_palette, color_index, color);
  return hb_map_allocation_successful (paint->custom_palette);
}

/**
 * hb_gpu_paint_set_scale:
 * @paint: a GPU color-glyph paint encoder
 * @x_scale: horizontal scale (typically from hb_font_get_scale())
 * @y_scale: vertical scale
 *
 * Sets the font scale used to dimension clip-glyph slug outlines
 * inside the encoded blob.  Called automatically by
 * hb_gpu_paint_glyph().
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_set_scale (hb_gpu_paint_t *paint,
			int             x_scale,
			int             y_scale)
{
  paint->x_scale = x_scale;
  paint->y_scale = y_scale;
}

/**
 * hb_gpu_paint_get_scale:
 * @paint: a GPU color-glyph paint encoder
 * @x_scale: (out): horizontal scale
 * @y_scale: (out): vertical scale
 *
 * Fetches the font scale previously set on @paint.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_get_scale (const hb_gpu_paint_t *paint,
			int                  *x_scale,
			int                  *y_scale)
{
  if (x_scale) *x_scale = paint->x_scale;
  if (y_scale) *y_scale = paint->y_scale;
}

/**
 * hb_gpu_paint_glyph_or_fail:
 * @paint: a GPU color-glyph paint encoder
 * @font: font to paint from
 * @glyph: glyph ID to paint
 *
 * Convenience to feed @glyph's paint tree into the encoder.
 * Equivalent to:
 *
 * |[<!-- language="plain" -->
 * hb_gpu_paint_set_scale (paint, x_scale, y_scale);
 * hb_font_paint_glyph_or_fail (font, glyph,
 *   hb_gpu_paint_get_funcs (paint), paint,
 *   palette, HB_COLOR (0, 0, 0, 0xff));
 * ]|
 *
 * Encoder-level limitations (unsupported paint ops, group-stack
 * overflow) do NOT fail here -- they surface later from
 * hb_gpu_paint_encode() which returns `NULL`.
 *
 * Return value: `true` if the font had paint data for @glyph,
 * `false` otherwise.
 *
 * Since: 14.2.0
 **/
hb_bool_t
hb_gpu_paint_glyph_or_fail (hb_gpu_paint_t *paint,
			    hb_font_t      *font,
			    hb_codepoint_t  glyph)
{
  int x_scale, y_scale;
  hb_font_get_scale (font, &x_scale, &y_scale);
  hb_gpu_paint_set_scale (paint, x_scale, y_scale);
  return hb_font_paint_glyph_or_fail (font, glyph,
				      hb_gpu_paint_get_funcs (paint), paint,
				      paint->palette,
				      /* Foreground RGB is not read from
				       * the encoded blob -- the
				       * is_foreground flag routes to the
				       * shader's foreground uniform.
				       * Alpha must be opaque so the
				       * baked color carries only the
				       * paint-tree alpha (which the
				       * shader applies on top of the
				       * uniform). */
				      HB_COLOR (0, 0, 0, 0xff));
}

/**
 * hb_gpu_paint_glyph:
 * @paint: a GPU color-glyph paint encoder
 * @font: font to paint from
 * @glyph: glyph ID to paint
 *
 * Feeds @glyph into the encoder.  Unlike
 * hb_gpu_paint_glyph_or_fail(), non-color glyphs are handled
 * transparently via a synthesized foreground-colored layer,
 * so any glyph with an outline produces output.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_glyph (hb_gpu_paint_t *paint,
		    hb_font_t      *font,
		    hb_codepoint_t  glyph)
{
  int x_scale, y_scale;
  hb_font_get_scale (font, &x_scale, &y_scale);
  hb_gpu_paint_set_scale (paint, x_scale, y_scale);
  hb_font_paint_glyph (font, glyph,
		       hb_gpu_paint_get_funcs (paint), paint,
		       paint->palette,
		       /* Foreground RGB is not read from
		        * the encoded blob -- the
		        * is_foreground flag routes to the
		        * shader's foreground uniform.
		        * Alpha must be opaque so the
		        * baked color carries only the
		        * paint-tree alpha (which the
		        * shader applies on top of the
		        * uniform). */
		       HB_COLOR (0, 0, 0, 0xff));
}

/**
 * hb_gpu_paint_encode:
 * @paint: a GPU color-glyph paint encoder
 * @extents: (out): receives the glyph's ink extents in font units
 *
 * Encodes the accumulated paint state into a GPU-renderable blob
 * and writes the glyph's ink extents to @extents.
 *
 * On return @paint is auto-cleared so it can be reused for the
 * next glyph; user configuration (palette, foreground, custom
 * palette overrides) is preserved.
 *
 * Return value: (transfer full):
 * A newly allocated blob, or `NULL` if the paint walk hit an
 * unsupported feature (see hb_gpu_paint_glyph()'s return value) or
 * encoding failed (allocation failure).  When the paint accumulated
 * no ink (e.g. a space glyph) returns the empty-blob singleton, so
 * callers can distinguish "nothing to render" (length 0) from a
 * real failure (`NULL`).
 *
 * Since: 14.2.0
 **/
hb_blob_t *
hb_gpu_paint_encode (hb_gpu_paint_t     *paint,
		     hb_glyph_extents_t *extents)
{
  HB_SCOPE_GUARD (hb_gpu_paint_clear (paint));

  if (unlikely (paint->unsupported))
    return nullptr;
  /* No ink (e.g. space glyph): return the empty-blob singleton, not
   * nullptr.  Same convention as hb_gpu_draw_encode(); callers can
   * distinguish "nothing to render" (length 0) from "encoder
   * failed" (NULL). */
  if (paint->num_ops == 0)
    return hb_blob_get_empty ();

  /* Layout:
   *   header          (3 texels = 24 bytes)
   *   op stream       (ops.length i16 words, multiple of 4)
   *   sub-payloads    (concat of each sub_blob's data, 8-byte
   *                    aligned since draw blobs are RGBA16I)
   */
  const unsigned header_texels = 3;
  const unsigned texel_bytes   = 8;

  unsigned ops_texels = paint->ops.length / 4;
  unsigned sub_bytes = 0;
  for (hb_blob_t *b : paint->sub_blobs)
    sub_bytes += hb_blob_get_length (b);
  /* Sub-blobs come from the draw encoder which produces 8-byte
   * aligned blobs; assert so we notice if that ever changes. */
  if (unlikely (sub_bytes % texel_bytes))
    return nullptr;

  unsigned total_bytes = header_texels * texel_bytes
			+ paint->ops.length * 2
			+ sub_bytes;

  unsigned buf_capacity = 0;
  char *replaced_recycled_buf = nullptr;
  char *buf_raw = hb_blob_t::recycle_acquire (paint->recycled_blob, total_bytes,
					&buf_capacity, &replaced_recycled_buf);
  if (unlikely (!buf_raw))
    return nullptr;
  int16_t *buf = (int16_t *) (void *) buf_raw;

  /* Compute each sub_blob's texel offset (relative to blob base). */
  unsigned sub_offsets_count = paint->sub_blobs.length;
  hb_vector_t<unsigned> sub_offsets;
  if (unlikely (!sub_offsets.resize (sub_offsets_count)))
  {
    hb_blob_t::recycle_abort (buf_raw, paint->recycled_blob);
    return nullptr;
  }
  unsigned cursor = header_texels + ops_texels;
  for (unsigned i = 0; i < sub_offsets_count; i++)
  {
    sub_offsets[i] = cursor;
    cursor += hb_blob_get_length (paint->sub_blobs[i]) / texel_bytes;
  }

  /* Header. */
  buf[0] = (int16_t) paint->num_ops;
  buf[1] = 0;
  buf[2] = 0;
  buf[3] = 0;
  buf[4] = (int16_t) hb_clamp (paint->ext_min_x, -0x7fff, 0x7fff);
  buf[5] = (int16_t) hb_clamp (paint->ext_min_y, -0x7fff, 0x7fff);
  buf[6] = (int16_t) hb_clamp (paint->ext_max_x, -0x7fff, 0x7fff);
  buf[7] = (int16_t) hb_clamp (paint->ext_max_y, -0x7fff, 0x7fff);
  buf[8] = (int16_t) header_texels;
  buf[9]  = 0;
  buf[10] = 0;
  buf[11] = 0;

  /* Op stream: copy raw, then patch payload slots to texel
   * offsets where op_type indicates a sub_blob reference. */
  int16_t *ops_out = buf + header_texels * 4;
  hb_memcpy (ops_out, paint->ops.arrayZ, paint->ops.length * 2);

  unsigned i = 0;
  while (i < paint->ops.length)
  {
    int16_t op_type = ops_out[i];
    switch (op_type)
    {
      case HB_GPU_PAINT_OP_LAYER_SOLID:
      case HB_GPU_PAINT_OP_LAYER_GRADIENT:
      {
	int16_t flags = ops_out[i + 1];
	/* Sub-blob slots in i16 offsets within the op:
	 *   clip1: [i+2, i+3]                     -- always present
	 *   clip2: [i+4, i+5]                     -- only if HAS_CLIP2
	 *   clip3: [i+6, i+7]                     -- only if HAS_CLIP3
	 *   grad : [i+8, i+9]  (LAYER_GRADIENT only) */
	unsigned slots[4] = {
	  2,
	  (flags & HB_GPU_PAINT_FLAG_HAS_CLIP2) ? 4u : 0u,
	  (flags & HB_GPU_PAINT_FLAG_HAS_CLIP3) ? 6u : 0u,
	  op_type == HB_GPU_PAINT_OP_LAYER_GRADIENT ? 8u : 0u
	};
	for (unsigned k = 0; k < 4; k++)
	{
	  if (!slots[k]) continue;
	  unsigned p = i + slots[k];
	  unsigned idx = ((uint16_t) ops_out[p] << 16)
		       |  (uint16_t) ops_out[p + 1];
	  if (idx < sub_offsets_count)
	  {
	    unsigned off = sub_offsets[idx];
	    ops_out[p]     = (int16_t) ((off >> 16) & 0xffff);
	    ops_out[p + 1] = (int16_t) (off & 0xffff);
	  }
	}
	i += 12;  /* 3 texels */
	break;
      }
      case HB_GPU_PAINT_OP_PUSH_GROUP:
      case HB_GPU_PAINT_OP_POP_GROUP:
	i += 4;  /* 1 texel */
	break;
      default:
	hb_blob_t::recycle_abort (buf_raw, paint->recycled_blob);
	return nullptr;
    }
  }

  /* Sub-payloads: concat in recorded order. */
  char *dst = (char *) buf + header_texels * texel_bytes
			+ paint->ops.length * 2;
  for (hb_blob_t *b : paint->sub_blobs)
  {
    unsigned len = hb_blob_get_length (b);
    hb_memcpy (dst, hb_blob_get_data (b, nullptr), len);
    dst += len;
  }

  if (extents)
  {
    extents->x_bearing = paint->ext_min_x;
    extents->y_bearing = paint->ext_max_y;
    extents->width     = (int) ((int64_t) paint->ext_max_x - paint->ext_min_x);
    extents->height    = (int) ((int64_t) paint->ext_min_y - paint->ext_max_y);
  }

  hb_blob_t *recycled = paint->recycled_blob;
  paint->recycled_blob = nullptr;
  return hb_blob_t::recycle_finalize (buf_raw, buf_capacity, total_bytes,
				recycled, replaced_recycled_buf);
}

/**
 * hb_gpu_paint_clear:
 * @paint: a GPU color-glyph paint encoder
 *
 * Discards accumulated paint state so @paint can be reused for
 * another encode.  User configuration (font scale) is preserved.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_clear (hb_gpu_paint_t *paint)
{
  /* Use reset() not resize(0): if an earlier push_or_fail() set
   * the vector's error state (common under failing-malloc),
   * resize(0) short-circuits without clearing length.  A
   * subsequent clear would double-destroy the blob pointers left
   * in the array, or keep stale ops across encodes. */
  paint->ops.reset ();
  paint->num_ops = 0;
  for (hb_blob_t *b : paint->sub_blobs)
    hb_blob_destroy (b);
  paint->sub_blobs.reset ();
  paint->clip_depth = 0;
  paint->pending_clip_path = false;
  paint->unsupported = false;
  paint->cur_transform = {1, 0, 0, 1, 0, 0};
  paint->transform_stack.reset ();
  paint->ext_min_x =  0x7fffffff;
  paint->ext_min_y =  0x7fffffff;
  paint->ext_max_x = -0x7fffffff;
  paint->ext_max_y = -0x7fffffff;
}

/**
 * hb_gpu_paint_reset:
 * @paint: a GPU color-glyph paint encoder
 *
 * Resets @paint, discarding accumulated state and user
 * configuration.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_reset (hb_gpu_paint_t *paint)
{
  paint->x_scale = 0;
  paint->y_scale = 0;
  paint->palette = 0;
  hb_map_destroy (paint->custom_palette);
  paint->custom_palette = nullptr;
  hb_gpu_paint_clear (paint);
}

/**
 * hb_gpu_paint_recycle_blob:
 * @paint: a GPU color-glyph paint encoder
 * @blob: (transfer full): a blob previously returned by hb_gpu_paint_encode()
 *
 * Returns a blob to the encoder for potential reuse.  The caller
 * transfers ownership of @blob.
 *
 * If @blob came from hb_gpu_paint_encode() its underlying buffer
 * will be reused by the next call to hb_gpu_paint_encode(),
 * avoiding a malloc / blob allocation per glyph.
 *
 * Since: 14.2.0
 **/
void
hb_gpu_paint_recycle_blob (hb_gpu_paint_t *paint,
			   hb_blob_t      *blob)
{
  hb_blob_t::recycle_stash (&paint->recycled_blob, blob);
}


#include "hb-gpu-paint-fragment-glsl.hh"
#include "hb-gpu-paint-fragment-msl.hh"
#include "hb-gpu-paint-fragment-wgsl.hh"
#include "hb-gpu-paint-fragment-hlsl.hh"

/**
 * hb_gpu_paint_shader_source:
 * @stage: pipeline stage (vertex or fragment)
 * @lang: shader language variant
 *
 * Returns the paint-renderer-specific shader source for the
 * specified stage and language.  The returned string is static
 * and must not be freed.
 *
 * This source assumes both the shared helpers
 * (hb_gpu_shader_source()) and the draw-renderer helpers
 * (hb_gpu_draw_shader_source()) are concatenated ahead of it --
 * the paint interpreter invokes hb_gpu_draw() to compute
 * clip-glyph coverage.  Full assembly:
 *
 *   [#version] + hb_gpu_shader_source ()
 *             + hb_gpu_draw_shader_source ()
 *             + hb_gpu_paint_shader_source ()
 *             + caller's main ()
 *
 * Return value: (transfer none):
 * A shader source string, or `NULL` if @stage or @lang is
 * unsupported.
 *
 * Since: 14.2.0
 **/
const char *
hb_gpu_paint_shader_source (hb_gpu_shader_stage_t stage,
			    hb_gpu_shader_lang_t  lang)
{
  switch (stage) {
  case HB_GPU_SHADER_STAGE_FRAGMENT:
    switch (lang) {
    case HB_GPU_SHADER_LANG_GLSL: return hb_gpu_paint_fragment_glsl;
    case HB_GPU_SHADER_LANG_MSL:  return hb_gpu_paint_fragment_msl;
    case HB_GPU_SHADER_LANG_WGSL: return hb_gpu_paint_fragment_wgsl;
    case HB_GPU_SHADER_LANG_HLSL: return hb_gpu_paint_fragment_hlsl;
    case HB_GPU_SHADER_LANG_INVALID:
    default: return nullptr;
    }
  case HB_GPU_SHADER_STAGE_VERTEX:
    switch (lang) {
    case HB_GPU_SHADER_LANG_GLSL:
    case HB_GPU_SHADER_LANG_MSL:
    case HB_GPU_SHADER_LANG_WGSL:
    case HB_GPU_SHADER_LANG_HLSL: return "";
    case HB_GPU_SHADER_LANG_INVALID:
    default: return nullptr;
    }
  default:
    return nullptr;
  }
}
