mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
wasm: support vendor:stb/truetype and vendor:fontstash
This commit is contained in:
@@ -96,7 +96,7 @@ wasi_match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) {
|
|||||||
|
|
||||||
prefix_matches :: proc(prefix, path: string) -> bool {
|
prefix_matches :: proc(prefix, path: string) -> bool {
|
||||||
// Empty is valid for any relative path.
|
// Empty is valid for any relative path.
|
||||||
if len(prefix) == 0 && len(path) > 0 && path[0] == '/' {
|
if len(prefix) == 0 && len(path) > 0 && path[0] != '/' {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-16
@@ -1,14 +1,14 @@
|
|||||||
//+build windows, linux, darwin
|
|
||||||
//+vet !using-param
|
//+vet !using-param
|
||||||
package fontstash
|
package fontstash
|
||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
import "core:os"
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:slice"
|
import "core:slice"
|
||||||
|
|
||||||
import stbtt "vendor:stb/truetype"
|
import stbtt "vendor:stb/truetype"
|
||||||
|
|
||||||
// This is a port from Fontstash into odin - specialized for nanovg
|
// This is a port from Fontstash into odin - specialized for nanovg
|
||||||
@@ -321,20 +321,6 @@ __AtlasAddWhiteRect :: proc(ctx: ^FontContext, w, h: int) -> bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
AddFontPath :: proc(
|
|
||||||
ctx: ^FontContext,
|
|
||||||
name: string,
|
|
||||||
path: string,
|
|
||||||
) -> int {
|
|
||||||
data, ok := os.read_entire_file(path)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
log.panicf("FONT: failed to read font at %s", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddFontMem(ctx, name, data, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// push a font to the font stack
|
// push a font to the font stack
|
||||||
// optionally init with ascii characters at a wanted size
|
// optionally init with ascii characters at a wanted size
|
||||||
AddFontMem :: proc(
|
AddFontMem :: proc(
|
||||||
|
|||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
//+build !js
|
||||||
|
package fontstash
|
||||||
|
|
||||||
|
import "core:log"
|
||||||
|
import "core:os"
|
||||||
|
|
||||||
|
AddFontPath :: proc(
|
||||||
|
ctx: ^FontContext,
|
||||||
|
name: string,
|
||||||
|
path: string,
|
||||||
|
) -> int {
|
||||||
|
data, ok := os.read_entire_file(path)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
log.panicf("FONT: failed to read font at %s", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return AddFontMem(ctx, name, data, true)
|
||||||
|
}
|
||||||
|
|
||||||
Vendored
BIN
Binary file not shown.
Vendored
+4
@@ -6,6 +6,10 @@ else
|
|||||||
all: unix
|
all: unix
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
wasm:
|
||||||
|
mkdir -p ../lib
|
||||||
|
clang -c -Os --target=wasm32 -nostdlib stb_truetype_wasm.c -o ../lib/stb_truetype_wasm.o
|
||||||
|
|
||||||
unix:
|
unix:
|
||||||
mkdir -p ../lib
|
mkdir -p ../lib
|
||||||
$(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c
|
$(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c
|
||||||
|
|||||||
Vendored
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void *stbtt_malloc(size_t size);
|
||||||
|
void stbtt_free(void *ptr);
|
||||||
|
|
||||||
|
void stbtt_qsort(void* base, size_t num, size_t size, int (*compare)(const void*, const void*));
|
||||||
|
|
||||||
|
double stbtt_floor(double x);
|
||||||
|
double stbtt_ceil(double x);
|
||||||
|
double stbtt_sqrt(double x);
|
||||||
|
double stbtt_pow(double x, double y);
|
||||||
|
double stbtt_fmod(double x, double y);
|
||||||
|
double stbtt_cos(double x);
|
||||||
|
double stbtt_acos(double x);
|
||||||
|
double stbtt_fabs(double x);
|
||||||
|
|
||||||
|
unsigned long stbtt_strlen(const char *str);
|
||||||
|
|
||||||
|
void *memcpy(void *dst, const void *src, size_t count);
|
||||||
|
void *memset(void *dst, int x, size_t count);
|
||||||
|
|
||||||
|
#define STBRP_SORT stbtt_qsort
|
||||||
|
#define STBRP_ASSERT(condition) ((void)0)
|
||||||
|
|
||||||
|
#define STBTT_malloc(x,u) ((void)(u),stbtt_malloc(x))
|
||||||
|
#define STBTT_free(x,u) ((void)(u),stbtt_free(x))
|
||||||
|
|
||||||
|
#define STBTT_assert(condition) ((void)0)
|
||||||
|
|
||||||
|
#define STBTT_ifloor(x) ((int) stbtt_floor(x))
|
||||||
|
#define STBTT_iceil(x) ((int) stbtt_ceil(x))
|
||||||
|
#define STBTT_sqrt(x) stbtt_sqrt(x)
|
||||||
|
#define STBTT_pow(x,y) stbtt_pow(x,y)
|
||||||
|
#define STBTT_fmod(x,y) stbtt_fmod(x,y)
|
||||||
|
#define STBTT_cos(x) stbtt_cos(x)
|
||||||
|
#define STBTT_acos(x) stbtt_acos(x)
|
||||||
|
#define STBTT_fabs(x) stbtt_fabs(x)
|
||||||
|
#define STBTT_strlen(x) stbtt_strlen(x)
|
||||||
|
#define STBTT_memcpy memcpy
|
||||||
|
#define STBTT_memset memset
|
||||||
|
|
||||||
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
#include "stb_rect_pack.h"
|
||||||
|
|
||||||
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
#include "stb_truetype.h"
|
||||||
+2
@@ -17,6 +17,8 @@ when LIB != "" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreign import stbtt { LIB }
|
foreign import stbtt { LIB }
|
||||||
|
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||||
|
foreign import stbtt "../lib/stb_truetype_wasm.o"
|
||||||
} else {
|
} else {
|
||||||
foreign import stbtt "system:stb_truetype"
|
foreign import stbtt "system:stb_truetype"
|
||||||
}
|
}
|
||||||
|
|||||||
+92
@@ -0,0 +1,92 @@
|
|||||||
|
//+build wasm32, wasm64p32
|
||||||
|
package stb_truetype
|
||||||
|
|
||||||
|
import "base:builtin"
|
||||||
|
import "base:intrinsics"
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
import "core:math"
|
||||||
|
import "core:mem"
|
||||||
|
import "core:sort"
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_malloc")
|
||||||
|
malloc :: proc "c" (size: uint) -> rawptr {
|
||||||
|
context = runtime.default_context()
|
||||||
|
ptr, _ := runtime.mem_alloc_non_zeroed(int(size))
|
||||||
|
return raw_data(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_free")
|
||||||
|
free :: proc "c" (ptr: rawptr) {
|
||||||
|
context = runtime.default_context()
|
||||||
|
builtin.free(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_qsort")
|
||||||
|
qsort :: proc "c" (base: rawptr, num: uint, size: uint, cmp: proc "c" (a, b: rawptr) -> i32) {
|
||||||
|
context = runtime.default_context()
|
||||||
|
|
||||||
|
Inputs :: struct {
|
||||||
|
base: rawptr,
|
||||||
|
num: uint,
|
||||||
|
size: uint,
|
||||||
|
cmp: proc "c" (a, b: rawptr) -> i32,
|
||||||
|
}
|
||||||
|
inputs := Inputs{base, num, size, cmp}
|
||||||
|
|
||||||
|
sort.sort({
|
||||||
|
collection = &inputs,
|
||||||
|
len = proc(it: sort.Interface) -> int {
|
||||||
|
inputs := (^Inputs)(it.collection)
|
||||||
|
return int(inputs.num)
|
||||||
|
},
|
||||||
|
less = proc(it: sort.Interface, i, j: int) -> bool {
|
||||||
|
inputs := (^Inputs)(it.collection)
|
||||||
|
a := rawptr(uintptr(inputs.base) + (uintptr(i) * uintptr(inputs.size)))
|
||||||
|
b := rawptr(uintptr(inputs.base) + (uintptr(j) * uintptr(inputs.size)))
|
||||||
|
return inputs.cmp(a, b) < 0
|
||||||
|
},
|
||||||
|
swap = proc(it: sort.Interface, i, j: int) {
|
||||||
|
inputs := (^Inputs)(it.collection)
|
||||||
|
|
||||||
|
a := rawptr(uintptr(inputs.base) + (uintptr(i) * uintptr(inputs.size)))
|
||||||
|
b := rawptr(uintptr(inputs.base) + (uintptr(j) * uintptr(inputs.size)))
|
||||||
|
|
||||||
|
tmp := intrinsics.alloca(inputs.size, runtime.DEFAULT_ALIGNMENT)
|
||||||
|
intrinsics.mem_copy_non_overlapping(tmp, a, inputs.size)
|
||||||
|
intrinsics.mem_copy_non_overlapping(a, b, inputs.size)
|
||||||
|
intrinsics.mem_copy_non_overlapping(b, tmp, inputs.size)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_floor")
|
||||||
|
floor :: proc "c" (x: f64) -> f64 { return math.floor(x) }
|
||||||
|
@(require, linkage="strong", link_name="stbtt_ceil")
|
||||||
|
ceil :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
|
||||||
|
@(require, linkage="strong", link_name="stbtt_sqrt")
|
||||||
|
sqrt :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
|
||||||
|
@(require, linkage="strong", link_name="stbtt_pow")
|
||||||
|
pow :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_fmod")
|
||||||
|
fmod :: proc "c" (x, y: f64) -> f64 {
|
||||||
|
context = runtime.default_context();
|
||||||
|
// NOTE: only called in the `stbtt_GetGlyphSDF` code path.
|
||||||
|
panic("`math.round` is broken on 32 bit targets, see #3856")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_cos")
|
||||||
|
cos :: proc "c" (x: f64) -> f64 { return math.cos(x) }
|
||||||
|
@(require, linkage="strong", link_name="stbtt_acos")
|
||||||
|
acos :: proc "c" (x: f64) -> f64 { return math.acos(x) }
|
||||||
|
@(require, linkage="strong", link_name="stbtt_fabs")
|
||||||
|
fabs :: proc "c" (x: f64) -> f64 { return math.abs(x) }
|
||||||
|
|
||||||
|
@(require, linkage="strong", link_name="stbtt_strlen")
|
||||||
|
strlen :: proc "c" (str: cstring) -> c.ulong { return c.ulong(len(str)) }
|
||||||
|
|
||||||
|
// NOTE: defined in runtime.
|
||||||
|
// void *memcpy(void *dst, const void *src, size_t count);
|
||||||
|
// void *memset(void *dst, int x, size_t count);
|
||||||
Reference in New Issue
Block a user