|
| 1 | +package vendor_kb_text_shape |
| 2 | + |
| 3 | +when ODIN_OS == .Windows { |
| 4 | + foreign import lib { |
| 5 | + "lib/kb_text_shape.lib", |
| 6 | + } |
| 7 | +} else { |
| 8 | + foreign import lib { |
| 9 | + "kb_text_shape.a", |
| 10 | + } |
| 11 | +} |
| 12 | + |
| 13 | +import "core:c" |
| 14 | +import "core:mem" |
| 15 | + |
| 16 | +#assert(size_of(c.int) == size_of(b32)) |
| 17 | +#assert(size_of(u32) == size_of(b32)) |
| 18 | + |
| 19 | +@(default_calling_convention="c", link_prefix="kbts_", require_results) |
| 20 | +foreign lib { |
| 21 | + FontIsValid :: proc(Font: ^font) -> b32 --- |
| 22 | + SizeOfShapeState :: proc(Font: ^font) -> un --- |
| 23 | + |
| 24 | + ResetShapeState :: proc(State: ^shape_state) --- |
| 25 | + |
| 26 | + ShapeConfig :: proc(Font: ^font, Script: script, Language: language) -> shape_config --- |
| 27 | + ShaperIsComplex :: proc(Shaper: shaper) -> b32 --- |
| 28 | + ScriptIsComplex :: proc(Script: script) -> b32 --- |
| 29 | + |
| 30 | + Shape :: proc(State: ^shape_state, Config: ^shape_config, |
| 31 | + MainDirection, RunDirection: direction, |
| 32 | + Glyphs: [^]glyph, GlyphCount: ^u32, GlyphCapacity: u32) -> c.int --- |
| 33 | + |
| 34 | + Cursor :: proc(Direction: direction) -> cursor --- |
| 35 | + BeginBreak :: proc(State: ^break_state, MainDirection: direction, JapaneseLineBreakStyle: japanese_line_break_style) --- |
| 36 | + BreakStateIsValid :: proc(State: ^break_state) -> b32 --- |
| 37 | + BreakAddCodepoint :: proc(State: ^break_state, Codepoint: rune, PositionIncrement: u32, EndOfText: c.int) --- |
| 38 | + BreakFlush :: proc(State: ^break_state) --- |
| 39 | + Break :: proc(State: ^break_state, Break: ^break_type) -> b32 --- |
| 40 | + CodepointToGlyph :: proc(Font: ^font, Codepoint: rune) -> glyph --- |
| 41 | + InferScript :: proc(Direction: ^direction, Script: ^script, GlyphScript: script) --- |
| 42 | +} |
| 43 | + |
| 44 | +@(require_results) |
| 45 | +PlaceShapeState :: proc "c" (Memory: []byte) -> ^shape_state { |
| 46 | + @(default_calling_convention="c", require_results) |
| 47 | + foreign lib { |
| 48 | + kbts_PlaceShapeState :: proc(Address: rawptr, Size: un) -> ^shape_state --- |
| 49 | + } |
| 50 | + |
| 51 | + return kbts_PlaceShapeState(raw_data(Memory), un(len(Memory))) |
| 52 | +} |
| 53 | + |
| 54 | +@(require_results) |
| 55 | +DecodeUtf8 :: proc "contextless" (String: string) -> (Codepoint: rune, SourceCharactersConsumed: u32, Valid: bool) { |
| 56 | + decode :: struct { |
| 57 | + Codepoint: rune, |
| 58 | + |
| 59 | + SourceCharactersConsumed: u32, |
| 60 | + Valid: b32, |
| 61 | + } |
| 62 | + |
| 63 | + @(default_calling_convention="c", require_results) |
| 64 | + foreign lib { |
| 65 | + kbts_DecodeUtf8 :: proc(Utf8: [^]byte, Length: uint) -> decode --- |
| 66 | + } |
| 67 | + |
| 68 | + Decode := kbts_DecodeUtf8(raw_data(String), len(String)) |
| 69 | + return Decode.Codepoint, Decode.SourceCharactersConsumed, bool(Decode.Valid) |
| 70 | +} |
| 71 | + |
| 72 | + |
| 73 | +@(require_results) |
| 74 | +ReadFontHeader :: proc "c" (Font: ^font, Data: []byte) -> un { |
| 75 | + @(default_calling_convention="c", require_results) |
| 76 | + foreign lib { |
| 77 | + kbts_ReadFontHeader :: proc(Font: ^font, Data: rawptr, Size: un) -> un --- |
| 78 | + } |
| 79 | + |
| 80 | + return kbts_ReadFontHeader(Font, raw_data(Data), un(len(Data))) |
| 81 | +} |
| 82 | +@(require_results) |
| 83 | +ReadFontData :: proc "c" (Font: ^font, Scratch: []byte) -> un { |
| 84 | + @(default_calling_convention="c", require_results) |
| 85 | + foreign lib { |
| 86 | + kbts_ReadFontData :: proc(Font: ^font, Scratch: rawptr, ScratchSize: un) -> un --- |
| 87 | + } |
| 88 | + |
| 89 | + return kbts_ReadFontData(Font, raw_data(Scratch), un(len(Scratch))) |
| 90 | +} |
| 91 | +@(require_results) |
| 92 | +PostReadFontInitialize :: proc "c" (Font: ^font, Memory: []byte) -> b32 { |
| 93 | + @(default_calling_convention="c", require_results) |
| 94 | + foreign lib { |
| 95 | + kbts_PostReadFontInitialize :: proc(Font: ^font, Memory: rawptr, MemorySize: un) -> b32 --- |
| 96 | + } |
| 97 | + |
| 98 | + return kbts_PostReadFontInitialize(Font, raw_data(Memory), un(len(Memory))) |
| 99 | +} |
| 100 | + |
| 101 | +@(require_results) |
| 102 | +FontFromMemory :: proc(Data: []byte, allocator: mem.Allocator) -> (Result: font, Err: mem.Allocator_Error) { |
| 103 | + ClonedData := mem.make_aligned([]byte, len(Data), 16, allocator) or_return |
| 104 | + defer if Err != nil { |
| 105 | + delete(ClonedData, allocator) |
| 106 | + } |
| 107 | + copy(ClonedData, Data) |
| 108 | + |
| 109 | + ScratchSize := ReadFontHeader(&Result, ClonedData) |
| 110 | + Scratch := mem.make_aligned([]byte, ScratchSize, 16, allocator) or_return |
| 111 | + MemorySize := ReadFontData(&Result, Scratch) |
| 112 | + |
| 113 | + Memory := Scratch |
| 114 | + if MemorySize > ScratchSize { |
| 115 | + delete(Scratch, allocator) |
| 116 | + Memory = mem.make_aligned([]byte, MemorySize, 16, allocator) or_return |
| 117 | + } |
| 118 | + defer if Err != nil { |
| 119 | + delete(Memory, allocator) |
| 120 | + } |
| 121 | + |
| 122 | + _ = PostReadFontInitialize(&Result, Memory) |
| 123 | + return |
| 124 | + |
| 125 | +} |
| 126 | +FreeFont :: proc(Font: ^font, allocator: mem.Allocator) { |
| 127 | + free(Font.FileBase, allocator) |
| 128 | + free(Font.GlyphLookupMatrix, allocator) |
| 129 | + Font^ = {} |
| 130 | +} |
| 131 | + |
| 132 | +@(require_results) |
| 133 | +CreateShapeState :: proc(Font: ^font, allocator: mem.Allocator) -> (Result: ^shape_state, Err: mem.Allocator_Error) { |
| 134 | + Size := SizeOfShapeState(Font) |
| 135 | + Memory := mem.make_aligned([]byte, Size, 16, allocator) or_return |
| 136 | + Result = PlaceShapeState(Memory) |
| 137 | + return |
| 138 | +} |
| 139 | +FreeShapeState :: proc(State: ^shape_state, allocator: mem.Allocator) { |
| 140 | + free(State, allocator) |
| 141 | +} |
| 142 | + |
| 143 | +@(require_results) |
| 144 | +PositionGlyph :: proc(Cursor: ^cursor, Glyph: ^glyph) -> (X, Y: i32) { |
| 145 | + @(default_calling_convention="c", require_results) |
| 146 | + foreign lib { |
| 147 | + kbts_PositionGlyph :: proc(Cursor: ^cursor, Glyph: ^glyph, X, Y: ^i32) --- |
| 148 | + } |
| 149 | + kbts_PositionGlyph(Cursor, Glyph, &X, &Y) |
| 150 | + return |
| 151 | +} |
0 commit comments