commit 55d0e193e2417318336a7eb5fd8e42fe8c519de0
parent 5f96463537ee5b750ce72138ef7d990cceed72c4
Author: rexim <reximkut@gmail.com>
Date: Fri, 2 Jul 2021 20:09:43 +0700
Factor out the notion of the line
Diffstat:
| M | Makefile | | | 2 | +- |
| A | buffer.c | | | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | buffer.h | | | 16 | ++++++++++++++++ |
| M | main.c | | | 78 | +++++++++++++++++++++--------------------------------------------------------- |
4 files changed, 94 insertions(+), 58 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,4 +2,4 @@ CFLAGS=-Wall -Wextra -std=c11 -pedantic -ggdb `pkg-config --cflags sdl2`
LIBS=`pkg-config --libs sdl2` -lm
te: main.c
- $(CC) $(CFLAGS) -o te main.c la.c $(LIBS)
+ $(CC) $(CFLAGS) -o te main.c la.c buffer.c $(LIBS)
diff --git a/buffer.c b/buffer.c
@@ -0,0 +1,56 @@
+#include <assert.h>
+#include <string.h>
+#include "./buffer.h"
+
+#define LINE_INIT_CAPACITY 1024
+
+static void line_grow(Line *line, size_t n)
+{
+ size_t new_capacity = line->capacity;
+
+ assert(new_capacity >= line->size);
+ while (new_capacity - line->size < n) {
+ if (new_capacity == 0) {
+ new_capacity = LINE_INIT_CAPACITY;
+ } else {
+ new_capacity *= 2;
+ }
+ }
+
+ if (new_capacity != line->capacity) {
+ line->chars = realloc(line->chars, new_capacity);
+ line->capacity = new_capacity;
+ }
+}
+
+void line_insert_text_before(Line *line, const char *text, size_t col)
+{
+ const size_t text_size = strlen(text);
+ line_grow(line, text_size);
+
+ memmove(line->chars + col + text_size,
+ line->chars + col,
+ line->size - col);
+ memcpy(line->chars + col, text, text_size);
+ line->size += text_size;
+}
+
+void line_backspace(Line *line, size_t col)
+{
+ if (col > 0 && line->size > 0) {
+ memmove(line->chars + col - 1,
+ line->chars + col,
+ line->size - col);
+ line->size -= 1;
+ }
+}
+
+void line_delete(Line *line, size_t col)
+{
+ if (col < line->size && line->size > 0) {
+ memmove(line->chars + col,
+ line->chars + col + 1,
+ line->size - col);
+ line->size -= 1;
+ }
+}
diff --git a/buffer.h b/buffer.h
@@ -0,0 +1,16 @@
+#ifndef BUFFER_H_
+#define BUFFER_H_
+
+#include <stdlib.h>
+
+typedef struct {
+ size_t capacity;
+ size_t size;
+ char *chars;
+} Line;
+
+void line_insert_text_before(Line *line, const char *text, size_t col);
+void line_backspace(Line *line, size_t col);
+void line_delete(Line *line, size_t col);
+
+#endif // BUFFER_H_
diff --git a/main.c b/main.c
@@ -9,6 +9,8 @@
#define STB_IMAGE_IMPLEMENTATION
#include "./stb_image.h"
+#include "./buffer.h"
+
#define FONT_WIDTH 128
#define FONT_HEIGHT 64
#define FONT_COLS 18
@@ -136,47 +138,8 @@ void render_text_sized(SDL_Renderer *renderer, Font *font, const char *text, siz
}
}
-#define BUFFER_CAPACITY 1024
-
-char buffer[BUFFER_CAPACITY];
-size_t buffer_cursor = 0;
-size_t buffer_size = 0;
-
-void buffer_insert_text_before_cursor(const char *text)
-{
- size_t text_size = strlen(text);
- const size_t free_space = BUFFER_CAPACITY - buffer_size;
- if (text_size > free_space) {
- text_size = free_space;
- }
- memmove(buffer + buffer_cursor + text_size,
- buffer + buffer_cursor,
- buffer_size - buffer_cursor);
- memcpy(buffer + buffer_cursor, text, text_size);
- buffer_size += text_size;
- buffer_cursor += text_size;
-}
-
-void buffer_backspace(void)
-{
- if (buffer_cursor > 0 && buffer_size > 0) {
- memmove(buffer + buffer_cursor - 1,
- buffer + buffer_cursor,
- buffer_size - buffer_cursor);
- buffer_size -= 1;
- buffer_cursor -= 1;
- }
-}
-
-void buffer_delete(void)
-{
- if (buffer_cursor < buffer_size && buffer_size > 0) {
- memmove(buffer + buffer_cursor,
- buffer + buffer_cursor + 1,
- buffer_size - buffer_cursor);
- buffer_size -= 1;
- }
-}
+Line line = {0};
+size_t cursor = 0;
#define UNHEX(color) \
((color) >> (8 * 0)) & 0xFF, \
@@ -186,7 +149,7 @@ void buffer_delete(void)
void render_cursor(SDL_Renderer *renderer, const Font *font)
{
- const Vec2f pos = vec2f((float) buffer_cursor * FONT_CHAR_WIDTH * FONT_SCALE, 0.0f);
+ const Vec2f pos = vec2f((float) cursor * FONT_CHAR_WIDTH * FONT_SCALE, 0.0f);
const SDL_Rect rect = {
.x = (int) floorf(pos.x),
@@ -199,25 +162,22 @@ void render_cursor(SDL_Renderer *renderer, const Font *font)
scc(SDL_RenderFillRect(renderer, &rect));
set_texture_color(font->spritesheet, 0xFF000000);
- if (buffer_cursor < buffer_size) {
- render_char(renderer, font, buffer[buffer_cursor], pos, FONT_SCALE);
+ if (cursor < line.size) {
+ render_char(renderer, font, line.chars[cursor], pos, FONT_SCALE);
}
}
-
+// TODO: Multiple lines
+// TODO: Save/Load file
// TODO: Jump forward/backward by a word
// TODO: Delete a word
// TODO: Blinking cursor
-// TODO: Multiple lines
-// TODO: Save/Load file
int main(int argc, char **argv)
{
(void) argc;
(void) argv;
- buffer_insert_text_before_cursor("Hello, World");
-
scc(SDL_Init(SDL_INIT_VIDEO));
SDL_Window *window =
@@ -243,24 +203,27 @@ int main(int argc, char **argv)
case SDL_KEYDOWN: {
switch (event.key.keysym.sym) {
case SDLK_BACKSPACE: {
- buffer_backspace();
+ line_backspace(&line, cursor);
+ if (cursor > 0) {
+ cursor -= 1;
+ }
}
break;
case SDLK_DELETE: {
- buffer_delete();
+ line_delete(&line, cursor);
} break;
case SDLK_LEFT: {
- if (buffer_cursor > 0) {
- buffer_cursor -= 1;
+ if (cursor > 0) {
+ cursor -= 1;
}
}
break;
case SDLK_RIGHT: {
- if (buffer_cursor < buffer_size) {
- buffer_cursor += 1;
+ if (cursor < line.size) {
+ cursor += 1;
}
}
break;
@@ -269,7 +232,8 @@ int main(int argc, char **argv)
break;
case SDL_TEXTINPUT: {
- buffer_insert_text_before_cursor(event.text.text);
+ line_insert_text_before(&line, event.text.text, cursor);
+ cursor += strlen(event.text.text);
}
break;
}
@@ -278,7 +242,7 @@ int main(int argc, char **argv)
scc(SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0));
scc(SDL_RenderClear(renderer));
- render_text_sized(renderer, &font, buffer, buffer_size, vec2f(0.0, 0.0), 0xFFFFFFFF, FONT_SCALE);
+ render_text_sized(renderer, &font, line.chars, line.size, vec2f(0.0, 0.0), 0xFFFFFFFF, FONT_SCALE);
render_cursor(renderer, &font);
SDL_RenderPresent(renderer);