2025-04-26 10:51:41 +03:00

538 lines
20 KiB
Plaintext

// TODO: generate this automatically
// ----------------------------------------
STBTT_MACSTYLE_DONTCARE :: 0;
STBTT_MACSTYLE_BOLD :: 1;
STBTT_MACSTYLE_ITALIC :: 2;
STBTT_MACSTYLE_UNDERSCORE :: 4;
STBTT_MACSTYLE_NONE :: 8;
// private structure
stbtt__buf :: struct {
data: *u8;
cursor: s32;
size: s32;
}
//////////////////////////////////////////////////////////////////////////////
//
// TEXTURE BAKING API
//
// If you use this API, you only have to call two functions ever.
//
stbtt_bakedchar :: struct {
x0: u16; // coordinates of bbox in bitmap
y0: u16; // coordinates of bbox in bitmap
x1: u16; // coordinates of bbox in bitmap
y1: u16; // coordinates of bbox in bitmap
xoff: float;
yoff: float;
xadvance: float;
}
// if return is positive, the first unused row of the bitmap
// if return is negative, returns the negative of the number of characters that fit
// if return is 0, no characters fit and no rows were used
// This uses a very crappy packing.
stbtt_aligned_quad :: struct {
x0: float; // top-left
y0: float; // top-left
s0: float; // top-left
t0: float; // top-left
x1: float; // bottom-right
y1: float; // bottom-right
s1: float; // bottom-right
t1: float; // bottom-right
}
//////////////////////////////////////////////////////////////////////////////
//
// NEW TEXTURE BAKING API
//
// This provides options for packing multiple fonts into one atlas, not
// perfectly but better than nothing.
stbtt_packedchar :: struct {
x0: u16; // coordinates of bbox in bitmap
y0: u16; // coordinates of bbox in bitmap
x1: u16; // coordinates of bbox in bitmap
y1: u16; // coordinates of bbox in bitmap
xoff: float;
yoff: float;
xadvance: float;
xoff2: float;
yoff2: float;
}
// stbrp_rect :: struct {}
// Creates character bitmaps from the font_index'th font found in fontdata (use
// font_index=0 if you don't know what that is). It creates num_chars_in_range
// bitmaps for characters with unicode values starting at first_unicode_char_in_range
// and increasing. Data for how to render them is stored in chardata_for_range;
// pass these to stbtt_GetPackedQuad to get back renderable quads.
//
// font_size is the full height of the character from ascender to descender,
// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
// and pass that result as 'font_size':
// ..., 20 , ... // font max minus min y is 20 pixels tall
// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
stbtt_pack_range :: struct {
font_size: float;
first_unicode_codepoint_in_range: s32; // if non-zero, then the chars are continuous, and this is the first codepoint
array_of_unicode_codepoints: *s32; // if non-zero, then this is an array of unicode codepoints
num_chars: s32;
chardata_for_range: *stbtt_packedchar; // output
h_oversample: u8; // don't set these, they're used internally
v_oversample: u8; // don't set these, they're used internally
}
// this is an opaque structure that you shouldn't mess with which holds
// all the context needed from PackBegin to PackEnd.
stbtt_pack_context :: struct {
user_allocator_context: *void;
pack_info: *void;
width: s32;
height: s32;
stride_in_bytes: s32;
padding: s32;
skip_missing: s32;
h_oversample: u32;
v_oversample: u32;
pixels: *u8;
nodes: *void;
}
// The following structure is defined publicly so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque.
stbtt_fontinfo :: struct {
userdata: *void;
data: *u8; // pointer to .ttf file
fontstart: s32; // offset of start of font
numGlyphs: s32; // number of glyphs, needed for range checking
loca: s32; // table locations as offset from start of .ttf
head: s32; // table locations as offset from start of .ttf
glyf: s32; // table locations as offset from start of .ttf
hhea: s32; // table locations as offset from start of .ttf
hmtx: s32; // table locations as offset from start of .ttf
kern: s32; // table locations as offset from start of .ttf
gpos: s32; // table locations as offset from start of .ttf
svg: s32; // table locations as offset from start of .ttf
index_map: s32; // a cmap mapping for our chosen character encoding
indexToLocFormat: s32; // format needed to map from glyph index to glyph
cff: stbtt__buf; // cff font data
charstrings: stbtt__buf; // the charstring index
gsubrs: stbtt__buf; // global charstring subroutines index
subrs: stbtt__buf; // private charstring subroutines index
fontdicts: stbtt__buf; // array of font dicts
fdselect: stbtt__buf; // map from glyph to fontdict
}
// as above, but takes one or more glyph indices for greater efficiency
stbtt_kerningentry :: struct {
glyph1: s32; // use stbtt_FindGlyphIndex
glyph2: s32;
advance: s32;
}
STBTT :: enum u32 {
vmove :: 1;
vline :: 2;
vcurve :: 3;
vcubic :: 4;
STBTT_vmove :: vmove;
STBTT_vline :: vline;
STBTT_vcurve :: vcurve;
STBTT_vcubic :: vcubic;
}
stbtt_vertex :: struct {
x: s16;
y: s16;
cx: s16;
cy: s16;
cx1: s16;
cy1: s16;
type: u8;
padding: u8;
}
// @TODO: don't expose this structure
stbtt__bitmap :: struct {
w: s32;
h: s32;
stride: s32;
pixels: *u8;
}
// returns the string (which may be big-endian double byte, e.g. for unicode)
// and puts the length in bytes in *length.
//
// some of the values for the IDs are below; for more see the truetype spec:
// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
// http://www.microsoft.com/typography/otspec/name.htm
STBTT_PLATFORM_ID :: enum u32 {
UNICODE :: 0;
MAC :: 1;
ISO :: 2;
MICROSOFT :: 3;
STBTT_PLATFORM_ID_UNICODE :: UNICODE;
STBTT_PLATFORM_ID_MAC :: MAC;
STBTT_PLATFORM_ID_ISO :: ISO;
STBTT_PLATFORM_ID_MICROSOFT :: MICROSOFT;
}
STBTT_UNICODE_EID :: enum u32 {
UNICODE_1_0 :: 0;
UNICODE_1_1 :: 1;
ISO_10646 :: 2;
UNICODE_2_0_BMP :: 3;
UNICODE_2_0_FULL :: 4;
STBTT_UNICODE_EID_UNICODE_1_0 :: UNICODE_1_0;
STBTT_UNICODE_EID_UNICODE_1_1 :: UNICODE_1_1;
STBTT_UNICODE_EID_ISO_10646 :: ISO_10646;
STBTT_UNICODE_EID_UNICODE_2_0_BMP :: UNICODE_2_0_BMP;
STBTT_UNICODE_EID_UNICODE_2_0_FULL :: UNICODE_2_0_FULL;
}
STBTT_MS_EID :: enum u32 {
SYMBOL :: 0;
UNICODE_BMP :: 1;
SHIFTJIS :: 2;
UNICODE_FULL :: 10;
STBTT_MS_EID_SYMBOL :: SYMBOL;
STBTT_MS_EID_UNICODE_BMP :: UNICODE_BMP;
STBTT_MS_EID_SHIFTJIS :: SHIFTJIS;
STBTT_MS_EID_UNICODE_FULL :: UNICODE_FULL;
}
STBTT_MAC_EID :: enum u32 {
ROMAN :: 0;
ARABIC :: 4;
JAPANESE :: 1;
HEBREW :: 5;
CHINESE_TRAD :: 2;
GREEK :: 6;
KOREAN :: 3;
RUSSIAN :: 7;
STBTT_MAC_EID_ROMAN :: ROMAN;
STBTT_MAC_EID_ARABIC :: ARABIC;
STBTT_MAC_EID_JAPANESE :: JAPANESE;
STBTT_MAC_EID_HEBREW :: HEBREW;
STBTT_MAC_EID_CHINESE_TRAD :: CHINESE_TRAD;
STBTT_MAC_EID_GREEK :: GREEK;
STBTT_MAC_EID_KOREAN :: KOREAN;
STBTT_MAC_EID_RUSSIAN :: RUSSIAN;
}
STBTT_MS_LANG :: enum u32 {
ENGLISH :: 1033;
ITALIAN :: 1040;
CHINESE :: 2052;
JAPANESE :: 1041;
DUTCH :: 1043;
KOREAN :: 1042;
FRENCH :: 1036;
RUSSIAN :: 1049;
GERMAN :: 1031;
SPANISH :: 1033;
HEBREW :: 1037;
SWEDISH :: 1053;
STBTT_MS_LANG_ENGLISH :: ENGLISH;
STBTT_MS_LANG_ITALIAN :: ITALIAN;
STBTT_MS_LANG_CHINESE :: CHINESE;
STBTT_MS_LANG_JAPANESE :: JAPANESE;
STBTT_MS_LANG_DUTCH :: DUTCH;
STBTT_MS_LANG_KOREAN :: KOREAN;
STBTT_MS_LANG_FRENCH :: FRENCH;
STBTT_MS_LANG_RUSSIAN :: RUSSIAN;
STBTT_MS_LANG_GERMAN :: GERMAN;
STBTT_MS_LANG_SPANISH :: SPANISH;
STBTT_MS_LANG_HEBREW :: HEBREW;
STBTT_MS_LANG_SWEDISH :: SWEDISH;
}
STBTT_MAC_LANG :: enum u32 {
ENGLISH :: 0;
JAPANESE :: 11;
ARABIC :: 12;
KOREAN :: 23;
DUTCH :: 4;
RUSSIAN :: 32;
FRENCH :: 1;
SPANISH :: 6;
GERMAN :: 2;
SWEDISH :: 5;
HEBREW :: 10;
CHINESE_SIMPLIFIED :: 33;
ITALIAN :: 3;
CHINESE_TRAD :: 19;
STBTT_MAC_LANG_ENGLISH :: ENGLISH;
STBTT_MAC_LANG_JAPANESE :: JAPANESE;
STBTT_MAC_LANG_ARABIC :: ARABIC;
STBTT_MAC_LANG_KOREAN :: KOREAN;
STBTT_MAC_LANG_DUTCH :: DUTCH;
STBTT_MAC_LANG_RUSSIAN :: RUSSIAN;
STBTT_MAC_LANG_FRENCH :: FRENCH;
STBTT_MAC_LANG_SPANISH :: SPANISH;
STBTT_MAC_LANG_GERMAN :: GERMAN;
STBTT_MAC_LANG_SWEDISH :: SWEDISH;
STBTT_MAC_LANG_HEBREW :: HEBREW;
STBTT_MAC_LANG_CHINESE_SIMPLIFIED :: CHINESE_SIMPLIFIED;
STBTT_MAC_LANG_ITALIAN :: ITALIAN;
STBTT_MAC_LANG_CHINESE_TRAD :: CHINESE_TRAD;
}
// ----------------------------------------
#module_parameters(DEBUG := false, USE_GL := false, USE_DLL := false);
#scope_export;
#if OS == .WINDOWS {
#if USE_DLL {
#if USE_GL {
#if DEBUG { sokol_fontstash_clib :: #library "sokol_fontstash_windows_x64_gl_debug"; }
else { sokol_fontstash_clib :: #library "sokol_fontstash_windows_x64_gl_release"; }
} else {
#if DEBUG { sokol_fontstash_clib :: #library "sokol_fontstash_windows_x64_d3d11_debug"; }
else { sokol_fontstash_clib :: #library "sokol_fontstash_windows_x64_d3d11_release"; }
}
} else {
#if USE_GL {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_windows_x64_gl_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_windows_x64_gl_release"; }
} else {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_windows_x64_d3d11_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_windows_x64_d3d11_release"; }
}
}
}
else #if OS == .MACOS {
#if USE_DLL {
#if USE_GL && CPU == .ARM64 && DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib"; }
else #if USE_GL && CPU == .ARM64 && !DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_arm64_gl_release.dylib"; }
else #if USE_GL && CPU == .X64 && DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_x64_gl_debug.dylib"; }
else #if USE_GL && CPU == .X64 && !DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_x64_gl_release.dylib"; }
else #if !USE_GL && CPU == .ARM64 && DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib"; }
else #if !USE_GL && CPU == .ARM64 && !DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_arm64_metal_release.dylib"; }
else #if !USE_GL && CPU == .X64 && DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_x64_metal_debug.dylib"; }
else #if !USE_GL && CPU == .X64 && !DEBUG { sokol_fontstash_clib :: #library "../dylib/sokol_dylib_macos_x64_metal_release.dylib"; }
} else {
#if USE_GL {
#if CPU == .ARM64 {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_arm64_gl_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_arm64_gl_release"; }
} else {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_x64_gl_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_x64_gl_release"; }
}
} else {
#if CPU == .ARM64 {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_arm64_metal_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_arm64_metal_release"; }
} else {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_x64_metal_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_macos_x64_metal_release"; }
}
}
}
} else #if OS == .LINUX {
#system_library,link_always "m";
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_linux_x64_gl_debug"; }
sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_linux_x64_gl_release";
} else #if OS == .WASM {
#if DEBUG { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_wasm_gl_debug"; }
else { sokol_fontstash_clib :: #library,no_dll "sokol_fontstash_wasm_gl_release"; }
} else {
log_error("This OS is currently not supported");
}
sfons_allocator_t :: struct {
alloc_fn : (a0: u64, a1: *void) -> *void #c_call;
free_fn : (a0: *void, a1: *void) #c_call;
user_data : *void;
}
sfons_desc_t :: struct {
width: s32; // initial width of font atlas texture (default: 512, must be power of 2)
height: s32; // initial height of font atlas texture (default: 512, must be power of 2)
allocator: sfons_allocator_t; // optional memory allocation overrides
}
FONS_VERTEX_COUNT :: 1024;
FONS_MAX_STATES :: 20;
FONS_MAX_FALLBACKS :: 20;
FONS_HASH_LUT_SIZE :: 256;
FONSparams :: struct {
width, height: s32;
flags: u8;
userPtr: *void;
renderCreate: (uptr: *void, width: s32, height: s32) -> s32;
renderResize: (uptr: *void, width: s32, height: s32) -> s32;
renderUpdate: (uptr: *void, rect: *s32, data: *u8) -> void;
renderDraw: (uptr: *void, verts: *float, tcoords: *float, colors: *s32, nverts: s32) -> void;
renderDelete: (uptr: *void) -> void;
}
FONSglyph :: struct {
codepoint: u32;
index: s32;
next: s32;
size, blur: s16;
x0,y0,x1,y1: s16;
xadv,xoff,yoff: s16;
}
FONSttFontImpl :: struct {
font: stbtt_fontinfo;
}
FONSfont :: struct {
font: FONSttFontImpl;
name: [64]u8;
data: *u8;
dataSize: s32;
freeData: u8;
ascender: float;
descender: float;
lineh: float;
glyphs: *FONSglyph;
cglyphs: s32;
nglyphs: s32;
lut: [FONS_HASH_LUT_SIZE]s32;
fallbacks: [FONS_MAX_FALLBACKS]s32;
nfallbacks: s32;
}
FONScontext :: struct {
params: FONSparams;
itw,ith: float;
texData: *u8;
dirtyRect: [4]s32;
fonts: **FONSfont;
atlas: *FONSatlas;
cfonts: s32;
nfonts: s32;
verts: [FONS_VERTEX_COUNT*2]float;
tcoords: [FONS_VERTEX_COUNT*2]float;
colors: [FONS_VERTEX_COUNT]u32;
nverts: s32;
scratch: *u8;
nscratch: s32;
states: [FONS_MAX_STATES]FONSstate;
nstates: s32;
handleError: (uptr: *void, error: s32, val: s32) -> *void;
errorUptr: *void;
}
FONSstate :: struct {
font: s32;
align: s32;
size: float;
color: u32;
blur: float;
spacing: float;
}
FONSatlasNode :: struct {
x, y, width: s16;
}
FONSatlas :: struct
{
width, height: s32;
nodes: *FONSatlasNode;
nnodes: s32;
cnodes: s32;
}
using FONSalign :: enum {
// Horizontal align
FONS_ALIGN_LEFT :: 1<<0; // Default
FONS_ALIGN_CENTER :: 1<<1;
FONS_ALIGN_RIGHT :: 1<<2;
// Vertical align
FONS_ALIGN_TOP :: 1<<3;
FONS_ALIGN_MIDDLE :: 1<<4;
FONS_ALIGN_BOTTOM :: 1<<5;
FONS_ALIGN_BASELINE :: 1<<6; // Default
}
FONS_INVALID :: -1;
sfons_create :: (desc: *sfons_desc_t) -> *FONScontext #foreign sokol_fontstash_clib;
sfons_destroy :: (ctx: *FONScontext) -> void #foreign sokol_fontstash_clib;
sfons_flush :: (ctx: *FONScontext) -> void #foreign sokol_fontstash_clib;
sfons_rgba :: (r: u8, g: u8, b: u8, a: u8) -> u32 #foreign sokol_fontstash_clib;
// Contructor and destructor.
fonsCreateInternal :: (params: *FONSparams) -> *FONScontext #foreign sokol_fontstash_clib;
fonsDeleteInternal :: (s: *FONScontext) -> void #foreign sokol_fontstash_clib;
fonsSetErrorCallback :: (s: *FONScontext, callback: #type (uptr: *void, error: s32, val: s32) -> void #c_call, uptr: *void) -> void #foreign sokol_fontstash_clib;
// Returns current atlas size.
fonsGetAtlasSize :: (s: *FONScontext, width: *s32, height: *s32) -> void #foreign sokol_fontstash_clib;
// Expands the atlas size.
fonsExpandAtlas :: (s: *FONScontext, width: s32, height: s32) -> s32 #foreign sokol_fontstash_clib;
// Resets the whole stash.
fonsResetAtlas :: (stash: *FONScontext, width: s32, height: s32) -> s32 #foreign sokol_fontstash_clib;
// Add fonts
fonsAddFont :: (s: *FONScontext, name: *u8, path: *u8) -> s32 #foreign sokol_fontstash_clib;
fonsAddFontMem :: (s: *FONScontext, name: *u8, data: *u8, ndata: s32, freeData: s32) -> s32 #foreign sokol_fontstash_clib;
fonsGetFontByName :: (s: *FONScontext, name: *u8) -> s32 #foreign sokol_fontstash_clib;
fonsAddFallbackFont :: (stash: *FONScontext, base: s32, fallback: s32) -> s32 #foreign sokol_fontstash_clib;
// State handling
fonsPushState :: (s: *FONScontext) -> void #foreign sokol_fontstash_clib;
fonsPopState :: (s: *FONScontext) -> void #foreign sokol_fontstash_clib;
fonsClearState :: (s: *FONScontext) -> void #foreign sokol_fontstash_clib;
// State setting
fonsSetSize :: (s: *FONScontext, size: float) -> void #foreign sokol_fontstash_clib;
fonsSetColor :: (s: *FONScontext, color: u32) -> void #foreign sokol_fontstash_clib;
fonsSetSpacing :: (s: *FONScontext, spacing: float) -> void #foreign sokol_fontstash_clib;
fonsSetBlur :: (s: *FONScontext, blur: float) -> void #foreign sokol_fontstash_clib;
fonsSetAlign :: (s: *FONScontext, align: s32) -> void #foreign sokol_fontstash_clib;
fonsSetFont :: (s: *FONScontext, font: s32) -> void #foreign sokol_fontstash_clib;
// Draw text
fonsDrawText :: (s: *FONScontext, x: float, y: float, _string: *u8, end: *u8) -> float #foreign sokol_fontstash_clib;
// Measure text
fonsTextBounds :: (s: *FONScontext, x: float, y: float, _string: *u8, end: *u8, bounds: *float) -> float #foreign sokol_fontstash_clib;
fonsLineBounds :: (s: *FONScontext, y: float, miny: *float, maxy: *float) -> void #foreign sokol_fontstash_clib;
fonsVertMetrics :: (s: *FONScontext, ascender: *float, descender: *float, lineh: *float) -> void #foreign sokol_fontstash_clib;
// Text iterator
// fonsTextIterInit :: (stash: *FONScontext, iter: *FONStextIter, x: float, y: float, str: *u8, end: *u8) -> s32 #foreign sokol_fontstash_clib;
// fonsTextIterNext :: (stash: *FONScontext, iter: *FONStextIter, quad: *FONSquad) -> s32 #foreign sokol_fontstash_clib;
// Pull texture changes
fonsGetTextureData :: (stash: *FONScontext, width: *s32, height: *s32) -> *u8 #foreign sokol_fontstash_clib;
fonsValidateTexture :: (s: *FONScontext, dirty: *s32) -> s32 #foreign sokol_fontstash_clib;
// Draws the stash texture for debugging
fonsDrawDebug :: (s: *FONScontext, x: float, y: float) -> void #foreign sokol_fontstash_clib;