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

@ -6,9 +6,10 @@ import util;
struct FlatBuffer
{
Arena arena;
u8[] data;
u64 length;
u64 line_count;
u8[] data;
u64 length;
u64 line_count;
Range pos;
}
struct Range
@ -17,6 +18,13 @@ struct Range
u32 y;
}
struct LineBuffers
{
Arena arena;
u8[][] lines;
u32[] lengths;
}
FlatBuffer
CreateFlatBuffer(u8[] data)
{
@ -42,6 +50,14 @@ CreateFlatBuffer(u8[] data)
);
}
LineBuffers
CreateLineBuffers(u64 arena_size)
{
return LineBuffers(
arena: CreateArena(arena_size),
);
}
void
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));
}
// TODO: handle case for when lines are longer than line buffer
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(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;
u64 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)
{
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;
continue;
}
@ -118,7 +142,9 @@ GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length)
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;
start = -1;
continue;
@ -126,7 +152,9 @@ GetLines(FlatBuffer* buffer, u8[][] lines, u64 start_line, u64 length)
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 math;
import alloc;
import buffer;
import std.stdio;
import std.exception;
@ -18,7 +19,7 @@ struct Editor
PlatformWindow* window;
Renderer rd;
ImageView font_atlas;
ImageView font_atlas;
Pipeline pipeline;
DescSetLayout desc_set_layout;
DescSet desc_set;
@ -30,8 +31,11 @@ struct Editor
u32[] indices;
u32 ui_count;
Buffer[] buffers;
FlatBuffer[] buffers;
u8[][] buffer_names;
u32 buffer_count;
FlatBuffer* active_buffer;
LineBuffers linebufs;
u8[] font_data;
FontFace font;
@ -59,7 +63,13 @@ Cycle(Editor* ed)
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);
@ -103,7 +113,7 @@ LoadFile(Arena* arena, string name)
}
Editor
CreateEditor(PlatformWindow* window)
CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
{
InitFreeType();
@ -124,7 +134,7 @@ CreateEditor(PlatformWindow* window)
u8[] font_data = LoadFile(&arena, "assets/pc-9800.ttf");
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 = {
window: window,
@ -134,8 +144,25 @@ CreateEditor(PlatformWindow* window)
font_data: font_data,
font: font,
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 = [
{ binding: 0, descriptorType: DT.Image, 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
DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
{
u32 tab_count = 2;
f32 x_pos = x;
f32 scale = px / ed.atlas_buf.atlas.size;
foreach(ch; str)
@ -196,29 +224,25 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
{
if (ch == glyph.ch)
{
Vertex* v = ed.vertices.ptr + ed.ui_count;
f32 r = glyph.plane_right * scale;
f32 l = glyph.plane_left * scale;
f32 w = r - l;
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
f32 y_pos = glyph.plane_top * scale;
v.dst_start.x = x_pos + l;
v.dst_start.y = y + h - y_pos;
v.dst_end.x = x_pos + w + l;
v.dst_end.y = y - y_pos;
v.src_start.x = glyph.atlas_left;
v.src_start.y = glyph.atlas_top;
v.src_end.x = glyph.atlas_right;
v.src_end.y = glyph.atlas_bottom;
v.col = Vec4(1.0, 1.0, 1.0, 1.0);
x_pos += glyph.advance * scale;
AddUIIndices(ed);
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;
}
@ -226,6 +250,41 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
}
}
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;
f32 r = glyph.plane_right * scale;
f32 l = glyph.plane_left * scale;
f32 w = r - l;
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
f32 y_pos = glyph.plane_top * scale;
v.dst_start.x = *x_pos + l;
v.dst_start.y = y + h - y_pos;
v.dst_end.x = *x_pos + w + l;
v.dst_end.y = y - y_pos;
v.src_start.x = glyph.atlas_left;
v.src_start.y = glyph.atlas_top;
v.src_end.x = glyph.atlas_right;
v.src_end.y = glyph.atlas_bottom;
v.col = Vec4(1.0, 1.0, 1.0, 1.0);
if (glyph.atlas_left == glyph.atlas_right)
{
v.col.r = v.col.g = v.col.b = 0.0;
}
AddUIIndices(ed);
}
*x_pos += glyph.advance * scale;
}
void
AddUIIndices(Editor* ed)
{

View File

@ -1,11 +1,25 @@
import aliases;
import platform;
import editor;
import std.stdio;
import alloc;
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);
Editor editor = CreateEditor(&window);
Editor editor = CreateEditor(&window, buffer, buffer_name);
while (true)
{