#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)
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) {
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;
}
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) {