From aa655134f275dfeb819f6b7f4d2d73f8bf0eb6e6 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 18 Apr 2018 12:58:16 -0400 Subject: [PATCH] reworked drawing glyphs to the screen. Still need to implement scrolling and clicking --- lib/view.c | 39 ++++++++++++++++++++++++++++++++++++++- lib/x11.c | 48 +++++++++++++++++++++++++----------------------- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/lib/view.c b/lib/view.c index 33825b3..bcff0eb 100644 --- a/lib/view.c +++ b/lib/view.c @@ -3,6 +3,9 @@ #include #include +/* 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) { diff --git a/lib/x11.c b/lib/x11.c index ddb03d1..f9e40f3 100644 --- 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) { -- 2.49.0