loading font data, woop!
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 21 Sep 2020 01:13:33 +0000 (20:13 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 21 Sep 2020 01:13:33 +0000 (20:13 -0500)
build.sh
res/Inconsolata-Regular.ttf [new file with mode: 0644]
src/font.onyx [new file with mode: 0644]
src/gfx/quad_renderer.onyx
src/main.onyx
src/vecmath.onyx [new file with mode: 0644]
tags

index d66a9bbb45673ef8aebd9819f8ff8fccf7ced95d..37baa37455aadedecdc853357d5f29aef4c80dc0 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -1,4 +1,3 @@
 #!/bin/sh
 
-onyx doc src/main.onyx
-onyx src/main.onyx
\ No newline at end of file
+onyx src/main.onyx && onyx doc src/main.onyx
diff --git a/res/Inconsolata-Regular.ttf b/res/Inconsolata-Regular.ttf
new file mode 100644 (file)
index 0000000..e329bbc
Binary files /dev/null and b/res/Inconsolata-Regular.ttf differ
diff --git a/src/font.onyx b/src/font.onyx
new file mode 100644 (file)
index 0000000..4617dac
--- /dev/null
@@ -0,0 +1,372 @@
+package ttf_font
+
+use package core
+use package vecmath
+
+// Very proud of how small this function can be using slices
+// However, it should be turned into a non-recursive solution
+// since this runs in factorial time.
+bezier_curve :: proc (t: f32, ps: [] V2f) -> V2f {
+    if ps.count == 1 do return ps[0];
+
+    ret := V2f.{ 0.0f, 0.0f };
+    ret = v2_add(ret, v2_mul(bezier_curve(t, ps.data[0 .. ps.count - 1]), 1.0f - t));
+    ret = v2_add(ret, v2_mul(bezier_curve(t, ps.data[1 .. ps.count]), t));
+    return ret;
+}
+
+BinaryReader :: struct {
+    data : [] u8;
+    pos  : u32;
+}
+
+binary_reader_create :: proc (data: [] u8, initial_pos := 0) -> BinaryReader {
+    return BinaryReader.{ data = data, pos = initial_pos };
+}
+
+#private_file seek :: proc (use br: ^BinaryReader, new_pos: u32) -> u32 {
+    old_pos :: pos;
+    pos = new_pos;
+    return old_pos;
+}
+
+#private_file tell :: proc (use br: ^BinaryReader) -> u32 do return pos;
+
+#private_file read_u8 :: proc (use br: ^BinaryReader) -> u8 {
+    ret := data[pos];
+    pos += 1;
+    return ret;
+}
+
+#private_file read_u16 :: proc (use br: ^BinaryReader) -> u16 do return ~~(read_u8(br) << ~~8  | read_u8(br));
+
+#private_file read_u32 :: proc (use br: ^BinaryReader) -> u32 {
+    // Encoding is big endian
+    ret := 0;
+    ret |= ~~read_u8(br) << 24;
+    ret |= ~~read_u8(br) << 16;
+    ret |= ~~read_u8(br) << 8;
+    ret |= ~~read_u8(br);
+    return ret;
+}
+
+#private_file read_i16 :: proc (use br: ^BinaryReader) -> i16 {
+    ret := read_u16(br);
+    if ret & ~~0x8000 != ~~0 do ret -= ~~(1 << 16);
+    return ret;
+}
+
+#private_file read_i32 :: proc (use br: ^BinaryReader) -> i32 {
+    return ~~read_u32(br);
+}
+
+#private_file read_fword :: proc (use br: ^BinaryReader) -> i16 do return read_i16(br);
+
+#private_file read_2dot14 :: proc (use br: ^BinaryReader) -> f32 {
+    val := cast(i32) read_i16(br);
+    return ~~val / cast(f32) (1 << 14);
+}
+
+#private_file read_fixed :: proc (use br: ^BinaryReader) -> f32 {
+    val := read_i32(br);
+    return ~~val / cast(f32) (1 << 16);
+}
+
+#private_file read_string :: proc (use br: ^BinaryReader, len: i32) -> string {
+    ret := data.data[pos .. pos + len];
+    pos += len;
+    return ret;
+}
+
+// NOT IMPLEMENTED
+#private_file read_date :: proc (use br: ^BinaryReader) -> u64 {
+    pos += 8;
+    return ~~0;
+}
+
+
+
+
+
+TrueTypeFont :: struct {
+    reader: BinaryReader;
+
+    // NOTE: I don't know how useful these are, but they're at
+    // the beginning of the ttf file.
+    scalar_type    : u32;
+    search_range   : u16;
+    entry_selector : u16;
+    range_shift    : u16;
+
+    table_map : I32Map(TTTableInfo);
+
+    version : u32;
+    font_revision : u32;
+    checksum_adjustment : u32;
+    magic_number : u32;
+    flags : u16;
+    units_per_em : u16;
+    // created : u64;
+    // modified : u64;
+    x_min : i16;
+    x_max : i16;
+    y_min : i16;
+    y_max : i16;
+    mac_style : u16;
+    lowest_rec_ppem : u16;
+    font_direction_hint : i16;
+    index_to_loc_format : TTIndexToLocFormat;
+    glyph_data_format : i16;
+}
+
+TTTableInfo :: struct {
+    checksum : u32 = 0;
+    offset   : u32 = 0;
+    length   : u32 = 0;
+}
+
+TTIndexToLocFormat :: enum (i16) {
+    Short :: 0x00;
+    Long  :: 0x01;
+}
+
+TTGlyph :: struct {
+    contour_count : i16;
+    x_min : i16;
+    x_max : i16;
+    y_min : i16;
+    y_max : i16;
+
+    points : [..] TTGlyphPoint;
+    contour_ends : [..] u16;
+}
+
+TTGlyphPoint :: struct {
+    on_curve : bool;
+    x : i16 = ~~0;
+    y : i16 = ~~0;
+}
+
+ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont {
+    ttf : TrueTypeFont;
+    ttf.reader = binary_reader_create(ttf_data);
+    i32map_init(^ttf.table_map);
+
+    return ttf;
+}
+
+ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) {
+    scalar_type = read_u32(^reader);
+    num_tables := read_u16(^reader);
+    search_range = read_u16(^reader);
+    entry_selector = read_u16(^reader);
+    range_shift = read_u16(^reader);
+
+    for i: 0 .. ~~num_tables {
+        tag := read_string(^reader, 4);
+        tag_int := string_to_beu32(tag);
+        println(tag);
+
+        table_info : TTTableInfo;
+        table_info.checksum = read_u32(^reader);
+        table_info.offset   = read_u32(^reader);
+        table_info.length   = read_u32(^reader);
+
+        i32map_put(^table_map, tag_int, table_info);
+
+        if !string_equal(tag, "head") {
+            // TODO: Calculate checksum to ensure everything looks right
+            csum := ttf_calc_table_checksum(^reader, table_info.offset, table_info.length);
+            if table_info.checksum != csum {
+                print("WARNING: Checksum for table '");
+                print(tag);
+                print("' did not match.");
+            }
+        }
+    }
+}
+
+ttf_read_head_table :: proc (use ttf: ^TrueTypeFont) {
+    empty_table_hack := TTTableInfo.{};
+    head_table_info  := i32map_get(^table_map, string_to_beu32("head"), empty_table_hack);
+    seek(^reader, head_table_info.offset);
+
+    version = read_u32(^reader);
+    font_revision = read_u32(^reader);
+    checksum_adjustment = read_u32(^reader);
+    magic_number = read_u32(^reader);            // NOTE: Should be 0x5f0f3cf5
+    flags = read_u16(^reader);
+    units_per_em = read_u16(^reader);
+    read_date(^reader); // created
+    read_date(^reader); // modified
+    x_min = read_fword(^reader);
+    y_min = read_fword(^reader);
+    x_max = read_fword(^reader);
+    y_max = read_fword(^reader);
+    mac_style = read_u16(^reader);
+    lowest_rec_ppem = read_u16(^reader);
+    font_direction_hint = read_i16(^reader);
+    index_to_loc_format = cast(TTIndexToLocFormat) read_i16(^reader);
+    glyph_data_format = read_i16(^reader);
+}
+
+ttf_lookup_glyph_offset :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> u32 {
+    empty_table_hack := TTTableInfo.{};
+    loca_table_info  := i32map_get(^table_map, string_to_beu32("loca"), empty_table_hack);
+    glyf_table_info  := i32map_get(^table_map, string_to_beu32("glyf"), empty_table_hack);
+
+    old: u32;
+    defer seek(^reader, old);
+
+    switch index_to_loc_format {
+        case TTIndexToLocFormat.Long {
+            old = seek(^reader, loca_table_info.offset + glyph_index * 4);
+            return read_u32(^reader) + glyf_table_info.offset;
+        }
+
+        case #default {
+            old = seek(^reader, loca_table_info.offset + glyph_index * 2);
+            return 2 * ~~read_u16(^reader) + glyf_table_info.offset;
+        }
+    }
+
+    return -1;
+}
+
+// Result is expected to be freed
+ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph {
+    offset := ttf_lookup_glyph_offset(ttf, glyph_index);
+
+    empty_table_hack := TTTableInfo.{};
+    glyf_table_info  := i32map_get(^table_map, string_to_beu32("glyf"), empty_table_hack);
+
+    if offset >= glyf_table_info.offset + glyf_table_info.length do return null;
+
+    seek(^reader, offset);
+
+    glyph := cast(^TTGlyph) calloc(sizeof TTGlyph);
+    glyph.contour_count = read_i16(^reader);
+    glyph.x_min = read_fword(^reader);
+    glyph.y_min = read_fword(^reader);
+    glyph.x_max = read_fword(^reader);
+    glyph.y_max = read_fword(^reader);
+
+    if glyph.contour_count < ~~0 { cfree(glyph); return null; }
+    if glyph.contour_count == ~~ -1 {
+        // Compound glyph
+        return null;
+    } else {
+        // Simple glyph
+        ttf_read_simple_glyph(ttf, glyph);
+    }
+
+    return glyph;
+}
+
+#private_file
+TTGlyphFlags :: enum #flags {
+    On_Curve :: 0x01;
+    X_Is_Byte :: 0x2;
+    Y_Is_Byte :: 0x4;
+    Repeat    :: 0x8;
+    X_Delta   :: 0x10;
+    Y_Delta   :: 0x20;
+}
+
+#private_file
+ttf_read_simple_glyph :: proc (use ttf: ^TrueTypeFont, glyph: ^TTGlyph) {
+    array_init(^glyph.contour_ends, ~~glyph.contour_count);
+    array_init(^glyph.points);
+
+    for i: 0 .. ~~glyph.contour_count {
+        array_push(^glyph.contour_ends, read_u16(^reader));
+    }
+
+    seek(^reader, ~~read_u16(^reader) + tell(^reader));
+
+    if glyph.contour_count == ~~0 do return;
+
+    num_points := array_fold(^glyph.contour_ends, cast(u16) 0, max_poly) + ~~1;
+
+    flags : [..] TTGlyphFlags;
+    array_init(^flags);
+    defer array_free(^flags);
+
+    for i: 0 .. ~~num_points {
+        flag := cast(TTGlyphFlags) read_u8(^reader);
+        array_push(^flags, flag);
+        array_push(^glyph.points, TTGlyphPoint.{ on_curve = (flag & TTGlyphFlags.On_Curve) != ~~0 });
+
+        if (flag & TTGlyphFlags.Repeat) != ~~0 {
+            rep_count := read_u8(^reader);
+            i += ~~rep_count;
+            for i: 0 .. ~~rep_count {
+                array_push(^flags, flag);
+                array_push(^glyph.points, TTGlyphPoint.{ on_curve = (flag & TTGlyphFlags.On_Curve) != ~~0 });
+            }
+        }
+    }
+
+    value := cast(i16) 0;
+    for i: 0 .. ~~num_points {
+        flag := flags[i];
+
+        if (flag & TTGlyphFlags.X_Is_Byte) != ~~0 {
+            if (flag & TTGlyphFlags.X_Delta) != ~~0 {
+                value += ~~read_u8(^reader);
+            } else {
+                value -= ~~read_u8(^reader);
+            }
+        } elseif (flag & TTGlyphFlags.X_Delta) == ~~0 {
+            value += read_i16(^reader);
+        }
+
+        glyph.points[i].x = value;
+    }
+
+    value = cast(i16) 0;
+    for i: 0 .. ~~num_points {
+        flag := flags[i];
+
+        if (flag & TTGlyphFlags.Y_Is_Byte) != ~~0 {
+            if (flag & TTGlyphFlags.Y_Delta) != ~~0 {
+                value += ~~read_u8(^reader);
+            } else {
+                value -= ~~read_u8(^reader);
+            }
+        } elseif (flag & TTGlyphFlags.Y_Delta) == ~~0 {
+            value += read_i16(^reader);
+        }
+
+        glyph.points[i].y = value;
+    }
+}
+
+
+ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 {
+    empty_table_hack := TTTableInfo.{};
+    maxp_table_info  := i32map_get(^table_map, string_to_beu32("maxp"), empty_table_hack);
+    old := seek(^reader, maxp_table_info.offset + 4);
+    defer seek(^reader, old);
+
+    return ~~read_u16(^reader);
+}
+
+#private_file
+ttf_calc_table_checksum :: proc (reader: ^BinaryReader, offset: u32, length: u32) -> u32 {
+    old := seek(reader, offset);
+    defer seek(reader, old);
+
+    sum := 0;
+    nlongs := (length + 3) >> 2;
+    for i: 0 .. nlongs do sum += read_u32(reader);
+    return sum;
+}
+
+#private_file
+string_to_beu32 :: proc (s: string) -> u32 {
+    return (~~s[0] << 24)
+         | (~~s[1] << 16)
+         | (~~s[2] << 8)
+         | (~~s[3]);
+}
index 9191818fabebbbe114c17721ea16d82f40386a5c..64a1c87927bc6fe543b58c180dcdf5be1736e04c 100644 (file)
@@ -28,13 +28,13 @@ QuadRenderer :: struct {
 Color4f32 :: struct { r: f32; g: f32; b: f32; a: f32; }
 
 Quad :: struct {
-    pos  : Vec2;
-    size : Vec2;
+    pos  : Vec2 = Vec2.{ 0f, 0f };
+    size : Vec2 = Vec2.{ 0f, 0f };
 
-    tex_pos  : Vec2;
-    tex_size : Vec2;
+    tex_pos  : Vec2 = Vec2.{ 0f, 0f };
+    tex_size : Vec2 = Vec2.{ 0f, 0f };
 
-    color : Color4f32;
+    color : Color4f32 = Color4f32.{ 0f, 0f, 0f, 0f };
 }
 
 quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
@@ -61,12 +61,7 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
 
     array_init(^quad_data, initial_quads);
 
-    default_quad : Quad;
-    default_quad.pos  = Vec2.{ 0.0f, 0.0f };
-    default_quad.size = Vec2.{ 0.0f, 0.0f };
-    default_quad.tex_pos = Vec2.{ 0.0f, 0.0f };
-    default_quad.tex_size = Vec2.{ 0.0f, 0.0f };
-    default_quad.color = Color4f32.{ 0.0f, 0.0f, 0.0f, 0.0f };
+    default_quad := Quad.{};
     for i: 0 .. initial_quads {
         array_push(^quad_data, default_quad);
     }
index 099623ce399dd4294de1923436f7968a555b798f..974ea10896101dedfe52c0acbfbb70dd73621f48 100644 (file)
@@ -9,21 +9,76 @@ package main
 #include_file "gfx/texture"
 #include_file "events"
 #include_file "input"
+#include_file "font"
+#include_file "vecmath"
 
 use package core
 use package gfx
 use package gl as gl
 use package event as event
 use package input as input { Key }
+use package vecmath
+use package ttf_font
+
+NUM_QUADS :: 1 << 10
+
+
+
+RenderContext :: struct {
+    quad_renderer: ^QuadRenderer;
+
+    curr_quad_idx: i32 = 0;
+    max_quad_idx:  i32 = 0;
+
+    // @CLEANUP  Allow for the syntax:
+    //      color := Color4f32.{ ... }
+    // OR
+    //      color: Color4f32 = .{ ... }
+    color: Color4f32 = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f };
+}
+
+render_context_init :: proc (use rc: ^RenderContext, qr: ^QuadRenderer = null) {
+    aqr := qr;
+
+    if aqr == null {
+        aqr = calloc(sizeof QuadRenderer);
+        quad_renderer_init(aqr, NUM_QUADS);
+    }
+
+    *rc = RenderContext.{
+        quad_renderer = aqr,
+        max_quad_idx = qr.quad_data.count,
+    };
+}
+
+draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) {
+    if curr_quad_idx >= max_quad_idx do return;
+
+    quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{
+        pos   = Vec2.{ x, y },
+        size  = Vec2.{ w, h },
+        color = color,
+    });
+
+    curr_quad_idx += 1;
+}
+
+render_context_flush :: proc (use rc: ^RenderContext) {
+    quad_rebuffer_data(quad_renderer);
+    quad_renderer_draw(quad_renderer);
+
+    curr_quad_idx = 0;
+}
+
 
-NUM_QUADS :: 1 << 7
 
 // @Cleanup
 window_width  := 0
 window_height := 0
 
-quad_renderer : QuadRenderer
+renderer      : RenderContext
 input_state   : input.InputState
+ttf           : TrueTypeFont
 
 Player :: struct { use pos : Vec2; }
 player : Player
@@ -47,7 +102,7 @@ poll_events :: proc () {
             gl.canvasSize(window_width, window_height);
             gl.viewport(0, 0, window_width, window_height);
 
-            quad_renderer_update_view(^quad_renderer);
+            quad_renderer_update_view(renderer.quad_renderer);
         }
     }
 }
@@ -63,34 +118,46 @@ update :: proc () {
     if input.key_down(^input_state, Key.ArrowDown)  do player.y += player_speed;
     if input.key_down(^input_state, Key.ArrowLeft)  do player.x -= player_speed;
     if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed;
+}
 
-    quad_update_at_index(^quad_renderer, NUM_QUADS - 1, Quad.{
-        pos = Vec2.{ ~~input_state.mouse.x, ~~input_state.mouse.y },
-        size = Vec2.{ 32.0f, 32.0f },
+draw :: proc () {
+    defer render_context_flush(^renderer);
 
-        tex_pos = Vec2.{ 0.25f, 0.25f },
-        tex_size = Vec2.{ 0.25f, 0.25f },
+    gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
+    gl.clear(gl.COLOR_BUFFER_BIT);
 
-        color = Color4f32.{ 1.0f, 0.0f, 0.0f, 0.5f },
-    });
+    renderer.color = Color4f32.{ 1f, 0f, 0f, 1f };
 
-    quad_update_at_index(^quad_renderer, 0, Quad.{
-        pos = player.pos,
-        size = Vec2.{ 100.0f, 100.0f },
 
-        tex_pos = Vec2.{ 0.0f, 0.0f },
-        tex_size = Vec2.{ 1.0f, 1.0f },
+    // points : [6] V2f;
+    // points[0] = V2f.{ 500.0f, 700.0f };
+    // points[1] = V2f.{ 600.0f, 200.0f };
+    // points[2] = V2f.{ 700.0f, 400.0f };
+    // points[3] = V2f.{ 1700.0f, 800.0f };
+    // points[4] = V2f.{ 1800.0f, 400.0f };
+    // points[5] = V2f.{ 1000.0f, 200.0f };
 
-        color = Color4f32.{ 0.0f, 0.0f, 1.0f, 1.0f },
-    });
-}
+    // for i: 0 .. 200 {
+    //     pos := bezier_curve(~~i / 200.0f, points[0 .. 6]);
+    //     draw_rect(^renderer, pos.x, pos.y, 16f, 16f);
+    // }
 
-draw :: proc () {
-    gl.clearColor(0.1f, 0.1f, 0.1f, 1.0f);
-    gl.clear(gl.COLOR_BUFFER_BIT);
+    glyph : ^TTGlyph = null;
+    idx := 230;
+    while glyph == null {
+        glyph = ttf_read_glyph(^ttf, idx);
+        idx += 1;
+    }
+    defer cfree(glyph);
+
+    rx := 100.0f / ~~ cast(i32) (glyph.x_max - glyph.x_min);
+    ry := 100.0f / ~~ cast(i32) (glyph.y_min - glyph.y_max);
+    for p: glyph.points {
+        draw_rect(^renderer, ~~ cast(i32) p.x * rx + 100f, ~~ cast(i32) p.y * ry + 100f, 10f, 10f);
+    }
 
-    quad_rebuffer_data(^quad_renderer);
-    quad_renderer_draw(^quad_renderer);
+    draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f);
+    draw_rect(^renderer, player.pos.x, player.pos.y, 100f, 100f);
 }
 
 // This procedure is called asynchronously from JS every frame.
@@ -113,15 +180,13 @@ main :: proc (args: [] cstring) {
     gl.enable(gl.BLEND);
     gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
 
-    quad_renderer_init(^quad_renderer, NUM_QUADS);
+    render_context_init(^renderer, null);
 
     // CLEANUP: Maybe there should be a way to cast between slices?
     // Automatically multiply / divide the count by the ratio of the type sizes?
     // This could be very buggy
-    image_data : [] Color3;
     raw_image_data := #file_contents "res/smile.data";
-    image_data.data  = cast(^Color3) raw_image_data.data;
-    image_data.count = raw_image_data.count / 3;
+    image_data := (cast(^Color3) raw_image_data.data)[0 .. raw_image_data.count / 3];
 
     smile := texture_create(image_data, 32, 32);
     texture_prepare(^smile);
@@ -130,6 +195,27 @@ main :: proc (args: [] cstring) {
     event.init();
     input.init(^input_state);
 
+    ttf_data := #file_contents "res/Inconsolata-Regular.ttf";
+    ttf = ttf_create(ttf_data);
+    ttf_read_offset_table(^ttf);
+    ttf_read_head_table(^ttf);
+
+    // for i: 0 .. ttf_glyph_count(^ttf) {
+    //     glyph := ttf_read_glyph(^ttf, i);
+    //     if glyph == null do continue;
+    //     defer cfree(glyph);
+
+    //     // println(glyph.points.count);
+    //     // for p: glyph.points {
+    //     //     print(p.on_curve);
+    //     //     print("   ");
+    //     //     print(cast(i32) p.x);
+    //     //     print(", ");
+    //     //     print(cast(i32) p.y);
+    //     //     print("\n");
+    //     // }
+    // }
+
     game_launch();
 }
 
diff --git a/src/vecmath.onyx b/src/vecmath.onyx
new file mode 100644 (file)
index 0000000..0d638e0
--- /dev/null
@@ -0,0 +1,28 @@
+package vecmath
+
+// BUG: Default values do not work on polymorphic structs.
+V2 :: struct ($T) { x: T; y: T; }
+
+V2f :: #type V2(f32);
+V2i :: #type V2(i32);
+
+v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) {
+    ret : V2(T);
+    ret.x = a.x + b.x;
+    ret.y = a.y + b.y;
+    return ret;
+}
+
+v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) {
+    ret : V2(T);
+    ret.x = a.x - b.x;
+    ret.y = a.y - b.y;
+    return ret;
+}
+
+v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) {
+    ret : V2(T);
+    ret.x = a.x * scalar;
+    ret.y = a.y * scalar;
+    return ret;
+}
diff --git a/tags b/tags
index c4c1d1fa03cd89c5f29bc8a540d7de1fd0c0e614..dc7befa9ee5595e92a13ff3a7b0c29ff9fedcb8f 100644 (file)
--- a/tags
+++ b/tags
@@ -42,6 +42,7 @@ BROWSER_DEFAULT_WEBGL /usr/share/onyx/core/js/webgl.onyx      /^BROWSER_DEFAULT_WEBGL
 BUFFER_SIZE    /usr/share/onyx/core/js/webgl.onyx      /^BUFFER_SIZE                    :: 0x8764$/
 BUFFER_USAGE   /usr/share/onyx/core/js/webgl.onyx      /^BUFFER_USAGE                   :: 0x8765$/
 BYTE   /usr/share/onyx/core/js/webgl.onyx      /^BYTE                           :: 0x1400$/
+BinaryReader   src/font.onyx   /^BinaryReader :: struct {$/
 Buffer /usr/share/onyx/core/builtin.onyx       /^Buffer :: #type []void;$/
 CCW    /usr/share/onyx/core/js/webgl.onyx      /^CCW                            :: 0x0901$/
 CLAMP_TO_EDGE  /usr/share/onyx/core/js/webgl.onyx      /^CLAMP_TO_EDGE                  :: 0x812F$/
@@ -308,7 +309,7 @@ NICEST      /usr/share/onyx/core/js/webgl.onyx      /^NICEST                         :: 0x
 NONE   /usr/share/onyx/core/js/webgl.onyx      /^NONE                           :: 0$/
 NOTEQUAL       /usr/share/onyx/core/js/webgl.onyx      /^NOTEQUAL                       :: 0x0205$/
 NO_ERROR       /usr/share/onyx/core/js/webgl.onyx      /^NO_ERROR                       :: 0$/
-NUM_QUADS      src/main.onyx   /^NUM_QUADS :: 1 << 7$/
+NUM_QUADS      src/main.onyx   /^NUM_QUADS :: 1 << 10$/
 OBJECT_TYPE    /usr/share/onyx/core/js/webgl.onyx      /^OBJECT_TYPE                                   :: 0x9112$/
 ONE    /usr/share/onyx/core/js/webgl.onyx      /^ONE                            :: 1$/
 ONE_MINUS_CONSTANT_ALPHA       /usr/share/onyx/core/js/webgl.onyx      /^ONE_MINUS_CONSTANT_ALPHA       :: 0x8004$/
@@ -413,6 +414,7 @@ RGBA8_SNORM /usr/share/onyx/core/js/webgl.onyx      /^RGBA8_SNORM
 RGBA_INTEGER   /usr/share/onyx/core/js/webgl.onyx      /^RGBA_INTEGER                                  :: 0x8D99$/
 RGB_INTEGER    /usr/share/onyx/core/js/webgl.onyx      /^RGB_INTEGER                                   :: 0x8D98$/
 RG_INTEGER     /usr/share/onyx/core/js/webgl.onyx      /^RG_INTEGER                                    :: 0x8228$/
+RenderContext  src/main.onyx   /^RenderContext :: struct {$/
 ResizeEvent    src/events.onyx /^ResizeEvent :: struct {$/
 SAMPLER_2D     /usr/share/onyx/core/js/webgl.onyx      /^SAMPLER_2D                     :: 0x8B5E$/
 SAMPLER_2D_ARRAY       /usr/share/onyx/core/js/webgl.onyx      /^SAMPLER_2D_ARRAY                              :: 0x8DC1$/
@@ -556,7 +558,12 @@ TRANSFORM_FEEDBACK_VARYINGS        /usr/share/onyx/core/js/webgl.onyx      /^TRANSFORM_FEEDB
 TRIANGLES      /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLES                      :: 0x0004$/
 TRIANGLE_FAN   /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLE_FAN                   :: 0x0006$/
 TRIANGLE_STRIP /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLE_STRIP                 :: 0x0005$/
+TTGlyph        src/font.onyx   /^TTGlyph :: struct {$/
+TTGlyphPoint   src/font.onyx   /^TTGlyphPoint :: struct {$/
+TTIndexToLocFormat     src/font.onyx   /^TTIndexToLocFormat :: enum (i16) {$/
+TTTableInfo    src/font.onyx   /^TTTableInfo :: struct {$/
 Texture        src/gfx/texture.onyx    /^Texture :: struct {$/
+TrueTypeFont   src/font.onyx   /^TrueTypeFont :: struct {$/
 UNIFORM_ARRAY_STRIDE   /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_ARRAY_STRIDE                          :: 0x8A3C$/
 UNIFORM_BLOCK_ACTIVE_UNIFORMS  /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_BLOCK_ACTIVE_UNIFORMS                 :: 0x8A42$/
 UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES   /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES          :: 0x8A43$/
@@ -603,6 +610,9 @@ UNSIGNED_SHORT      /usr/share/onyx/core/js/webgl.onyx      /^UNSIGNED_SHORT
 UNSIGNED_SHORT_4_4_4_4 /usr/share/onyx/core/js/webgl.onyx      /^UNSIGNED_SHORT_4_4_4_4         :: 0x8033$/
 UNSIGNED_SHORT_5_5_5_1 /usr/share/onyx/core/js/webgl.onyx      /^UNSIGNED_SHORT_5_5_5_1         :: 0x8034$/
 UNSIGNED_SHORT_5_6_5   /usr/share/onyx/core/js/webgl.onyx      /^UNSIGNED_SHORT_5_6_5           :: 0x8363$/
+V2     src/vecmath.onyx        /^V2 :: struct ($T) { x: T; y: T; }$/
+V2f    src/vecmath.onyx        /^V2f :: #type V2(f32);$/
+V2i    src/vecmath.onyx        /^V2i :: #type V2(i32);$/
 VALIDATE_STATUS        /usr/share/onyx/core/js/webgl.onyx      /^VALIDATE_STATUS                  :: 0x8B83$/
 VENDOR /usr/share/onyx/core/js/webgl.onyx      /^VENDOR                         :: 0x1F00$/
 VERSION        /usr/share/onyx/core/js/webgl.onyx      /^VERSION                        :: 0x1F02$/
@@ -646,6 +656,8 @@ array_remove        /usr/share/onyx/core/array.onyx /^array_remove :: proc (arr: ^[..]
 array_sort     /usr/share/onyx/core/array.onyx /^array_sort :: proc (arr: ^[..] $T, cmp: proc (T, T) -> i32) {$/
 array_to_slice /usr/share/onyx/core/array.onyx /^array_to_slice :: proc (arr: ^[..] $T) -> [] T {$/
 attachShader   /usr/share/onyx/core/js/webgl.onyx      /^attachShader                   :: proc (program: GLProgram, shader: GLShader) -> GLProgram #foreign "gl" "attachShader" ---$/
+bezier_curve   src/font.onyx   /^bezier_curve :: proc (t: f32, ps: [] V2f) -> V2f {$/
+binary_reader_create   src/font.onyx   /^binary_reader_create :: proc (data: [] u8, initial_pos := 0) -> BinaryReader {$/
 bindAttribLocation     /usr/share/onyx/core/js/webgl.onyx      /^bindAttribLocation             :: proc (program: GLProgram, index: GLuint, name: string) #foreign "gl" "bindAttribLocation" ---$/
 bindBuffer     /usr/share/onyx/core/js/webgl.onyx      /^bindBuffer                     :: proc (target: GLenum, buffer: GLBuffer) #foreign "gl" "bindBuffer" ---$/
 bindFramebuffer        /usr/share/onyx/core/js/webgl.onyx      /^bindFramebuffer                :: proc (target: GLenum, framebuffer: GLFramebuffer) #foreign "gl" "bindFramebuffer" ---$/
@@ -719,6 +731,7 @@ drawArrays  /usr/share/onyx/core/js/webgl.onyx      /^drawArrays                     :
 drawArraysInstanced    /usr/share/onyx/core/js/webgl.onyx      /^drawArraysInstanced            :: proc (mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei) #foreign "gl" "drawArraysInstanced" ---$/
 drawElements   /usr/share/onyx/core/js/webgl.onyx      /^drawElements                   :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint) #foreign "gl" "drawElements" ---$/
 drawElementsInstanced  /usr/share/onyx/core/js/webgl.onyx      /^drawElementsInstanced          :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint, instanceCount: GLsizei) #foreign "gl" "drawElementsInstanced" ---$/
+draw_rect      src/main.onyx   /^draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) {$/
 enable /usr/share/onyx/core/js/webgl.onyx      /^enable                         :: proc (cap: GLenum) #foreign "gl" "enable" ---$/
 enableVertexAttribArray        /usr/share/onyx/core/js/webgl.onyx      /^enableVertexAttribArray        :: proc (index: GLuint) #foreign "gl" "enableVertexAttribArray" ---$/
 finish /usr/share/onyx/core/js/webgl.onyx      /^finish                         :: proc () #foreign "gl" "finish" ---$/
@@ -775,12 +788,14 @@ link_program      src/utils/gl.onyx       /^link_program :: proc (vertex_shader: gl.GLShade
 main   src/main.onyx   /^main :: proc (args: [] cstring) {$/
 max_f32        /usr/share/onyx/core/intrinsics.onyx    /^max_f32      :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/
 max_f64        /usr/share/onyx/core/intrinsics.onyx    /^max_f64      :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/
+max_poly       /usr/share/onyx/core/math.onyx  /^max_poly :: proc (a: $T, b: T) -> T {$/
 memory_copy    /usr/share/onyx/core/memory.onyx        /^memory_copy :: proc (dst_: rawptr, src_: rawptr, len: u32) {$/
 memory_grow    /usr/share/onyx/core/intrinsics.onyx    /^memory_grow  :: proc (val: i32) -> i32 #intrinsic ---$/
 memory_init    /usr/share/onyx/core/alloc.onyx /^memory_init :: proc () {$/
 memory_size    /usr/share/onyx/core/intrinsics.onyx    /^memory_size  :: proc () -> i32 #intrinsic ---$/
 min_f32        /usr/share/onyx/core/intrinsics.onyx    /^min_f32      :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/
 min_f64        /usr/share/onyx/core/intrinsics.onyx    /^min_f64      :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/
+min_poly       /usr/share/onyx/core/math.onyx  /^min_poly :: proc (a: $T, b: T) -> T {$/
 nearest_f32    /usr/share/onyx/core/intrinsics.onyx    /^nearest_f32  :: proc (val: f32) -> f32 #intrinsic ---$/
 nearest_f64    /usr/share/onyx/core/intrinsics.onyx    /^nearest_f64  :: proc (val: f64) -> f64 #intrinsic ---$/
 new_frame_callback     src/main.onyx   /^new_frame_callback :: proc () #export {$/
@@ -819,7 +834,6 @@ ptrmap_has  /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_has :: proc (use pmap: ^Ptr
 ptrmap_init    /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_init :: proc (use pmap: ^PtrMap, hash_count: i32 = 16) {$/
 ptrmap_put     /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_put :: proc (use pmap: ^PtrMap, key: rawptr, value: rawptr) {$/
 quad_rebuffer_data     src/gfx/quad_renderer.onyx      /^quad_rebuffer_data :: proc (use qr: ^QuadRenderer) {$/
-quad_renderer  src/main.onyx   /^quad_renderer : QuadRenderer$/
 quad_renderer_draw     src/gfx/quad_renderer.onyx      /^quad_renderer_draw :: proc (use qr: ^QuadRenderer) {$/
 quad_renderer_init     src/gfx/quad_renderer.onyx      /^quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {$/
 quad_renderer_update_view      src/gfx/quad_renderer.onyx      /^quad_renderer_update_view :: proc (use qr: ^QuadRenderer) {$/
@@ -831,7 +845,10 @@ random_seed        /usr/share/onyx/core/random.onyx        /^random_seed :: proc (s: u32) do s
 range  /usr/share/onyx/core/builtin.onyx       /^range :: struct {$/
 readBuffer     /usr/share/onyx/core/js/webgl.onyx      /^readBuffer                     :: proc (src: GLenum) #foreign "gl" "readBuffer" ---$/
 readPixels     /usr/share/onyx/core/js/webgl.onyx      /^readPixels                     :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "readPixels" ---$/
+render_context_flush   src/main.onyx   /^render_context_flush :: proc (use rc: ^RenderContext) {$/
+render_context_init    src/main.onyx   /^render_context_init :: proc (use rc: ^RenderContext, qr: ^QuadRenderer = null) {$/
 renderbufferStorageMultisample /usr/share/onyx/core/js/webgl.onyx      /^renderbufferStorageMultisample :: proc (target: GLenum, samples: GLsizei, internalforamt: GLenum, width: GLsizei, height: GLsizei) #foreign "gl" "renderbufferStorageMultisample" ---$/
+renderer       src/main.onyx   /^renderer      : RenderContext$/
 resize /usr/share/onyx/core/builtin.onyx       /^resize :: proc (use a: Allocator, ptr: rawptr, size: u32) -> rawptr {$/
 rotl_i32       /usr/share/onyx/core/intrinsics.onyx    /^rotl_i32     :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/
 rotl_i64       /usr/share/onyx/core/intrinsics.onyx    /^rotl_i64     :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/
@@ -872,6 +889,7 @@ string_builder_make /usr/share/onyx/core/string.onyx        /^string_builder_make :: pr
 string_builder_to_string       /usr/share/onyx/core/string.onyx        /^string_builder_to_string :: proc (use sb: ^StringBuilder) -> string {$/
 string_concat  /usr/share/onyx/core/string.onyx        /^string_concat :: proc (s1: string, s2: string) -> string {$/
 string_contains        /usr/share/onyx/core/string.onyx        /^string_contains :: proc (str: string, c: u8) -> bool {$/
+string_equal   /usr/share/onyx/core/string.onyx        /^string_equal :: proc (str1: string, str2: string) -> bool {$/
 string_free    /usr/share/onyx/core/string.onyx        /^string_free :: proc (s: string) do cfree(s.data);$/
 string_length  /usr/share/onyx/core/string.onyx        /^string_length :: proc {$/
 string_make    /usr/share/onyx/core/string.onyx        /^string_make :: proc (s: cstring) -> string {$/
@@ -892,6 +910,13 @@ texture_prepare    src/gfx/texture.onyx    /^texture_prepare :: proc (use tex: ^Textur
 texture_use    src/gfx/texture.onyx    /^texture_use :: proc (use tex: ^Texture) {$/
 trunc_f32      /usr/share/onyx/core/intrinsics.onyx    /^trunc_f32    :: proc (val: f32) -> f32 #intrinsic ---$/
 trunc_f64      /usr/share/onyx/core/intrinsics.onyx    /^trunc_f64    :: proc (val: f64) -> f64 #intrinsic ---$/
+ttf    src/main.onyx   /^ttf           : TrueTypeFont$/
+ttf_create     src/font.onyx   /^ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont {$/
+ttf_glyph_count        src/font.onyx   /^ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 {$/
+ttf_lookup_glyph_offset        src/font.onyx   /^ttf_lookup_glyph_offset :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> u32 {$/
+ttf_read_glyph src/font.onyx   /^ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph {$/
+ttf_read_head_table    src/font.onyx   /^ttf_read_head_table :: proc (use ttf: ^TrueTypeFont) {$/
+ttf_read_offset_table  src/font.onyx   /^ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) {$/
 uniform1f      /usr/share/onyx/core/js/webgl.onyx      /^uniform1f                      :: proc (loc: GLUniformLocation, x: GLfloat) #foreign "gl" "uniform1f" ---$/
 uniform1i      /usr/share/onyx/core/js/webgl.onyx      /^uniform1i                      :: proc (loc: GLUniformLocation, x: GLint) #foreign "gl" "uniform1i" ---$/
 uniform2f      /usr/share/onyx/core/js/webgl.onyx      /^uniform2f                      :: proc (loc: GLUniformLocation, x: GLfloat, y: GLfloat) #foreign "gl" "uniform2f" ---$/
@@ -905,6 +930,9 @@ uniformMatrix3      /usr/share/onyx/core/js/webgl.onyx      /^uniformMatrix3
 uniformMatrix4 /usr/share/onyx/core/js/webgl.onyx      /^uniformMatrix4                 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat4) #foreign "gl" "uniformMatrix4" ---$/
 update src/main.onyx   /^update :: proc () {$/
 useProgram     /usr/share/onyx/core/js/webgl.onyx      /^useProgram                     :: proc (program: GLProgram) #foreign "gl" "useProgram" ---$/
+v2_add src/vecmath.onyx        /^v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/
+v2_mul src/vecmath.onyx        /^v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) {$/
+v2_sub src/vecmath.onyx        /^v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/
 validateProgram        /usr/share/onyx/core/js/webgl.onyx      /^validateProgram                :: proc (program: GLProgram) #foreign "gl" "validateProgram" ---$/
 vertexAttrib1f /usr/share/onyx/core/js/webgl.onyx      /^vertexAttrib1f                 :: proc (idx: GLuint, x: GLfloat) #foreign "gl" "vertexAttrib1f" ---$/
 vertexAttrib2f /usr/share/onyx/core/js/webgl.onyx      /^vertexAttrib2f                 :: proc (idx: GLuint, x: GLfloat, y: GLfloat) #foreign "gl" "vertexAttrib2f" ---$/