Skip to content

Commit d25cd01

Browse files
authored
Merge pull request #5371 from odin-lang/bill/vendor/kb-text-shape
`vendor/kb_text_shape`
2 parents 4b99498 + 0a7cf8c commit d25cd01

File tree

7 files changed

+24388
-1
lines changed

7 files changed

+24388
-1
lines changed

examples/all/all_vendor.odin

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,7 @@ package all
4545
@(require) import stbi "vendor:stb/image"
4646
@(require) import "vendor:stb/rect_pack"
4747
@(require) import "vendor:stb/truetype"
48-
@(require) import "vendor:stb/vorbis"
48+
@(require) import "vendor:stb/vorbis"
49+
50+
51+
@(require) import "vendor:kb_text_shape"
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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

Comments
 (0)