Просмотр исходного кода

Improved color and unicode handling

Kajetan Johannes Hammerle 1 месяц назад
Родитель
Сommit
fbf95af121
1 измененных файлов с 86 добавлено и 29 удалено
  1. 86 29
      src/Main.cpp

+ 86 - 29
src/Main.cpp

@@ -7,13 +7,75 @@ import Core.List;
 import Core.Math;
 import Core.ToString;
 import Core.Logger;
+import Core.Unicode;
 
 using SizeVector = Core::Vector<2, size_t>;
 
 enum class Mode { NORMAL, INSERT };
 
 struct Cell {
-    Core::String<200> content{};
+    Core::List<u32> content{};
+};
+
+struct ColoredString {
+    struct SubColoredString {
+        Core::String<32> color{};
+        Core::List<u32> content{};
+    };
+
+    Core::List<SubColoredString> strings;
+
+    void print() {
+        for(const SubColoredString& s : strings) {
+            s.color.print();
+            for(u32 u : s.content) {
+                Core::UTF8 c = Core::convertUnicodeToUTF8(u);
+                for(u32 l = 0; l < c.length; l++) {
+                    putchar(c.data[l]);
+                }
+            }
+        }
+    }
+
+    void addColor(const char* s) {
+        strings.put().color.add(s);
+    }
+
+    void add(u32 u) {
+        strings.getLast().content.add(u);
+    }
+
+    void add(const Core::List<u32>& l) {
+        for(u32 u : l) {
+            add(u);
+        }
+    }
+
+    void clear() {
+        strings.clear();
+    }
+
+    void removeFirst(size_t amount) {
+        size_t index = 0;
+        while(index < strings.getLength() && amount > 0) {
+            while(strings[index].content.getLength() > 0 && amount > 0) {
+                strings[index].content.remove(0);
+                amount--;
+            }
+            index++;
+        }
+    }
+
+    void removeLast(size_t amount) {
+        size_t index = strings.getLength();
+        while(index > 0 && amount > 0) {
+            index--;
+            while(strings[index].content.getLength() > 0 && amount > 0) {
+                strings[index].content.removeLast();
+                amount--;
+            }
+        }
+    }
 };
 
 static bool running = true;
@@ -25,7 +87,7 @@ static Mode mode = Mode::NORMAL;
 static void init() {
     cells.resize(tableSize[0] * tableSize[1]);
     for(Cell& c : cells) {
-        c.content.format(" ");
+        c.content.add(U' ');
     }
 }
 
@@ -45,17 +107,11 @@ static size_t getColumnWidth(size_t x) {
     size_t w = 0;
     for(size_t y = 0; y < tableSize[1]; y++) {
         Cell& c = getCell(x, y);
-        w = Core::max(w, strlen(c.content));
+        w = Core::max(w, c.content.getLength());
     }
     return w;
 }
 
-static void addString(Core::List<char>& line, const char* s) {
-    while(*s != '\0') {
-        line.add(*(s++));
-    }
-}
-
 static void render() {
     static constexpr const char* lc[2] = {
         Core::Terminal::BG_WHITE, Core::Terminal::BG_BRIGHT_WHITE};
@@ -72,7 +128,12 @@ static void render() {
     int leftWidth = size[0];
     leftWidth -= columnWidths[rangeMin] + 1;
     int left = leftWidth / 2;
-    int right = left + (leftWidth & 1);
+    int right = left;
+    if(leftWidth >= 0) {
+        right += (leftWidth & 1);
+    } else {
+        right -= (leftWidth & 1);
+    }
     while(left > 0 && rangeMin > 0) {
         rangeMin--;
         left -= columnWidths[rangeMin];
@@ -102,38 +163,34 @@ static void render() {
         }
     }
 
-    Core::List<char> line;
+    ColoredString line;
     for(size_t y = 0; y < tableSize[1]; y++) {
         line.clear();
-        addString(line, lc[y & 1]);
-        size_t removeIndex = line.getLength();
+        line.addColor(lc[y & 1]);
         for(size_t x = rangeMin; x <= rangeMax; x++) {
             Cell& c = getCell(x, y);
             if(cursorPosition[0] == x && cursorPosition[1] == y) {
-                addString(line, Core::Terminal::BG_BRIGHT_BLUE);
+                line.addColor(Core::Terminal::BG_BRIGHT_BLUE);
             }
-            addString(line, c.content);
-            size_t filler = columnWidths[x] - strlen(c.content);
+            line.add(c.content);
+            size_t filler = columnWidths[x] - c.content.getLength();
             while(filler > 0) {
                 filler--;
-                addString(line, " ");
+                line.add(U' ');
             }
             if(cursorPosition[0] == x && cursorPosition[1] == y) {
-                addString(line, lc[y & 1]);
+                line.addColor(lc[y & 1]);
             }
-            addString(line, "|");
-        }
-        for(int i = 0; i > left; i--) {
-            line.remove(removeIndex);
-        }
-        for(int i = 0; i > right; i--) {
-            line.removeLast();
+            line.add(U'|');
         }
-        line.add('\0');
-        puts(line.begin());
+        line.removeFirst(static_cast<size_t>(-left));
+        line.removeLast(static_cast<size_t>(-right));
+        line.print();
     }
     print(Core::Terminal::RESET);
-    printf("%d %d\n", left, right);
+    printf(
+        "%zu %zu %zu %d %d %d\n", rangeMin, rangeMax,
+        columnWidths[cursorPosition[0]], size[0], left, right);
 
     Core::resetCursor();
     Core::moveCursorDown(size[1] - 2);
@@ -176,7 +233,7 @@ static void loop(u64 input) {
     } else if(mode == Mode::INSERT) {
         if(!Core::isSpecialChar(input) && input >= ' ') {
             Cell& c = getCell(cursorPosition);
-            c.content.add(static_cast<char>(input));
+            c.content.add(static_cast<u32>(input));
         }
     }
     render();