]> git.mdlowis.com Git - projs/tide.git/commitdiff
reworked drawing glyphs to the screen. Still need to implement scrolling and clicking
authorMichael D. Lowis <mike.lowis@gentex.com>
Wed, 18 Apr 2018 16:58:16 +0000 (12:58 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Wed, 18 Apr 2018 16:58:16 +0000 (12:58 -0400)
lib/view.c
lib/x11.c

index 33825b340ba9bc9bf5d551996d1a63b47b04a0a3..bcff0eb581fba45dbefea9a1528231d283ee9971 100644 (file)
@@ -3,6 +3,9 @@
 #include <edit.h>
 #include <ctype.h>
 
+/* Provided by x11.c */
+extern size_t glyph_width(int c);
+
 #define BUF    (&(view->buffer))
 #define CSRPOS (view->buffer.selection.end)
 
@@ -83,16 +86,50 @@ size_t view_limitrows(View* view, size_t maxrows, size_t ncols) {
     return 1;
 }
 
+size_t rune_width(int c, size_t xpos, size_t width) {
+    if (c == '\r')
+        return 0;
+    else if (c == '\n')
+        return (width-xpos);
+    else if (c == '\t')
+        return (glyph_width(c) - (xpos % glyph_width(c)));
+    else
+        return glyph_width(c);
+}
+
 void view_resize(View* view, size_t width, size_t nrows) {
     /* free up the old data */
     if (view->rows) {
         for (size_t i = 0; i < view->nrows; i++)
             free(view->rows[i]);
         free(view->rows);
+        view->rows = NULL;
         view->nrows = 0;
     }
+    size_t off = 0;
     /* start from beginning of first line and populate row by row */
-
+    for (size_t i = 0; i < nrows; i++) {
+        view->nrows++;
+        view->rows = realloc(view->rows, sizeof(Row*) * view->nrows);
+        view->rows[view->nrows-1] = calloc(1, sizeof(Row));
+        view->rows[view->nrows-1]->off = off;
+
+        size_t xpos = 0;
+        while (xpos < width) {
+            int rune = buf_getrat(&(view->buffer), off);
+            size_t rwidth = rune_width(rune, xpos, width);
+            xpos += rwidth;
+            if (xpos <= width) {
+                size_t len = view->rows[view->nrows-1]->len + 1;
+                view->rows[view->nrows-1] = realloc(
+                    view->rows[view->nrows-1], sizeof(Row) + (len * sizeof(UGlyph)));
+                view->rows[view->nrows-1]->len = len;
+                view->rows[view->nrows-1]->cols[len-1].rune  = rune;
+                view->rows[view->nrows-1]->cols[len-1].width = rwidth;
+                off = buf_byrune(&(view->buffer), off, RIGHT);
+            }
+        }
+    }
 }
 
 void view_update(View* view, size_t* csrx, size_t* csry) {
index ddb03d152f2e2b356e2fa1167f159418146120e8..f9e40f363462f529189324af22c2adcd3387454b 100644 (file)
--- a/lib/x11.c
+++ b/lib/x11.c
@@ -282,6 +282,19 @@ static void getglyph(XGlyphSpec* spec, uint32_t rune) {
     spec->font  = CurrFont.match;
 }
 
+size_t glyph_width(int c) {
+    XGlyphInfo extents;
+    if (c == '\t') {
+        FcChar32 index = XftCharIndex(X.display, CurrFont.match, '0');
+        XftTextExtents32(X.display, CurrFont.match, &index, 1, &extents);
+        return (4 *  extents.xOff);
+    } else {
+        FcChar32 index = XftCharIndex(X.display, CurrFont.match, c);
+        XftTextExtents32(X.display, CurrFont.match, &index, 1, &extents);
+        return extents.xOff;
+    }
+}
+
 static size_t getglyphs(XGlyphSpec* specs, const XGlyph* glyphs, int len, int x, int y) {
     int winx = x, winy = y;
     size_t numspecs = 0;
@@ -316,32 +329,21 @@ static void place_glyphs(int fg, XGlyphSpec* specs, size_t nspecs, bool eol) {
 }
 
 static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t len) {
-#if 0
-    XGlyphSpec specs[rlen];
+    XGlyphSpec specs[len];
     size_t i = 0;
     bool eol = false;
-    while (rlen && i < ncols) {
-        int numspecs = 0;
-        while (i < ncols) {
-            if (glyphs[i].rune == '\n')
-                glyphs[i].rune = ' ', eol = true;
-            getglyph(&(specs[numspecs]), glyphs[i].rune);
-            XGlyphInfo extents;
-            XftTextExtents32(X.display, CurrFont.match, &(const FcChar32){glyphs[i].rune}, 1, &extents);
-            specs[numspecs].x = x;
-            specs[numspecs].y = y - font_descent();
-            x += extents.xOff;
-            numspecs++;
-            i++;
-            /* skip over null chars which mark multi column runes */
-            for (; i < ncols && !glyphs[i].rune; i++)
-                x += font_width();
-        }
-        /* Draw the glyphs with the proper colors */
-        place_glyphs(EditFg, specs, numspecs, eol);
-        eol = false, rlen -= numspecs;
+    for (size_t i = 0; i < len; i++) {
+        if (glyphs[i].rune == '\r' || glyphs[i].rune == '\n' ||  glyphs[i].rune == '\t')
+            glyphs[i].rune = ' ';
+        getglyph(&(specs[i]), glyphs[i].rune);
+        specs[i].x = x;
+        specs[i].y = y - font_descent();
+        x += glyphs[i].width;
     }
-#endif
+    XftColor fgc;
+    xftcolor(&fgc, EditFg);
+    XftDrawGlyphFontSpec(X.xft, &fgc, (XftGlyphFontSpec*)specs, len);
+    XftColorFree(X.display, X.visual, X.colormap, &fgc);
 }
 
 static void draw_view(int i, size_t nrows, drawcsr* csr, int bg, int fg, int sel) {