--- rxvt-unicode/src/rxvtfont.C 2011/01/07 21:17:08 1.173 +++ rxvt-unicode/src/rxvtfont.C 2021/06/17 00:49:20 1.200 @@ -1,12 +1,12 @@ /*----------------------------------------------------------------------* * File: rxvtfont.C *----------------------------------------------------------------------* - * Copyright (c) 2003-2008 Marc Lehmann + * Copyright (c) 2003-2008 Marc Lehmann * - original version. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -24,7 +24,7 @@ #include "rxvtutil.h" #include "rxvtfont.h" -#include +#include #include @@ -134,7 +134,6 @@ # endif #endif - { CS_UNICODE, "-*-lucidatypewriter-*-*-*-*-*-*-*-*-m-*-iso10646-1" }, //{ CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" }, // this gem of a font has actual dotted circles within the combining character glyphs. #if XFT { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false:autohint=true" }, @@ -215,7 +214,7 @@ ///////////////////////////////////////////////////////////////////////////// rxvt_font::rxvt_font () -: name(0), width(rxvt_fontprop::unset), height(rxvt_fontprop::unset) +: name(0), width(rxvt_fontprop::unset), height(rxvt_fontprop::unset), can_compose(false) { } @@ -242,8 +241,8 @@ #if XFT Picture dst; -# ifdef HAVE_BG_PIXMAP - if (term->bgPixmap.pixmap +# ifdef HAVE_IMG + if (term->bg_img && !term->pix_colors[color].is_opaque () && ((dst = XftDrawPicture (d)))) { @@ -265,7 +264,8 @@ ///////////////////////////////////////////////////////////////////////////// -struct rxvt_font_default : rxvt_font { +struct rxvt_font_default : rxvt_font +{ struct rxvt_fontset *fs; rxvt_font_default (rxvt_fontset *fs) @@ -347,15 +347,15 @@ while (len) { -#if ENABLE_COMBINING - compose_char *cc; -#endif const text_t *tp = text; text_t t = *tp; while (++text, --len && *text == NOCHAR) ; +#if ENABLE_COMBINING + compose_char *cc; +#endif int width = text - tp; int fwidth = term->fwidth * width; @@ -444,10 +444,32 @@ ; #endif #if ENABLE_COMBINING - else if (IS_COMPOSE (t) && (cc = rxvt_composite[t])) + else if (IS_COMPOSE (t) && rxvt_composite[t]) { min_it (width, 2); // we only support wcwidth up to 2 + #if NOT_YET + vector chrs; + chrs.reserve (rxvt_composite.expand (t)); + rxvt_composite.expand (t, &chrs[0]); + + while (!chrs.empty ()) + { + rxvt_font *f1 = fs->find_font_idx (chrs[0]) + + int i = 0; + while (i < chrs.size () - 1 + && f1->can_combine + && f1->has-char (chrs[i + 1], careful) + && !careful + ++i; + + (*fs)[f1]->draw (d, x, y, &chrs[0], width, fg, bg); + chrs.erase (&chrs[0], &chrs[i]); + } + #endif + + #if 1 text_t chrs[2]; chrs [1] = NOCHAR; @@ -467,6 +489,7 @@ f2->draw (d, x, y, chrs, width, fg, Color_none); } + #endif } #endif else @@ -477,6 +500,15 @@ case NOCHAR: break; + /* + * If the base font does not support variation selectors, treat them as ZWC. + * a point could be made to do this for all wcwidth == 0 characters, but I + * decided against that until more data is available. + */ + case 0xfe00: case 0xfe01: case 0xfe02: case 0xfe03: case 0xfe04: case 0xfe05: case 0xfe06: case 0xfe07: + case 0xfe08: case 0xfe09: case 0xfe0a: case 0xfe0b: case 0xfe0c: case 0xfe0d: case 0xfe0e: case 0xfe0f: + break; + default: XDrawRectangle (disp, d, gc, x + 2, y + 2, fwidth - 4, term->fheight - 4); @@ -486,7 +518,8 @@ } } -struct rxvt_font_overflow : rxvt_font { +struct rxvt_font_overflow : rxvt_font +{ struct rxvt_fontset *fs; rxvt_font_overflow (rxvt_fontset *fs) @@ -526,19 +559,24 @@ const text_t *text, int len, int fg, int bg) { - while (len--) + while (len) { int fid = fs->find_font_idx (*text); - (*fs)[fid]->draw (d, x, y, text, 1, fg, bg); - ++text; - x += term->fwidth; + int w = 1; + while (w < len && text[w] == NOCHAR) + w++; + (*fs)[fid]->draw (d, x, y, text, w, fg, bg); + text += w; + len -= w; + x += term->fwidth * w; } } }; ///////////////////////////////////////////////////////////////////////////// -struct rxvt_font_x11 : rxvt_font { +struct rxvt_font_x11 : rxvt_font +{ rxvt_font_x11 () { f = 0; } void clear (); @@ -815,10 +853,10 @@ // this loop only iterates when the guessed font-size is too small for (;;) { - font_weight *best = fonts + count - 1; + font_weight *best = fonts; - for (font_weight *w = best; w-- > fonts; ) - if (w->diff <= best->diff) + for (font_weight *w = fonts + 1; w < fonts + count; w++) + if (w->diff < best->diff) best = w; if (!best->name @@ -923,7 +961,7 @@ width = 1; - for (uint16_t *t = extent_test_chars + ARRAY_LENGTH(extent_test_chars); t-- > extent_test_chars; ) + for (uint16_t *t = extent_test_chars; t < extent_test_chars + ecb_array_length (extent_test_chars); t++) { if (FROM_UNICODE (cs, *t) == NOCHAR) continue; @@ -933,7 +971,8 @@ if (!has_char (*t, &prop, careful)) continue; - XChar2b ch = { *t >> 8, *t }; + // the casts are needed in C++11 (see 8.5.1) + XChar2b ch = { (unsigned char)(*t >> 8), (unsigned char)*t }; XCharStruct g; int dir_ret, asc_ret, des_ret; @@ -969,6 +1008,8 @@ bool rxvt_font_x11::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const { + careful = false; + uint32_t ch = FROM_UNICODE (cs, unicode); if (ch == NOCHAR) @@ -1041,7 +1082,8 @@ bool slow = this->slow || width != term->fwidth - || height != term->fheight; + || height != term->fheight + || ascent != f->ascent; int base = ascent; // sorry, incorrect: term->fbase; @@ -1119,8 +1161,13 @@ #if XFT -struct rxvt_font_xft : rxvt_font { - rxvt_font_xft () { f = 0; } +struct rxvt_font_xft : rxvt_font +{ + rxvt_font_xft () + { + can_compose = true; + f = 0; + } void clear (); @@ -1220,10 +1267,12 @@ for (;;) { - f = XftFontOpenPattern (disp, FcPatternDuplicate (match)); + p = FcPatternDuplicate (match); + f = XftFontOpenPattern (disp, p); if (!f) { + FcPatternDestroy (p); success = false; break; } @@ -1241,7 +1290,7 @@ int glheight = height; - for (uint16_t *t = extent_test_chars + ARRAY_LENGTH(extent_test_chars); t-- > extent_test_chars; ) + for (uint16_t *t = extent_test_chars; t < extent_test_chars + ecb_array_length (extent_test_chars); t++) { FcChar16 ch = *t; @@ -1403,25 +1452,25 @@ { rxvt_drawable &d2 = d.screen->scratch_drawable (w, h); -#ifdef HAVE_BG_PIXMAP +#ifdef HAVE_IMG Picture dst = 0; // the only assignment is done conditionally in the following if condition - if (term->bgPixmap.pixmap + if (term->bg_img && (bg == Color_transparent || bg == Color_bg || (bg >= 0 && !term->pix_colors[bg].is_opaque () && ((dst = XftDrawPicture (d2)))))) { int src_x = x, src_y = y; - if (term->bgPixmap.flags & bgPixmap_t::isTransparent) + if (term->bg_flags & rxvt_term::BG_IS_TRANSPARENT) { src_x += term->window_vt_x; src_y += term->window_vt_y; } - if (term->bgPixmap.pmap_width >= src_x + w - && term->bgPixmap.pmap_height >= src_y + h) + if (term->bg_img->w >= src_x + w + && term->bg_img->h >= src_y + h) { - XCopyArea (disp, term->bgPixmap.pixmap, d2, gc, + XCopyArea (disp, term->bg_img->pm, d2, gc, src_x, src_y, w, h, 0, 0); } else @@ -1429,7 +1478,7 @@ XGCValues gcv; gcv.fill_style = FillTiled; - gcv.tile = term->bgPixmap.pixmap; + gcv.tile = term->bg_img->pm; gcv.ts_x_origin = -src_x; gcv.ts_y_origin = -src_y; @@ -1599,7 +1648,7 @@ rxvt_warn ("unknown parameter '%s' in font specification, skipping.\n", spec); desc++; - while (*desc <= ' ') desc++; + while (*desc <= ' ' && *desc) desc++; } end = strchr (desc, ','); @@ -1727,6 +1776,7 @@ // TODO: this is a real resource hog, xft takes ages(?) #if XFT && USE_SLOW_LOOKUP // grab the first xft font that seems suitable + // TOOD: should go first for cellchar (spacing 110) then mono, then else FcPattern *p = FcPatternCreate (); FcCharSet *s = FcCharSetCreate (); @@ -1780,7 +1830,7 @@ if (!fmap[hi]) { - fmap[hi] = (pagemap *)new pagemap; + fmap[hi] = new pagemap; memset (fmap[hi], 0xff, sizeof (pagemap)); }