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);

Reply via email to