library: vendors/kb_text_shape + vendors/file_utils; modules/ffi/stb_truetype.sx retired
kb_text_shape (v2.10, JimmyLefevre) had been LOST from the sx tree — ffi/stb_truetype.sx referenced repo paths that no longer existed (and nothing runs glyph_cache, so the dangling unit never fired). The trimmed copy returns from the m3te project as a proper vendor: curated c/kbts_api.h decls over the full upstream header, README with provenance, and examples/1627 pinning context + font creation so the unit compiles and runs in-suite. file_utils (in-house asset-read helper with the Android AAssetManager hook) gets the same unit shape. modules/ffi/stb_truetype.sx is gone: glyph_cache imports the three vendored units (stb_truetype, kb_text_shape, file_utils) directly.
This commit is contained in:
28
examples/1627-vendor-kbts-shape-context.sx
Normal file
28
examples/1627-vendor-kbts-shape-context.sx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// The sx library ships kb_text_shape: `#import "vendors/kb_text_shape/
|
||||||
|
// kb_text_shape.sx"` resolves through the stdlib search paths and the
|
||||||
|
// ~30k-line implementation compiles through the object cache (decls
|
||||||
|
// come from the curated c/kbts_api.h). Pins INVARIANTS only: a shape
|
||||||
|
// context constructs, the system Helvetica loads as a shaping font,
|
||||||
|
// and teardown is clean.
|
||||||
|
#import "modules/std.sx";
|
||||||
|
fs :: #import "modules/std/fs.sx";
|
||||||
|
kb :: #import "vendors/kb_text_shape/kb_text_shape.sx";
|
||||||
|
|
||||||
|
main :: () -> i32 {
|
||||||
|
data := fs.read_file("/System/Library/Fonts/Helvetica.ttc");
|
||||||
|
if data == null {
|
||||||
|
print("font missing\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bytes := data!;
|
||||||
|
|
||||||
|
ctx := kb.kbts_CreateShapeContext(xx 0, xx 0);
|
||||||
|
print("context created: {}\n", xx ctx != 0);
|
||||||
|
|
||||||
|
font := kb.kbts_ShapePushFontFromMemory(ctx, xx bytes.ptr, xx bytes.len, 0);
|
||||||
|
print("font pushed: {}\n", xx font != 0);
|
||||||
|
|
||||||
|
kb.kbts_DestroyShapeContext(ctx);
|
||||||
|
print("context destroyed\n");
|
||||||
|
0
|
||||||
|
}
|
||||||
1
examples/expected/1627-vendor-kbts-shape-context.exit
Normal file
1
examples/expected/1627-vendor-kbts-shape-context.exit
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0
|
||||||
3
examples/expected/1627-vendor-kbts-shape-context.stdout
Normal file
3
examples/expected/1627-vendor-kbts-shape-context.stdout
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
context created: true
|
||||||
|
font pushed: true
|
||||||
|
context destroyed
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Font stack for the ui modules: the sx-shipped stb_truetype
|
|
||||||
// (vendors/stb_truetype/) plus the in-repo text-shaping companions
|
|
||||||
// (file_utils, kb_text_shape — repo-root vendors/, not yet promoted
|
|
||||||
// to the library).
|
|
||||||
#import "vendors/stb_truetype/stb_truetype.sx";
|
|
||||||
|
|
||||||
#import c {
|
|
||||||
#include "vendors/file_utils/file_utils.h";
|
|
||||||
#source "vendors/file_utils/file_utils.c";
|
|
||||||
|
|
||||||
#include "vendors/kb_text_shape/kbts_api.h";
|
|
||||||
#source "vendors/kb_text_shape/kb_text_shape_impl.c";
|
|
||||||
};
|
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
#import "modules/ffi/opengl.sx";
|
#import "modules/ffi/opengl.sx";
|
||||||
#import "modules/gpu/types.sx";
|
#import "modules/gpu/types.sx";
|
||||||
#import "modules/gpu/api.sx";
|
#import "modules/gpu/api.sx";
|
||||||
#import "modules/ffi/stb_truetype.sx";
|
#import "vendors/stb_truetype/stb_truetype.sx";
|
||||||
|
#import "vendors/kb_text_shape/kb_text_shape.sx";
|
||||||
|
#import "vendors/file_utils/file_utils.sx";
|
||||||
#import "vendors/stb_image/stb_image.sx";
|
#import "vendors/stb_image/stb_image.sx";
|
||||||
#import "modules/ui/types.sx";
|
#import "modules/ui/types.sx";
|
||||||
|
|
||||||
|
|||||||
10
library/vendors/file_utils/README.md
vendored
Normal file
10
library/vendors/file_utils/README.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# vendors/file_utils — in-house asset-read helper
|
||||||
|
|
||||||
|
Not third-party: a small in-house C helper kept under vendors/ because
|
||||||
|
it ships as a `#import c` unit like the rest.
|
||||||
|
|
||||||
|
- `read_file_bytes(path, *out_size)` — whole-file read, malloc'd bytes.
|
||||||
|
- On Android, paths rooted inside the APK resolve through the
|
||||||
|
`AAssetManager` installed via `sx_android_set_asset_manager`
|
||||||
|
(modules/platform/android.sx calls it during activity startup; the
|
||||||
|
hook only exists in the `__ANDROID__` build of the unit).
|
||||||
55
library/vendors/file_utils/c/file_utils.c
vendored
Normal file
55
library/vendors/file_utils/c/file_utils.c
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <android/asset_manager.h>
|
||||||
|
|
||||||
|
// Caller-installed AAssetManager pointer. Chess's android_main extracts
|
||||||
|
// it from `app->activity->assetManager` (via sx-side platform module's
|
||||||
|
// `g_android_asset_manager` global) and feeds it here once at startup.
|
||||||
|
// Until the setter has been called, Android falls through to fopen —
|
||||||
|
// gives a predictable "file not found" rather than a NULL-deref.
|
||||||
|
static AAssetManager* g_aam = NULL;
|
||||||
|
|
||||||
|
void sx_android_set_asset_manager(void* m) {
|
||||||
|
g_aam = (AAssetManager*)m;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned char* read_file_bytes(const char* path, int* out_size) {
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
if (g_aam != NULL) {
|
||||||
|
// AAssetManager paths are relative to the APK's `assets/`
|
||||||
|
// directory. Strip a leading "assets/" so callers can use the
|
||||||
|
// same paths across iOS/macOS/Android (those platforms read
|
||||||
|
// assets via `assets/...` rooted in the bundle or CWD).
|
||||||
|
const char* lookup = path;
|
||||||
|
if (strncmp(path, "assets/", 7) == 0) {
|
||||||
|
lookup = path + 7;
|
||||||
|
}
|
||||||
|
AAsset* a = AAssetManager_open(g_aam, lookup, AASSET_MODE_BUFFER);
|
||||||
|
if (a != NULL) {
|
||||||
|
off_t n = AAsset_getLength(a);
|
||||||
|
*out_size = (int)n;
|
||||||
|
unsigned char* buf = (unsigned char*)malloc((size_t)n);
|
||||||
|
if (buf != NULL) {
|
||||||
|
memcpy(buf, AAsset_getBuffer(a), (size_t)n);
|
||||||
|
}
|
||||||
|
AAsset_close(a);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
// Falls through to fopen — useful when assets land in the data
|
||||||
|
// dir via extraction or app updates.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
FILE* f = fopen(path, "rb");
|
||||||
|
if (!f) return 0;
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
*out_size = (int)ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
unsigned char* buf = (unsigned char*)malloc(*out_size);
|
||||||
|
fread(buf, 1, *out_size, f);
|
||||||
|
fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
13
library/vendors/file_utils/c/file_utils.h
vendored
Normal file
13
library/vendors/file_utils/c/file_utils.h
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef FILE_UTILS_H
|
||||||
|
#define FILE_UTILS_H
|
||||||
|
|
||||||
|
unsigned char* read_file_bytes(const char* path, int* out_size);
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
// Install the AAssetManager that `read_file_bytes` consults for paths
|
||||||
|
// rooted inside the APK. Caller is responsible for passing the manager
|
||||||
|
// from `ANativeActivity->assetManager` before any read_file_bytes call.
|
||||||
|
void sx_android_set_asset_manager(void* m);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
12
library/vendors/file_utils/file_utils.sx
vendored
Normal file
12
library/vendors/file_utils/file_utils.sx
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// =====================================================================
|
||||||
|
// vendors/file_utils — in-house C helper: `read_file_bytes` with an
|
||||||
|
// Android twist. On most platforms it is a plain stdio read; on
|
||||||
|
// Android, paths rooted inside the APK resolve through the
|
||||||
|
// AAssetManager installed via `sx_android_set_asset_manager`
|
||||||
|
// (modules/platform/android.sx wires that during activity startup).
|
||||||
|
// =====================================================================
|
||||||
|
|
||||||
|
#import c {
|
||||||
|
#include "c/file_utils.h";
|
||||||
|
#source "c/file_utils.c";
|
||||||
|
};
|
||||||
22
library/vendors/kb_text_shape/README.md
vendored
Normal file
22
library/vendors/kb_text_shape/README.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# vendors/kb_text_shape — OpenType text shaping for sx programs
|
||||||
|
|
||||||
|
- Version: **v2.10** (version history at the top of the header)
|
||||||
|
- Source: <https://github.com/JimmyLefevre/kb> (`kb_text_shape.h`)
|
||||||
|
- License: zlib-style permissive (see the header's license block)
|
||||||
|
- Files: `c/kb/kb_text_shape.h` (the full upstream single-header,
|
||||||
|
~30k lines), `c/kb_text_shape_impl.c` (defines
|
||||||
|
`KB_TEXT_SHAPE_IMPLEMENTATION` and includes it), and
|
||||||
|
`c/kbts_api.h` — a hand-curated MINIMAL declaration header carrying
|
||||||
|
only the bound surface, so decl synthesis never parses the full
|
||||||
|
upstream header.
|
||||||
|
|
||||||
|
`#import "vendors/kb_text_shape/kb_text_shape.sx"` resolves through
|
||||||
|
the stdlib search paths; the implementation compiles once per machine
|
||||||
|
through sx's object cache. Shape contexts, fonts, runs, and glyphs are
|
||||||
|
opaque pointers on the sx side (modules/ui/glyph_cache.sx is the
|
||||||
|
reference consumer; `examples/1627-vendor-kbts-shape-context.sx` pins
|
||||||
|
context + font creation in the sx suite).
|
||||||
|
|
||||||
|
To upgrade: replace `c/kb/kb_text_shape.h` with a newer upstream copy,
|
||||||
|
extend `c/kbts_api.h` if the bound surface grows, update this file,
|
||||||
|
and rebuild (the object cache keys on source bytes).
|
||||||
30737
library/vendors/kb_text_shape/c/kb/kb_text_shape.h
vendored
Normal file
30737
library/vendors/kb_text_shape/c/kb/kb_text_shape.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
library/vendors/kb_text_shape/c/kb_text_shape_impl.c
vendored
Normal file
2
library/vendors/kb_text_shape/c/kb_text_shape_impl.c
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#define KB_TEXT_SHAPE_IMPLEMENTATION
|
||||||
|
#include "kb/kb_text_shape.h"
|
||||||
15
library/vendors/kb_text_shape/c/kbts_api.h
vendored
Normal file
15
library/vendors/kb_text_shape/c/kbts_api.h
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// Minimal API declarations for SX import.
|
||||||
|
// Only the functions/types we actually use — avoids parsing the full 30k-line header.
|
||||||
|
|
||||||
|
typedef struct kbts_shape_context kbts_shape_context;
|
||||||
|
typedef struct kbts_font kbts_font;
|
||||||
|
|
||||||
|
kbts_shape_context *kbts_CreateShapeContext(void *Allocator, void *AllocatorData);
|
||||||
|
void kbts_DestroyShapeContext(kbts_shape_context *Context);
|
||||||
|
kbts_font *kbts_ShapePushFontFromMemory(kbts_shape_context *Context, void *Memory, int Size, int FontIndex);
|
||||||
|
void kbts_GetFontInfo2(kbts_font *Font, void *Info);
|
||||||
|
void kbts_ShapeBegin(kbts_shape_context *Context, unsigned int ParagraphDirection, unsigned int Language);
|
||||||
|
void kbts_ShapeUtf8(kbts_shape_context *Context, const char *Utf8, int Length, unsigned int UserIdGenerationMode);
|
||||||
|
void kbts_ShapeEnd(kbts_shape_context *Context);
|
||||||
|
int kbts_ShapeRun(kbts_shape_context *Context, void *Run);
|
||||||
|
int kbts_GlyphIteratorNext(void *It, void **Glyph);
|
||||||
18
library/vendors/kb_text_shape/kb_text_shape.sx
vendored
Normal file
18
library/vendors/kb_text_shape/kb_text_shape.sx
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// =====================================================================
|
||||||
|
// vendors/kb_text_shape — Jimmy Lefevre's kb_text_shape (OpenType text
|
||||||
|
// shaping) as a `#import c` unit (c/, see README.md for version +
|
||||||
|
// provenance).
|
||||||
|
//
|
||||||
|
// `#import "vendors/kb_text_shape/kb_text_shape.sx"` gives any sx
|
||||||
|
// program text shaping with no system dependency. The decls come from
|
||||||
|
// c/kbts_api.h — a hand-curated MINIMAL declaration header covering
|
||||||
|
// only the bound surface (the full upstream header is ~30k lines and
|
||||||
|
// is included only by the implementation unit). Shape contexts, fonts,
|
||||||
|
// runs, and glyphs are opaque pointers on the sx side; see
|
||||||
|
// modules/ui/glyph_cache.sx for the reference consumer.
|
||||||
|
// =====================================================================
|
||||||
|
|
||||||
|
#import c {
|
||||||
|
#include "c/kbts_api.h";
|
||||||
|
#source "c/kb_text_shape_impl.c";
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user