Move to integer based rendering, fix Big line

This commit is contained in:
Krzosa Karol
2024-07-21 09:59:50 +02:00
parent 4c1630d61d
commit c9cd2e6c1e
6 changed files with 92 additions and 84 deletions

View File

@@ -4,6 +4,12 @@ void LoadBigText(Buffer *buffer) {
}
}
void LoadBigLine(Buffer *buffer) {
for (int i = 0; i < 5000000; i += 1) {
ReplaceText(buffer, GetEndAsRange(*buffer), L"Line number and another meme or something of the sort which is here or there frankly somewhere");
}
}
void LoadTextA(Buffer *buffer) {
Scratch scratch;
for (int i = 0; i < 1000; i += 1) {

View File

@@ -3,37 +3,23 @@ struct Vec2 {
float y;
};
struct Vec2I {
Int x;
Int y;
};
struct Rect2 {
Vec2 min;
Vec2 max;
};
struct Rect2I {
Vec2I min;
Vec2I max;
};
Vec2 GetSize(Rect2 r) {
Vec2 result = {r.max.x - r.min.x, r.max.y - r.min.y};
return result;
}
Vec2I GetSize(Rect2I r) {
Vec2I result = {(r.max.x - r.min.x), (r.max.y - r.min.y)};
return result;
}
Vec2 GetSizeF(Rect2I r) {
Vec2 result = {(float)(r.max.x - r.min.x), (float)(r.max.y - r.min.y)};
return result;
}
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; }
Vec2I ToVec2I(Vec2 v) { return {(Int)v.x, (Int)v.y}; }
// clang-format off
Rect2 operator-(Rect2 r, Rect2 value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }
@@ -155,4 +141,4 @@ float SafeDivide(float a, float b) {
return 0.f;
}
return a / b;
}
}

View File

@@ -3,18 +3,23 @@ Rectangle ToRectangle(Rect2 r) {
return result;
}
Rect2 GetScreenRect() {
Rect2 result = {0, 0, (float)GetRenderWidth(), (float)GetRenderHeight()};
Rectangle ToRectangle(Rect2I r) {
Rectangle result = {(float)r.min.x, (float)r.min.y, (float)(r.max.x - r.min.x), (float)(r.max.y - r.min.y)};
return result;
}
float GetCharSpacing(Font font, float font_size, float spacing) {
Rect2I GetScreenRect() {
Rect2I result = {0, 0, GetRenderWidth(), GetRenderHeight()};
return result;
}
Int GetCharSpacing(Font font, Int font_size, Int spacing) {
int index = GetGlyphIndex(font, '_');
float textOffsetX = 0;
float scaleFactor = font_size / font.baseSize; // Character quad scaling factor
if (font.glyphs[index].advanceX == 0) textOffsetX += ((float)font.recs[index].width * scaleFactor + spacing);
else textOffsetX += ((float)font.glyphs[index].advanceX * scaleFactor + spacing);
Int textOffsetX = 0;
Int scaleFactor = font_size / font.baseSize; // Character quad scaling factor
if (font.glyphs[index].advanceX == 0) textOffsetX += ((Int)font.recs[index].width * scaleFactor + spacing);
else textOffsetX += ((Int)font.glyphs[index].advanceX * scaleFactor + spacing);
return textOffsetX;
}
@@ -25,7 +30,7 @@ void DrawString(Font font, String16 text, Vector2 position, float fontSize, floa
float scaleFactor = fontSize / font.baseSize; // Character quad scaling factor
for (int i = 0; i < text.len; i += 1) {
for (Int i = 0; i < text.len; i += 1) {
// Get next codepoint from byte string and glyph index in font
int codepoint = text[i];
int index = GetGlyphIndex(font, codepoint);

View File

@@ -3,6 +3,7 @@
#include "new_basic.cpp"
#include "string16.cpp"
#include <math.h>
#include "math_int.cpp"
#include "math.cpp"
#include "../profiler/profiler.cpp"
@@ -20,6 +21,8 @@
#include "view_draw.cpp"
/*
- when no new line at the end - END button sets cursor before last char
- Ctrl + Z, Ctrl + C - Undo redo history
- Ctrl + D - create new cursor at next occurence of word
- Ctrl + X, Ctrl + C, Ctrl + V - Copy paste
@@ -33,6 +36,8 @@
- Line numbers
- Colored strings
- file dock on left side
- file info bar at bottom
- multiple windows
- multiple views per window
*/
@@ -60,10 +65,10 @@ int main(void) {
View view = {};
{
float font_size = 32;
float font_spacing = 1;
float line_spacing = font_size;
Font font = LoadFontEx("c:\\Windows\\Fonts\\consola.ttf", (int)font_size, NULL, 250);
Int font_size = 32;
Int font_spacing = 1;
Int line_spacing = font_size;
Font font = LoadFontEx("c:\\Windows\\Fonts\\consola.ttf", (int)font_size, NULL, 250);
view.font = font;
view.font_size = font_size;
@@ -72,6 +77,7 @@ int main(void) {
view.char_spacing = GetCharSpacing(font, font_size, font_spacing);
Add(&view.carets, {0, 0});
view.buffer = CreateBuffer(Perm);
// LoadBigLine(view.buffer);
LoadTextA(view.buffer);
}

View File

@@ -1,16 +1,16 @@
struct View {
Font font;
float font_size;
float font_spacing;
float line_spacing;
float char_spacing;
Font font;
Int font_size;
Int font_spacing;
Int line_spacing;
Int char_spacing;
bool mouse_selecting;
Vec2 scroll;
Vec2I scroll;
Buffer *buffer;
Array<Caret> carets;
Rect2 rect;
Rect2I rect;
};
Rect2I GetVisibleCells(const View &view);
@@ -161,13 +161,17 @@ void HandleKeybindings(View *_view) {
Caret main_caret_on_begin_frame = view.carets[0];
if (IsKeyDown(KEY_F1)) {
view.scroll.x -= GetMouseWheelMove() * 48;
view.scroll.x -= (Int)(GetMouseWheelMove() * 48);
} else {
view.scroll.y -= GetMouseWheelMove() * 48;
view.scroll.y -= (Int)(GetMouseWheelMove() * 48);
}
if (IsKeyDown(KEY_F2)) {
LoadBigText(view.buffer);
if (IsKeyDown(KEY_LEFT_CONTROL)) {
LoadBigLine(view.buffer);
} else {
LoadBigText(view.buffer);
}
}
{
@@ -242,13 +246,14 @@ void HandleKeybindings(View *_view) {
{
ProfileScope(mouse);
Vec2 mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(mouse, ToRectangle(view.rect));
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(view.rect));
Vec2I mouse = ToVec2I(_mouse);
Vec2 mworld = mouse - view.rect.min + view.scroll;
Vec2 pos = mworld / Vec2{view.char_spacing, view.line_spacing};
XY xy = {(Int)(pos.x), (Int)(pos.y)};
Int p = XYToPosWithoutNL(buf, xy);
Vec2I mworld = mouse - view.rect.min + view.scroll;
Vec2I pos = mworld / Vec2I{view.char_spacing, view.line_spacing};
XY xy = {(Int)(pos.x), (Int)(pos.y)};
Int p = XYToPosWithoutNL(buf, xy);
if (mouse_in_view && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
@@ -275,20 +280,19 @@ void HandleKeybindings(View *_view) {
// 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])) {
Caret c = view.carets[0];
Int front = GetFront(c);
XY xy = PosToXY(buf, front);
Rect2I visible = GetVisibleCells(view);
Vec2I visible_cells = GetSize(visible);
Vec2 visible_size = ToVec2(visible_cells) * Vec2{view.char_spacing, view.line_spacing};
Vec2 rect_size = GetSize(view.rect);
Vec2I visible_size = visible_cells * Vec2I{view.char_spacing, view.line_spacing};
Vec2I rect_size = GetSize(view.rect);
if (xy.line > visible.max.y - 3) {
Int set_view_at_line = xy.line - (visible_cells.y - 1);
float cut_off_y = Max(0.f, visible_size.y - rect_size.y);
view.scroll.y = ((float)set_view_at_line * view.line_spacing) + cut_off_y;
if (xy.line > visible.max.y - 2) {
Int set_view_at_line = xy.line - (visible_cells.y - 1);
Int cut_off_y = Max((Int)0, visible_size.y - rect_size.y);
view.scroll.y = (set_view_at_line * view.line_spacing) + cut_off_y;
}
if (xy.line < visible.min.y + 1) {
@@ -296,9 +300,9 @@ void HandleKeybindings(View *_view) {
}
if (xy.col >= visible.max.x - 1) {
Int set_view_at_line = xy.col - (visible_cells.x - 1);
float cut_off_x = Max(0.f, visible_size.x - rect_size.x);
view.scroll.x = ((float)set_view_at_line * view.char_spacing) + cut_off_x;
Int set_view_at_line = xy.col - (visible_cells.x - 1);
Int cut_off_x = Max((Int)0, visible_size.x - rect_size.x);
view.scroll.x = (set_view_at_line * view.char_spacing) + cut_off_x;
}
if (xy.col <= visible.min.x) {
@@ -310,12 +314,12 @@ void HandleKeybindings(View *_view) {
{
ProfileScope(clip_scroll);
Int last_line = LastLine(view.buffer[0]);
view.scroll.y = Clamp(view.scroll.y, 0.f, Max(0.f, (last_line - 1) * view.line_spacing));
view.scroll.y = Clamp(view.scroll.y, (Int)0, Max((Int)0, (last_line - 1) * view.line_spacing));
// @note:
// GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for
// calculating this value incrementally but do we even need X scrollbar or x clipping?
view.scroll.x = ClampBottom(view.scroll.x, 0.f);
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

@@ -1,14 +1,20 @@
Vec2I GetCellSize(const View &view) {
Vec2I result = {(Int)view.char_spacing, (Int)view.line_spacing};
return result;
}
Rect2I GetVisibleCells(const View &view) {
ProfileFunction();
Vec2 size = GetSize(view.rect);
float _cx = size.x / view.char_spacing;
float _cy = size.y / view.line_spacing;
int cx = (int)ceilf(_cx) + 1;
int cy = (int)ceilf(_cy) + 1;
Vec2I size = GetSize(view.rect);
Vec2 pos = {SafeDivide(view.scroll.x, view.char_spacing), SafeDivide(view.scroll.y, view.line_spacing)};
int x = (int)floorf(pos.x);
int y = (int)floorf(pos.y);
Int _cx = size.x / view.char_spacing;
Int _cy = size.y / view.line_spacing;
Int cx = _cx + 1;
Int cy = _cy + 1;
Vec2I pos = {SafeDivide(view.scroll.x, view.char_spacing), SafeDivide(view.scroll.y, view.line_spacing)};
Int x = pos.x;
Int y = pos.y;
Rect2I result = {x, y, x + cx, y + cy};
return result;
}
@@ -22,40 +28,35 @@ void DrawVisibleCells(const View &view) {
line_string = Skip(line_string, visible.min.x);
line_string = GetPrefix(line_string, visible.max.x - visible.min.x);
Vec2 pos = {visible.min.x * view.char_spacing, line_index * view.line_spacing};
Vec2I pos = {visible.min.x * (Int)view.char_spacing, line_index * (Int)view.line_spacing};
pos -= view.scroll;
DrawString(view.font, line_string, pos, view.font_size, view.font_spacing, BLACK);
DrawString(view.font, line_string, ToVec2(pos), (float)view.font_size, (float)view.font_spacing, BLACK);
}
}
Vec2 GetCellSize(const View &view) {
Vec2 result = {view.char_spacing, view.line_spacing};
Vec2I XYToWorldPos(const View &view, XY xy) {
Vec2I result = {xy.col * (Int)view.char_spacing, xy.line * (Int)view.line_spacing};
return result;
}
Vec2 XYToWorldPos(const View &view, XY xy) {
Vec2 result = {(float)xy.col * view.char_spacing, (float)xy.line * view.line_spacing};
return result;
}
Rect2 XYToRect(const View &view, XY xy) {
Rect2 result = Rect2FromSize(XYToWorldPos(view, xy), GetCellSize(view));
Rect2I XYToRect(const View &view, XY xy) {
Rect2I result = Rect2IFromSize(XYToWorldPos(view, xy), GetCellSize(view));
return result;
}
void DrawCaret(const View &view, XY xy, float size, Color color) {
Rect2 _rect = XYToRect(view, xy);
Rect2 rect = CutLeft(&_rect, size * view.char_spacing);
Rect2I _rect = XYToRect(view, xy);
Rect2I rect = CutLeft(&_rect, (Int)(size * (float)view.char_spacing));
rect -= view.scroll;
DrawRectangleRec(ToRectangle(rect), color);
}
void DrawLineHighlight(const View &view, XY fxy, Color color) {
Vec2 w = XYToWorldPos(view, XYLine(fxy.line));
Vec2I w = XYToWorldPos(view, XYLine(fxy.line));
w -= view.scroll;
Range range = GetLineRange(*view.buffer, fxy.line);
float xsize = view.char_spacing * (float)GetSize(range);
Rect2 rect = Rect2FromSize(w, {xsize, view.line_spacing});
Range range = GetLineRange(*view.buffer, fxy.line);
Int xsize = (Int)view.char_spacing * GetSize(range);
Rect2I rect = Rect2IFromSize(w, {xsize, view.line_spacing});
DrawRectangleRec(ToRectangle(rect), color);
}
@@ -95,9 +96,9 @@ void DrawCaret(const View &view, Caret &it) {
bool d = min.line == max.line && line == max.line && col >= min.col && col < max.col;
if (a || b || c || d) {
Vec2 pos = {col * view.char_spacing, line * view.line_spacing};
Vec2I pos = {col * view.char_spacing, line * view.line_spacing};
pos -= view.scroll;
Rectangle rectangle = {pos.x, pos.y, view.char_spacing, view.line_spacing};
Rectangle rectangle = {(float)pos.x, (float)pos.y, (float)view.char_spacing, (float)view.line_spacing};
DrawRectangleRec(rectangle, {0, 50, 150, 20});
}
}