Hi,
I have made a patch on xterm so that, it can accept one more option /
resource, to utilize two fonts when using xft.
Originally, -fa option will make xterm to use xft instead of XFontSet,
but however, in most cases, this option is broken, as most CJK TTF fonts
can't have good (acceptable) monospaced appearance. Hence, I add one
more option '-fd' to accpet another font for 'double width' char.
Regards,
Zarick Lau
diff -u xterm/charproc.c xterm-new/charproc.c
--- xterm/charproc.c 2003-11-28 08:49:17.000000000 +0800
+++ xterm-new/charproc.c 2003-12-17 14:43:24.000000000 +0800
@@ -625,6 +625,7 @@
#ifdef XRENDERFONT
Ires(XtNfaceSize, XtCFaceSize, misc.face_size, DEFFACESIZE),
Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME),
+ Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME),
#endif
};
@@ -4948,6 +4949,8 @@
#ifdef XRENDERFONT
wnew->screen.renderFont = 0;
wnew->screen.renderFontBold = 0;
+ wnew->screen.renderFontWide = 0;
+ wnew->screen.renderFontWideBold = 0;
wnew->screen.renderDraw = 0;
#endif
diff -u xterm/fontutils.c xterm-new/fontutils.c
--- xterm/fontutils.c 2003-10-29 07:11:58.000000000 +0800
+++ xterm-new/fontutils.c 2003-12-22 12:06:33.000000000 +0800
@@ -1130,6 +1130,27 @@
if (!screen->renderFontBold && match)
XftPatternDestroy(match);
+ if (!screen->renderFontWide && term->misc.face_wide_name) {
+ screen->renderFontWide = XftFontOpen (dpy, DefaultScreen (dpy),
+ XFT_FAMILY,
+ XftTypeString,
+ term->misc.face_wide_name,
+ XFT_PIXEL_SIZE,
+ XftTypeInteger,
+ screen->renderFont->max_advance_width * 2,
+ (void *) 0);
+ screen->renderFontWideBold = NULL;
+ }
+ else {
+ screen->renderFontWide = XftFontOpen (dpy, DefaultScreen (dpy),
+ XFT_FAMILY, XftTypeString, "mono",
+ XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD,
+ XFT_PIXEL_SIZE, XftTypeInteger,
+ screen->renderFont->max_advance_width * 2,
+ (void *) 0);
+ screen->renderFontWideBold = NULL;
+ }
+
/*
* FIXME: just assume that the corresponding font has no graphics
* characters.
diff -u xterm/main.c xterm-new/main.c
--- xterm/main.c 2003-11-25 09:54:43.000000000 +0800
+++ xterm-new/main.c 2003-12-17 14:49:58.000000000 +0800
@@ -778,6 +778,7 @@
#endif /* NO_ACTIVE_ICON */
#ifdef XRENDERFONT
{"-fa", "*faceName", XrmoptionSepArg, (caddr_t) NULL},
+{"-fd", "*faceNameDoublesize", XrmoptionSepArg, (caddr_t) NULL},
{"-fs", "*faceSize", XrmoptionSepArg, (caddr_t) NULL},
#endif
#if OPT_WIDE_CHARS
@@ -925,6 +926,7 @@
{ "-/+fbx", "turn off/on linedrawing characters"},
#ifdef XRENDERFONT
{ "-fa pattern", "FreeType font-selection pattern" },
+{ "-fd pattern", "FreeType Doublesize font-selection pattern" },
{ "-fs size", "FreeType font-size" },
#endif
#if OPT_WIDE_CHARS
diff -u xterm/os2main.c xterm-new/os2main.c
--- xterm/os2main.c 2003-05-22 06:59:13.000000000 +0800
+++ xterm-new/os2main.c 2003-12-17 14:48:48.000000000 +0800
@@ -344,6 +344,7 @@
#endif /* NO_ACTIVE_ICON */
#ifdef XRENDERFONT
{"-fa", "*faceName", XrmoptionSepArg, (caddr_t) NULL},
+{"-fd", "*faceNameDoublesize", XrmoptionSepArg, (caddr_t) NULL},
{"-fs", "*faceSize", XrmoptionSepArg, (caddr_t) NULL},
#endif
#if OPT_WIDE_CHARS
@@ -484,6 +485,7 @@
{ "-/+fbx", "turn off/on linedrawing characters"},
#ifdef XRENDERFONT
{ "-fa pattern", "FreeType font-selection pattern" },
+{ "-fd pattern", "FreeType Doublesize font-selection pattern" },
{ "-fs size", "FreeType font-size" },
#endif
#if OPT_WIDE_CHARS
diff -u xterm/ptyx.h xterm-new/ptyx.h
--- xterm/ptyx.h 2003-10-27 09:07:57.000000000 +0800
+++ xterm-new/ptyx.h 2003-12-17 10:02:29.000000000 +0800
@@ -1376,6 +1376,8 @@
#ifdef XRENDERFONT
XftFont *renderFont;
XftFont *renderFontBold;
+ XftFont *renderFontWide;
+ XftFont *renderFontWideBold;
XftDraw *renderDraw;
#endif
#if OPT_INPUT_METHOD
@@ -1513,6 +1515,7 @@
#endif
#ifdef XRENDERFONT
char *face_name;
+ char *face_wide_name;
int face_size;
#endif
} Misc;
diff -u xterm/util.c xterm-new/util.c
--- xterm/util.c 2003-10-27 09:07:57.000000000 +0800
+++ xterm-new/util.c 2003-12-22 12:04:34.000000000 +0800
@@ -1411,6 +1411,7 @@
xtermXftDrawString(XftDraw * draw,
XftColor * color,
XftFont * font,
+ XftFont * wfont,
int x,
int y,
PAIRED_CHARS(Char * text, Char * text2),
@@ -1419,28 +1420,60 @@
int *deltax)
{
#if OPT_WIDE_CHARS && defined(HAVE_TYPE_XFTCHARSPEC)
- static XftCharSpec *sbuf;
- static unsigned slen;
int n;
int ncells = 0; /* # of 'half-width' charcells */
+ static XftCharSpec * specs;
+ static int nspecs = 0;
+ XftFont * lastFont = 0;
+ XftFont * currFont = 0;
+ int start = 0;
+ int charWidth;
+ FcChar32 wc;
+
+ if ((int) nspecs < len) {
+ nspecs = (len + 1) * 2;
+ specs = (XftCharSpec *) XtRealloc((char *) specs,
+ nspecs * sizeof(XftCharSpec));
+ }
+
+ if (len == 0 || !(*text || *text2)) {
+ return;
+ }
+
+ if (text2)
+ wc = *text++ | (*text2++ << 8);
+ else
+ wc = *text++;
+
+ specs[0].ucs4 = wc;
+ specs[0].x = x + fwidth * ncells;
+ specs[0].y = y;
+ charWidth = my_wcwidth(wc);
+ lastFont = (charWidth == 2) ? wfont : font;
+ ncells += charWidth;
+ start = 0;
- if ((int) slen < len) {
- slen = (len + 1) * 2;
- sbuf = (XftCharSpec *) XtRealloc((char *) sbuf,
- slen * sizeof(XftCharSpec));
- }
- for (n = 0; n < len; n++) {
- FcChar32 wc;
+ for (n = 1; n < len; n++) {
if (text2)
wc = *text++ | (*text2++ << 8);
else
wc = *text++;
- sbuf[n].ucs4 = wc;
- sbuf[n].x = x + fwidth * ncells;
- ncells += my_wcwidth(wc);
- sbuf[n].y = y;
+ specs[n].ucs4 = wc;
+ if (wc == 0xFFFF)
+ continue;
+ specs[n].x = x + fwidth * ncells;
+ specs[n].y = y;
+ charWidth = my_wcwidth(wc);
+ currFont = (charWidth == 2) ? wfont : font;
+ ncells += charWidth;
+ if (lastFont != currFont) {
+ XftDrawCharSpec (draw, color, lastFont, specs + start, n - start);
+ start = n;
+ lastFont = currFont;
+ }
}
- XftDrawCharSpec(draw, color, font, sbuf, len);
+ XftDrawCharSpec (draw, color, lastFont, specs + start, n - start);
+
if (deltax)
*deltax = ncells * fwidth;
#else
@@ -1519,7 +1552,7 @@
#ifdef XRENDERFONT
if (screen->renderFont) {
Display *dpy = screen->display;
- XftFont *font;
+ XftFont *font, *wfont;
XGCValues values;
if (!screen->renderDraw) {
@@ -1533,10 +1566,14 @@
DefaultColormap(dpy, scr));
}
if ((flags & (BOLD | BLINK))
- && screen->renderFontBold)
+ && screen->renderFontBold) {
font = screen->renderFontBold;
- else
+ wfont = screen->renderFontWideBold;
+ }
+ else {
font = screen->renderFont;
+ wfont = screen->renderFontWide;
+ }
XGetGCValues(dpy, gc, GCForeground | GCBackground, &values);
if (!(flags & NOBACKGROUND))
XftDrawRect(screen->renderDraw,
@@ -1571,7 +1608,7 @@
if (last > first) {
xtermXftDrawString(screen->renderDraw,
getColor(values.foreground),
- font, curX, y,
+ font, wfont, curX, y,
PAIRED_CHARS(text + first,
text2 + first),
last - first, FontWidth(screen),
@@ -1593,7 +1630,7 @@
if (last > first) {
xtermXftDrawString(screen->renderDraw,
getColor(values.foreground),
- font, curX, y,
+ font, wfont, curX, y,
PAIRED_CHARS(text + first, text2 + first),
last - first, FontWidth(screen), NULL);
}
@@ -1602,7 +1639,7 @@
{
xtermXftDrawString(screen->renderDraw,
getColor(values.foreground),
- font, x, y, PAIRED_CHARS(text, text2),
+ font, wfont, x, y, PAIRED_CHARS(text, text2),
len, FontWidth(screen), NULL);
}
diff -u xterm/xterm.h xterm-new/xterm.h
--- xterm/xterm.h 2003-12-19 05:12:16.000000000 +0800
+++ xterm-new/xterm.h 2003-12-17 14:44:14.000000000 +0800
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/xterm/xterm.h,v 3.93 2003/12/18 21:12:16 dickey Exp $ */
+/* $XFree86: xc/programs/xterm/xterm.h,v 3.93 2003/10/27 01:07:58 dickey Exp $ */
/************************************************************
@@ -317,6 +317,7 @@
#define XtNeightBitInput "eightBitInput"
#define XtNeightBitOutput "eightBitOutput"
#define XtNfaceName "faceName"
+#define XtNfaceNameDoublesize "faceNameDoublesize"
#define XtNfaceSize "faceSize"
#define XtNfont1 "font1"
#define XtNfont2 "font2"
@@ -433,6 +434,7 @@
#define XtCEightBitInput "EightBitInput"
#define XtCEightBitOutput "EightBitOutput"
#define XtCFaceName "FaceName"
+#define XtCFaceNameDoublesize "FaceNameDoublesize"
#define XtCFaceSize "FaceSize"
#define XtCFont1 "Font1"
#define XtCFont2 "Font2"
@@ -775,7 +777,7 @@
(Char *)(((long)SCRN_BUF_FLAGS(screen, row + screen->topline) | LINEWRAPPED))
#define ScrnTstWrapped(screen, row) \
- ((row + screen->topline) >= 0 && ((long)SCRN_BUF_FLAGS(screen, row + screen->topline) & LINEWRAPPED) != 0)
+ (((long)SCRN_BUF_FLAGS(screen, row + screen->topline) & LINEWRAPPED) != 0)
/* scrollbar.c */
extern void DoResizeScreen (XtermWidget xw);