Update kb_text_shape to v2.21

This commit is contained in:
Kamron Bhavnagri
2026-07-04 12:57:16 +10:00
parent 94be05ead1
commit ef3e946b5a
3 changed files with 4086 additions and 5012 deletions

View File

@@ -20,7 +20,9 @@ import "core:c"
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
SizeOfShapeContext :: proc() -> c.int ---
PlaceShapeContext2 :: proc(Allocator: allocator_function, AllocatorData: rawptr, Memory: rawptr, Flags: shape_context_flags) -> ^shape_context ---
PlaceShapeContext :: proc(Allocator: allocator_function, AllocatorData: rawptr, Memory: rawptr) -> ^shape_context ---
CreateShapeContext2 :: proc(Allocator: allocator_function, AllocatorData: rawptr, Flags: shape_context_flags) -> ^shape_context ---
CreateShapeContext :: proc(Allocator: allocator_function, AllocatorData: rawptr) -> ^shape_context ---
DestroyShapeContext :: proc(Context: ^shape_context) ---
ShapePushFont :: proc(Context: ^shape_context, Font: ^font) -> ^font ---
@@ -38,6 +40,14 @@ foreign lib {
ShapeManualBreak :: proc(Context: ^shape_context) ---
}
@(require_results)
PlaceShapeContextFixedMemory2 :: proc "c" (Memory: []byte, Flags: shape_context_flags) -> ^shape_context {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PlaceShapeContextFixedMemory2 :: proc(Memory: rawptr, Size: c.int, Flags: shape_context_flags) -> ^shape_context ---
}
return kbts_PlaceShapeContextFixedMemory2(raw_data(Memory), c.int(len(Memory)), Flags)
}
@(require_results)
PlaceShapeContextFixedMemory :: proc "c" (Memory: []byte) -> ^shape_context {
@(default_calling_convention="c", require_results)
@@ -120,10 +130,11 @@ ShapeCodepointIteratorNext :: proc "contextless" (It: ^shape_codepoint_iterator)
//
@(default_calling_convention="c", link_prefix="kbts_", require_results)
foreign lib {
FreeFont :: proc(Font: ^font) ---
FontIsValid :: proc(Font: ^font) -> b32 ---
PlaceBlob :: proc(Font: ^font, State: ^load_font_state, ScratchMemory: rawptr, OutputMemory: rawptr) -> load_font_error ---
GetFontInfo :: proc(Font: ^font, Info: ^font_info) ---
FreeFont :: proc(Font: ^font) ---
FontIsValid :: proc(Font: ^font) -> b32 ---
PlaceBlob :: proc(Font: ^font, State: ^load_font_state, ScratchMemory: rawptr, OutputMemory: rawptr) -> load_font_error ---
GetFontInfo :: proc(Font: ^font, Info: ^font_info) ---
GetFontInfo2 :: proc(Font: ^font, Info: ^font_info2) ---
// A shape_config is a bag of pre-computed data for a specific shaping setup.
SizeOfShapeConfig :: proc(Font: ^font, Script: script, Language: language) -> b32 ---
@@ -145,6 +156,14 @@ foreign lib {
// A single glyph_config can be shared by multiple glyphs.
DestroyGlyphConfig :: proc(Config: ^glyph_config) ---
// A shape_scratchpad holds all transient runtime shaping data.
// While the shape_config is immutable and can be trivially shared among threads, a shape_scratchpad is mutable and needs to be per-thread.
SizeOfShapeScratchpad :: proc(Config: ^shape_config) -> un ---
PlaceShapeScratchpad :: proc(Config: ^shape_config, Memory: rawptr, Allocator: allocator_function, AllocatorData: rawptr) -> shape_scratchpad ---
PlaceShapeScratchpadFixedMemory :: proc(Config: ^shape_config, Memory: rawptr, Size: c.int) -> shape_scratchpad ---
CreateShapeScratchpad :: proc(Config: ^shape_config, Allocator: allocator_function, AllocatorData: rawptr) -> shape_scratchpad ---
DestroyShapeScratchpad :: proc(Scratchpad: ^shape_scratchpad) ---
}
@(require_results)
@@ -177,51 +196,41 @@ FontFromMemory :: proc "c" (FileData: []byte, FontIndex: c.int, Allocator: alloc
@(require_results)
ShapeDirect :: proc "contextless" (Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Allocator: allocator_function, AllocatorData: rawptr) -> (Output: glyph_iterator, Err: shape_error) {
ShapeDirect :: proc "contextless" (Scratchpad: ^shape_scratchpad, Storage: ^glyph_storage, RunDirection: direction) -> (Output: glyph_iterator, Err: shape_error) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeDirect :: proc(Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Allocator: allocator_function, AllocatorData: rawptr, Output: ^glyph_iterator) -> shape_error ---
kbts_ShapeDirect :: proc(Scratchpad: ^shape_scratchpad, Storage: ^glyph_storage, RunDirection: direction, Output: ^glyph_iterator) -> shape_error ---
}
Err = kbts_ShapeDirect(Config, Storage, RunDirection, Allocator, AllocatorData, &Output)
return
}
@(require_results)
ShapeDirectFixedMemory :: proc "contextless" (Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Memory: rawptr, MemorySize: c.int) -> (Output: glyph_iterator, Err: shape_error) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_ShapeDirectFixedMemory :: proc(Config: ^shape_config, Storage: ^glyph_storage, RunDirection: direction, Memory: rawptr, MemorySize: c.int, Output: ^glyph_iterator) -> shape_error ---
}
Err = kbts_ShapeDirectFixedMemory(Config, Storage, RunDirection, Memory, MemorySize, &Output)
Err = kbts_ShapeDirect(Scratchpad, Storage, RunDirection, &Output)
return
}
@(require_results)
SizeOfGlyphConfig :: proc "c" (Overrides: []feature_override) -> c.int {
SizeOfGlyphConfig :: proc "c" (ShapeConfig: ^shape_config, Overrides: []feature_override) -> c.int {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_SizeOfGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int) -> c.int ---
kbts_SizeOfGlyphConfig :: proc(ShapeConfig: ^shape_config, Overrides: [^]feature_override, OverrideCount: c.int) -> c.int ---
}
return kbts_SizeOfGlyphConfig(raw_data(Overrides), c.int(len(Overrides)))
return kbts_SizeOfGlyphConfig(ShapeConfig, raw_data(Overrides), c.int(len(Overrides)))
}
@(require_results)
PlaceGlyphConfig :: proc "c" (Overrides: []feature_override, Memory: rawptr) -> ^glyph_config {
PlaceGlyphConfig :: proc "c" (ShapeConfig: ^shape_config, Overrides: []feature_override, Memory: rawptr) -> ^glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_PlaceGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int, Memory: rawptr) -> ^glyph_config ---
kbts_PlaceGlyphConfig :: proc(ShapeConfig: ^shape_config, Overrides: [^]feature_override, OverrideCount: c.int, Memory: rawptr) -> ^glyph_config ---
}
return kbts_PlaceGlyphConfig(raw_data(Overrides), c.int(len(Overrides)), Memory)
return kbts_PlaceGlyphConfig(ShapeConfig, raw_data(Overrides), c.int(len(Overrides)), Memory)
}
@(require_results)
CreateGlyphConfig :: proc(Overrides: []feature_override, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config {
CreateGlyphConfig :: proc(ShapeConfig: ^shape_config, Overrides: []feature_override, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_CreateGlyphConfig :: proc(Overrides: [^]feature_override, OverrideCount: c.int, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config ---
kbts_CreateGlyphConfig :: proc(ShapeConfig: ^shape_config, Overrides: [^]feature_override, OverrideCount: c.int, Allocator: allocator_function, AllocatorData: rawptr) -> ^glyph_config ---
}
return kbts_CreateGlyphConfig(raw_data(Overrides), c.int(len(Overrides)), Allocator, AllocatorData)
return kbts_CreateGlyphConfig(ShapeConfig, raw_data(Overrides), c.int(len(Overrides)), Allocator, AllocatorData)
}
@(default_calling_convention="c", link_prefix="kbts_", require_results)
@@ -262,43 +271,43 @@ Break :: proc "contextless" (State: ^break_state) -> (Break: break_type, Ok: b32
BreakEntireString :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Input: []byte, InputFormat: text_format,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
Input: []byte, InputFormat: text_format,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireString :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Input: rawptr, InputSizeInBytes: c.int, InputFormat: text_format,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
Input: rawptr, InputSizeInBytes: c.int, InputFormat: text_format,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireString(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Input), c.int(len(Input)), InputFormat, raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
BreakEntireStringUtf32 :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf32: []rune,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
Utf32: []rune,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireStringUtf32 :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf32: [^]rune, Utf32Count: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
Utf32: [^]rune, Utf32Count: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireStringUtf32(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Utf32), c.int(len(Utf32)), raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
BreakEntireStringUtf8 :: proc "c" (Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf8: string,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
Utf8: string,
Breaks: []break_type, BreakCount: ^c.int,
BreakFlags: []break_flags, BreakFlagCount: ^c.int) {
@(default_calling_convention="c", require_results)
foreign lib {
kbts_BreakEntireStringUtf8 :: proc(Direction: direction, JapaneseLineBreakStyle: japanese_line_break_style, ConfigFlags: break_config_flags,
Utf8: [^]byte, Utf8Length: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
Utf8: [^]byte, Utf8Length: c.int,
Breaks: [^]break_type, BreakCapacity: c.int, BreakCount: ^c.int,
BreakFlags: [^]break_flags, BreakFlagCapacity: c.int, BreakFlagCount: ^c.int) ---
}
kbts_BreakEntireStringUtf8(Direction, JapaneseLineBreakStyle, ConfigFlags, raw_data(Utf8), c.int(len(Utf8)), raw_data(Breaks), c.int(len(Breaks)), BreakCount, raw_data(BreakFlags), c.int(len(BreakFlags)), BreakFlagCount)
}
@@ -390,7 +399,7 @@ AllocatorFromOdinAllocator :: proc "contextless" (allocator: ^runtime.Allocator)
case .ALLOCATE:
res, _ := runtime.mem_alloc(int(Op.Allocate.Size), runtime.DEFAULT_ALIGNMENT)
Op.Allocate.Pointer = raw_data(res)
Op.Allocate.Size = u32(len(res))
Op.Allocate.Size = u32(len(res))
case .FREE:
_ = runtime.mem_free(Op.Free.Pointer)
}

View File

@@ -12,9 +12,9 @@ un :: distinct (
u64
)
// sn :: distinct (
// int when (size_of(uintptr) == size_of(int)) else
// i32 when size_of(uintptr) == 4 else
// i64
// int when (size_of(uintptr) == size_of(int)) else
// i32 when size_of(uintptr) == 4 else
// i64
// )
@@ -781,6 +781,12 @@ break_state_flag :: enum u32 {
SAW_AL_AFTER_LR = 4,
LAST_WAS_BRACKET = 5,
}
// TODO: Was this supposed to be a bitset or regular enum?
shape_context_flag :: enum u32 {
KBTS_SHAPE_CONTEXT_FLAG_NONE,
KBTS_SHAPE_CONTEXT_FLAG_FONT_PRIORITY_BOTTOM_TO_TOP,
}
shape_context_flags :: distinct bit_set[shape_context_flag; u32]
@@ -1750,18 +1756,20 @@ feature_tag :: enum u32 {
zero = 'z' | 'e'<<8 | 'r'<<16 | 'o'<<24, // Slashed Zero
}
_gdef :: struct {}
_cmap_14 :: struct {}
_gsub_gpos :: struct {}
_maxp :: struct {}
_hea :: struct {}
shaper_properties :: struct {}
_feature :: struct {}
_head :: struct {}
_langsys :: struct {}
shape_config :: struct {}
glyph_config :: struct {}
shape_context :: struct {}
_gdef :: struct {}
_cmap_14 :: struct {}
_gsub_gpos :: struct {}
_maxp :: struct {}
_hea :: struct {}
shaper_properties :: struct {}
_feature :: struct {}
_head :: struct {}
_langsys :: struct {}
shape_config :: struct {}
glyph_config :: struct {}
bucketed_glyph :: struct {}
shape_context :: struct {}
shape_scratchpad :: struct {}
allocator_op_allocate :: struct {
Pointer: rawptr,
@@ -1849,6 +1857,23 @@ font_info :: struct {
Weight: font_weight,
Width: font_width,
}
font_info2 :: struct {
Size: u32,
using FontInfo: font_info,
}
font_info2_1 :: struct {
using FontInfo2: font_info2,
UnitsPerEm: u16,
XMin, YMin, XMax, YMax: i16,
Ascent, Descent, LineGap: i16,
}
font_info2_2 :: struct {
using FontInfo2_1: font_info2_1,
// For now, this is just OS2.sCapHeight.
// If/when this is zero, we might consider trying to communicate a useful height instead of simply passing the zero along.
CapitalHeight: i16,
}
feature_override :: struct {
Tag: feature_tag,
@@ -2033,6 +2058,11 @@ glyph :: struct {
ParentInfo: u32,
Bucketed: ^bucketed_glyph,
SortKey: u32,
SortKeyInterval: u32,
BucketedBucketIndex: u16,
// This is set by GSUB and used by GPOS.
// A 0-index means that we should attach to the last component in the ligature.
//
@@ -2064,7 +2094,9 @@ glyph :: struct {
shape_codepoint :: struct {
Font: ^font, // Only set when (.GRAPHEME in BreakFlags)
Config: ^glyph_config,
FeatureOverrides: [^]feature_override `fmt:"v,FeatureOverrideCount"`,
FeatureOverrideCount: c.int,
Codepoint: rune,
UserId: c.int,
@@ -2121,8 +2153,8 @@ glyph_storage :: struct {
}
glyph_parent :: struct {
Decomposition: u64,
Codepoint: rune,
Codepoint1: rune,
}
font_coverage_test :: struct {
@@ -2144,4 +2176,5 @@ run :: struct {
Flags: break_flags,
Glyphs: glyph_iterator,
}
}

File diff suppressed because it is too large Load Diff