#ifndef DAEGUN_H
#define DAEGUN_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int32_t daegun_status;
#define DAEGUN_OK 0
#define DAEGUN_NULL -1
#define DAEGUN_PARSE -2
#define DAEGUN_RANGE -3
#define DAEGUN_ABSENT -4
#define DAEGUN_UNSUPPORTED -5
typedef struct {
const uint8_t *data;
size_t len;
} daegun_bytes;
typedef struct {
const char *data;
size_t len;
} daegun_str;
typedef struct daegun_font daegun_font;
uint32_t daegun_abi_version(void);
#define DAEGUN_ABI_VERSION ((1u << 16) | (1u << 8) | 5u)
daegun_str daegun_last_error(void);
daegun_status daegun_font_open(const uint8_t *data, size_t len, daegun_font **out);
uint8_t *daegun_font_buffer_new(size_t len);
void daegun_font_buffer_free(uint8_t *data, size_t len);
daegun_status daegun_font_open_owned(uint8_t *data, size_t len, daegun_font **out);
daegun_status daegun_font_open_collection(const uint8_t *data, size_t len, size_t index,
daegun_font **out);
void daegun_font_free(daegun_font *font);
daegun_status daegun_font_glyph_id(const daegun_font *font, uint32_t codepoint, uint16_t *out);
daegun_status daegun_font_num_glyphs(const daegun_font *font, uint16_t *out);
daegun_status daegun_font_upm(const daegun_font *font, uint16_t *out);
daegun_status daegun_ttc_font_count(const uint8_t *data, size_t len, size_t *out);
daegun_status daegun_font_set_glyph_cache_bytes(const daegun_font *font, size_t bytes);
daegun_status daegun_font_clear_glyph_cache(const daegun_font *font);
daegun_status daegun_font_glyph_cache_stats(const daegun_font *font, size_t *out_count,
size_t *out_bytes);
daegun_status daegun_font_set_curve_cache_bytes(const daegun_font *font, size_t bytes);
daegun_status daegun_font_clear_curve_cache(const daegun_font *font);
daegun_status daegun_font_curve_cache_stats(const daegun_font *font, size_t *out_count,
size_t *out_bytes);
daegun_status daegun_font_set_outline_cache_bytes(const daegun_font *font, size_t bytes);
daegun_status daegun_font_outline_cache_stats(const daegun_font *font, size_t *out_count,
size_t *out_bytes);
daegun_status daegun_font_set_shape_cache_bytes(const daegun_font *font, size_t bytes);
daegun_status daegun_font_clear_shape_cache(const daegun_font *font);
daegun_status daegun_font_shape_cache_stats(const daegun_font *font, size_t *out_count,
size_t *out_bytes);
daegun_status daegun_font_set_instance_cache_bytes(const daegun_font *font, size_t bytes);
daegun_status daegun_font_instance_cache_stats(const daegun_font *font, size_t *out_locations,
size_t *out_tables);
daegun_status daegun_font_set_cmap_index_allowance(const daegun_font *font, size_t bytes);
daegun_status daegun_font_cmap_index_allowance(const daegun_font *font, size_t *out_bytes);
#define DAEGUN_LAYOUT_GRAYSCALE 0
#define DAEGUN_LAYOUT_RGB_H 1
#define DAEGUN_LAYOUT_BGR_H 2
#define DAEGUN_LAYOUT_RGB_V 3
#define DAEGUN_LAYOUT_BGR_V 4
#define DAEGUN_LAYOUT_RGB_H_UNFILTERED 5
#define DAEGUN_LAYOUT_BGR_H_UNFILTERED 6
#define DAEGUN_LAYOUT_RGB_V_UNFILTERED 7
#define DAEGUN_LAYOUT_BGR_V_UNFILTERED 8
#define DAEGUN_HINT_NONE 0
#define DAEGUN_HINT_SUBPIXEL 1
#define DAEGUN_HINT_CLASSIC 2
#define DAEGUN_HINT_AUTO 3
#define DAEGUN_HINT_AUTO_FORCE 4
#define DAEGUN_JOIN_MITER 0
#define DAEGUN_JOIN_ROUND 1
#define DAEGUN_JOIN_BEVEL 2
#define DAEGUN_CAP_BUTT 0
#define DAEGUN_CAP_ROUND 1
#define DAEGUN_CAP_SQUARE 2
typedef struct {
int32_t layout;
int32_t hinting;
int32_t has_gamma;
float gamma;
int32_t has_transform;
float transform[6];
int32_t has_stroke;
float stroke_width;
int32_t stroke_join;
float stroke_miter_limit;
int32_t stroke_cap;
int32_t has_embolden;
float embolden;
int32_t has_oblique;
float oblique;
} daegun_raster_options;
daegun_status daegun_raster_options_default(daegun_raster_options *out);
typedef struct daegun_u16_list daegun_u16_list;
typedef struct daegun_i32_list daegun_i32_list;
typedef struct daegun_f64_list daegun_f64_list;
typedef struct daegun_blob daegun_blob;
typedef struct daegun_str_list daegun_str_list;
typedef struct daegun_text daegun_text;
typedef struct daegun_usize_list daegun_usize_list;
typedef struct daegun_glyph_value_list daegun_glyph_value_list;
typedef struct {
uint16_t glyph;
uint16_t value;
} daegun_glyph_value;
const uint16_t *daegun_u16_list_data(const daegun_u16_list *list, size_t *out_count);
const int32_t *daegun_i32_list_data(const daegun_i32_list *list, size_t *out_count);
const double *daegun_f64_list_data(const daegun_f64_list *list, size_t *out_count);
const uint8_t *daegun_blob_data(const daegun_blob *blob, size_t *out_count);
const size_t *daegun_usize_list_data(const daegun_usize_list *list, size_t *out_count);
const daegun_glyph_value *daegun_glyph_value_list_data(const daegun_glyph_value_list *list,
size_t *out_count);
void daegun_u16_list_free(daegun_u16_list *list);
void daegun_i32_list_free(daegun_i32_list *list);
void daegun_f64_list_free(daegun_f64_list *list);
void daegun_blob_free(daegun_blob *blob);
void daegun_usize_list_free(daegun_usize_list *list);
void daegun_glyph_value_list_free(daegun_glyph_value_list *list);
daegun_status daegun_str_list_count(const daegun_str_list *list, size_t *out);
daegun_status daegun_str_list_at(const daegun_str_list *list, size_t index, daegun_str *out);
void daegun_str_list_free(daegun_str_list *list);
daegun_status daegun_text_str(const daegun_text *text, daegun_str *out);
void daegun_text_free(daegun_text *text);
typedef struct {
const char *tag;
double value;
} daegun_axis;
daegun_status daegun_font_is_variable(const daegun_font *font, bool *out);
daegun_status daegun_font_ascender(const daegun_font *font, int32_t *out);
daegun_status daegun_font_descender(const daegun_font *font, int32_t *out);
daegun_status daegun_font_cap_height(const daegun_font *font, int32_t *out);
daegun_status daegun_font_flags(const daegun_font *font, uint32_t *out);
daegun_status daegun_font_italic_angle(const daegun_font *font, double *out);
daegun_status daegun_font_family_name(const daegun_font *font, daegun_text **out);
daegun_status daegun_font_style(const daegun_font *font, daegun_text **out);
daegun_status daegun_font_name_string(const daegun_font *font, uint16_t name_id, daegun_text **out);
daegun_status daegun_font_names(const daegun_font *font, daegun_u16_list **out_ids,
daegun_str_list **out_strings);
daegun_status daegun_font_bbox(const daegun_font *font, daegun_i32_list **out);
daegun_status daegun_font_tracking(const daegun_font *font, double ptem, bool horizontal,
double *out);
typedef struct {
double ascent;
double descent;
double line_gap;
} daegun_line_metrics;
daegun_status daegun_font_line_metrics(const daegun_font *font, bool vertical,
daegun_line_metrics *out);
typedef struct {
uint16_t version;
uint16_t has_family_class;
uint16_t family_class;
uint16_t has_selection;
uint16_t selection;
uint16_t has_win_metrics;
int32_t win_ascent;
int32_t win_descent;
uint16_t has_typo_metrics;
int32_t typo_ascender;
int32_t typo_descender;
int32_t typo_line_gap;
} daegun_os2_info;
daegun_status daegun_font_os2_info(const daegun_font *font, daegun_os2_info *out);
daegun_status daegun_font_is_italic(const daegun_font *font, bool *out);
daegun_status daegun_font_is_bold(const daegun_font *font, bool *out);
daegun_status daegun_font_is_regular(const daegun_font *font, bool *out);
daegun_status daegun_font_is_oblique(const daegun_font *font, bool *out);
daegun_status daegun_font_uses_typo_metrics(const daegun_font *font, bool *out);
typedef struct {
int32_t x_height;
int32_t underline_position;
int32_t underline_thickness;
int32_t strikeout_size;
int32_t strikeout_position;
int32_t subscript_x_size;
int32_t subscript_y_size;
int32_t subscript_x_offset;
int32_t subscript_y_offset;
int32_t superscript_x_size;
int32_t superscript_y_size;
int32_t superscript_x_offset;
int32_t superscript_y_offset;
} daegun_typographic_metrics;
daegun_status daegun_font_typographic_metrics(const daegun_font *font, const daegun_axis *axes,
size_t axes_len, daegun_typographic_metrics *out);
daegun_status daegun_font_axes(const daegun_font *font, daegun_str_list **out_tags,
daegun_f64_list **out_ranges);
daegun_status daegun_font_normalized_axes(const daegun_font *font, const daegun_axis *axes,
size_t axes_len, daegun_f64_list **out);
daegun_status daegun_font_instance(const daegun_font *font, const daegun_axis *axes,
size_t axes_len, daegun_blob **out);
daegun_status daegun_font_named_instance_count(const daegun_font *font, size_t *out);
daegun_status daegun_font_named_instance(const daegun_font *font, size_t index,
daegun_text **out_name, daegun_text **out_postscript_name,
daegun_str_list **out_coord_tags,
daegun_f64_list **out_coord_values);
typedef struct daegun_subset daegun_subset;
const uint8_t *daegun_subset_ttf(const daegun_subset *subset, size_t *out_len);
const uint16_t *daegun_subset_gid_map(const daegun_subset *subset, size_t *out_len);
void daegun_subset_free(daegun_subset *subset);
daegun_status daegun_font_subset(const daegun_font *font, const uint16_t *gids, size_t gids_len,
const daegun_axis *axes, size_t axes_len, daegun_subset **out);
daegun_status daegun_font_subset_text(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len,
daegun_subset **out);
daegun_status daegun_font_glyph_closure(const daegun_font *font, const uint16_t *gids,
size_t gids_len, const daegun_axis *axes, size_t axes_len,
daegun_u16_list **out);
#define DAEGUN_MATH_SCRIPT_PERCENT_SCALE_DOWN 0
#define DAEGUN_MATH_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN 1
#define DAEGUN_MATH_DELIMITED_SUB_FORMULA_MIN_HEIGHT 2
#define DAEGUN_MATH_DISPLAY_OPERATOR_MIN_HEIGHT 3
#define DAEGUN_MATH_MATH_LEADING 4
#define DAEGUN_MATH_AXIS_HEIGHT 5
#define DAEGUN_MATH_ACCENT_BASE_HEIGHT 6
#define DAEGUN_MATH_FLATTENED_ACCENT_BASE_HEIGHT 7
#define DAEGUN_MATH_SUBSCRIPT_SHIFT_DOWN 8
#define DAEGUN_MATH_SUBSCRIPT_TOP_MAX 9
#define DAEGUN_MATH_SUBSCRIPT_BASELINE_DROP_MIN 10
#define DAEGUN_MATH_SUPERSCRIPT_SHIFT_UP 11
#define DAEGUN_MATH_SUPERSCRIPT_SHIFT_UP_CRAMPED 12
#define DAEGUN_MATH_SUPERSCRIPT_BOTTOM_MIN 13
#define DAEGUN_MATH_SUPERSCRIPT_BASELINE_DROP_MAX 14
#define DAEGUN_MATH_SUB_SUPERSCRIPT_GAP_MIN 15
#define DAEGUN_MATH_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT 16
#define DAEGUN_MATH_SPACE_AFTER_SCRIPT 17
#define DAEGUN_MATH_UPPER_LIMIT_GAP_MIN 18
#define DAEGUN_MATH_UPPER_LIMIT_BASELINE_RISE_MIN 19
#define DAEGUN_MATH_LOWER_LIMIT_GAP_MIN 20
#define DAEGUN_MATH_LOWER_LIMIT_BASELINE_DROP_MIN 21
#define DAEGUN_MATH_STACK_TOP_SHIFT_UP 22
#define DAEGUN_MATH_STACK_TOP_DISPLAY_STYLE_SHIFT_UP 23
#define DAEGUN_MATH_STACK_BOTTOM_SHIFT_DOWN 24
#define DAEGUN_MATH_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN 25
#define DAEGUN_MATH_STACK_GAP_MIN 26
#define DAEGUN_MATH_STACK_DISPLAY_STYLE_GAP_MIN 27
#define DAEGUN_MATH_STRETCH_STACK_TOP_SHIFT_UP 28
#define DAEGUN_MATH_STRETCH_STACK_BOTTOM_SHIFT_DOWN 29
#define DAEGUN_MATH_STRETCH_STACK_GAP_ABOVE_MIN 30
#define DAEGUN_MATH_STRETCH_STACK_GAP_BELOW_MIN 31
#define DAEGUN_MATH_FRACTION_NUMERATOR_SHIFT_UP 32
#define DAEGUN_MATH_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP 33
#define DAEGUN_MATH_FRACTION_DENOMINATOR_SHIFT_DOWN 34
#define DAEGUN_MATH_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN 35
#define DAEGUN_MATH_FRACTION_NUMERATOR_GAP_MIN 36
#define DAEGUN_MATH_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN 37
#define DAEGUN_MATH_FRACTION_RULE_THICKNESS 38
#define DAEGUN_MATH_FRACTION_DENOMINATOR_GAP_MIN 39
#define DAEGUN_MATH_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN 40
#define DAEGUN_MATH_SKEWED_FRACTION_HORIZONTAL_GAP 41
#define DAEGUN_MATH_SKEWED_FRACTION_VERTICAL_GAP 42
#define DAEGUN_MATH_OVERBAR_VERTICAL_GAP 43
#define DAEGUN_MATH_OVERBAR_RULE_THICKNESS 44
#define DAEGUN_MATH_OVERBAR_EXTRA_ASCENDER 45
#define DAEGUN_MATH_UNDERBAR_VERTICAL_GAP 46
#define DAEGUN_MATH_UNDERBAR_RULE_THICKNESS 47
#define DAEGUN_MATH_UNDERBAR_EXTRA_DESCENDER 48
#define DAEGUN_MATH_RADICAL_VERTICAL_GAP 49
#define DAEGUN_MATH_RADICAL_DISPLAY_STYLE_VERTICAL_GAP 50
#define DAEGUN_MATH_RADICAL_RULE_THICKNESS 51
#define DAEGUN_MATH_RADICAL_EXTRA_ASCENDER 52
#define DAEGUN_MATH_RADICAL_KERN_BEFORE_DEGREE 53
#define DAEGUN_MATH_RADICAL_KERN_AFTER_DEGREE 54
#define DAEGUN_MATH_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT 55
int32_t daegun_math_constant_count(void);
daegun_status daegun_font_math_constant(const daegun_font *font, int32_t which, double *out);
daegun_status daegun_font_math_italics_correction(const daegun_font *font, uint16_t gid, double *out);
daegun_status daegun_font_math_top_accent_attachment(const daegun_font *font, uint16_t gid,
double *out);
daegun_status daegun_font_math_is_extended_shape(const daegun_font *font, uint16_t gid, bool *out);
daegun_status daegun_font_math_min_connector_overlap(const daegun_font *font, double *out);
#define DAEGUN_MATH_KERN_TOP_RIGHT 0
#define DAEGUN_MATH_KERN_TOP_LEFT 1
#define DAEGUN_MATH_KERN_BOTTOM_RIGHT 2
#define DAEGUN_MATH_KERN_BOTTOM_LEFT 3
daegun_status daegun_font_math_kern(const daegun_font *font, uint16_t gid, int32_t corner,
double height, double *out);
typedef struct daegun_math_construction daegun_math_construction;
daegun_status daegun_font_math_glyph_variants(const daegun_font *font, uint16_t gid, bool vertical,
daegun_math_construction **out);
daegun_status daegun_math_construction_variants(const daegun_math_construction *c, size_t *out_count,
const uint16_t **out_gids,
const double **out_advances);
daegun_status daegun_math_construction_assembly(const daegun_math_construction *c,
double *out_italics_correction,
size_t *out_part_count,
const uint16_t **out_part_gids,
const double **out_part_values);
void daegun_math_construction_free(daegun_math_construction *c);
daegun_status daegun_font_base_is_glyph_free(const daegun_font *font, bool *out);
daegun_status daegun_font_base_info(const daegun_font *font, const char *script_tag, bool vertical,
daegun_text **out_default_baseline,
daegun_str_list **out_baseline_tags,
daegun_f64_list **out_baseline_coords);
typedef struct daegun_stat daegun_stat;
daegun_status daegun_font_stat_info(const daegun_font *font, daegun_stat **out);
daegun_status daegun_stat_axes(const daegun_stat *stat, size_t *out_count,
daegun_str_list **out_tags, const uint16_t **out_orderings);
daegun_status daegun_stat_value_count(const daegun_stat *stat, size_t *out);
daegun_status daegun_stat_elided_fallback_name(const daegun_stat *stat, daegun_text **out);
void daegun_stat_free(daegun_stat *stat);
daegun_status daegun_font_script_tags(const daegun_font *font, daegun_str_list **out);
daegun_status daegun_font_language_tags(const daegun_font *font, const char *script,
daegun_str_list **out);
daegun_status daegun_font_feature_tags(const daegun_font *font, const char *script,
const char *language, daegun_str_list **out);
daegun_status daegun_font_justification_glyphs(const daegun_font *font, const char *script_tag,
daegun_u16_list **out);
typedef struct daegun_u32_list daegun_u32_list;
const uint32_t *daegun_u32_list_data(const daegun_u32_list *list, size_t *out_count);
void daegun_u32_list_free(daegun_u32_list *list);
daegun_status daegun_font_has_glyph(const daegun_font *font, uint32_t codepoint, bool *out);
daegun_status daegun_font_glyph_ids(const daegun_font *font, const char *text,
daegun_u16_list **out_gids, daegun_blob **out_present);
daegun_status daegun_font_coverage(const daegun_font *font, daegun_u32_list **out_codepoints,
daegun_u16_list **out_gids);
daegun_status daegun_font_codepoints(const daegun_font *font, daegun_u32_list **out);
daegun_status daegun_font_glyph_bounds(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len, double *out);
daegun_status daegun_font_variation_glyph_id(const daegun_font *font, uint32_t base,
uint32_t selector, uint16_t *out);
daegun_status daegun_font_advance_widths(const daegun_font *font, const uint16_t *gids,
size_t gids_len, const daegun_axis *axes, size_t axes_len,
daegun_f64_list **out);
daegun_status daegun_font_vertical_advance(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len, uint32_t *out);
daegun_status daegun_font_vertical_origin(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len, int32_t *out);
daegun_status daegun_font_default_vertical_origin(const daegun_font *font, int32_t *out);
daegun_status daegun_font_ligature_carets(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len,
daegun_f64_list **out);
daegun_status daegun_font_caret_positions(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, bool vertical,
daegun_f64_list **out);
#define DAEGUN_GLYPH_CLASS_BASE 0
#define DAEGUN_GLYPH_CLASS_LIGATURE 1
#define DAEGUN_GLYPH_CLASS_MARK 2
#define DAEGUN_GLYPH_CLASS_COMPONENT 3
daegun_status daegun_font_glyph_class(const daegun_font *font, uint16_t gid, int32_t *out);
daegun_status daegun_font_mark_attachment_class(const daegun_font *font, uint16_t gid, uint16_t *out);
daegun_status daegun_font_glyph_name(const daegun_font *font, uint16_t gid, daegun_text **out);
daegun_status daegun_font_glyph_names(const daegun_font *font, daegun_str_list **out_names,
daegun_blob **out_present);
typedef struct {
void (*move_to)(void *user, float x, float y);
void (*line_to)(void *user, float x, float y);
void (*quad_to)(void *user, float cx, float cy, float x, float y);
void (*curve_to)(void *user, float c1x, float c1y, float c2x, float c2y, float x, float y);
void (*close)(void *user);
void *user;
} daegun_pen;
daegun_status daegun_font_outline_glyph(const daegun_font *font, uint16_t gid,
const daegun_pen *pen);
daegun_status daegun_font_outline_glyph_instanced(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len,
const daegun_pen *pen);
daegun_status daegun_font_prewarm(const daegun_font *font, const uint16_t *gids, size_t gids_len,
const daegun_axis *axes, size_t axes_len, size_t *out_added);
daegun_status daegun_font_clear_prewarm(const daegun_font *font);
typedef struct daegun_bitmap daegun_bitmap;
typedef struct {
int32_t xmin;
int32_t ymin;
size_t width;
size_t height;
float advance_width;
float advance_height;
float bounds_xmin;
float bounds_ymin;
float bounds_width;
float bounds_height;
} daegun_metrics;
daegun_status daegun_bitmap_metrics(const daegun_bitmap *bitmap, daegun_metrics *out);
const uint8_t *daegun_bitmap_pixels(const daegun_bitmap *bitmap, size_t *out_len);
void daegun_bitmap_free(daegun_bitmap *bitmap);
daegun_status daegun_font_rasterize_glyph(const daegun_font *font, uint16_t gid, float px,
const daegun_axis *axes, size_t axes_len,
daegun_bitmap **out);
daegun_status daegun_font_rasterize_glyph_with(const daegun_font *font, uint16_t gid, float px,
const daegun_axis *axes, size_t axes_len,
const daegun_raster_options *opts,
daegun_bitmap **out);
typedef struct daegun_hinted_outline daegun_hinted_outline;
#define DAEGUN_FLAG_ON_CURVE 0x01
daegun_status daegun_font_hinted_glyph(const daegun_font *font, uint16_t gid, float px,
const daegun_axis *axes, size_t axes_len, int32_t hint_mode,
daegun_hinted_outline **out);
daegun_status daegun_hinted_outline_points(const daegun_hinted_outline *outline, size_t *out_count,
const int32_t **out_x, const int32_t **out_y,
const uint8_t **out_flags);
const size_t *daegun_hinted_outline_contours(const daegun_hinted_outline *outline,
size_t *out_count);
void daegun_hinted_outline_free(daegun_hinted_outline *outline);
typedef struct daegun_cff_hints daegun_cff_hints;
daegun_status daegun_font_cff_hints(const daegun_font *font, uint16_t gid, daegun_cff_hints **out);
const double *daegun_cff_hints_stems(const daegun_cff_hints *hints, size_t *out_count);
void daegun_cff_hints_free(daegun_cff_hints *hints);
typedef struct daegun_run daegun_run;
const uint16_t *daegun_run_glyphs(const daegun_run *run, size_t *out_count);
const double *daegun_run_advances(const daegun_run *run, size_t *out_count);
const double *daegun_run_offsets(const daegun_run *run, size_t *out_count);
const uint32_t *daegun_run_clusters(const daegun_run *run, size_t *out_count);
const uint8_t *daegun_run_unsafe_to_break(const daegun_run *run, size_t *out_count);
const uint8_t *daegun_run_unsafe_to_concat(const daegun_run *run, size_t *out_count);
const uint8_t *daegun_run_safe_to_insert_tatweel(const daegun_run *run, size_t *out_count);
daegun_status daegun_run_complete(const daegun_run *run, bool *out);
daegun_status daegun_run_has_broken_syllable(const daegun_run *run, bool *out);
daegun_status daegun_run_shaper(const daegun_run *run, daegun_str *out);
void daegun_run_free(daegun_run *run);
typedef struct {
const char *tag;
uint32_t value;
} daegun_feature;
daegun_status daegun_font_shape(const daegun_font *font, const char *text, const daegun_axis *axes,
size_t axes_len, bool vertical, daegun_run **out);
daegun_status daegun_font_shape_with_language(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len,
bool vertical, const char *language,
daegun_run **out);
daegun_status daegun_font_shape_with_features(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len,
bool vertical, const char *script,
const daegun_feature *features, size_t features_len,
daegun_run **out);
#define DAEGUN_CLUSTER_MONOTONE_GRAPHEMES 0
#define DAEGUN_CLUSTER_MONOTONE_CHARACTERS 1
#define DAEGUN_CLUSTER_CHARACTERS 2
#define DAEGUN_CLUSTER_GRAPHEMES 3
#define DAEGUN_IGNORABLES_HIDE 0
#define DAEGUN_IGNORABLES_REMOVE 1
#define DAEGUN_IGNORABLES_PRESERVE 2
typedef struct {
int32_t cluster_level;
int32_t ignorables;
const char *before;
const char *after;
bool beginning_of_text;
bool has_point_size;
double point_size;
const daegun_feature *features;
size_t features_len;
const char *script;
const char *language;
bool report_unsafe_to_concat;
bool report_tatweel_positions;
bool suppress_dotted_circle;
bool has_invisible_glyph;
uint16_t invisible_glyph;
} daegun_shape_options;
daegun_status daegun_shape_options_default(daegun_shape_options *out);
daegun_status daegun_font_shape_with_options(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len,
bool vertical, const daegun_shape_options *opts,
daegun_run **out);
daegun_status daegun_font_measure_width(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, double font_size,
double *out);
typedef struct daegun_jstf_priorities daegun_jstf_priorities;
typedef struct daegun_jstf_mods daegun_jstf_mods;
typedef struct daegun_justified daegun_justified;
daegun_status daegun_font_justification_extenders(const daegun_font *font, const char *script_tag,
daegun_u16_list **out);
daegun_status daegun_font_justification_priorities(const daegun_font *font, const char *script_tag,
const char *lang_sys_tag,
daegun_jstf_priorities **out);
daegun_status daegun_jstf_priorities_count(const daegun_jstf_priorities *p, size_t *out);
daegun_status daegun_jstf_priorities_at(const daegun_jstf_priorities *p, size_t index,
const daegun_jstf_mods **out);
void daegun_jstf_priorities_free(daegun_jstf_priorities *p);
daegun_status daegun_font_shape_justified(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, bool vertical,
const daegun_jstf_mods *mods, bool shrink,
daegun_run **out);
daegun_status daegun_font_justify(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, bool vertical,
const char *script_tag, const char *lang_sys_tag,
double target_width, double tolerance, daegun_justified **out);
const daegun_run *daegun_justified_run(const daegun_justified *j);
daegun_status daegun_justified_info(const daegun_justified *j, bool *out_has_level,
size_t *out_level, bool *out_shrink, double *out_width,
bool *out_best_effort);
void daegun_justified_free(daegun_justified *j);
typedef struct daegun_bidi_runs daegun_bidi_runs;
daegun_status daegun_font_shape_bidi(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, int32_t base,
daegun_bidi_runs **out);
daegun_status daegun_font_shape_bidi_with(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len, int32_t base,
const daegun_shape_options *opts,
daegun_bidi_runs **out);
daegun_status daegun_bidi_runs_count(const daegun_bidi_runs *runs, size_t *out);
daegun_status daegun_bidi_runs_at(const daegun_bidi_runs *runs, size_t index,
const daegun_run **out_run, uint8_t *out_level,
const size_t **out_chars, size_t *out_chars_count);
void daegun_bidi_runs_free(daegun_bidi_runs *runs);
#define DAEGUN_ALIGN_START 0
#define DAEGUN_ALIGN_END 1
#define DAEGUN_ALIGN_CENTER 2
#define DAEGUN_ALIGN_JUSTIFY 3
#define DAEGUN_WRITING_HORIZONTAL 0
#define DAEGUN_WRITING_VERTICAL_RL 1
#define DAEGUN_WRITING_VERTICAL_LR 2
#define DAEGUN_ORIENTATION_MIXED 0
#define DAEGUN_ORIENTATION_UPRIGHT 1
#define DAEGUN_ORIENTATION_SIDEWAYS 2
#define DAEGUN_BREAK_GREEDY 0
#define DAEGUN_BREAK_OPTIMAL 1
bool daegun_writing_mode_is_vertical(int32_t mode);
typedef struct {
double max_inline_size;
int32_t align;
int32_t writing_mode;
int32_t text_orientation;
int32_t base_direction;
const char *language;
bool has_line_height;
double line_height;
int32_t strategy;
bool has_max_lines;
size_t max_lines;
} daegun_layout_options;
typedef struct daegun_layout daegun_layout;
daegun_status daegun_layout_options_default(daegun_layout_options *out);
daegun_status daegun_font_layout(const daegun_font *font, const char *text,
const daegun_axis *axes, size_t axes_len,
const daegun_layout_options *opts, daegun_layout **out);
daegun_status daegun_layout_info(const daegun_layout *layout, size_t *out_line_count,
double *out_inline_size, double *out_block_size,
bool *out_has_truncated, size_t *out_truncated);
daegun_status daegun_layout_line(const daegun_layout *layout, size_t index, size_t *out_run_count,
size_t *out_char_start, size_t *out_char_end, double *out_baseline,
double *out_inline_size, double *out_ascent, double *out_descent,
bool *out_hard_break);
daegun_status daegun_layout_run(const daegun_layout *layout, size_t line, size_t index,
const daegun_run **out_run, double *out_offset_x,
double *out_offset_y, uint8_t *out_level, size_t *out_char_start,
size_t *out_char_end, bool *out_upright);
void daegun_layout_free(daegun_layout *layout);
daegun_status daegun_text_grapheme_boundaries(const char *text, daegun_u32_list **out);
daegun_status daegun_text_word_boundaries(const char *text, daegun_u32_list **out);
daegun_status daegun_text_line_break_opportunities(const char *text, daegun_u32_list **out_at,
daegun_blob **out_mandatory);
daegun_status daegun_text_script_runs(const char *text, daegun_u32_list **out);
daegun_status daegun_script_name(uint16_t script, daegun_text **out);
daegun_status daegun_script_is_rtl(uint16_t script, bool *out);
daegun_status daegun_text_resolve_bidi(const char *text, int32_t base, uint8_t *out_base_level,
daegun_blob **out_levels, daegun_u32_list **out_visual_order);
typedef struct daegun_bidi_paragraph daegun_bidi_paragraph;
typedef struct daegun_visual_runs daegun_visual_runs;
daegun_status daegun_text_bidi_paragraph(const char *text, int32_t base,
daegun_bidi_paragraph **out);
daegun_status daegun_bidi_paragraph_base_level(const daegun_bidi_paragraph *p, uint8_t *out);
void daegun_bidi_paragraph_free(daegun_bidi_paragraph *p);
daegun_status daegun_text_line_visual_runs(const daegun_bidi_paragraph *p, size_t start, size_t end,
daegun_visual_runs **out);
daegun_status daegun_visual_runs_count(const daegun_visual_runs *runs, size_t *out);
daegun_status daegun_visual_runs_at(const daegun_visual_runs *runs, size_t index,
uint8_t *out_level, const size_t **out_chars,
size_t *out_chars_count);
void daegun_visual_runs_free(daegun_visual_runs *runs);
typedef struct daegun_colr_layers daegun_colr_layers;
typedef struct daegun_palettes daegun_palettes;
typedef struct daegun_glyph_bitmap daegun_glyph_bitmap;
typedef struct daegun_paint daegun_paint;
typedef struct daegun_scene daegun_scene;
typedef struct {
uint16_t gid;
uint8_t r, g, b, a;
bool is_foreground;
} daegun_colr_layer;
daegun_status daegun_font_colr_layers(const daegun_font *font, uint16_t gid,
daegun_colr_layers **out);
daegun_status daegun_font_colr_layers_for_palette(const daegun_font *font, uint16_t gid,
uint16_t palette_index,
daegun_colr_layers **out);
const daegun_colr_layer *daegun_colr_layers_data(const daegun_colr_layers *layers,
size_t *out_count);
void daegun_colr_layers_free(daegun_colr_layers *layers);
typedef struct {
uint16_t index;
bool light_safe;
bool dark_safe;
bool has_name_id;
uint16_t name_id;
} daegun_palette_info;
daegun_status daegun_font_palette_count(const daegun_font *font, uint16_t *out);
daegun_status daegun_font_palette_info(const daegun_font *font, daegun_palettes **out);
const daegun_palette_info *daegun_palettes_data(const daegun_palettes *p, size_t *out_count);
void daegun_palettes_free(daegun_palettes *p);
daegun_status daegun_font_glyph_bitmap(const daegun_font *font, uint16_t gid, uint16_t target_ppem,
daegun_glyph_bitmap **out);
const uint8_t *daegun_glyph_bitmap_png(const daegun_glyph_bitmap *b, size_t *out_len,
uint16_t *out_ppem, int16_t *out_origin_x,
int16_t *out_origin_y);
void daegun_glyph_bitmap_free(daegun_glyph_bitmap *b);
#define DAEGUN_PAINT_LAYERS 0
#define DAEGUN_PAINT_GLYPH 1
#define DAEGUN_PAINT_COLR_GLYPH 2
#define DAEGUN_PAINT_SOLID 3
#define DAEGUN_PAINT_LINEAR_GRADIENT 4
#define DAEGUN_PAINT_RADIAL_GRADIENT 5
#define DAEGUN_PAINT_SWEEP_GRADIENT 6
#define DAEGUN_PAINT_TRANSFORM 7
#define DAEGUN_PAINT_TRANSLATE 8
#define DAEGUN_PAINT_SCALE 9
#define DAEGUN_PAINT_SCALE_UNIFORM 10
#define DAEGUN_PAINT_ROTATE 11
#define DAEGUN_PAINT_SKEW 12
#define DAEGUN_PAINT_COMPOSITE 13
typedef struct {
int32_t kind;
uint32_t child_start;
uint32_t child_count;
uint32_t stops_start;
uint32_t stops_count;
uint16_t glyph_id;
uint8_t is_foreground;
uint8_t r, g, b, alpha;
uint8_t extend;
uint8_t composite_mode;
uint8_t has_center;
double numbers[8];
} daegun_paint_node;
daegun_status daegun_font_colr_v1_paint(const daegun_font *font, uint16_t gid,
const daegun_axis *axes, size_t axes_len,
uint16_t palette_index, daegun_paint **out);
const daegun_paint_node *daegun_paint_nodes(const daegun_paint *p, size_t *out_count);
const uint32_t *daegun_paint_children(const daegun_paint *p, size_t *out_count);
daegun_status daegun_paint_stops(const daegun_paint *p, size_t *out_count,
const double **out_offsets, const uint8_t **out_colors);
void daegun_paint_free(daegun_paint *p);
daegun_status daegun_font_render_colr_glyph(const daegun_font *font, uint16_t gid, float px,
const daegun_axis *axes, size_t axes_len,
uint16_t palette_index, daegun_scene **out);
daegun_status daegun_font_render_colr_glyph_with(const daegun_font *font, uint16_t gid, float px,
const daegun_axis *axes, size_t axes_len,
uint16_t palette_index,
const uint8_t foreground[4],
daegun_scene **out);
const uint8_t *daegun_scene_rgba(const daegun_scene *s, size_t *out_len, size_t *out_width,
size_t *out_height, int32_t *out_left, int32_t *out_top,
size_t *out_skipped_ops);
void daegun_scene_free(daegun_scene *s);
typedef struct daegun_batch daegun_batch;
typedef struct daegun_drawn daegun_drawn;
typedef struct daegun_color_slots daegun_color_slots;
typedef struct {
uint32_t band_base;
uint32_t h_bands;
uint32_t v_bands;
uint32_t hull_base;
float box_min[2];
float box_max[2];
} daegun_glyph_slot;
typedef struct {
float x;
float y;
} daegun_curve_point;
typedef struct {
uint32_t first_curve;
uint32_t curve_count;
} daegun_band;
typedef struct {
float pos[2];
float dilate[4];
} daegun_hull_vertex;
typedef struct {
daegun_glyph_slot slot;
float tint[4];
} daegun_color_slot;
daegun_status daegun_batch_new(daegun_batch **out);
daegun_status daegun_batch_clear(daegun_batch *batch);
daegun_status daegun_batch_append(daegun_batch *batch, const float *quads, size_t count,
daegun_glyph_slot *out);
daegun_status daegun_batch_revision(const daegun_batch *batch, uint64_t *out);
const daegun_curve_point *daegun_batch_curves(const daegun_batch *batch, size_t *out_count);
const uint32_t *daegun_batch_band_curves(const daegun_batch *batch, size_t *out_count);
const daegun_band *daegun_batch_bands(const daegun_batch *batch, size_t *out_count);
const daegun_hull_vertex *daegun_batch_hulls(const daegun_batch *batch, size_t *out_count);
void daegun_batch_free(daegun_batch *batch);
daegun_status daegun_font_gpu_glyph(const daegun_font *font, daegun_batch *batch, uint16_t gid,
const daegun_axis *axes, size_t axes_len,
daegun_glyph_slot *out);
daegun_status daegun_font_gpu_color_glyph(const daegun_font *font, daegun_batch *batch,
uint16_t gid, const daegun_axis *axes, size_t axes_len,
uint16_t palette_index, daegun_color_slots **out);
daegun_status daegun_font_gpu_color_glyph_with(const daegun_font *font, daegun_batch *batch,
uint16_t gid, const daegun_axis *axes,
size_t axes_len, uint16_t palette_index,
const uint8_t foreground[4],
daegun_color_slots **out);
const daegun_color_slot *daegun_color_slots_data(const daegun_color_slots *slots,
size_t *out_count);
void daegun_color_slots_free(daegun_color_slots *slots);
#define DAEGUN_PREFER_AUTO 0
#define DAEGUN_PREFER_CPU 1
#define DAEGUN_PREFER_GPU 2
#define DAEGUN_PREFER_REFERENCE 3
typedef struct {
int32_t prefer;
bool strict;
bool has_cpu_below_ppem;
float cpu_below_ppem;
bool avoid_software_gpu;
} daegun_policy;
daegun_status daegun_policy_default(daegun_policy *out);
#define DAEGUN_DRAWN_NOTHING 0
#define DAEGUN_DRAWN_CPU 1
#define DAEGUN_DRAWN_GPU 2
#define DAEGUN_DRAWN_GPU_COLOR 3
#define DAEGUN_DRAWN_SCENE 4
#define DAEGUN_DRAWN_REFERENCE 5
#define DAEGUN_DRAWN_BATCH_FULL 6
#define DAEGUN_DRAWN_REFUSED 7
daegun_status daegun_font_draw_glyph(const daegun_font *font, daegun_batch *batch,
const void *device, const daegun_policy *policy, uint16_t gid,
float px, const daegun_axis *axes, size_t axes_len,
const daegun_raster_options *opts, int32_t palette,
daegun_drawn **out);
daegun_status daegun_font_draw_glyph_with(const daegun_font *font, daegun_batch *batch,
const void *device, const daegun_policy *policy,
uint16_t gid, float px, const daegun_axis *axes,
size_t axes_len, const daegun_raster_options *opts,
int32_t palette, const uint8_t foreground[4],
daegun_drawn **out);
daegun_status daegun_drawn_kind(const daegun_drawn *d, int32_t *out);
daegun_status daegun_drawn_is_ok(const daegun_drawn *d, bool *out);
daegun_status daegun_drawn_bitmap(const daegun_drawn *d, const daegun_bitmap **out);
daegun_status daegun_drawn_slot(const daegun_drawn *d, daegun_glyph_slot *out);
const daegun_color_slot *daegun_drawn_color_slots(const daegun_drawn *d, size_t *out_count);
daegun_status daegun_drawn_scene(const daegun_drawn *d, const daegun_scene **out);
void daegun_drawn_free(daegun_drawn *d);
typedef struct daegun_path daegun_path;
#define DAEGUN_VERB_MOVE 0
#define DAEGUN_VERB_LINE 1
#define DAEGUN_VERB_QUAD 2
#define DAEGUN_VERB_CUBIC 3
#define DAEGUN_VERB_CLOSE 4
typedef struct {
float width;
int32_t cap;
int32_t join;
float miter_limit;
} daegun_stroke_style;
daegun_path *daegun_path_new(void);
void daegun_path_free(daegun_path *path);
daegun_status daegun_path_move_to(daegun_path *path, float x, float y);
daegun_status daegun_path_line_to(daegun_path *path, float x, float y);
daegun_status daegun_path_quad_to(daegun_path *path, float cx, float cy, float x, float y);
daegun_status daegun_path_curve_to(daegun_path *path, float c1x, float c1y,
float c2x, float c2y, float x, float y);
daegun_status daegun_path_close(daegun_path *path);
daegun_status daegun_path_is_empty(const daegun_path *path, int32_t *out);
daegun_status daegun_path_cost(const daegun_path *path, size_t *out);
daegun_status daegun_path_bounds(const daegun_path *path, double *out_min_x, double *out_min_y,
double *out_max_x, double *out_max_y);
daegun_status daegun_path_verbs(const daegun_path *path, uint8_t *out, size_t capacity,
size_t *out_count);
daegun_status daegun_path_points(const daegun_path *path, float *out_x, float *out_y,
size_t capacity, size_t *out_count);
daegun_status daegun_path_replay(const daegun_path *path, const double *transform,
const daegun_pen *pen);
daegun_status daegun_path_as_pen(daegun_path *path, daegun_pen *out);
daegun_status daegun_path_stroke(const daegun_path *path, const daegun_stroke_style *style,
float tolerance, const daegun_pen *pen);
daegun_status daegun_path_stroke_simplified(const daegun_path *path,
const daegun_stroke_style *style,
float tolerance, const daegun_pen *pen);
typedef struct daegun_scene_builder daegun_scene_builder;
daegun_scene_builder *daegun_scene_builder_new(void);
void daegun_scene_builder_free(daegun_scene_builder *b);
daegun_status daegun_scene_builder_push_path(daegun_scene_builder *b, const daegun_path *path,
size_t *out_id);
#define DAEGUN_FILL_NONZERO 0
#define DAEGUN_FILL_EVENODD 1
daegun_status daegun_scene_builder_fill(daegun_scene_builder *b, size_t path_id,
const uint8_t rgba[4], int32_t rule,
const double transform[6]);
daegun_status daegun_scene_builder_render(const daegun_scene_builder *b, float px, float upem,
daegun_scene **out);
daegun_status daegun_scene_builder_is_empty(const daegun_scene_builder *b, bool *out);
daegun_status daegun_scene_builder_op_count(const daegun_scene_builder *b, size_t *out);
daegun_status daegun_scene_builder_path(const daegun_scene_builder *b, size_t path_id,
daegun_path **out);
daegun_status daegun_hinted_outline_draw(const daegun_hinted_outline *outline,
const daegun_pen *pen);
daegun_status daegun_font_table(const daegun_font *font, const char *tag, daegun_bytes *out);
daegun_status daegun_font_table_tags(const daegun_font *font, daegun_str_list **out);
daegun_status daegun_font_has_table(const daegun_font *font, const char *tag, int32_t *out);
typedef struct daegun_table_map daegun_table_map;
daegun_status daegun_font_instance_tables(const daegun_font *font, const daegun_axis *axes,
size_t axis_count, daegun_table_map **out);
daegun_status daegun_font_instance_table(const daegun_font *font, const daegun_axis *axes,
size_t axis_count, const char *tag, daegun_blob **out);
daegun_table_map *daegun_table_map_new(void);
void daegun_table_map_free(daegun_table_map *map);
daegun_status daegun_table_map_count(const daegun_table_map *map, size_t *out);
daegun_status daegun_table_map_tag_at(const daegun_table_map *map, size_t index, daegun_str *out);
daegun_status daegun_table_map_bytes_at(const daegun_table_map *map, size_t index,
daegun_bytes *out);
daegun_status daegun_table_map_get(const daegun_table_map *map, const char *tag, daegun_bytes *out);
daegun_status daegun_table_map_set(daegun_table_map *map, const char *tag,
const uint8_t *data, size_t len);
daegun_status daegun_table_map_remove(daegun_table_map *map, const char *tag);
daegun_status daegun_table_map_build(const daegun_table_map *map, daegun_blob **out);
daegun_status daegun_parse_loca(const uint8_t *loca, size_t len, int16_t format,
size_t num_glyphs, daegun_usize_list **out);
daegun_status daegun_outline_glyf_bytes(const uint8_t *glyf, size_t glyf_len,
const size_t *loca, size_t loca_len,
uint16_t glyph, const daegun_pen *pen);
daegun_status daegun_read_u16_be(const uint8_t *data, size_t len, size_t off, uint16_t *out);
daegun_status daegun_read_i16_be(const uint8_t *data, size_t len, size_t off, int16_t *out);
daegun_status daegun_read_u24_be(const uint8_t *data, size_t len, size_t off, uint32_t *out);
daegun_status daegun_read_u32_be(const uint8_t *data, size_t len, size_t off, uint32_t *out);
daegun_status daegun_read_offset24(const uint8_t *data, size_t len, size_t off, size_t *out);
daegun_status daegun_write_u16_be(uint8_t *data, size_t len, size_t off, uint16_t value);
daegun_status daegun_write_i16_be(uint8_t *data, size_t len, size_t off, int16_t value);
daegun_status daegun_write_u32_be(uint8_t *data, size_t len, size_t off, uint32_t value);
daegun_status daegun_write_offset24(uint8_t *data, size_t len, size_t off, size_t value);
int32_t daegun_records_fit(size_t start, size_t count, size_t stride, size_t len);
const uint8_t *daegun_bytes_window(const uint8_t *data, size_t len, size_t off, size_t n);
daegun_status daegun_search_records(size_t count, uint32_t target,
int32_t (*key_at)(size_t index, void *user, uint32_t *out_key),
void *user, size_t *out_index, int32_t *out_found);
int32_t daegun_ot_round(double value);
daegun_status daegun_coverage_index(const uint8_t *data, size_t len, uint16_t glyph, uint16_t *out);
daegun_status daegun_coverage_glyphs(const uint8_t *buf, size_t len, size_t off,
daegun_u16_list **out);
typedef struct daegun_aat_lookup daegun_aat_lookup;
daegun_status daegun_aat_lookup_open(const uint8_t *data, size_t len, uint16_t num_glyphs,
daegun_aat_lookup **out);
daegun_status daegun_aat_lookup_value(const daegun_aat_lookup *lookup, uint16_t glyph,
uint16_t *out);
daegun_status daegun_aat_lookup_entries(const daegun_aat_lookup *lookup,
daegun_glyph_value_list **out);
void daegun_aat_lookup_free(daegun_aat_lookup *lookup);
typedef struct {
uint16_t new_state;
uint16_t flags;
uint16_t word1;
uint16_t word2;
} daegun_aat_entry;
#define DAEGUN_AAT_CLASS_END_OF_TEXT 0
#define DAEGUN_AAT_CLASS_DELETED_GLYPH 2
#define DAEGUN_AAT_STATE_START_OF_TEXT 0
typedef struct daegun_aat_state_table daegun_aat_state_table;
daegun_status daegun_aat_state_table_open(const uint8_t *data, size_t len, size_t extra_words,
uint16_t num_glyphs, daegun_aat_state_table **out);
daegun_status daegun_aat_state_table_class(const daegun_aat_state_table *table, uint16_t glyph,
uint16_t *out);
daegun_status daegun_aat_state_table_entry(const daegun_aat_state_table *table, uint16_t state,
uint16_t class_, daegun_aat_entry *out);
void daegun_aat_state_table_free(daegun_aat_state_table *table);
typedef struct daegun_ankr daegun_ankr;
daegun_status daegun_ankr_version(const uint8_t *data, size_t len, uint16_t *out);
daegun_status daegun_ankr_control_point(const uint8_t *data, size_t len, size_t at,
int16_t *out_x, int16_t *out_y);
daegun_status daegun_ankr_open(const uint8_t *data, size_t len, uint16_t num_glyphs,
daegun_ankr **out);
daegun_status daegun_ankr_point_count(const daegun_ankr *ankr, uint16_t glyph, uint32_t *out);
daegun_status daegun_ankr_anchor_point(const daegun_ankr *ankr, uint16_t glyph, uint16_t index,
int16_t *out_x, int16_t *out_y);
void daegun_ankr_free(daegun_ankr *ankr);
typedef struct daegun_feature_variations daegun_feature_variations;
daegun_status daegun_feature_variations_open(const uint8_t *layout, size_t len,
daegun_feature_variations **out);
daegun_status daegun_feature_variations_at(const uint8_t *layout, size_t len, size_t at,
daegun_feature_variations **out);
daegun_status daegun_feature_variations_find(const daegun_feature_variations *vars,
const int32_t *coords, size_t coord_count,
uint16_t *out);
daegun_status daegun_feature_variations_substitute(const daegun_feature_variations *vars,
uint16_t variation, uint16_t feature,
size_t *out);
void daegun_feature_variations_free(daegun_feature_variations *vars);
typedef struct {
double start;
double peak;
double end;
} daegun_region_axis;
typedef struct daegun_ivs daegun_ivs;
daegun_status daegun_ivs_parse(const uint8_t *buf, size_t len, size_t base, daegun_ivs **out);
daegun_status daegun_ivs_axis_count(const daegun_ivs *ivs, size_t *out);
daegun_status daegun_ivs_region_count(const daegun_ivs *ivs, size_t *out);
daegun_status daegun_ivs_region_axis(const daegun_ivs *ivs, size_t region, size_t axis,
daegun_region_axis *out);
daegun_status daegun_ivs_ivd_count(const daegun_ivs *ivs, size_t *out);
daegun_status daegun_ivs_ivd_rows(const daegun_ivs *ivs, size_t ivd, size_t *out);
const size_t *daegun_ivs_ivd_region_indices(const daegun_ivs *ivs, size_t ivd, size_t *out_count);
const int32_t *daegun_ivs_ivd_row(const daegun_ivs *ivs, size_t ivd, size_t inner,
size_t *out_count);
daegun_status daegun_ivs_region_scalars(const daegun_ivs *ivs, const double *location,
size_t axis_count, daegun_f64_list **out);
daegun_status daegun_ivs_delta(const daegun_ivs *ivs, size_t outer, size_t inner,
const double *scalars, size_t scalar_count, double *out);
void daegun_ivs_free(daegun_ivs *ivs);
typedef struct daegun_delta_set_index_map daegun_delta_set_index_map;
daegun_status daegun_delta_set_index_map_parse(const uint8_t *buf, size_t len, size_t base,
daegun_delta_set_index_map **out);
daegun_status daegun_delta_set_index_map_count(const daegun_delta_set_index_map *map, size_t *out);
daegun_status daegun_delta_set_index_map_lookup(const daegun_delta_set_index_map *map, size_t index,
size_t *out_outer, size_t *out_inner);
void daegun_delta_set_index_map_free(daegun_delta_set_index_map *map);
#define DAEGUN_GC_UNASSIGNED 0
#define DAEGUN_GC_CONTROL 1
#define DAEGUN_GC_FORMAT 2
#define DAEGUN_GC_PRIVATE_USE 3
#define DAEGUN_GC_SURROGATE 4
#define DAEGUN_GC_LOWERCASE_LETTER 5
#define DAEGUN_GC_MODIFIER_LETTER 6
#define DAEGUN_GC_OTHER_LETTER 7
#define DAEGUN_GC_TITLECASE_LETTER 8
#define DAEGUN_GC_UPPERCASE_LETTER 9
#define DAEGUN_GC_SPACING_MARK 10
#define DAEGUN_GC_ENCLOSING_MARK 11
#define DAEGUN_GC_NONSPACING_MARK 12
#define DAEGUN_GC_DECIMAL_NUMBER 13
#define DAEGUN_GC_LETTER_NUMBER 14
#define DAEGUN_GC_OTHER_NUMBER 15
#define DAEGUN_GC_CONNECT_PUNCTUATION 16
#define DAEGUN_GC_DASH_PUNCTUATION 17
#define DAEGUN_GC_CLOSE_PUNCTUATION 18
#define DAEGUN_GC_FINAL_PUNCTUATION 19
#define DAEGUN_GC_INITIAL_PUNCTUATION 20
#define DAEGUN_GC_OTHER_PUNCTUATION 21
#define DAEGUN_GC_OPEN_PUNCTUATION 22
#define DAEGUN_GC_CURRENCY_SYMBOL 23
#define DAEGUN_GC_MODIFIER_SYMBOL 24
#define DAEGUN_GC_MATH_SYMBOL 25
#define DAEGUN_GC_OTHER_SYMBOL 26
#define DAEGUN_GC_LINE_SEPARATOR 27
#define DAEGUN_GC_PARAGRAPH_SEPARATOR 28
#define DAEGUN_GC_SPACE_SEPARATOR 29
daegun_status daegun_char_general_category(uint32_t codepoint, int32_t *out);
daegun_status daegun_char_is_upright(uint32_t codepoint, int32_t has_vertical_form, int32_t *out);
daegun_status daegun_char_vertical_form(uint32_t codepoint, uint32_t *out);
#define DAEGUN_SHADER_GLSL 0
#define DAEGUN_SHADER_HLSL 1
#define DAEGUN_SHADER_MSL 2
#define DAEGUN_STAGE_VERTEX 0
#define DAEGUN_STAGE_FRAGMENT 1
#define DAEGUN_STAGE_SUBPIXEL_FRAGMENT 2
daegun_status daegun_shader_source(int32_t language, int32_t stage, daegun_text **out);
typedef struct {
float glyph_box[4];
float tint[4];
float offset[2];
float em_pixels[2];
float scale;
uint32_t band_base;
uint32_t bands_per_axis;
uint32_t hull_base;
float inv_scale;
float _pad[3];
} daegun_glyph_instance;
#define DAEGUN_MAX_SUBPIXEL_WEIGHTS 64
#define DAEGUN_MAX_SUBPIXEL_TAPS 8
#define DAEGUN_MAX_SUPERSAMPLE 4
typedef struct {
float weights[DAEGUN_MAX_SUBPIXEL_WEIGHTS * 3];
uint32_t oversample[2];
uint32_t taps[2];
int32_t origin[2];
uint32_t channels;
uint32_t supersample;
} daegun_subpixel_params;
daegun_status daegun_glyph_slot_instance(const daegun_glyph_slot *slot, const float *offset,
float scale, const float *em_pixels, const float *tint,
daegun_glyph_instance *out);
daegun_status daegun_subpixel_params_from_layout(int32_t layout, daegun_subpixel_params *out);
#define DAEGUN_MODE_GRAYSCALE 0
#define DAEGUN_MODE_SUBPIXEL 1
typedef struct daegun_device_profile daegun_device_profile;
#define DAEGUN_DEVICE_UNKNOWN 0
#define DAEGUN_DEVICE_DISCRETE 1
#define DAEGUN_DEVICE_INTEGRATED 2
#define DAEGUN_DEVICE_VIRTUAL 3
#define DAEGUN_DEVICE_SOFTWARE 4
daegun_status daegun_device_profile_new(int32_t kind, const char *name,
daegun_device_profile **out);
daegun_status daegun_device_profile_from_vulkan(int32_t device_type, const char *name,
daegun_device_profile **out);
daegun_status daegun_device_profile_kind(const daegun_device_profile *profile, int32_t *out);
daegun_status daegun_device_profile_name(const daegun_device_profile *profile, daegun_text **out);
void daegun_device_profile_free(daegun_device_profile *profile);
#define DAEGUN_GPU_OK 0
#define DAEGUN_GPU_NO_OUTLINE 1
#define DAEGUN_GPU_TOO_COMPLEX 2
#define DAEGUN_GPU_NON_FINITE 3
#define DAEGUN_GPU_BATCH_FULL 4
#define DAEGUN_GPU_NOT_FLAT_COLOR 5
#define DAEGUN_ROUTED_NOTHING 0
#define DAEGUN_ROUTED_CPU 1
#define DAEGUN_ROUTED_GPU 2
#define DAEGUN_ROUTED_REFERENCE 3
#define DAEGUN_ROUTED_SCENE 4
#define DAEGUN_ROUTED_FLUSH_AND_RETRY 5
#define DAEGUN_ROUTED_REFUSED_NON_FINITE 6
#define DAEGUN_ROUTED_REFUSED_PREFERENCE_UNMET 7
typedef struct {
float ppem;
int32_t hinted;
int32_t stroked;
int32_t gamma;
int32_t emboldened;
int32_t obliqued;
} daegun_request;
daegun_status daegun_route(int32_t attempt, const daegun_request *request,
const daegun_device_profile *device, const daegun_policy *policy,
int32_t *out);
#define DAEGUN_REFUSAL_NO_DEVICE 0
#define DAEGUN_REFUSAL_BAD_TARGET 1
#define DAEGUN_REFUSAL_UNSUPPORTED 2
#define DAEGUN_REFUSAL_FAILED 3
#define DAEGUN_DECLARE_BACKEND(b) \
typedef struct daegun_##b##_renderer daegun_##b##_renderer; \
typedef struct daegun_##b##_target daegun_##b##_target; \
typedef struct daegun_##b##_geometry daegun_##b##_geometry; \
\
\
daegun_status daegun_##b##_renderer_new(daegun_##b##_renderer **out); \
\
void daegun_##b##_renderer_free(daegun_##b##_renderer *renderer); \
\
daegun_status daegun_##b##_renderer_device_name(const daegun_##b##_renderer *renderer, \
daegun_text **out); \
\
daegun_status daegun_##b##_renderer_profile(const daegun_##b##_renderer *renderer, \
daegun_device_profile **out); \
daegun_status daegun_##b##_renderer_supports_subpixel(const daegun_##b##_renderer *renderer, \
int32_t *out); \
\
daegun_status daegun_##b##_ortho(uint32_t width, uint32_t height, float *out); \
\
daegun_status daegun_##b##_target_new(const daegun_##b##_renderer *renderer, \
uint32_t width, uint32_t height, \
daegun_##b##_target **out); \
daegun_status daegun_##b##_target_width(const daegun_##b##_target *target, uint32_t *out); \
daegun_status daegun_##b##_target_height(const daegun_##b##_target *target, uint32_t *out); \
\
const uint8_t *daegun_##b##_target_pixels(const daegun_##b##_target *target, \
size_t *out_count); \
\
daegun_status daegun_##b##_target_pixel(const daegun_##b##_target *target, \
uint32_t x, uint32_t y, uint8_t *out); \
void daegun_##b##_target_free(daegun_##b##_target *target); \
\
daegun_status daegun_##b##_target_with_format(const daegun_##b##_renderer *renderer, \
uint32_t width, uint32_t height, int32_t format, \
daegun_##b##_target **out); \
\
daegun_status daegun_##b##_target_set_clear(daegun_##b##_target *target, \
const uint8_t clear[4]); \
\
daegun_status daegun_##b##_geometry_new(const daegun_##b##_renderer *renderer, \
const daegun_batch *batch, \
daegun_##b##_geometry **out); \
\
daegun_status daegun_##b##_geometry_revision(const daegun_##b##_geometry *geometry, \
uint64_t *out); \
void daegun_##b##_geometry_free(daegun_##b##_geometry *geometry); \
\
daegun_status daegun_##b##_draw(const daegun_##b##_renderer *renderer, \
daegun_##b##_target *target, \
const daegun_##b##_geometry *geometry, \
const daegun_glyph_instance *instances, size_t instance_count, \
const daegun_subpixel_params *subpixel, int32_t mode); \
\
daegun_status daegun_##b##_draw_with(const daegun_##b##_renderer *renderer, \
daegun_##b##_target *target, \
const daegun_##b##_geometry *geometry, \
const daegun_glyph_instance *instances, \
size_t instance_count, \
const daegun_subpixel_params *subpixel, int32_t mode, \
const float *projection); \
daegun_status daegun_##b##_wait(const daegun_##b##_renderer *renderer, \
daegun_##b##_target *target); \
\
const uint8_t *daegun_##b##_read_pixels(const daegun_##b##_renderer *renderer, \
daegun_##b##_target *target, size_t *out_count)
#define DAEGUN_SURFACE_RGBA8 0
#define DAEGUN_SURFACE_BGRA8 1
#if defined(__APPLE__)
DAEGUN_DECLARE_BACKEND(metal);
daegun_status daegun_metal_geometry_sync(daegun_metal_geometry *geometry,
const daegun_metal_renderer *renderer,
const daegun_batch *batch);
daegun_status daegun_metal_renderer_from_device(void *device, daegun_metal_renderer **out);
daegun_status daegun_metal_target_from_texture(const daegun_metal_renderer *renderer, void *texture,
uint32_t width, uint32_t height,
daegun_metal_target **out);
daegun_status daegun_metal_target_from_drawable(const daegun_metal_renderer *renderer,
void *drawable, uint32_t width, uint32_t height,
daegun_metal_target **out);
#endif
DAEGUN_DECLARE_BACKEND(vulkan);
daegun_status daegun_vulkan_target_from_image(const daegun_vulkan_renderer *renderer,
uint64_t image, uint32_t width, uint32_t height,
int32_t format, daegun_vulkan_target **out);
daegun_status daegun_vulkan_renderer_handles(const daegun_vulkan_renderer *renderer,
void **out_instance, void **out_physical_device,
void **out_device, uint32_t *out_queue_family);
daegun_status daegun_vulkan_renderer_from_device(void *instance, void *physical_device,
void *device, uint32_t queue_family,
int32_t dual_src_blend,
daegun_vulkan_renderer **out);
#if defined(_WIN32)
DAEGUN_DECLARE_BACKEND(d3d11);
DAEGUN_DECLARE_BACKEND(d3d12);
daegun_status daegun_d3d11_feature_level(const daegun_d3d11_renderer *renderer, daegun_text **out);
daegun_status daegun_d3d11_is_software(const daegun_d3d11_renderer *renderer, int32_t *out);
daegun_status daegun_d3d11_renderer_handles(const daegun_d3d11_renderer *renderer,
void **out_device, void **out_second);
daegun_status daegun_d3d11_renderer_from_device(void *device, void *context,
daegun_d3d11_renderer **out);
daegun_status daegun_d3d12_renderer_from_device(void *device, void *queue,
daegun_d3d12_renderer **out);
daegun_status daegun_d3d11_target_from_texture(const daegun_d3d11_renderer *renderer, void *texture,
uint32_t width, uint32_t height, int32_t format,
daegun_d3d11_target **out);
daegun_status daegun_d3d12_target_from_texture(const daegun_d3d12_renderer *renderer, void *texture,
uint32_t width, uint32_t height, int32_t format,
daegun_d3d12_target **out);
daegun_status daegun_d3d12_feature_level(const daegun_d3d12_renderer *renderer, daegun_text **out);
daegun_status daegun_d3d12_is_software(const daegun_d3d12_renderer *renderer, int32_t *out);
daegun_status daegun_d3d12_renderer_handles(const daegun_d3d12_renderer *renderer,
void **out_device, void **out_second);
#endif
typedef struct {
size_t x;
size_t y;
size_t w;
size_t h;
} daegun_rect;
typedef struct daegun_shelf_packer daegun_shelf_packer;
daegun_shelf_packer *daegun_shelf_packer_new(size_t width, size_t height);
void daegun_shelf_packer_free(daegun_shelf_packer *packer);
daegun_status daegun_shelf_packer_insert(daegun_shelf_packer *packer, size_t width, size_t height,
daegun_rect *out);
daegun_status daegun_shelf_packer_reset(daegun_shelf_packer *packer);
daegun_status daegun_line_metrics_height(const daegun_line_metrics *metrics, double *out);
daegun_status daegun_subset_new_gid(const daegun_subset *subset, uint16_t old_gid, uint16_t *out);
daegun_status daegun_hint_mode_may_autohint(int32_t mode, int32_t *out);
daegun_status daegun_cluster_level_is_graphemes(int32_t level, int32_t *out);
daegun_status daegun_cluster_level_is_monotone(int32_t level, int32_t *out);
daegun_status daegun_script_opentype_tags(uint16_t script, daegun_str_list **out);
daegun_status daegun_script_is_context_dependent(uint16_t script, int32_t *out);
#define DAEGUN_STAT_SINGLE 0
#define DAEGUN_STAT_RANGE 1
#define DAEGUN_STAT_LINKED 2
#define DAEGUN_STAT_COMBO 3
typedef struct {
int32_t kind;
uint16_t axis_index;
uint8_t elidable;
uint8_t has_name;
double value;
double min;
double max;
double linked_value;
uint32_t combo_start;
uint32_t combo_count;
} daegun_stat_value;
typedef struct {
uint16_t axis_index;
double value;
} daegun_axis_value;
daegun_status daegun_stat_value_at(const daegun_stat *stat, size_t index, daegun_stat_value *out);
daegun_status daegun_stat_value_name(const daegun_stat *stat, size_t index, daegun_str *out);
const daegun_axis_value *daegun_stat_combo_values(const daegun_stat *stat, size_t *out_count);
daegun_status daegun_device_profile_from_d3d(int32_t software, int32_t uma, const char *name,
daegun_device_profile **out);
daegun_status daegun_device_profile_from_metal(int32_t uma, const char *name,
daegun_device_profile **out);
daegun_status daegun_device_profile_is_software(const daegun_device_profile *profile, int32_t *out);
daegun_status daegun_glyph_slot_instance_affine(const daegun_glyph_slot *slot, const float *offset,
float scale, const float *transform,
const float *tint, daegun_glyph_instance *out);
daegun_status daegun_subpixel_params_dilation(const daegun_subpixel_params *params, float *out);
daegun_status daegun_subpixel_params_pad(const daegun_subpixel_params *params, size_t *out);
daegun_status daegun_subpixel_params_with_supersampling(const daegun_subpixel_params *params,
uint32_t n, daegun_subpixel_params *out);
daegun_status daegun_subpixel_params_from_weights(uint8_t oversample_x, uint8_t oversample_y,
uint8_t taps_x, uint8_t taps_y,
int8_t origin_x, int8_t origin_y,
const float *weights,
daegun_subpixel_params *out);
daegun_status daegun_subpixel_layout_key(int32_t layout, uint64_t *out);
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(daegun_status) == 4, "status must be an int32");
_Static_assert(sizeof(daegun_bytes) == 2 * sizeof(size_t), "bytes view must be two words");
_Static_assert(sizeof(daegun_str) == 2 * sizeof(size_t), "string view must be two words");
_Static_assert(sizeof(daegun_raster_options) == 80, "raster options must be twenty words");
_Static_assert(sizeof(daegun_line_metrics) == 24, "line metrics must be three doubles");
_Static_assert(sizeof(daegun_typographic_metrics) == 52, "typographic metrics must be thirteen ints");
_Static_assert(sizeof(daegun_axis) == sizeof(void *) + 8, "an axis is a pointer and a double");
_Static_assert(sizeof(daegun_pen) == 6 * sizeof(void *), "a pen is six pointers");
_Static_assert(sizeof(daegun_colr_layer) == 8, "a COLR v0 layer is eight bytes");
_Static_assert(sizeof(daegun_glyph_value) == 4, "a glyph-value pair is two uint16");
_Static_assert(sizeof(daegun_aat_entry) == 8, "a state-table entry is four uint16");
_Static_assert(sizeof(daegun_region_axis) == 24, "a region axis is three doubles");
_Static_assert(sizeof(daegun_stroke_style) == 16, "a stroke style is four words");
_Static_assert(sizeof(daegun_glyph_instance) == 80, "a glyph instance is twenty words");
_Static_assert(sizeof(daegun_subpixel_params) == 800, "subpixel params are two hundred words");
_Static_assert(sizeof(daegun_request) == 24, "a request is a float and five ints");
_Static_assert(sizeof(daegun_rect) == 4 * sizeof(size_t), "a rect is four size_t");
_Static_assert(sizeof(daegun_stat_value) == 48, "a STAT value is six words and four doubles");
_Static_assert(sizeof(daegun_axis_value) == 16, "an axis value is a uint16 and a double");
_Static_assert(sizeof(daegun_feature) == 16, "a feature is a tag, a value and a range");
_Static_assert(sizeof(daegun_glyph_slot) == 32, "a glyph slot is four uints and two float pairs");
_Static_assert(sizeof(daegun_layout_options) == 64, "layout options are sixteen words");
_Static_assert(sizeof(daegun_metrics) == 48, "glyph metrics are twelve words");
_Static_assert(sizeof(daegun_os2_info) == 36, "OS/2 info is nine words");
_Static_assert(sizeof(daegun_paint_node) == 96, "a paint node is eight doubles and its tags");
_Static_assert(sizeof(daegun_palette_info) == 8, "palette info is two words");
_Static_assert(sizeof(daegun_policy) == 16, "a policy is four words");
_Static_assert(sizeof(daegun_shape_options) == 80, "shape options are twenty words");
_Static_assert(offsetof(daegun_glyph_slot, band_base) == 0, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_slot, h_bands) == 4, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_slot, v_bands) == 8, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_slot, hull_base) == 12, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_slot, box_min) == 16, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_slot, box_max) == 24, "glyph slot layout");
_Static_assert(offsetof(daegun_glyph_instance, glyph_box) == 0, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, tint) == 16, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, offset) == 32, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, em_pixels) == 40, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, scale) == 48, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, band_base) == 52, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, bands_per_axis) == 56, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, hull_base) == 60, "glyph instance layout");
_Static_assert(offsetof(daegun_glyph_instance, inv_scale) == 64, "glyph instance layout");
_Static_assert(offsetof(daegun_subpixel_params, weights) == 0, "subpixel params layout");
_Static_assert(offsetof(daegun_subpixel_params, oversample) == 768, "subpixel params layout");
_Static_assert(offsetof(daegun_subpixel_params, taps) == 776, "subpixel params layout");
_Static_assert(offsetof(daegun_subpixel_params, origin) == 784, "subpixel params layout");
_Static_assert(offsetof(daegun_subpixel_params, channels) == 792, "subpixel params layout");
_Static_assert(offsetof(daegun_subpixel_params, supersample) == 796, "subpixel params layout");
_Static_assert(sizeof(daegun_curve_point) == 8, "a curve point is two floats");
_Static_assert(sizeof(daegun_band) == 8, "a band is two uint32");
_Static_assert(offsetof(daegun_band, curve_count) == 4, "band layout");
_Static_assert(sizeof(daegun_hull_vertex) == 24, "a hull vertex is six floats");
_Static_assert(offsetof(daegun_hull_vertex, dilate) == 8, "hull vertex layout");
_Static_assert(sizeof(daegun_color_slot) == 48, "a color slot is a glyph slot and a tint");
_Static_assert(offsetof(daegun_color_slot, tint) == 32, "color slot layout");
#endif
#ifdef __cplusplus
}
#endif
#endif