/*
 * 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-test.h"
#include "hb-gpu.h"
#include <hb-ot.h>
#include <cmath>

#define FONT_FILE      "fonts/Roboto-Regular.abc.ttf"
#define COLR_FONT_FILE "fonts/test_glyphs-glyf_colr_1.ttf"

struct hb_gpu_test_texel_t
{
  int16_t r, g, b, a;
};

static const hb_gpu_test_texel_t *
blob_as_texels (hb_blob_t *blob,
		unsigned  *texel_count)
{
  unsigned length = hb_blob_get_length (blob);
  g_assert_cmpuint (length % sizeof (hb_gpu_test_texel_t), ==, 0);

  *texel_count = length / sizeof (hb_gpu_test_texel_t);
  /* hb_blob_get_data returns malloc'd memory which is suitably
   * aligned for any standard type; the cast is safe. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
  return (const hb_gpu_test_texel_t *) hb_blob_get_data (blob, nullptr);
#pragma GCC diagnostic pop
}

static hb_bool_t
blob_has_texel (hb_blob_t                   *blob,
		const hb_gpu_test_texel_t  needle)
{
  unsigned texel_count;
  const hb_gpu_test_texel_t *texels = blob_as_texels (blob, &texel_count);

  for (unsigned i = 0; i < texel_count; i++)
    if (texels[i].r == needle.r &&
	texels[i].g == needle.g &&
	texels[i].b == needle.b &&
	texels[i].a == needle.a)
      return true;

  return false;
}


static void
test_create_destroy (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_gpu_draw_t *ref = hb_gpu_draw_reference (draw);
  g_assert_true (ref == draw);
  hb_gpu_draw_destroy (ref);

  hb_gpu_draw_destroy (draw);
}

static void
test_empty_encode (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  /* Encode with no curves should return empty blob and zero extents. */
  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), ==, 0);
  hb_blob_destroy (blob);

  g_assert_cmpint (ext.x_bearing, ==, 0);
  g_assert_cmpint (ext.y_bearing, ==, 0);
  g_assert_cmpint (ext.width, ==, 0);
  g_assert_cmpint (ext.height, ==, 0);

  hb_gpu_draw_destroy (draw);
}

static void
test_encode_glyph (void)
{
  hb_face_t *face = hb_test_open_font_file (FONT_FILE);
  g_assert_nonnull (face);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  /* Draw glyph for 'a' (glyph index from cmap). */
  hb_codepoint_t gid;
  hb_bool_t found = hb_font_get_nominal_glyph (font, 'a', &gid);
  g_assert_true (found);

  hb_gpu_draw_glyph (draw, font, gid);

  /* Encode should produce non-empty blob with non-zero extents. */
  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);

  /* Blob size should be a multiple of 8 (RGBA16I texels). */
  g_assert_cmpuint (hb_blob_get_length (blob) % 8, ==, 0);

  g_assert_cmpint (ext.width, >, 0);
  g_assert_cmpint (ext.height, <, 0); /* height is negative (y-down) */

  hb_blob_destroy (blob);
  hb_gpu_draw_destroy (draw);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void
test_reset (void)
{
  hb_face_t *face = hb_test_open_font_file (FONT_FILE);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_codepoint_t gid;
  hb_font_get_nominal_glyph (font, 'a', &gid);

  /* Draw, encode, reset, encode again — should work. */
  hb_gpu_draw_glyph (draw, font, gid);
  hb_blob_t *blob1 = hb_gpu_draw_encode (draw, nullptr);
  g_assert_cmpuint (hb_blob_get_length (blob1), >, 0);
  hb_blob_destroy (blob1);

  hb_gpu_draw_reset (draw);

  /* After reset, encode should be empty. */
  hb_blob_t *blob2 = hb_gpu_draw_encode (draw, nullptr);
  g_assert_cmpuint (hb_blob_get_length (blob2), ==, 0);
  hb_blob_destroy (blob2);

  /* Draw again after reset. */
  hb_gpu_draw_glyph (draw, font, gid);
  hb_blob_t *blob3 = hb_gpu_draw_encode (draw, nullptr);
  g_assert_cmpuint (hb_blob_get_length (blob3), >, 0);
  hb_blob_destroy (blob3);

  hb_gpu_draw_destroy (draw);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void
test_draw_funcs (void)
{
  hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs (nullptr);
  g_assert_nonnull (funcs);

  /* Should be the same instance each time. */
  g_assert_true (funcs == hb_gpu_draw_get_funcs (nullptr));
}

static void
test_shader_sources (void)
{
  g_assert_nonnull (hb_gpu_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_GLSL));
  g_assert_nonnull (hb_gpu_shader_source (HB_GPU_SHADER_STAGE_VERTEX, HB_GPU_SHADER_LANG_GLSL));
  g_assert_nonnull (hb_gpu_draw_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_GLSL));
  g_assert_nonnull (hb_gpu_draw_shader_source (HB_GPU_SHADER_STAGE_VERTEX, HB_GPU_SHADER_LANG_GLSL));
}

static void
test_encode_quantizes_extents_outward (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs (draw);
  hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
  hb_draw_move_to (funcs, draw, &st, 0.24f, 0.24f);
  hb_draw_line_to (funcs, draw, &st, 0.76f, 0.24f);
  hb_draw_line_to (funcs, draw, &st, 0.76f, 0.76f);
  hb_draw_close_path (funcs, draw, &st);

  hb_blob_t *blob = hb_gpu_draw_encode (draw, nullptr);
  g_assert_nonnull (blob);

  unsigned texel_count;
  const hb_gpu_test_texel_t *texels = blob_as_texels (blob, &texel_count);
  g_assert_cmpuint (texel_count, >, 0);
  g_assert_cmpint (texels[0].r, ==, 0);
  g_assert_cmpint (texels[0].g, ==, 0);
  g_assert_cmpint (texels[0].b, ==, 4);
  g_assert_cmpint (texels[0].a, ==, 4);

  hb_blob_destroy (blob);
  hb_gpu_draw_destroy (draw);
}

static void
test_encode_preserves_touching_contours (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs (draw);
  hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;

  hb_draw_move_to (funcs, draw, &st, 0.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 1.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 0.f, 1.f);
  hb_draw_close_path (funcs, draw, &st);

  hb_draw_move_to (funcs, draw, &st, 0.f, 0.f);
  hb_draw_quadratic_to (funcs, draw, &st, -0.75f, 0.25f, -0.25f, -1.f);
  hb_draw_close_path (funcs, draw, &st);

  hb_blob_t *blob = hb_gpu_draw_encode (draw, nullptr);
  g_assert_nonnull (blob);

  g_assert_true (blob_has_texel (blob, {0, 0, -3, 1}));

  hb_blob_destroy (blob);
  hb_gpu_draw_destroy (draw);
}

static void
test_recycle_blob (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs (draw);
  hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;

  hb_draw_move_to (funcs, draw, &st, 0.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 1.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 0.f, 1.f);
  hb_draw_close_path (funcs, draw, &st);

  hb_blob_t *blob = hb_gpu_draw_encode (draw, nullptr);
  g_assert_nonnull (blob);
  unsigned first_length = hb_blob_get_length (blob);
  g_assert_cmpuint (first_length, >, 0);

  hb_gpu_draw_recycle_blob (draw, blob);

  hb_gpu_draw_reset (draw);

  hb_draw_move_to (funcs, draw, &st, 0.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 2.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 2.f, 2.f);
  hb_draw_line_to (funcs, draw, &st, 0.f, 2.f);
  hb_draw_close_path (funcs, draw, &st);
  hb_draw_move_to (funcs, draw, &st, 0.25f, 0.25f);
  hb_draw_quadratic_to (funcs, draw, &st, 1.f, 1.75f, 1.75f, 0.25f);
  hb_draw_quadratic_to (funcs, draw, &st, 1.f, -0.5f, 0.25f, 0.25f);
  hb_draw_close_path (funcs, draw, &st);

  hb_blob_t *blob2 = hb_gpu_draw_encode (draw, nullptr);
  g_assert_nonnull (blob2);
  g_assert_cmpuint (hb_blob_get_length (blob2), >, first_length);

  hb_blob_destroy (blob2);
  hb_gpu_draw_destroy (draw);
}

static void
test_extents_saturate_overflow (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);

  hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs (draw);
  hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;

  hb_draw_move_to (funcs, draw, &st, -0x1p31f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 821.f, 0.f);
  hb_draw_line_to (funcs, draw, &st, 821.f, 1.f);
  hb_draw_close_path (funcs, draw, &st);

  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (draw, &ext);
  hb_blob_destroy (blob);

  g_assert_cmpint (ext.x_bearing, ==, G_MININT32);
  g_assert_cmpint (ext.y_bearing, ==, 1);
  g_assert_cmpint (ext.width, ==, G_MAXINT32);
  g_assert_cmpint (ext.height, ==, -1);

  hb_gpu_draw_destroy (draw);
}

/* ===== Paint encoder tests ===== */

static void
test_paint_create_destroy (void)
{
  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  g_assert_nonnull (p);

  hb_gpu_paint_t *ref = hb_gpu_paint_reference (p);
  g_assert_true (ref == p);
  hb_gpu_paint_destroy (ref);

  hb_gpu_paint_destroy (p);
}

static void
test_paint_get_funcs (void)
{
  hb_paint_funcs_t *funcs = hb_gpu_paint_get_funcs (nullptr);
  g_assert_nonnull (funcs);
  /* Same instance each call. */
  g_assert_true (funcs == hb_gpu_paint_get_funcs (nullptr));
}

static void
test_paint_shader_sources (void)
{
  /* Fragment helpers exist for all four supported languages. */
  g_assert_nonnull (hb_gpu_paint_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_GLSL));
  g_assert_nonnull (hb_gpu_paint_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_MSL));
  g_assert_nonnull (hb_gpu_paint_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_HLSL));
  g_assert_nonnull (hb_gpu_paint_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT, HB_GPU_SHADER_LANG_WGSL));
}

static void
test_paint_empty_encode (void)
{
  /* Nothing painted -> empty blob (no ops to encode).  Reserved for
   * the "no ink" case; nullptr is only returned for unsupported
   * features. */
  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  g_assert_nonnull (p);
  hb_blob_t *blob = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), ==, 0);
  hb_blob_destroy (blob);
  hb_gpu_paint_destroy (p);
}

static void
test_paint_encode_monochrome (void)
{
  /* hb_gpu_paint_glyph synthesizes a single foreground-colored
   * layer for non-color glyphs; the encoded blob should be
   * non-empty and 8-byte (RGBA16I texel) aligned. */
  hb_face_t *face = hb_test_open_font_file (FONT_FILE);
  g_assert_nonnull (face);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  g_assert_nonnull (p);

  hb_codepoint_t gid;
  g_assert_true (hb_font_get_nominal_glyph (font, 'a', &gid));
  /* Use hb_gpu_paint_glyph (not _or_fail) so that non-color
   * glyphs still produce a blob via the synthesize fallback. */
  hb_gpu_paint_glyph (p, font, gid);

  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_paint_encode (p, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  g_assert_cmpuint (hb_blob_get_length (blob) % 8, ==, 0);
  g_assert_cmpint (ext.width, >, 0);
  g_assert_cmpint (ext.height, <, 0);

  hb_blob_destroy (blob);
  hb_gpu_paint_destroy (p);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void
test_paint_encode_color (void)
{
  /* Real COLRv1 paint tree: scan for any color glyph that we
   * support end-to-end (the test font deliberately exercises
   * features we may flag as unsupported, so check several rather
   * than asserting on the first). */
  hb_face_t *face = hb_test_open_font_file (COLR_FONT_FILE);
  g_assert_nonnull (face);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  g_assert_nonnull (p);

  unsigned num = hb_face_get_glyph_count (face);
  for (unsigned i = 0; i < num; i++)
  {
    if (!hb_ot_color_glyph_has_paint (face, i))
      continue;
    /* paint_glyph's return is the supported flag; we don't gate
     * on it -- encode handles both cases (returns empty blob for
     * unsupported / empty, nullptr only on allocation failure). */
    hb_gpu_paint_glyph (p, font, i);
    hb_blob_t *blob = hb_gpu_paint_encode (p, nullptr);
    g_assert_nonnull (blob);
    g_assert_cmpuint (hb_blob_get_length (blob) % 8, ==, 0);
    hb_blob_destroy (blob);
  }
  /* Test exists to confirm we don't crash / corrupt while walking
   * a real COLRv1 paint tree, not that our encoder covers every
   * COLRv1 feature. */

  hb_gpu_paint_destroy (p);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void
test_paint_auto_clear_on_encode (void)
{
  /* hb_gpu_paint_encode auto-clears so the encoder can be reused
   * straight away; user configuration (palette) is preserved. */
  hb_face_t *face = hb_test_open_font_file (FONT_FILE);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  hb_gpu_paint_set_palette (p, 3);
  g_assert_cmpuint (hb_gpu_paint_get_palette (p), ==, 3);

  hb_codepoint_t gid;
  hb_font_get_nominal_glyph (font, 'a', &gid);

  hb_gpu_paint_glyph (p, font, gid);
  hb_blob_t *blob1 = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (blob1);
  hb_blob_destroy (blob1);

  /* Auto-clear: re-encoding without painting again returns the
   * empty-blob singleton (nothing accumulated). */
  hb_blob_t *empty = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (empty);
  g_assert_cmpuint (hb_blob_get_length (empty), ==, 0);
  hb_blob_destroy (empty);

  /* Palette config is preserved. */
  g_assert_cmpuint (hb_gpu_paint_get_palette (p), ==, 3);

  /* Paint another glyph -- works because state is clean and config
   * is still in effect. */
  hb_font_get_nominal_glyph (font, 'b', &gid);
  hb_gpu_paint_glyph (p, font, gid);
  hb_blob_t *blob2 = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (blob2);
  hb_blob_destroy (blob2);

  hb_gpu_paint_destroy (p);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void
test_paint_reset (void)
{
  /* paint_reset wipes user configuration too (vs. paint_clear which
   * keeps it). */
  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  hb_gpu_paint_set_palette (p, 5);
  g_assert_cmpuint (hb_gpu_paint_get_palette (p), ==, 5);
  hb_gpu_paint_reset (p);
  g_assert_cmpuint (hb_gpu_paint_get_palette (p), ==, 0);
  hb_gpu_paint_destroy (p);
}

static void
test_paint_recycle_blob (void)
{
  hb_face_t *face = hb_test_open_font_file (FONT_FILE);
  hb_font_t *font = hb_font_create (face);

  hb_gpu_paint_t *p = hb_gpu_paint_create_or_fail ();
  hb_codepoint_t gid;
  hb_font_get_nominal_glyph (font, 'a', &gid);

  hb_gpu_paint_glyph (p, font, gid);
  hb_blob_t *blob = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (blob);
  hb_gpu_paint_recycle_blob (p, blob);

  /* Encoder still works after recycling. */
  hb_gpu_paint_glyph (p, font, gid);
  hb_blob_t *blob2 = hb_gpu_paint_encode (p, nullptr);
  g_assert_nonnull (blob2);
  hb_blob_destroy (blob2);

  hb_gpu_paint_destroy (p);
  hb_font_destroy (font);
  hb_face_destroy (face);
}


static void
test_shapes (void)
{
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  g_assert_nonnull (draw);
  /* Use a reasonable scale so the coordinates below stay in
   * the encoder's representable range. */
  hb_gpu_draw_set_scale (draw, 1000, 1000);

  hb_draw_funcs_t *dfuncs = hb_gpu_draw_get_funcs (draw);
  hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;

  /* Tapered line. */
  hb_draw_line (dfuncs, draw, &st,
		10.f, 10.f, 4.f,
		50.f, 30.f, 2.f,
		HB_DRAW_LINE_CAP_BUTT);
  hb_glyph_extents_t ext;
  hb_blob_t *blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  g_assert_cmpint (ext.width, >, 0);
  hb_blob_destroy (blob);

  /* Degenerate line (zero length) is silently a no-op. */
  hb_draw_line (dfuncs, draw, &st,
		10.f, 10.f, 3.f,
		10.f, 10.f, 3.f,
		HB_DRAW_LINE_CAP_BUTT);
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_cmpuint (hb_blob_get_length (blob), ==, 0);
  hb_blob_destroy (blob);

  /* NaN second width defaults to first; square cap extends each
   * end by half the stroke width along the line direction.
   * Horizontal line of length 40, stroke width 4: with butt
   * caps the bbox width would be 40, with square caps it's
   * 40 + 4 = 44. */
  hb_draw_line (dfuncs, draw, &st,
		10.f, 10.f, 4.f,
		50.f, 10.f, (float) std::nan (""),
		HB_DRAW_LINE_CAP_SQUARE);
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpint (ext.width, ==, 44);
  hb_blob_destroy (blob);

  /* Filled rect (stroke_width = NaN). */
  hb_draw_rectangle (dfuncs, draw, &st,
		0.f, 0.f, 20.f, 10.f,
		(float) std::nan (""));
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  g_assert_cmpint (ext.width, ==, 20);
  hb_blob_destroy (blob);

  /* Stroked rect: outer edge extends stroke_width/2 beyond the
   * nominal rect on each side. */
  hb_draw_rectangle (dfuncs, draw, &st,
		0.f, 0.f, 20.f, 10.f, 2.f);
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  g_assert_cmpint (ext.width, ==, 22);
  hb_blob_destroy (blob);

  /* Filled circle. */
  hb_draw_circle (dfuncs, draw, &st,
		  50.f, 50.f, 25.f,
		  (float) std::nan (""));
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  hb_blob_destroy (blob);

  /* Stroked circle. */
  hb_draw_circle (dfuncs, draw, &st,
		  50.f, 50.f, 25.f, 2.f);
  blob = hb_gpu_draw_encode (draw, &ext);
  g_assert_nonnull (blob);
  g_assert_cmpuint (hb_blob_get_length (blob), >, 0);
  hb_blob_destroy (blob);

  hb_gpu_draw_destroy (draw);
}


int
main (int argc, char **argv)
{
  hb_test_init (&argc, &argv);

  hb_test_add (test_create_destroy);
  hb_test_add (test_empty_encode);
  hb_test_add (test_encode_glyph);
  hb_test_add (test_reset);
  hb_test_add (test_draw_funcs);
  hb_test_add (test_shader_sources);
  hb_test_add (test_encode_quantizes_extents_outward);
  hb_test_add (test_encode_preserves_touching_contours);
  hb_test_add (test_recycle_blob);
  hb_test_add (test_extents_saturate_overflow);
  hb_test_add (test_shapes);

  hb_test_add (test_paint_create_destroy);
  hb_test_add (test_paint_get_funcs);
  hb_test_add (test_paint_shader_sources);
  hb_test_add (test_paint_empty_encode);
  hb_test_add (test_paint_encode_monochrome);
  hb_test_add (test_paint_encode_color);
  hb_test_add (test_paint_auto_clear_on_encode);
  hb_test_add (test_paint_reset);
  hb_test_add (test_paint_recycle_blob);

  return hb_test_run ();
}
