blob: a635f1f50c41f23013d445e620d62391fecada1b [file] [edit]
/*
* Copyright © 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-raster.h"
#include "hb-gpu.h"
static void
draw_rect (hb_draw_funcs_t *funcs,
void *data,
float x0,
float y0,
float x1,
float y1)
{
hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
hb_draw_move_to (funcs, data, &st, x0, y0);
hb_draw_line_to (funcs, data, &st, x1, y0);
hb_draw_line_to (funcs, data, &st, x1, y1);
hb_draw_line_to (funcs, data, &st, x0, y1);
hb_draw_close_path (funcs, data, &st);
}
static void
draw_test_shape_gpu (hb_gpu_draw_t *draw)
{
hb_draw_funcs_t *funcs = hb_gpu_draw_get_funcs ();
draw_rect (funcs, draw, 1.f, 1.f, 4.f, 3.f);
draw_rect (funcs, draw, 6.f, 0.f, 8.f, 2.f);
}
#ifndef HB_NO_RASTER_GPU
static uint8_t
pixel_at (hb_raster_image_t *img,
int x,
int y)
{
hb_raster_extents_t ext;
hb_raster_image_get_extents (img, &ext);
int col = x - ext.x_origin;
int row = y - ext.y_origin;
if (col < 0 || row < 0 ||
(unsigned) col >= ext.width || (unsigned) row >= ext.height)
return 0;
return hb_raster_image_get_buffer (img)[row * ext.stride + col];
}
#endif
static void
test_render_from_gpu_empty (void)
{
#ifdef HB_NO_RASTER_GPU
g_assert_null (hb_raster_gpu_render_from_blob_or_fail (hb_blob_get_empty ()));
#else
hb_raster_image_t *img = hb_raster_gpu_render_from_blob_or_fail (hb_blob_get_empty ());
g_assert_nonnull (img);
hb_raster_extents_t ext;
hb_raster_image_get_extents (img, &ext);
g_assert_cmpuint (ext.width, ==, 0);
g_assert_cmpuint (ext.height, ==, 0);
hb_raster_image_destroy (img);
#endif
}
static void
test_render_from_gpu_invalid (void)
{
hb_blob_t *blob = hb_blob_create_or_fail ("\0\0\0", 3,
HB_MEMORY_MODE_READONLY,
nullptr, nullptr);
g_assert_nonnull (blob);
g_assert_null (hb_raster_gpu_render_from_blob_or_fail (blob));
hb_blob_destroy (blob);
}
static void
test_render_from_gpu_roundtrip (void)
{
#ifdef HB_NO_RASTER_GPU
hb_gpu_draw_t *gpu = hb_gpu_draw_create_or_fail ();
g_assert_nonnull (gpu);
draw_test_shape_gpu (gpu);
hb_blob_t *blob = hb_gpu_draw_encode (gpu);
g_assert_nonnull (blob);
g_assert_null (hb_raster_gpu_render_from_blob_or_fail (blob));
hb_blob_destroy (blob);
hb_gpu_draw_destroy (gpu);
#else
hb_gpu_draw_t *gpu = hb_gpu_draw_create_or_fail ();
g_assert_nonnull (gpu);
draw_test_shape_gpu (gpu);
hb_blob_t *blob = hb_gpu_draw_encode (gpu);
g_assert_nonnull (blob);
hb_raster_image_t *from_gpu = hb_raster_gpu_render_from_blob_or_fail (blob);
g_assert_nonnull (from_gpu);
hb_raster_extents_t ext;
hb_raster_image_get_extents (from_gpu, &ext);
g_assert_cmpint (ext.x_origin, ==, 0);
g_assert_cmpint (ext.y_origin, ==, -1);
g_assert_cmpuint (ext.width, ==, 9);
g_assert_cmpuint (ext.height, ==, 5);
static const uint8_t expected[5][9] = {
{0, 0, 0, 0, 0, 0, 43, 43, 0},
{0, 43, 43, 43, 0, 43, 191, 191, 42},
{43, 191, 213, 191, 43, 43, 191, 191, 42},
{43, 191, 213, 191, 43, 0, 42, 42, 0},
{0, 42, 42, 42, 0, 0, 0, 0, 0},
};
for (unsigned y = 0; y < ext.height; y++)
for (unsigned x = 0; x < ext.width; x++)
g_assert_cmpuint (pixel_at (from_gpu,
ext.x_origin + x,
ext.y_origin + y),
==,
expected[y][x]);
hb_raster_image_destroy (from_gpu);
hb_blob_destroy (blob);
hb_gpu_draw_destroy (gpu);
#endif
}
int
main (int argc, char **argv)
{
hb_test_init (&argc, &argv);
hb_test_add (test_render_from_gpu_empty);
hb_test_add (test_render_from_gpu_invalid);
hb_test_add (test_render_from_gpu_roundtrip);
return hb_test_run ();
}