Skip to content

Commit

Permalink
cache fribidi and harfbuzz builds
Browse files Browse the repository at this point in the history
  • Loading branch information
martinfouilleul committed Nov 5, 2024
1 parent e2edfb2 commit cd4c210
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 8 deletions.
1 change: 1 addition & 0 deletions deps/fribidi-commit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
68162babff4f39c4e2dc164a5e825af93bda9983
2 changes: 1 addition & 1 deletion samples/clock/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ wasmFlags=(--target=wasm32 \
-I "$ORCA_DIR"/src/ext)

# build sample as wasm module and link it with the orca module
clang "${wasmFlags[@]}" -L "$ORCA_DIR"/bin -lorca_wasm -o module.wasm src/main.c
clang -v "${wasmFlags[@]}" -L "$ORCA_DIR"/bin -lorca_wasm -o module.wasm src/main.c

# create app directory and copy files into it
orca bundle --name Clock --icon icon.png --resource-dir data module.wasm
23 changes: 23 additions & 0 deletions samples/clock/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
**************************************************************************/
#include <math.h>
#include <orca.h>
#include <fribidi/include/fribidi.h>

const oc_str8 clockNumberStrings[] = {
OC_STR8_LIT("12"),
Expand Down Expand Up @@ -47,6 +48,28 @@ ORCA_EXPORT void oc_on_init(void)
context = oc_canvas_context_create();

font = oc_font_create_from_path(OC_STR8("/segoeui.ttf"));

////////////////////////////////
const char* text = "bahrain مصر kuwait";

oc_arena_scope scratch = oc_scratch_begin();
oc_str32 codepoints = oc_utf8_push_to_codepoints(scratch.arena, OC_STR8(text));

FriBidiParType baseDir = FRIBIDI_TYPE_LTR_VAL;
FriBidiLevel levels[256];

fribidi_log2vis(codepoints.ptr,
codepoints.len,
&baseDir,
0, 0, 0,
levels);

for(u64 i = 0; i < codepoints.len; i++)
{
oc_log_info("%i\n", levels[i]);
}

oc_scratch_end(scratch);
}

ORCA_EXPORT void oc_on_resize(u32 width, u32 height)
Expand Down
272 changes: 265 additions & 7 deletions scripts/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def attach_dev_commands(subparsers):
sdk_cmd.add_argument("--release", action="store_true", help="compile in release mode (default is debug)")
sdk_cmd.set_defaults(func=dev_shellish(build_sdk))

fribidi_cmd = subparsers.add_parser("build-fribidi", help="Build Fribidi.")
fribidi_cmd.add_argument("--release", action="store_true", help="compile in release mode (default is debug)")
fribidi_cmd.set_defaults(func=dev_shellish(build_fribidi))

tool_cmd = subparsers.add_parser("build-tool", help="Build the Orca CLI tool from source.")
tool_cmd.add_argument("--version", help="embed a version string in the Orca CLI tool (default is git commit hash)")
tool_cmd.add_argument("--release", action="store_true", help="compile Orca CLI tool in release mode (default is debug)")
Expand Down Expand Up @@ -472,10 +476,238 @@ def build_angle_internal(release, force):

print("Done")

#------------------------------------------------------
# build fribidi
#------------------------------------------------------

def check_fribidi():
print("Checking fribidi cache...", end="")

with open("deps/fribidi-commit.txt", "r") as f:
FRIBIDI_COMMIT = f.read().strip()

fribidi_ok = True

if not os.path.exists("build/fribidi.out/checksums.json"):
print("checksums.json not found")
fribidi_ok = False
else:
with pushd("build/fribidi.out"):
with open("checksums.json", "r") as f:
sums = json.load(f)

if "commit" not in sums:
print("commit not found in checksums.json")
fribidi_ok = False
elif sums["commit"] != FRIBIDI_COMMIT:
found = sums["commit"]
print(f"Cache does not match commit (expected {FRIBIDI_COMMIT}, found {found})")
fribidi_ok = False
elif "sums" not in sums:
print("sums not found in checksums.json")
fribidi_ok = False
else:
for entry in sums["sums"]:
if "file" not in entry or "sum" not in entry:
print("file or sum not found in cache entry")
print(entry)
fribidi_ok = False
break

if not os.path.exists(entry["file"]):
f = entry["file"]
print(f"file {f} does not exist in cache")
fribidi_ok = False
break

fileSum = checksum.filesum(entry["file"])
if fileSum != entry["sum"]:
f = entry["file"]
s = entry["sum"]
print(f"file {f} does not match checksum (expected {s}, got {fileSum})")
fribidi_ok = False
break

if not fribidi_ok:
build_fribidi()
else:
print("ok")

# copy fribidi bin/includes
os.makedirs("src/ext/fribidi/include", exist_ok=True)
shutil.copytree("build/fribidi.out/include", "src/ext/fribidi/include", dirs_exist_ok=True)

for f in glob.glob("build/fribidi.out/bin/*"):
shutil.copy(f, "build/bin")


def build_fribidi(release=False):
print("Building fribidi...")

with open("deps/fribidi-commit.txt", "r") as f:
FRIBIDI_COMMIT = f.read().strip()

os.makedirs("build/bin", exist_ok=True)

# check fribidi repo
with pushd("build"):
if not os.path.exists("fribidi"):
subprocess.run([
"git", "clone", "--no-tags", "--single-branch",
"https://github.com/fribidi/fribidi.git"
], check=True)

with pushd("fribidi"):
subprocess.run([
"git", "fetch", "--no-tags"
], check=True)

subprocess.run([
"git", "reset", "--hard", FRIBIDI_COMMIT
], check=True)

# build native
subprocess.run([
"./autogen.sh"
], check=True)

subprocess.run([
"./configure"
], check=True)

subprocess.run([
"make"
], check=True)

# build wasm
source_files = glob.glob("lib/*.c");

subprocess.run([
"clang",
"--target=wasm32",
"--no-standard-libraries",
"-mbulk-memory",
"-Wl,--no-entry",
"-Wl,--export-dynamic",
"-Wl,--relocatable",
"-DHAVE_CONFIG_H",
"-I.",
"-Ilib",
"-I../../src/orca-libc/include",
*source_files,
"-o", "libfribidi_wasm.a",
], check=True)

# copying artifacts
os.makedirs("build/fribidi.out/bin", exist_ok=True)
os.makedirs("build/fribidi.out/include", exist_ok=True)

sums = []

if platform.system() == "Windows":
shutil.copy("build/fribidi/lib/.libs/libfribidi.dll", "build/fribidi.out/bin")
sums.append({
"file": "bin/libfribidi.dll",
"sum": checksum.filesum("build/fribidi.out/bin/libfribidi.dll")
})
shutil.copy("build/fribidi/lib/.libs/libfribidi.dll.lib", "build/fribidi.out/bin")
sums.append({
"file": "bin/libfribidi.dll.lib",
"sum": checksum.filesum("build/fribidi.out/bin/libfribidi.dll.lib")
})
else:
shutil.copy("build/fribidi/lib/.libs/libfribidi.dylib", "build/fribidi.out/bin")
sums.append({
"file": "bin/libfribidi.dylib",
"sum": checksum.filesum("build/fribidi.out/bin/libfribidi.dylib")
})

shutil.copy("build/fribidi/libfribidi_wasm.a", "build/fribidi.out/bin")
sums.append({
"file": "bin/libfribidi_wasm.a",
"sum": checksum.filesum("build/fribidi.out/bin/libfribidi_wasm.a")
})

for f in glob.iglob("build/fribidi/lib/*.h"):
shutil.copy(f, "build/fribidi.out/include")
sums.append({
"file": f"include/{os.path.basename(f)}",
"sum": checksum.filesum(f"build/fribidi.out/include/{os.path.basename(f)}")
})

# write checksums
with open("build/fribidi.out/checksums.json", "w") as f:
d = {
"commit" : FRIBIDI_COMMIT,
"sums": sums
}
json.dump(d, f)


#------------------------------------------------------
# build harfbuzz
#------------------------------------------------------

def check_harfbuzz():
print("Checking harfbuzz cache...", end="")

with open("deps/harfbuzz-commit.txt", "r") as f:
HARFBUZZ_COMMIT = f.read().strip()

harfbuzz_ok = True

if not os.path.exists("build/harfbuzz.out/checksums.json"):
print("checksums.json not found")
harfbuzz_ok = False
else:
with pushd("build/harfbuzz.out"):
with open("checksums.json", "r") as f:
sums = json.load(f)

if "commit" not in sums:
print("commit not found in checksums.json")
harfbuzz_ok = False
elif sums["commit"] != HARFBUZZ_COMMIT:
found = sums["commit"]
print(f"Cache does not match commit (expected {HARFBUZZ_COMMIT}, found {found})")
harfbuzz_ok = False
elif "sums" not in sums:
print("sums not found in checksums.json")
harfbuzz_ok = False
else:
for entry in sums["sums"]:
if "file" not in entry or "sum" not in entry:
print("file or sum not found in cache entry")
print(entry)
harfbuzz_ok = False
break

if not os.path.exists(entry["file"]):
f = entry["file"]
print(f"file {f} does not exist in cache")
harfbuzz_ok = False
break

fileSum = checksum.filesum(entry["file"])
if fileSum != entry["sum"]:
f = entry["file"]
s = entry["sum"]
print(f"file {f} does not match checksum (expected {s}, got {fileSum})")
harfbuzz_ok = False
break

if not harfbuzz_ok:
build_harfbuzz()
else:
print("ok")

# copy harfbuzz bin/includes
os.makedirs("src/ext/harfbuzz/include", exist_ok=True)
shutil.copytree("build/harfbuzz.out/include", "src/ext/harfbuzz/include", dirs_exist_ok=True)

for f in glob.glob("build/harfbuzz.out/bin/*"):
shutil.copy(f, "build/bin")

def build_harfbuzz():
print("Building harfbuzz...")

Expand Down Expand Up @@ -519,15 +751,40 @@ def build_harfbuzz():
], check=True)


# copying artifacts
shutil.copy(f"build/harfbuzz/{libname}", "build/bin")
# copying artifacts and computing checksums
sums = []

os.makedirs("build/harfbuzz.out/bin", exist_ok=True)
os.makedirs("build/harfbuzz.out/include", exist_ok=True)

shutil.copy(f"build/harfbuzz/{libname}", "build/harfbuzz.out/bin")
sums.append({
"file": f"bin/{libname}",
"sum": checksum.filesum(f"build/harfbuzz.out/bin/{libname}")
})

if platform.system() == "Windows":
shutil.copy("build/harfbuzz/libharfbuzz.dll.lib", "build/bin")
shutil.copy("build/harfbuzz/libharfbuzz.dll.lib", "build/harfbuzz.out/bin")
sums.append({
"file": f"bin/libharfbuzz.dll.lib",
"sum": checskum.filesum(f"build/harfbuzz.out/bin/libharfbuzz.dll.lib")
})

os.makedirs("src/ext/harfbuzz/include", exist_ok=True)
for f in glob.iglob("build/harfbuzz/src/*.h"):
shutil.copy(f, "src/ext/harfbuzz/include")
shutil.copy(f, "build/harfbuzz.out/include")
sums.append({
"file": f"include/{os.path.basename(f)}",
"sum": checksum.filesum(f"build/harfbuzz.out/include/{os.path.basename(f)}")
})

# write checksums
with open("build/harfbuzz.out/checksums.json", "w") as f:
d = {
"commit" : HARFBUZZ_COMMIT,
"sums": sums
}

json.dump(d, f)


#------------------------------------------------------
Expand Down Expand Up @@ -752,7 +1009,8 @@ def build_platform_layer_internal(release):

# build harfbuzz
#TODO: skip if already built
build_harfbuzz()
check_harfbuzz()
check_fribidi()

print("Building Orca platform layer...")

Expand Down Expand Up @@ -1032,7 +1290,7 @@ def build_sdk_internal(release):
subprocess.run([
clang, *flags, *includes,
"-o", "build/bin/liborca_wasm.a",
"src/orca.c"
"src/orca.c", "build/bin/libfribidi_wasm.a"
], check=True)

#------------------------------------------------------
Expand Down
19 changes: 19 additions & 0 deletions src/graphics/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ typedef struct oc_text_shape_settings

typedef struct oc_glyph_run oc_glyph_run;

typedef struct oc_text_attributes
{
oc_font font;
f32 fontSize;
oc_color color;
} oc_text_attributes;

typedef struct oc_text_line oc_text_line;

//------------------------------------------------------------------------------------------
//SECTION: color helpers
//------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -341,6 +350,16 @@ ORCA_API void oc_text_draw_run(oc_glyph_run* run, f32 fontSize);
ORCA_API void oc_text_draw_utf8(oc_str8 text, oc_font font, f32 fontSize);
ORCA_API void oc_text_draw_utf32(oc_str32 codepoints, oc_font font, f32 fontSize);

// text lines
oc_text_line* oc_text_line_from_utf8(oc_arena* arena, oc_str8 string, oc_text_attributes* attributes);
oc_text_line* oc_text_line_from_utf32(oc_arena* arena, oc_str32 string, oc_text_attributes* attributes);

oc_text_metrics oc_text_line_get_metrics(oc_text_line* line);
u64 oc_text_line_codepoint_index_for_position(oc_text_line* line, oc_vec2 position);
oc_vec2 oc_text_line_position_for_codepoint_index(oc_text_line* line, u64 index);

void oc_text_line_draw(oc_text_line* line);

//------------------------------------------------------------------------------------------
//SECTION: shapes helpers
//------------------------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit cd4c210

Please sign in to comment.