-
- if(base.mode & ATTR_BOLD) {
- /*
- * change basic system colors [0-7]
- * to bright system colors [8-15]
- */
- if(BETWEEN(base.fg, 0, 7) && !(base.mode & ATTR_FAINT))
- fg = &dc.col[base.fg + 8];
-
- if(base.mode & ATTR_ITALIC) {
- font = &dc.ibfont;
- frcflags = FRC_ITALICBOLD;
- } else {
- font = &dc.bfont;
- frcflags = FRC_BOLD;
- }
- }
-
- if(IS_SET(MODE_REVERSE)) {
- if(fg == &dc.col[defaultfg]) {
- fg = &dc.col[defaultbg];
- } else {
- colfg.red = ~fg->color.red;
- colfg.green = ~fg->color.green;
- colfg.blue = ~fg->color.blue;
- colfg.alpha = fg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg,
- &revfg);
- fg = &revfg;
- }
-
- if(bg == &dc.col[defaultbg]) {
- bg = &dc.col[defaultfg];
- } else {
- colbg.red = ~bg->color.red;
- colbg.green = ~bg->color.green;
- colbg.blue = ~bg->color.blue;
- colbg.alpha = bg->color.alpha;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg,
- &revbg);
- bg = &revbg;
- }
- }
-
- if(base.mode & ATTR_REVERSE) {
- temp = fg;
- fg = bg;
- bg = temp;
- }
-
- if(base.mode & ATTR_FAINT && !(base.mode & ATTR_BOLD)) {
- colfg.red = fg->color.red / 2;
- colfg.green = fg->color.green / 2;
- colfg.blue = fg->color.blue / 2;
- XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg);
- fg = &revfg;
- }
-
- if(base.mode & ATTR_BLINK && term.mode & MODE_BLINK)
- fg = bg;
-
- if(base.mode & ATTR_INVISIBLE)
- fg = bg;
-
- /* Intelligent cleaning up of the borders. */
- if(x == 0) {
- xclear(0, (y == 0)? 0 : winy, borderpx,
- winy + xw.ch + ((y >= term.row-1)? xw.h : 0));
- }
- if(x + charlen >= term.col) {
- xclear(winx + width, (y == 0)? 0 : winy, xw.w,
- ((y >= term.row-1)? xw.h : (winy + xw.ch)));
- }
- if(y == 0)
- xclear(winx, 0, winx + width, borderpx);
- if(y == term.row-1)
- xclear(winx, winy + xw.ch, winx + width, xw.h);
-
- /* Clean up the region we want to draw to. */
- XftDrawRect(xw.draw, bg, winx, winy, width, xw.ch);
-
- /* Set the clip region because Xft is sometimes dirty. */
- r.x = 0;
- r.y = 0;
- r.height = xw.ch;
- r.width = width;
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
-
- for(xp = winx; bytelen > 0;) {
- /*
- * Search for the range in the to be printed string of glyphs
- * that are in the main font. Then print that range. If
- * some glyph is found that is not in the font, do the
- * fallback dance.
- */
- u8fs = s;
- u8fblen = 0;
- u8fl = 0;
- oneatatime = font->width != xw.cw;
- for(;;) {
- u8c = s;
- u8cblen = utf8decode(s, &unicodep, UTF_SIZ);
- s += u8cblen;
- bytelen -= u8cblen;
-
- doesexist = XftCharExists(xw.dpy, font->match, unicodep);
- if(doesexist) {
- u8fl++;
- u8fblen += u8cblen;
- if(!oneatatime && bytelen > 0)
- continue;
- }
-
- if(u8fl > 0) {
- XftDrawStringUtf8(xw.draw, fg,
- font->match, xp,
- winy + font->ascent,
- (FcChar8 *)u8fs,
- u8fblen);
- xp += xw.cw * u8fl;
- }
- break;
- }
- if(doesexist) {
- if(oneatatime)
- continue;
- break;
- }
-
- /* Search the font cache. */
- for(i = 0; i < frclen; i++) {
- charexists = XftCharExists(xw.dpy, frc[i].font, unicodep);
- /* Everything correct. */
- if(charexists && frc[i].flags == frcflags)
- break;
- /* We got a default font for a not found glyph. */
- if(!charexists && frc[i].flags == frcflags \
- && frc[i].unicodep == unicodep) {
- break;
- }
- }
-
- /* Nothing was found. */
- if(i >= frclen) {
- if(!font->set)
- font->set = FcFontSort(0, font->pattern,
- FcTrue, 0, &fcres);
- fcsets[0] = font->set;
-
- /*
- * Nothing was found in the cache. Now use
- * some dozen of Fontconfig calls to get the
- * font for one single character.
- *
- * Xft and fontconfig are design failures.
- */
- fcpattern = FcPatternDuplicate(font->pattern);
- fccharset = FcCharSetCreate();
-
- FcCharSetAddChar(fccharset, unicodep);
- FcPatternAddCharSet(fcpattern, FC_CHARSET,
- fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE,
- FcTrue);
-
- FcConfigSubstitute(0, fcpattern,
- FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
-
- fontpattern = FcFontSetMatch(0, fcsets, 1,
- fcpattern, &fcres);
-
- /*
- * Overwrite or create the new cache entry.
- */
- if(frclen >= LEN(frc)) {
- frclen = LEN(frc) - 1;
- XftFontClose(xw.dpy, frc[frclen].font);
- frc[frclen].unicodep = 0;
- }
-
- frc[frclen].font = XftFontOpenPattern(xw.dpy,
- fontpattern);
- frc[frclen].flags = frcflags;
- frc[frclen].unicodep = unicodep;
-
- i = frclen;
- frclen++;
-
- FcPatternDestroy(fcpattern);
- FcCharSetDestroy(fccharset);
- }
-
- XftDrawStringUtf8(xw.draw, fg, frc[i].font,
- xp, winy + frc[i].font->ascent,
- (FcChar8 *)u8c, u8cblen);
-
- xp += xw.cw * wcwidth(unicodep);
- }
-
- /*
- * This is how the loop above actually should be. Why does the
- * application have to care about font details?
- *
- * I have to repeat: Xft and Fontconfig are design failures.
- */
- /*
- XftDrawStringUtf8(xw.draw, fg, font->set, winx,
- winy + font->ascent, (FcChar8 *)s, bytelen);
- */
-
- if(base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + font->ascent + 1,
- width, 1);
- }
-
- if(base.mode & ATTR_STRUCK) {
- XftDrawRect(xw.draw, fg, winx, winy + 2 * font->ascent / 3,
- width, 1);
- }
-
- /* Reset clip to none. */
- XftDrawSetClip(xw.draw, 0);
-}
-
-void
-xdrawcursor(void) {
- static int oldx = 0, oldy = 0;
- int sl, width, curx;
- Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs};
-
- LIMIT(oldx, 0, term.col-1);
- LIMIT(oldy, 0, term.row-1);
-
- curx = term.c.x;
-
- /* adjust position if in dummy */
- if(term.line[oldy][oldx].mode & ATTR_WDUMMY)
- oldx--;
- if(term.line[term.c.y][curx].mode & ATTR_WDUMMY)
- curx--;
-
- memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ);
-
- /* remove the old cursor */
- sl = utf8len(term.line[oldy][oldx].c);
- width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1;
- xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx,
- oldy, width, sl);
-
- if(IS_SET(MODE_HIDE))
- return;
-
- /* draw the new one */
- if(xw.state & WIN_FOCUSED) {
- switch (xw.cursor) {
- case 0: /* Blinking Block */
- case 1: /* Blinking Block (Default) */
- case 2: /* Steady Block */
- if(IS_SET(MODE_REVERSE)) {
- g.mode |= ATTR_REVERSE;
- g.fg = defaultcs;
- g.bg = defaultfg;
- }
-
- sl = utf8len(g.c);
- width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\
- ? 2 : 1;
- xdraws(g.c, g, term.c.x, term.c.y, width, sl);
- break;
- case 3: /* Blinking Underline */
- case 4: /* Steady Underline */
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + curx * xw.cw,
- borderpx + (term.c.y + 1) * xw.ch - cursorthickness,
- xw.cw, cursorthickness);
- break;
- case 5: /* Blinking bar */
- case 6: /* Steady bar */
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + curx * xw.cw,
- borderpx + term.c.y * xw.ch,
- cursorthickness, xw.ch);
- break;
- }
- } else {
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + curx * xw.cw,
- borderpx + term.c.y * xw.ch,
- xw.cw - 1, 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + curx * xw.cw,
- borderpx + term.c.y * xw.ch,
- 1, xw.ch - 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + (curx + 1) * xw.cw - 1,
- borderpx + term.c.y * xw.ch,
- 1, xw.ch - 1);
- XftDrawRect(xw.draw, &dc.col[defaultcs],
- borderpx + curx * xw.cw,
- borderpx + (term.c.y + 1) * xw.ch - 1,
- xw.cw, 1);
- }
- oldx = curx, oldy = term.c.y;