Manual rendering and small fixes

This commit is contained in:
Krzosa Karol
2024-07-21 10:46:07 +02:00
parent 6ac1c8711c
commit 816c24c1b6
6 changed files with 52 additions and 18 deletions

View File

@@ -46,10 +46,12 @@ Int LastLine(Buffer &buffer) {
} }
const Int LAST_LINE = INT64_MAX; const Int LAST_LINE = INT64_MAX;
Range GetLineRange(Buffer &buffer, Int line) { Range GetLineRange(Buffer &buffer, Int line, Int *end_of_buffer = NULL) {
Range result = {buffer.line_starts[line], buffer.len}; Range result = {buffer.line_starts[line], buffer.len};
if (line + 1 < buffer.line_starts.len) { if (line + 1 < buffer.line_starts.len) {
result.max = buffer.line_starts[line + 1]; result.max = buffer.line_starts[line + 1];
} else if (end_of_buffer) {
*end_of_buffer = 1;
} }
return result; return result;
} }
@@ -97,9 +99,10 @@ Int XYToPos(Buffer &buffer, XY xy) {
} }
Int XYToPosWithoutNL(Buffer &buffer, XY xy) { Int XYToPosWithoutNL(Buffer &buffer, XY xy) {
xy.line = Clamp(xy.line, (Int)0, buffer.line_starts.len - 1); xy.line = Clamp(xy.line, (Int)0, buffer.line_starts.len - 1);
Range line_range = GetLineRange(buffer, xy.line); Int end_of_buffer = 0;
Int pos = Clamp(xy.col + line_range.min, line_range.min, line_range.max - 1); Range line_range = GetLineRange(buffer, xy.line, &end_of_buffer);
Int pos = Clamp(xy.col + line_range.min, line_range.min, line_range.max - 1 + end_of_buffer);
return pos; return pos;
} }

View File

@@ -18,3 +18,9 @@ void LoadTextA(Buffer *buffer) {
ReplaceText(buffer, GetEndAsRange(*buffer), s16); ReplaceText(buffer, GetEndAsRange(*buffer), s16);
} }
} }
void LoadLine(Buffer *buffer) {
Scratch scratch;
String s = "Line number and so on óźćż";
ReplaceText(buffer, {}, ToString16(scratch, s));
}

View File

@@ -35,7 +35,9 @@ void DrawString(Font font, String16 text, Vector2 position, float fontSize, floa
int codepoint = text[i]; int codepoint = text[i];
int index = GetGlyphIndex(font, codepoint); int index = GetGlyphIndex(font, codepoint);
if ((codepoint != '\n') && (codepoint != ' ') && (codepoint != '\t')) { if (codepoint == '\n') {
// DrawCircle((int)position.x + (int)textOffsetX, (int)position.y, fontSize / 10, tint);
} else if ((codepoint != ' ') && (codepoint != '\t')) {
DrawTextCodepoint(font, codepoint, {position.x + textOffsetX, position.y}, fontSize, tint); DrawTextCodepoint(font, codepoint, {position.x + textOffsetX, position.y}, fontSize, tint);
} }

View File

@@ -68,7 +68,7 @@ int main(void) {
Int font_size = 32; Int font_size = 32;
Int font_spacing = 1; Int font_spacing = 1;
Int line_spacing = font_size; Int line_spacing = font_size;
Font font = LoadFontEx("c:\\Windows\\Fonts\\consola.ttf", (int)font_size, NULL, 250); Font font = LoadFontEx("c:\\Windows\\Fonts\\consola.ttf", (int)font_size, NULL, 500);
view.font = font; view.font = font;
view.font_size = font_size; view.font_size = font_size;
@@ -78,7 +78,8 @@ int main(void) {
Add(&view.carets, {0, 0}); Add(&view.carets, {0, 0});
view.buffer = CreateBuffer(Perm); view.buffer = CreateBuffer(Perm);
// LoadBigLine(view.buffer); // LoadBigLine(view.buffer);
LoadTextA(view.buffer); // LoadTextA(view.buffer);
LoadLine(view.buffer);
} }
while (!WindowShouldClose()) { while (!WindowShouldClose()) {

View File

@@ -216,20 +216,32 @@ void HandleKeybindings(View *_view) {
{ {
int keys[2] = {KEY_HOME, KEY_END}; int keys[2] = {KEY_HOME, KEY_END};
for (int i = 0; i < 2; i += 1) { for (Int i = 0; i < 2; i += 1) {
if (IsKeyPressed(keys[i]) || IsKeyPressedRepeat(keys[i])) { if (IsKeyPressed(keys[i]) || IsKeyPressedRepeat(keys[i])) {
For(view.carets) { For(view.carets) {
Range line_range = GetLineRange(buf, PosToLine(buf, GetFront(it))); Int end_of_buffer = 0;
Range line_range = GetLineRange(buf, PosToLine(buf, GetFront(it)), &end_of_buffer);
Int diff = keys[i] == KEY_END ? i - end_of_buffer : 0;
if (IsKeyDown(KEY_LEFT_SHIFT)) { if (IsKeyDown(KEY_LEFT_SHIFT)) {
it = ChangeFront(it, line_range.e[i] - i); it = ChangeFront(it, line_range.e[i] - diff);
} else { } else {
it.range.max = it.range.min = line_range.e[i] - i; it.range.max = it.range.min = line_range.e[i] - diff;
} }
} }
} }
} }
} }
if (IsKeyPressed(KEY_ENTER) || IsKeyPressedRepeat(KEY_ENTER)) {
MergeCarets(&view.carets);
Scratch scratch;
Array<Edit> edits = {scratch};
For(view.carets) AddEdit(&edits, it.range, L"\n");
ApplyEdits(view.buffer, edits);
AfterEdit(&view, edits);
}
for (int c = GetCharPressed(); c; c = GetCharPressed()) { for (int c = GetCharPressed(); c; c = GetCharPressed()) {
String16 string = L"?"; String16 string = L"?";
UTF16Result result = UTF32ToUTF16((uint32_t)c); UTF16Result result = UTF32ToUTF16((uint32_t)c);
@@ -275,10 +287,6 @@ void HandleKeybindings(View *_view) {
} }
// Scrolling with caret // Scrolling with caret
// @refactor: this should happen after we calculate rect for the view
// Usually in other text editors apart from view there is also a 'window'
// which is exactly the thing which shows the view, will need
// to think about this later
if (!AreEqual(main_caret_on_begin_frame, view.carets[0])) { if (!AreEqual(main_caret_on_begin_frame, view.carets[0])) {
Caret c = view.carets[0]; Caret c = view.carets[0];
Int front = GetFront(c); Int front = GetFront(c);
@@ -320,7 +328,5 @@ void HandleKeybindings(View *_view) {
// GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for // GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for
// calculating this value incrementally but do we even need X scrollbar or x clipping? // calculating this value incrementally but do we even need X scrollbar or x clipping?
view.scroll.x = ClampBottom(view.scroll.x, (Int)0); view.scroll.x = ClampBottom(view.scroll.x, (Int)0);
// Int line_chars = GetCharCountOfLongestLine(view.buffer[0]);
// view.scroll.x = Clamp(view.scroll.x, 0.f, Max(0.f, (line_chars - 2) * view.char_spacing));
} }
} }

View File

@@ -21,6 +21,7 @@ Rect2I GetVisibleCells(const View &view) {
void DrawVisibleCells(const View &view) { void DrawVisibleCells(const View &view) {
ProfileFunction(); ProfileFunction();
Color tint = BLACK;
Rect2I visible = GetVisibleCells(view); Rect2I visible = GetVisibleCells(view);
for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < view.buffer->line_starts.len; line_index += 1) { for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < view.buffer->line_starts.len; line_index += 1) {
Range line_range = GetLineRange(*view.buffer, line_index); Range line_range = GetLineRange(*view.buffer, line_index);
@@ -30,7 +31,22 @@ void DrawVisibleCells(const View &view) {
Vec2I pos = {visible.min.x * (Int)view.char_spacing, line_index * (Int)view.line_spacing}; Vec2I pos = {visible.min.x * (Int)view.char_spacing, line_index * (Int)view.line_spacing};
pos -= view.scroll; pos -= view.scroll;
DrawString(view.font, line_string, ToVec2(pos), (float)view.font_size, (float)view.font_spacing, BLACK);
float text_offset_x = 0;
float scale_factor = (float)view.font_size / view.font.baseSize; // Character quad scaling factor
for (Int col_index = visible.min.x; col_index < visible.max.x && col_index >= 0 && col_index < line_string.len; col_index += 1) {
int codepoint = line_string[col_index];
int index = GetGlyphIndex(view.font, codepoint);
if (codepoint == '\n') {
DrawCircle((int)pos.x + (int)text_offset_x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, tint);
} else if ((codepoint != ' ') && (codepoint != '\t')) {
DrawTextCodepoint(view.font, codepoint, {(float)pos.x + text_offset_x, (float)pos.y}, (float)view.font_size, tint);
}
if (view.font.glyphs[index].advanceX == 0) text_offset_x += ((float)view.font.recs[index].width * scale_factor + view.font_spacing);
else text_offset_x += ((float)view.font.glyphs[index].advanceX * scale_factor + view.font_spacing);
}
} }
} }