/* Screen management functions
*****************************************************************************/
+typedef struct {
+ Rune rune;
+ uint8_t fg;
+ uint8_t bg;
+} UGlyph;
+
typedef struct {
unsigned off; /* offset of the first rune in the row */
unsigned rlen; /* number of runes displayed in the row */
unsigned len; /* number of screen columns taken up by row */
- Rune cols[]; /* row data */
+ UGlyph cols[]; /* row data */
} Row;
void screen_reflow(Buf* buf);
void screen_clearrow(unsigned row);
void screen_setrowoff(unsigned row, unsigned off);
unsigned screen_setcell(unsigned row, unsigned col, Rune r);
-Rune screen_getcell(unsigned row, unsigned col);
+UGlyph* screen_getcell(unsigned row, unsigned col);
void screen_status(char* fmt, ...);
/* Color Scheme Handling
/* create the new row data */
Rows = calloc(nrows, sizeof(Row*));
for (unsigned i = 0; i < nrows; i++)
- Rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(Rune)));
+ Rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(UGlyph)));
/* update dimensions */
NumRows = nrows;
NumCols = ncols;
Row* scrrow = screen_getrow(row);
if (!scrrow) return;
for (unsigned i = 0; i < NumCols; i++)
- scrrow->cols[i] = (Rune)' ';
+ scrrow->cols[i].rune = (Rune)' ';
scrrow->rlen = 0;
scrrow->len = 0;
}
/* write the rune to the screen buf */
unsigned ncols = 1;
if (r == '\t') {
- scrrow->cols[col] = ' ';
+ scrrow->cols[col].rune = ' ';
ncols = (TabWidth - (col % TabWidth));
} else if (r != '\n') {
- scrrow->cols[col] = r;
+ scrrow->cols[col].rune = r;
}
/* Update lengths */
scrrow->rlen += 1;
return ncols;
}
-Rune screen_getcell(unsigned row, unsigned col) {
+UGlyph* screen_getcell(unsigned row, unsigned col) {
if (row >= NumRows || col >= NumCols) return 0;
Row* scrrow = screen_getrow(row);
- return scrrow->cols[col];
+ return &(scrrow->cols[col]);
}
static void fill_row(Buf* buf, unsigned row, unsigned pos) {
/* delete the last row and shift the others */
free(Rows[NumRows - 1]);
memmove(&Rows[2], &Rows[1], sizeof(Row*) * (NumRows-2));
- Rows[1] = calloc(1, sizeof(Row) + (NumCols * sizeof(Rune)));
+ Rows[1] = calloc(1, sizeof(Row) + (NumCols * sizeof(UGlyph)));
Rows[1]->off = prevln;
/* fill in row content */
fill_row(buf, 1, Rows[1]->off);
/* delete the first row and shift the others */
free(Rows[1]);
memmove(&Rows[1], &Rows[2], sizeof(Row*) * (NumRows-2));
- Rows[NumRows-1] = calloc(1, sizeof(Row) + (NumCols * sizeof(Rune)));
+ Rows[NumRows-1] = calloc(1, sizeof(Row) + (NumCols * sizeof(UGlyph)));
Rows[NumRows-1]->off = (Rows[NumRows-2]->off + Rows[NumRows-2]->rlen);
/* fill in row content */
fill_row(buf, NumRows-1, Rows[NumRows-1]->off);
Rows[0]->len = NumCols;
Rows[0]->rlen = NumCols;
for (unsigned i = 0; buffer[i] && i < NumCols; i++)
- Rows[0]->cols[i] = (Rune)buffer[i];
+ Rows[0]->cols[i].rune = (Rune)buffer[i];
}
FcCharSetDestroy(fccharset);
}
-int font_makespecs(XftGlyphFontSpec* specs, const Rune* runes, int len, int x, int y) {
+int font_makespecs(XftGlyphFontSpec* specs, const UGlyph* glyphs, int len, int x, int y) {
int winx = x * Fonts.base.width, winy = y * Fonts.base.height;
int numspecs = 0;
for (int i = 0, xp = winx, yp = winy + Fonts.base.ascent; i < len; ++i) {
- if (!runes[i]) continue;
- font_find(&(specs[numspecs]), runes[i]);
- int runewidth = wcwidth(runes[i]) * Fonts.base.width;
+ if (!glyphs[i].rune) continue;
+ font_find(&(specs[numspecs]), glyphs[i].rune);
+ int runewidth = wcwidth(glyphs[i].rune) * Fonts.base.width;
specs[numspecs].x = xp;
specs[numspecs].y = yp;
xp += runewidth;
}
}
-void draw_runes(unsigned x, unsigned y, XftColor* fg, XftColor* bg, Rune* runes, size_t rlen) {
+void draw_runes(unsigned x, unsigned y, XftColor* fg, XftColor* bg, UGlyph* glyphs, size_t rlen) {
(void)bg;
XftGlyphFontSpec specs[rlen];
- size_t nspecs = font_makespecs(specs, runes, rlen, x, y);
+ size_t nspecs = font_makespecs(specs, glyphs, rlen, x, y);
XftDrawGlyphFontSpec(X.xft, fg, specs, nspecs);
}
}
/* Place cursor on screen */
- Rune csrrune = screen_getcell(csry,csrx);
+ UGlyph* csrrune = screen_getcell(csry,csrx);
if (Buffer.insert_mode) {
XftDrawRect(X.xft, &csrclr, csrx * Fonts.base.width, csry * Fonts.base.height, 2, Fonts.base.height);
} else {
unsigned width = ('\t' == buf_get(&Buffer, CursorPos) ? (TabWidth - (csrx % TabWidth)) : 1);
XftDrawRect(X.xft, &csrclr, csrx * Fonts.base.width, csry * Fonts.base.height, width * Fonts.base.width, Fonts.base.height);
- draw_runes(csrx, csry, &bkgclr, NULL, (FcChar32*)&csrrune, 1);
+ draw_runes(csrx, csry, &bkgclr, NULL, csrrune, 1);
}
/* flush pixels to the screen */