You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
3.3 KiB
207 lines
3.3 KiB
#include <math.h> |
|
#include <wchar.h> // wchar_t, wcslen |
|
#include <stdbool.h> |
|
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
|
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
|
|
|
#define MAX_INTERSECTIONS 16 |
|
#define F32EPS 1e-5f |
|
#define MAX_CONTOURS 256 |
|
|
|
#define TTF_ENGINE_STACK 4096 |
|
|
|
#define ASSERT(expr) if (!(expr)) { fprintf(stderr, "[ASSERT] Assertion fail %s:%d\n", __FILE__, __LINE__); abort(); } |
|
|
|
struct v2 { |
|
int x; |
|
int y; |
|
}; |
|
|
|
struct v2u32 { |
|
u32 x; |
|
u32 y; |
|
}; |
|
|
|
struct v2f { |
|
f32 x; |
|
f32 y; |
|
}; |
|
|
|
struct line { |
|
struct v2f a; |
|
struct v2f b; |
|
}; |
|
|
|
struct line_contour { |
|
int ncontours; |
|
int from[MAX_CONTOURS]; |
|
struct line *data; |
|
}; |
|
|
|
struct intersection { |
|
f32 x; |
|
int dir; |
|
}; |
|
|
|
enum rgb_channel { |
|
RED = 0x000000FF, |
|
GREEN = 0x0000FF00, |
|
BLUE = 0x00FF0000, |
|
}; |
|
|
|
struct font_buffer { |
|
u8 *data; |
|
u64 offset; |
|
u64 size; |
|
}; |
|
|
|
struct font_directory { |
|
u32 cmap_offset; |
|
u32 head_offset; |
|
u32 hhea_offset; |
|
u32 loca_offset; |
|
u32 glyf_offset; |
|
u32 hmtx_offset; |
|
u32 maxp_offset; |
|
u32 post_offset; |
|
|
|
u32 cvt_offset; |
|
u32 cvt_size; |
|
|
|
u32 prep_offset; |
|
u32 prep_size; |
|
|
|
u32 fpgm_offset; |
|
u32 fpgm_size; |
|
}; |
|
|
|
union glyph_flag { |
|
struct { |
|
u8 on_curve : 1; |
|
u8 x_short : 1; |
|
u8 y_short : 1; |
|
u8 repeat : 1; |
|
u8 x_short_pos : 1; |
|
u8 y_short_pos : 1; |
|
u8 reserved1 : 1; |
|
u8 reserved2 : 1; |
|
}; |
|
u8 flag; |
|
}; |
|
|
|
enum compund_glyph_flag { |
|
ARG_1_AND_2_ARE_WORDS = 0x1, |
|
ARGS_ARE_XY_VALUES = 0x2, |
|
ROUND_XY_TO_GRID = 0x4, |
|
WE_HAVE_A_SCALE = 0x8, |
|
|
|
MORE_COMPONENTS = 0x20, |
|
WE_HAVE_AN_X_AND_Y_SCALE = 0x40, |
|
WE_HAVE_A_TWO_BY_TWO = 0x80, |
|
WE_HAVE_INSTRUCTIONS = 0x100, |
|
USE_MY_METRICS = 0x200, |
|
OVERLAP_COMPOUND = 0x400 |
|
}; |
|
|
|
struct maxp_table { |
|
u16 max_component_points; |
|
u16 max_component_contours; |
|
u16 max_storage; |
|
u16 max_fdefs; |
|
}; |
|
|
|
struct head_table { |
|
int itl_format; |
|
int units_per_em; |
|
}; |
|
|
|
struct hhea_table { |
|
int ascent; |
|
int descent; |
|
int line_gap; |
|
int max_advance; |
|
}; |
|
|
|
struct glyph_point { |
|
s16 x; |
|
s16 y; |
|
bool on_curve; |
|
}; |
|
|
|
struct glyph_segment { |
|
bool is_curve; |
|
struct v2f p0; |
|
struct v2f p1; |
|
struct v2f p2; |
|
}; |
|
|
|
struct glyph { |
|
s16 xmin, ymin; |
|
s16 xmax, ymax; |
|
|
|
s32 baseline; |
|
u16 advance; |
|
s16 lsb; |
|
|
|
u16 ncontours; |
|
u16 *end_pts_of_contours; |
|
struct glyph_point *points; |
|
}; |
|
|
|
struct ttf_font { |
|
struct font_buffer file; |
|
|
|
struct maxp_table maxp; |
|
struct head_table head; |
|
struct hhea_table hhea; |
|
|
|
s16 *cvt; |
|
int cmap_format; |
|
int is_monospace; |
|
|
|
struct font_directory dir; |
|
struct ttf_function *functions; |
|
|
|
u32 *storage; |
|
|
|
char *name; |
|
}; |
|
|
|
static int |
|
clamp_u32(u32 val, u32 cap) |
|
{ |
|
u32 result = val; |
|
if (val > cap) result = cap; |
|
return(result); |
|
} |
|
|
|
static f32 |
|
abs_f32(f32 v) |
|
{ |
|
f32 result = (v > 0 ? v : -v); |
|
return(result); |
|
} |
|
|
|
static int |
|
round_f32(f32 v) |
|
{ |
|
int towards_zero = (int) v; |
|
f32 diff = abs_f32(v - towards_zero); |
|
|
|
if (diff >= 0.5f) { |
|
return(v > 0 ? towards_zero + 1 : towards_zero - 1); |
|
} else { |
|
return(towards_zero); |
|
} |
|
} |
|
|
|
static int |
|
ceil_f32(f32 v) |
|
{ |
|
int trunc = v; |
|
if (v - trunc < F32EPS) { |
|
return(trunc); |
|
} |
|
return(trunc + 1); |
|
}
|
|
|