add opening files and rendering file text
This commit is contained in:
parent
487b402b9f
commit
39aa8af6e2
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user