let wasm_instance;
let canvasElem;
let canvasCtx;
+let __loaded_images = [];
const MAGIC_CANVAS_NUMBER = 0x5052455A;
if (max_width > 0) canvasCtx.fillText(str, x, y, max_width);
else canvasCtx.fillText(str, x, y);
+ },
+
+ drawImage(canvas, image_idx, x, y, w, h) {
+ let image = __loaded_images[image_idx];
+
+ canvasCtx.drawImage(image, x, y, w, h);
+ }
+}
+
+let html_import_obj = {
+ load_image(path_str, path_len, out_image) {
+ const data = new Uint8Array(wasm_instance.exports.memory.buffer, path_str, path_len);
+ const path = new TextDecoder().decode(data);
+
+ let image = new Image();
+ __loaded_images.push(image);
+
+ let data_view = new DataView(wasm_instance.exports.memory.buffer, out_image, 3 * 4);
+ data_view.setInt32(0, __loaded_images.length - 1, true);
+
+ image.src = path;
+ },
+
+ store_image_size(out_image) {
+ let data_view = new DataView(wasm_instance.exports.memory.buffer, out_image, 3 * 4);
+ let image_idx = data_view.getInt32(0, true);
+
+ let image = __loaded_images[image_idx];
+ data_view.setInt32(4, image.width, true);
+ data_view.setInt32(8, image.height, true);
}
}
canvas: canvas_import_obj,
event: event_import_obj,
+ html: html_import_obj,
}
function main() {
r: f32, g: f32, b: f32, a := 1.0f) -> void #foreign "canvas" "fillRect" ---
fill_text :: (handle: Handle, text: str, x: f32, y: f32, max_width: f32 = -1.0f) -> void #foreign "canvas" "fillText" ---
+
+ draw_image :: (handle: Handle, image: i32, x: f32, y: f32, width: f32, height: f32) -> void #foreign "canvas" "drawImage" ---
}
// :GlobalVariable
}
}
+ case #default do redraw = 0;
+
} else {
redraw = 0;
}
{ // Slide 2
slide := slideshow_insert_slide(^the_slideshow);
- slide_init(slide, background_color = Color.{ 0.2, 0.1, 0.1 }, item_count = 3);
+ slide_init(slide, background_color = Color.{ 0.2, 0.1, 0.1 }, item_count = 4);
slide.items[0] = slideshow_make_item(^the_slideshow);
slide.items[0].kind = Slide_Item.Kind.Text;
- slide.items[0].text.text = "The Second Slide! Duh duh duhhhh";
+ slide.items[0].text.text = "The Second Slide!";
slide.items[0].text.y_pos = .2;
slide.items[0].text.font_name = "Arail";
slide.items[0].text.font_size = 72;
slide.items[1] = slideshow_make_item(^the_slideshow);
slide.items[1].kind = Slide_Item.Kind.Text;
slide.items[1].text.text = "Here is some monospace text.";
- slide.items[1].text.y_pos = .4;
+ slide.items[1].text.y_pos = .3;
slide.items[1].text.font_name = "monospace";
slide.items[1].text.font_size = 36;
slide.items[1].text.padding = .07;
slide.items[2] = slideshow_make_item(^the_slideshow);
slide.items[2].text = Slide_Item_Text.{
text = "Here is a block of much longer text that will not wrap correctly, which is annoying but I think the best thing to do is... I don't know yet.",
- y_pos = .45,
+ y_pos = .35,
font_name = "Calibri",
font_size = 36,
padding = .07,
justify = Slide_Item_Text.Justify.Left,
};
+
+ slideshow_load_image(^the_slideshow, "first_image", "images/first.jpg");
+
+ slide.items[3] = slideshow_make_item(^the_slideshow);
+ slide.items[3].image = Slide_Item_Image.{
+ name = "first_image",
+ x = .3,
+ y = .4,
+ width = .4,
+ };
}
}
use package core
+HTML_Image :: struct {
+ handle: i32 = -1;
+ width: i32 = 1; // To avoid dividing by 0
+ height: i32 = 1;
+}
+
Color :: struct {
r, g, b: f32;
a: f32 = 1;
slides : [..] Slide;
current_slide : i32;
+
+ image_map : map.Map(str, HTML_Image);
}
Slide :: struct {
Kind :: enum {
Undefined;
Text;
+ Image;
}
use base: Slide_Item_Base;
- text: Slide_Item_Text;
+ text : Slide_Item_Text;
+ image : Slide_Item_Image;
}
Slide_Item_Base :: struct {
}
Slide_Item_Image :: struct {
- use base := Slide_Item_Base.{ Slide_Item.Kind.Text };
+ use base := Slide_Item_Base.{ Slide_Item.Kind.Image };
- path : str;
+ name : str;
x, y : f32; // Between 0 and 1
width : f32; // Between 0 and 1
arena = alloc.arena.make(allocator, arena_size = 16 * 1024);
array.init(^slides, 4);
+
+ map.init(^image_map, default = HTML_Image.{});
}
slideshow_reset :: (use s: ^Slideshow) {
alloc.arena.free(^arena);
array.free(^slides);
+ map.free(^image_map);
+
slideshow_init(s);
}
return new(Slide_Item, allocator = allocator);
}
+slideshow_load_image :: (use s: ^Slideshow, image_name: str, image_path: str) -> HTML_Image {
+ if map.has(^image_map, image_name) {
+ printf("Warning: the image '%s' was already defined.", image_name);
+ return image_map.default_value;
+ }
+
+ html_image_load :: (path: str, out_image: ^HTML_Image) -> void #foreign "html" "load_image" ---
+ image: HTML_Image;
+ html_image_load(image_path, ^image);
+
+ map.put(^image_map, image_name, image);
+ return image;
+}
+
slide_init :: (use slide: ^Slide, background_color := Color.{0, 0, 0, 1}, item_count := 4) {
background = background_color;
}
case Image {
- assert(false, "Slide_Item_Image not implemented!");
+ use Canvas
+
+ if html_image := map.get(^the_slideshow.image_map, image.name); html_image.handle != -1 {
+ width, height := cast(f32) get_width(canvas), cast(f32) get_height(canvas);
+
+ // @Speed: There is a much better way of doing this...
+ store_image_size :: (html_image: ^HTML_Image) -> void #foreign "html" "store_image_size" ---
+ store_image_size(^html_image);
+
+ x := image.x * width;
+ y := image.y * height;
+ w := image.width * width;
+ h := w * (cast(f32) html_image.height / cast(f32) html_image.width);
+
+ draw_image(canvas, html_image.handle, x, y, w, h);
+ }
}
}