add opening files and rendering file text

This commit is contained in:
Matthew 2025-08-18 04:45:45 +10:00
parent 487b402b9f
commit 39aa8af6e2
3 changed files with 138 additions and 37 deletions

View File

@ -9,6 +9,7 @@ struct FlatBuffer
u8[] data; u8[] data;
u64 length; u64 length;
u64 line_count; u64 line_count;
Range pos;
} }
struct Range struct Range
@ -17,6 +18,13 @@ struct Range
u32 y; u32 y;
} }
struct LineBuffers
{
Arena arena;
u8[][] lines;
u32[] lengths;
}
FlatBuffer FlatBuffer
CreateFlatBuffer(u8[] data) CreateFlatBuffer(u8[] data)
{ {
@ -42,6 +50,14 @@ CreateFlatBuffer(u8[] data)
); );
} }
LineBuffers
CreateLineBuffers(u64 arena_size)
{
return LineBuffers(
arena: CreateArena(arena_size),
);
}
void void
Insert(FlatBuffer* buffer, u8[] insert, u64 length, u64 pos) Insert(FlatBuffer* buffer, u8[] insert, u64 length, u64 pos)
{ {
@ -81,11 +97,17 @@ Insert(FlatBuffer* buffer, u8[] insert, u64 length, Range pos)
Insert(buffer, insert, length, RangeToPos(buffer, pos)); Insert(buffer, insert, length, RangeToPos(buffer, pos));
} }
// TODO: handle case for when lines are longer than line buffer
void void
GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length) GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
{ {
assert(length <= lines.length, "GetLines failure: selection cannot fit within lines buffer");
assert(start_line < buffer.line_count, "GetLines failure: start is not less than line_count"); assert(start_line < buffer.line_count, "GetLines failure: start is not less than line_count");
assert(linebufs != null, "GetLines failure: linebufs is null");
Reset(&linebufs.arena);
linebufs.lines = AllocArray!(u8[])(&linebufs.arena, length);
linebufs.lengths = AllocArray!(u32)(&linebufs.arena, length);
i64 start = -1; i64 start = -1;
u64 line = 0; u64 line = 0;
u64 current_line = 0; u64 current_line = 0;
@ -105,7 +127,9 @@ GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length)
if (start < 0 && new_line) if (start < 0 && new_line)
{ {
lines[current_line] = buffer.data[i .. i+1]; linebufs.lines[current_line] = AllocArray!(u8)(&linebufs.arena, 1);
linebufs.lines[current_line][0] = '\n';
linebufs.lengths[current_line] = 1;
current_line += 1; current_line += 1;
continue; continue;
} }
@ -118,7 +142,9 @@ GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length)
if (new_line) if (new_line)
{ {
lines[current_line] = buffer.data[start .. i]; linebufs.lines[current_line] = AllocArray!(u8)(&linebufs.arena, i-start);
linebufs.lines[current_line][0 .. $] = buffer.data[start .. i];
linebufs.lengths[current_line] = cast(u32)(i-start);
current_line += 1; current_line += 1;
start = -1; start = -1;
continue; continue;
@ -126,7 +152,9 @@ GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length)
if (i == buffer.length-1) if (i == buffer.length-1)
{ {
lines[current_line] = buffer.data[start .. buffer.length]; linebufs.lines[current_line] = AllocArray!(u8)(&linebufs.arena, buffer.length-start);
linebufs.lines[current_line][0 .. $] = buffer.data[start .. buffer.length];
linebufs.lengths[current_line] = cast(u32)(buffer.length-start);
} }
} }
} }

View File

@ -5,6 +5,7 @@ import fonts;
import vulkan; import vulkan;
import math; import math;
import alloc; import alloc;
import buffer;
import std.stdio; import std.stdio;
import std.exception; import std.exception;
@ -30,8 +31,11 @@ struct Editor
u32[] indices; u32[] indices;
u32 ui_count; u32 ui_count;
Buffer[] buffers; FlatBuffer[] buffers;
u8[][] buffer_names; u8[][] buffer_names;
u32 buffer_count;
FlatBuffer* active_buffer;
LineBuffers linebufs;
u8[] font_data; u8[] font_data;
FontFace font; FontFace font;
@ -59,7 +63,13 @@ Cycle(Editor* ed)
Reset(&ed.temp_arena); Reset(&ed.temp_arena);
DrawText(ed, 200.0, 200.0, 16.0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); f32 pos = 0.0;
f32 h = ed.atlas_buf.atlas.size;
foreach(i, line; ed.linebufs.lines)
{
DrawText(ed, 0.0, pos, h, line[0 .. ed.linebufs.lengths[i]]);
pos += h;
}
BeginFrame(&ed.rd); BeginFrame(&ed.rd);
@ -103,7 +113,7 @@ LoadFile(Arena* arena, string name)
} }
Editor Editor
CreateEditor(PlatformWindow* window) CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
{ {
InitFreeType(); InitFreeType();
@ -124,7 +134,7 @@ CreateEditor(PlatformWindow* window)
u8[] font_data = LoadFile(&arena, "assets/pc-9800.ttf"); u8[] font_data = LoadFile(&arena, "assets/pc-9800.ttf");
FontFace font = OpenFont(font_data); FontFace font = OpenFont(font_data);
FontAtlasBuf atlas_buf = CreateAtlas(&arena, font, 16.0, 256); FontAtlasBuf atlas_buf = CreateAtlas(&arena, font, 14.0, 256);
Editor editor = { Editor editor = {
window: window, window: window,
@ -134,8 +144,25 @@ CreateEditor(PlatformWindow* window)
font_data: font_data, font_data: font_data,
font: font, font: font,
atlas_buf: atlas_buf, atlas_buf: atlas_buf,
buffers: MAllocArray!(FlatBuffer)(32),
buffer_names: MAllocArray!(u8[])(32),
linebufs: CreateLineBuffers(MB(32)),
}; };
if (buffer_data != null)
{
assert(buffer_name != null, "CreateEditor failure: buffer_name is null while buffer_data is not");
editor.buffers[0] = CreateFlatBuffer(buffer_data);
editor.buffer_names[0] = AllocArray!(u8)(&editor.arena, buffer_name.length);
editor.buffer_names[0][0 .. $] = buffer_name[0 .. $];
editor.buffer_count += 1;
editor.active_buffer = &editor.buffers[0];
GetLines(editor.active_buffer, &editor.linebufs, 0, editor.active_buffer.line_count);
}
DescLayoutBinding[2] layout_bindings = [ DescLayoutBinding[2] layout_bindings = [
{ binding: 0, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, { binding: 0, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All },
{ binding: 1, descriptorType: DT.Storage, descriptorCount: 1, stageFlags: SS.All }, { binding: 1, descriptorType: DT.Storage, descriptorCount: 1, stageFlags: SS.All },
@ -188,6 +215,7 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, string str)
void void
DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str) DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
{ {
u32 tab_count = 2;
f32 x_pos = x; f32 x_pos = x;
f32 scale = px / ed.atlas_buf.atlas.size; f32 scale = px / ed.atlas_buf.atlas.size;
foreach(ch; str) foreach(ch; str)
@ -195,6 +223,37 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
foreach(glyph; ed.atlas_buf.atlas.glyphs) foreach(glyph; ed.atlas_buf.atlas.glyphs)
{ {
if (ch == glyph.ch) if (ch == glyph.ch)
{
if (ch == '\t')
{
Glyph g = glyph;
g.atlas_left = g.atlas_right = 0.0;
foreach(i; 0 .. tab_count)
{
DrawGlyph(ed, &g, scale, &x_pos, y);
}
}
else if (ch == '\n')
{
Glyph g = glyph;
g.atlas_left = g.atlas_right = 0.0;
DrawGlyph(ed, &g, scale, &x_pos, y);
}
else
{
DrawGlyph(ed, &glyph, scale, &x_pos, y);
}
break;
}
}
}
}
pragma(inline): void
DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y)
{
if (glyph.atlas_left != glyph.atlas_right)
{ {
Vertex* v = ed.vertices.ptr + ed.ui_count; Vertex* v = ed.vertices.ptr + ed.ui_count;
@ -204,9 +263,9 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale; f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
f32 y_pos = glyph.plane_top * scale; f32 y_pos = glyph.plane_top * scale;
v.dst_start.x = x_pos + l; v.dst_start.x = *x_pos + l;
v.dst_start.y = y + h - y_pos; v.dst_start.y = y + h - y_pos;
v.dst_end.x = x_pos + w + l; v.dst_end.x = *x_pos + w + l;
v.dst_end.y = y - y_pos; v.dst_end.y = y - y_pos;
v.src_start.x = glyph.atlas_left; v.src_start.x = glyph.atlas_left;
@ -215,15 +274,15 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
v.src_end.y = glyph.atlas_bottom; v.src_end.y = glyph.atlas_bottom;
v.col = Vec4(1.0, 1.0, 1.0, 1.0); v.col = Vec4(1.0, 1.0, 1.0, 1.0);
if (glyph.atlas_left == glyph.atlas_right)
x_pos += glyph.advance * scale; {
v.col.r = v.col.g = v.col.b = 0.0;
}
AddUIIndices(ed); AddUIIndices(ed);
}
break; *x_pos += glyph.advance * scale;
}
}
}
} }
void void

View File

@ -1,11 +1,25 @@
import aliases;
import platform; import platform;
import editor; import editor;
import std.stdio;
import alloc;
void main(string[] argv) void main(string[] argv)
{ {
u8[] buffer = null;
u8[] buffer_name = null;
if (argv.length > 1)
{
buffer_name = (cast(u8*)argv[1].ptr)[0 .. argv[1].length];
File f = File(argv[1], "rb");
buffer = MAllocArray!(u8)(f.size());
f.rawRead(buffer);
f.close();
}
PlatformWindow window = CreateWindow("Editor", 1920, 1080); PlatformWindow window = CreateWindow("Editor", 1920, 1080);
Editor editor = CreateEditor(&window); Editor editor = CreateEditor(&window, buffer, buffer_name);
while (true) while (true)
{ {