diff -uP xft-2.1.1-orig/makebold.c xft-2.1.1-new/makebold.c
--- xft-2.1.1-orig/makebold.c	Thu Jan  1 09:00:00 1970
+++ xft-2.1.1-new/makebold.c	Mon Apr  5 01:58:02 2004
@@ -0,0 +1,520 @@
+
+#ifndef MIN
+#define MIN( x, y ) (((x) > (y)) ? (y) : (x))
+#endif
+
+typedef struct Target_Pixel_
+{
+    FT_Byte	rate[2];
+    FT_Long	pos[2];
+
+} T_Pixel;
+
+
+static void
+BitmapDownscale (FT_Byte	*buffer,
+		 FT_Vector	*origin,
+		 short		*bearingX,
+		 short		*bearingY,
+		 int		x_size,
+		 int		y_size,
+		 FT_Fixed	x_scale,
+		 FT_Fixed	y_scale,
+		 int		hmul,
+		 int		vmul)
+{
+    FT_Byte	*mem_tmp = 0;
+    T_Pixel	*x_tpx = 0;
+    T_Pixel	*y_tpx = 0;
+    long	mem_size = 0;
+    int		vertical;
+
+
+    if (x_scale >= 0x10000L && y_scale >= 0x10000L)
+	return;
+
+    x_size *= hmul;
+    y_size *= vmul;
+
+    mem_size = (x_size + y_size) * sizeof(T_Pixel) + (x_size * y_size);
+    mem_tmp = (FT_Byte *) malloc (mem_size);
+    if (!mem_tmp)
+	return;
+
+    memset (mem_tmp, 0, mem_size);
+
+    x_tpx = (T_Pixel *)mem_tmp;
+    y_tpx = x_tpx + x_size;
+
+
+    for (vertical = 0; vertical < 2; vertical++ )
+    {
+	FT_F26Dot6  size  = vertical ? y_size  : x_size;
+	FT_Fixed    scale = vertical ? y_scale : x_scale;
+	T_Pixel	    *tpx  = vertical ? y_tpx   : x_tpx;
+	int	    pitch = vertical ? x_size  : 1;
+	int	    mul   = vertical ? vmul    : hmul;
+	FT_F26Dot6  z, z0, z1, d0, d1, origin0, origin1;
+
+
+	origin0 = vertical ? origin->y : origin->x;
+	origin1 = origin0 - ((FT_MulFix (-origin0, scale) + origin0) & -64);
+
+	if ( vertical )
+	    *bearingY += (origin1 - origin0) >> 6;
+	else
+	    *bearingX -= (origin1 - origin0) >> 6;
+
+	if (scale >= 0x10000L)
+	{
+	    for (z = 0; z < size; z++, tpx++) {
+		tpx->rate[0] = 64;
+		tpx->pos[0]  = z * pitch;
+	    }
+	    continue;
+	}
+
+	size <<= 6;
+	origin0 *= mul;
+	origin1 *= mul;
+
+	z0 = FT_MulFix (-origin0, scale) + origin1;
+	d0 = z0 & 63;
+
+	for (z = 64; z <= size; z += 64, tpx++, z0 = z1, d0 = d1)
+	{
+	    z1 = FT_MulFix (z - origin0, scale) + origin1;
+	    d1 = z1 & 63;
+
+	    if (d1 > d0 || d1 == 0) {
+		if (z0 >= 0 && z0 < size) {
+		    tpx->rate[0] = z1 - z0;
+		    tpx->pos[0]  = (z0 >> 6) * pitch;
+		}
+	    } else {
+		if (z0 >= 0 && z0 < size) {
+		    tpx->rate[0] = 64 - d0;
+		    tpx->pos[0]  = (z0 >> 6) * pitch;
+		}
+
+		if (z1 >= 0 && z1 < size) {
+		    tpx->rate[1] = d1;
+		    tpx->pos[1]  = (z1 >> 6) * pitch;
+		}
+	    }
+	}
+    }
+
+
+    {
+	FT_Byte	    *src = buffer;
+	FT_Byte	    *dst;
+	FT_Byte	    *buf = mem_tmp + (x_size + y_size) * sizeof(T_Pixel);
+	long	    g0, g1, g2, g3, g4;
+	int	    x, y;
+
+
+	for (y = 0; y < y_size; y++, y_tpx++)
+	{
+	    x_tpx = (T_Pixel *)mem_tmp;
+
+	    for (x = 0; x < x_size; x++, x_tpx++)
+	    {
+		g0 = *src++;
+		g1 = (g0 * x_tpx->rate[0] * y_tpx->rate[0] + 0xFFF) >> 12;
+		g2 = (g0 * x_tpx->rate[0] * y_tpx->rate[1] + 0xFFF) >> 12;
+		g3 = (g0 * x_tpx->rate[1] * y_tpx->rate[0] + 0xFFF) >> 12;
+		g4 = (g0 * x_tpx->rate[1] * y_tpx->rate[1] + 0xFFF) >> 12;
+
+		if (g1 > 0) {
+		    dst  = buf + x_tpx->pos[0] + y_tpx->pos[0];
+		    g1  += *dst;
+		    *dst = (FT_Byte) MIN(g1, 255);
+		}
+
+		if (g2 > 0) {
+		    dst  = buf + x_tpx->pos[0] + y_tpx->pos[1];
+		    g2  += *dst;
+		    *dst = (FT_Byte) MIN(g2, 255);
+		}
+
+		if (g3 > 0) {
+		    dst  = buf + x_tpx->pos[1] + y_tpx->pos[0];
+		    g3  += *dst;
+		    *dst = (FT_Byte) MIN(g3, 255);
+		}
+
+		if (g4 > 0) {
+		    dst  = buf + x_tpx->pos[1] + y_tpx->pos[1];
+		    g4  += *dst;
+		    *dst = (FT_Byte) MIN(g4, 255);
+		}
+	    }
+	}
+
+	memcpy (buffer, buf, x_size * y_size);
+    }
+
+    free (mem_tmp);
+}
+
+
+static void
+MakeBoldBitmap (XftFont	    *pub,
+		FT_Bitmap   *bitmap,
+		short	    *left_bearing,
+		short	    *top_bearing,
+		FT_F26Dot6  *advanceX,
+		FT_F26Dot6  *advanceY,
+		int	    *max_bufSize)
+{
+    XftFontInt	*font = (XftFontInt *) pub;
+    FT_Byte	*buffer = bitmap->buffer;
+    FT_Byte	*buf_tmp = 0;
+    FT_F26Dot6	x_volume = font->x_volume * 2;
+    FT_F26Dot6	y_volume = font->y_volume * 2;
+    FcBool	monochrome = FcFalse;
+    FT_F26Dot6	dx, dy;
+    int		width, rows, pitch, hmul, vmul;
+
+
+    if (!font->info.antialias || bitmap->pixel_mode == ft_pixel_mode_mono)
+	monochrome = FcTrue;
+
+
+    if (y_volume > x_volume * 3 / 4)
+	y_volume = x_volume * 3 / 4;
+
+    if (monochrome) {
+	if (x_volume < 44)
+	    x_volume = 44;
+	if (font->info.xsize < 20*64)
+	    y_volume = 0;
+    } else {
+	if (x_volume < 36)
+	    x_volume = 36;
+    }
+
+
+    hmul = vmul = 1;
+    if (font->info.antialias)
+    {
+	switch (font->info.rgba) {
+	case FC_RGBA_RGB:
+	case FC_RGBA_BGR:
+	    hmul = 3;
+	    break;
+	case FC_RGBA_VRGB:
+	case FC_RGBA_VBGR:
+	    vmul = 3;
+	    break;
+	}
+    }
+
+
+    dx = (x_volume + 63) >> 6;
+    dy = (y_volume + 63) >> 6;
+    width = bitmap->width + dx * hmul;
+    rows  = bitmap->rows  + dy * vmul;
+
+    *top_bearing += dy;
+    dx = dx / 2;
+    dy = ( dy + 1 ) / 2;
+
+    if (*left_bearing > 0 || *left_bearing < -width)
+      width += hmul;
+
+    if (*top_bearing < 0 || *top_bearing > rows)
+      rows += vmul;
+
+
+    pitch   = width;
+    buf_tmp = (FT_Byte *) malloc ((long)pitch * rows);
+    if (!buf_tmp)
+	return;
+
+    memset (buf_tmp, 0, (long)pitch * rows);
+
+    dx *= hmul;
+    dy *= vmul;
+
+    if (font->info.antialias)
+    {
+	int x, y;
+	int w = bitmap->width;
+	int r = bitmap->rows;
+	int offset = dx + dy * pitch;
+
+	for (y = 0; y < r; y++) {
+	    FT_Byte *src = buffer + y * bitmap->pitch;
+	    FT_Byte *dst = buf_tmp + offset + y * pitch;
+
+	    for (x = 0; x < w; x++)
+		*dst++ = *src++;
+	}
+    }
+    else
+    {
+	int x, y, s;
+	int w1 = bitmap->width >> 3;
+	int w2 = 8 - (bitmap->width - w1 * 8);
+	int r  = bitmap->rows;
+	int offset = dx + dy * pitch;
+
+	for (y = 0; y < r; y++) {
+	    FT_Byte *src = buffer + y * bitmap->pitch;
+	    FT_Byte *dst = buf_tmp + offset + y * pitch;
+
+	    for (x = 0; x < w1; x++) {
+		FT_Byte b = *src++;
+
+		for (s = 7; s >= 0; s--)
+		    *dst++ = ((b >> s) & 1)? 0xff : 0x00;
+	    }
+
+	    if (w2 < 8) {
+		FT_Byte b = *src;
+
+		for (s = 7; s >= w2; s--)
+		    *dst++ = ((b >> s) & 1)? 0xff : 0x00;
+	    }
+	}
+    }
+
+    {
+	int	    rows1  = bitmap->rows;
+	int	    width1 = bitmap->width;
+	FT_F26Dot6  x_volume1 = x_volume;
+	FT_F26Dot6  y_volume1 = y_volume;
+	int	    count = hmul;
+	int	    direction, rotation; /* 0=right: 1=up: 2=left: 3=down */
+
+
+	direction = (((x_volume1 + 63) >> 6) & 1) ? 0 :  2;
+	rotation  = (((y_volume1 + 63) >> 6) & 1) ? 1 : -1;
+
+	if (direction == 2)
+	    rotation = -rotation;
+
+	x_volume1 *= hmul;
+	y_volume1 *= vmul;
+
+
+	while (x_volume1 > 0 || y_volume1 > 0)
+	{
+	    FT_Byte*    line;
+	    FT_Byte*    pos;
+	    int		g0, g1, g2;
+	    int		i, j, count1, count2, pitch1, pitch2;
+	    FT_F26Dot6  volume;
+
+
+	    if (direction & 1)
+	    {
+		if (y_volume1 <= 0)
+		    goto Next;
+
+		volume = (y_volume1 >= 64) ? 255 : y_volume1 * 4;
+		line   = buf_tmp + dx +
+			 ((direction == 1) ? 0 : (rows - 1) * pitch);
+		count1 = width1;
+		count2 = rows;
+		pitch1 = 1;
+		pitch2 = (direction == 1) ? pitch : -pitch;
+
+		rows1++;
+		y_volume1 -= 64;
+		dy -= (direction == 1) ? 1 : 0;
+	    }
+	    else
+	    {
+		if (x_volume1 <= 0)
+		    goto Next;
+
+		volume = (x_volume1 >= 64) ? 255 : x_volume1 * 4;
+		line   = buf_tmp + dy * pitch +
+			 ((direction == 2) ? 0 : width - 1);
+		count1 = rows1;
+		count2 = width;
+		pitch1 = pitch;
+		pitch2 = (direction == 2) ? 1 : -1;
+
+		width1++;
+		x_volume1 -= 64;
+		dx -= (direction == 2) ? 1 : 0;
+	    }
+
+
+	    for (i = 1; i <= count1; i++, line += pitch1)
+	    {
+		pos = line;
+		g0  = 0;
+		g1  = *pos;
+
+		for (j = 1; j <= count2; j++, pos += pitch2)
+		{
+		    g2 = (j == count2) ? 0 : *(pos + pitch2);
+
+		    if (g1 || g2)
+		    {
+			int	gray  = g1;
+			int	diff0 = g1 - g0;
+			int	diff1 = g2 - g1;
+
+
+			if (diff0 > 0 && diff1 < 0)
+			{
+			    if (volume > diff0)
+			    {
+				gray += diff0;
+				g0    = *(pos - pitch2) + volume - diff0;
+
+				*(pos - pitch2) = (FT_Byte) MIN(g0, g1);
+			    }
+			    else
+			    {
+				gray += volume;
+			    }
+
+			    *pos = (FT_Byte) MIN(gray, 255);
+			}
+			else if (diff1 >= 0)
+			{
+			    if ((diff0 = g2 + volume - 255) > 0)
+				gray += diff0;
+
+			    *pos = (FT_Byte) MIN(gray, g2);
+			}
+		    }
+
+		    g0 = g1;
+		    g1 = g2;
+		}
+	    }
+
+	Next:
+	    if (--count == 0)
+	    {
+		direction = (direction + rotation) & 3;
+		count     = (direction & 1) ? vmul : hmul;
+	    }
+	}
+    }
+
+
+    {
+	FT_Fixed    x_scale, y_scale;
+	FT_F26Dot6  xsize = font->info.xsize;
+	FT_F26Dot6  ysize = font->info.ysize;
+	FT_F26Dot6  old_advance = *advanceX;
+	FT_Vector   origin;
+
+
+	if (!font->fixedpitch) {
+	    if (*advanceX > 0 && *advanceX < xsize)
+		*advanceX = FT_MulDiv (*advanceX + x_volume,
+				       xsize, xsize + x_volume);
+
+	    if (monochrome && xsize < 32*64 && *advanceX <= old_advance + 64)
+		*advanceX = old_advance + 64;
+
+	    if (*advanceY > 0 && *advanceY < ysize)
+		*advanceY = FT_MulDiv (*advanceY + y_volume,
+				       ysize, ysize + y_volume);
+	}
+
+	if (monochrome)
+	{
+	    if (xsize < 32*64) x_volume = 0;
+	    if (ysize < 32*64) y_volume = 0;
+	}
+	else
+	{
+	    if (xsize < 20*64) x_volume /= 2;
+	    if (ysize < 20*64) y_volume /= 2;
+	}
+
+	if (font->fixedpitch || old_advance >= xsize)
+	    xsize = old_advance;
+
+	x_scale = FT_DivFix (xsize, xsize + x_volume);
+	y_scale = FT_DivFix (ysize, ysize + y_volume);
+	origin.x = -(*left_bearing << 6);
+	origin.y = *top_bearing << 6;
+
+	BitmapDownscale (buf_tmp, &origin,
+			 left_bearing, top_bearing,
+			 width / hmul, rows / vmul,
+			 x_scale, y_scale, hmul, vmul);
+    }
+
+
+    {
+	long size, pitch1;
+
+
+	if (font->info.antialias)
+	    pitch1 = (width + 3) & ~3;
+	else
+	    pitch1 = ((width + 31) & ~31) >> 3;
+
+	size = pitch1 * rows;
+
+	if (size > *max_bufSize) {
+	    buffer = (FT_Byte *) malloc (size);
+	    if (!buffer)
+		goto Exit;
+
+	    bitmap->buffer = buffer;
+	    *max_bufSize = (int)size;
+	}
+
+	bitmap->pitch = pitch1;
+	bitmap->width = width;
+	bitmap->rows  = rows;
+	memset (buffer, 0, size);
+    }
+
+
+    if (font->info.antialias)
+    {
+	int x, y;
+
+    
+	for (y = 0; y < rows; y++) {
+	    FT_Byte *src = buf_tmp + y * pitch;
+	    FT_Byte *dst = buffer + y * bitmap->pitch;
+
+	    for (x = 0; x < width; x++)
+		*dst++ = *src++;
+	}
+    }
+    else
+    {
+	int	x, y, s;
+	int	w1 = width >> 3;
+	int	w2 = 8 - (width & 7);
+	FT_Byte b;
+
+	for (y = 0; y < rows; y++) {
+	    FT_Byte *src = buf_tmp + y * pitch;
+	    FT_Byte *dst = buffer + y * bitmap->pitch;
+
+	    for (x = 0; x < w1; x++) {
+		for (b = 0, s = 7; s >= 0; s--)
+		    b |= ((*src++ >= 0x80) ? (1 << s) : 0);
+		*dst++ = b;
+	    }
+
+	    if (w2 < 8) {
+		for (b = 0, s = 7; s >= w2; s--)
+		    b |= ((*src++ >= 0x80) ? (1 << s) : 0);
+		*dst = b;
+	    }
+	}
+    }
+
+Exit:
+    free (buf_tmp);
+}
+
diff -uP xft-2.1.1-orig/xftfreetype.c xft-2.1.1-new/xftfreetype.c
--- xft-2.1.1-orig/xftfreetype.c	Thu Apr 17 13:29:24 2003
+++ xft-2.1.1-new/xftfreetype.c	Tue Sep 23 05:15:18 2003
@@ -28,6 +28,8 @@
 #include "xftint.h"
 #include <X11/Xlibint.h>
 
+#include <freetype/tttables.h>
+
 FT_Library  _XftFTlibrary;
 
 #define FT_Matrix_Equal(a,b)	((a)->xx == (b)->xx && \
@@ -329,6 +331,7 @@
     FcChar32	    hash, *hashp;
     FT_Face	    face;
     int		    nhash;
+    FcBool	    accept_bitmap;
 
     if (!info)
 	return FcFalse;
@@ -451,8 +454,19 @@
      */
     fi->load_flags = FT_LOAD_DEFAULT;
 
-    /* disable bitmaps when anti-aliasing or transforming glyphs */
-    if (fi->antialias || fi->transform)
+    /* disable bitmaps embedded in scalable fonts */
+    /* when not requested or transforming glyphs  */
+    switch (FcPatternGetBool (pattern, "embeddedbitmap", 0, &accept_bitmap)) {
+    case FcResultNoMatch:
+	accept_bitmap = FcFalse;
+	break;
+    case FcResultMatch:
+	break;
+    default:
+	goto bail1;
+    }
+
+    if ((!accept_bitmap && fi->antialias) || fi->transform)
 	fi->load_flags |= FT_LOAD_NO_BITMAP;
     
     /* disable hinting if requested */
@@ -553,6 +567,19 @@
     }
 
     /*
+     * Check for weight
+     */
+    switch (FcPatternGetInteger (pattern, FC_WEIGHT, 0, &fi->weight)) {
+    case FcResultNoMatch:
+	fi->weight = FC_WEIGHT_MEDIUM;
+	break;
+    case FcResultMatch:
+	break;
+    default:
+	goto bail1;
+    }
+
+    /*
      * Step over hash value in the structure
      */
     hash = 0;
@@ -893,6 +920,61 @@
     font->max_glyph_memory = max_glyph_memory;
     font->use_free_glyphs = info->use_free_glyphs;
     
+    /*
+     * Parameters used to make a faked bold bitmap
+     */
+    font->make_bold = FcFalse;
+    if (fi->weight > FC_WEIGHT_MEDIUM &&
+	(face->style_flags & FT_STYLE_FLAG_BOLD) == 0) {
+	if (fi->matrix.xy == 0 || fi->matrix.yx == 0)
+	    font->make_bold = FcTrue;
+    }
+
+    font->x_volume = font->y_volume = 0;
+    font->fixedpitch = (fi->spacing == FC_PROPORTIONAL) ? FcFalse : FcTrue;
+
+    if (font->make_bold) {
+	TT_OS2	    *os2 = (TT_OS2 *)FT_Get_Sfnt_Table (face, ft_sfnt_os2);
+	FT_F26Dot6  xsize = FT_MulFix (fi->xsize, fi->matrix.xx);
+	FT_F26Dot6  ysize = FT_MulFix (fi->ysize, fi->matrix.yy);
+
+	font->x_volume = xsize/80;
+	font->y_volume = ysize/80;
+
+	if (os2) {
+	    FT_Byte	bSerif = os2->panose[1];
+	    FT_Byte	bWeight = os2->panose[2];
+	    FT_Byte	bProportion = os2->panose[3];
+
+	    if (bSerif >= 2 && bSerif <= 10) {
+		font->x_volume = xsize/64;
+		font->y_volume = ysize/256;
+	    }
+
+	    if (bWeight >= 2 && bWeight != 6 && bWeight <= 11) {
+	        font->x_volume = font->x_volume * 10 / (bWeight + 4);
+	        font->y_volume = font->y_volume * 10 / (bWeight + 4);
+	    }
+
+	    if (bProportion == 9)
+		font->fixedpitch = FcTrue;
+	}
+
+#if 1
+	if (xsize < 20*64 && font->x_volume < xsize/50) {
+	    font->x_volume = font->x_volume * (40*64 - fi->xsize) / (20*64);
+	    if (font->x_volume > xsize/50)
+		font->x_volume = xsize/50;
+	}
+
+	if (ysize < 20*64 && font->y_volume < ysize/50) {
+	    font->y_volume = font->y_volume * (40*64 - fi->ysize) / (20*64);
+	    if (font->y_volume > ysize/50)
+		font->y_volume = ysize/50;
+	}
+#endif
+    }
+
     _XftUnlockFile (fi->file);
 
     return &font->public;
diff -uP xft-2.1.1-orig/xftglyphs.c xft-2.1.1-new/xftglyphs.c
--- xft-2.1.1-orig/xftglyphs.c	Thu Apr 17 13:29:24 2003
+++ xft-2.1.1-new/xftglyphs.c	Tue Sep 23 04:21:29 2003
@@ -29,6 +29,8 @@
 #include <freetype/ftoutln.h>
 #include <fontconfig/fcfreetype.h>
 
+#include "makebold.c"
+
 static const int    filters[3][3] = {
     /* red */
 #if 0
@@ -309,7 +311,8 @@
 	 * If the glyph is relatively large (> 1% of server memory),
 	 * don't send it until necessary
 	 */
-	if (!need_bitmaps && size > info->max_glyph_memory / 100)
+	if (!need_bitmaps && size > info->max_glyph_memory / 100 &&
+	    !font->make_bold)
 	    continue;
 	
 	/*
@@ -403,6 +406,45 @@
 	    continue;
 	}
 	
+	/*
+	 * Make bold bitmap
+	 */
+	if (font->make_bold) {
+	    ftbit.width = width * hmul;
+	    ftbit.rows = height * vmul;
+	    ftbit.pitch = pitch;
+	    ftbit.buffer = bufBitmap;
+	    xftg->metrics.x = -xftg->metrics.x;
+
+	    if (glyphslot->format == ft_glyph_format_bitmap)
+		ftbit.pixel_mode = glyphslot->bitmap.pixel_mode;
+
+	    MakeBoldBitmap (pub, &ftbit,
+			    &xftg->metrics.x,
+			    &xftg->metrics.y,
+			    &glyphslot->advance.x,
+			    &glyphslot->advance.y, &bufSize);
+
+	    xftg->metrics.width = width = ftbit.width / hmul;
+	    xftg->metrics.height = height = ftbit.rows / vmul;
+	    xftg->metrics.x = -xftg->metrics.x;
+
+	    if (font->info.spacing == FC_PROPORTIONAL) {
+		xftg->metrics.xOff = TRUNC(ROUND(glyphslot->advance.x));
+		xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
+	    }
+
+	    pitch = ftbit.pitch;
+	    size = pitch * height * vmul;
+
+	    if (ftbit.buffer != bufBitmap) {
+		if (bufBitmap != bufLocal)
+		    free (bufBitmap);
+
+		bufBitmap = ftbit.buffer;
+	    }
+	}
+
 	if (XftDebug() & XFT_DBG_GLYPH)
 	{
 	    printf ("glyph %d:\n", (int) glyphindex);
diff -uP xft-2.1.1-orig/xftint.h xft-2.1.1-new/xftint.h
--- xft-2.1.1-orig/xftint.h	Thu Apr 17 13:29:24 2003
+++ xft-2.1.1-new/xftint.h	Mon Sep 22 08:39:52 2003
@@ -116,6 +116,7 @@
     int			spacing;
     FcBool		minspace;
     int			char_width;
+    int			weight;
 };
 
 /*
@@ -152,6 +153,13 @@
     unsigned long	glyph_memory;
     unsigned long	max_glyph_memory;
     FcBool		use_free_glyphs;   /* Use XRenderFreeGlyphs */
+    /*
+     * Parameters used to make a faked bold bitmap
+     */
+    FcBool		make_bold;
+    FT_Pos		x_volume;
+    FT_Pos		y_volume;
+    FcBool		fixedpitch; /* for CJK fixed TrueType fonts */
 } XftFontInt;
 
 typedef enum _XftClipType {
