static void FVDrawGlyph(GWindow pixmap, FontView *fv, int index, int forcebg ) {
    GRect box, old2;
    int feat_gid;
    SplineChar *sc;
    struct _GImage base;
    GImage gi;
    GClut clut;
    int i,j;
    int em = fv->b.sf->ascent+fv->b.sf->descent;
    int yorg = fv->magnify*(fv->show->ascent);

    i = index / fv->colcnt;
    j = index - i*fv->colcnt;
    i -= fv->rowoff;

    if ( index<fv->b.map->enccount && (fv->b.selected[index] || forcebg)) {
	box.x = j*fv->cbw+1; box.width = fv->cbw-1;
	box.y = i*fv->cbh+fv->lab_height+1; box.height = fv->cbw;
	GDrawFillRect(pixmap,&box,fv->b.selected[index] ? fvselcol : view_bgcol );
    }
    feat_gid = FeatureTrans(fv,index);
    sc = feat_gid!=-1 ? fv->b.sf->glyphs[feat_gid]: NULL;
    if ( !SCWorthOutputting(sc) ) {
	int x = j*fv->cbw+1, xend = x+fv->cbw-2;
	int y = i*fv->cbh+fv->lab_height+1, yend = y+fv->cbw-1;
	GDrawDrawLine(pixmap,x,y,xend,yend,fvemtpyslotfgcol);
	GDrawDrawLine(pixmap,x,yend,xend,y,fvemtpyslotfgcol);
    }
    if ( sc!=NULL ) {
	BDFChar *bdfc;

	if ( fv->show!=NULL && fv->show->piecemeal &&
		feat_gid!=-1 &&
		(feat_gid>=fv->show->glyphcnt || fv->show->glyphs[feat_gid]==NULL) &&
		fv->b.sf->glyphs[feat_gid]!=NULL )
	    BDFPieceMeal(fv->show,feat_gid);

	if ( fv->show!=NULL && feat_gid!=-1 &&
		feat_gid < fv->show->glyphcnt &&
		fv->show->glyphs[feat_gid]==NULL &&
		SCWorthOutputting(fv->b.sf->glyphs[feat_gid]) ) {
	    /* If we have an outline but no bitmap for this slot */
	    box.x = j*fv->cbw+1; box.width = fv->cbw-2;
	    box.y = i*fv->cbh+fv->lab_height+2; box.height = box.width+1;
	    GDrawDrawRect(pixmap,&box,0xff0000);
	    ++box.x; ++box.y; box.width -= 2; box.height -= 2;
	    GDrawDrawRect(pixmap,&box,0xff0000);
/* When reencoding a font we can find times where index>=show->charcnt */
	} else if ( fv->show!=NULL && feat_gid<fv->show->glyphcnt && feat_gid!=-1 &&
		fv->show->glyphs[feat_gid]!=NULL ) {
	    /* If fontview is set to display an embedded bitmap font (not a temporary font, */
	    /* rasterized specially for this purpose), then we can't use it directly, as bitmap */
	    /* glyphs may contain selections and references. So create a temporary copy of */
	    /* the glyph merging all such elements into a single bitmap */
	    bdfc = fv->show->piecemeal ?
		fv->show->glyphs[feat_gid] : BDFGetMergedChar( fv->show->glyphs[feat_gid] );

	    memset(&gi,'\0',sizeof(gi));
	    memset(&base,'\0',sizeof(base));
	    if ( bdfc->byte_data ) {
		gi.u.image = &base;
		base.image_type = it_index;
		if ( !fv->b.selected[index] )
		    base.clut = fv->show->clut;
		else {
		    int bgr=((fvselcol>>16)&0xff), bgg=((fvselcol>>8)&0xff), bgb= (fvselcol&0xff);
		    int fgr=((fvselfgcol>>16)&0xff), fgg=((fvselfgcol>>8)&0xff), fgb= (fvselfgcol&0xff);
		    int i;
		    memset(&clut,'\0',sizeof(clut));
		    base.clut = &clut;
		    clut.clut_len = fv->show->clut->clut_len;
		    for ( i=0; i<clut.clut_len; ++i ) {
			clut.clut[i] =
				COLOR_CREATE( bgr + (i*(fgr-bgr))/(clut.clut_len-1),
						bgg + (i*(fgg-bgg))/(clut.clut_len-1),
						bgb + (i*(fgb-bgb))/(clut.clut_len-1));
		    }
		}
		GDrawSetDither(NULL, false);	/* on 8 bit displays we don't want any dithering */
	    } else {
		memset(&clut,'\0',sizeof(clut));
		gi.u.image = &base;
		base.image_type = it_mono;
		base.clut = &clut;
		clut.clut_len = 2;
		clut.clut[0] = fv->b.selected[index] ? fvselcol : view_bgcol ;
		clut.clut[1] = fv->b.selected[index] ? fvselfgcol : 0 ;
	    }
	    base.trans = 0;
	    base.clut->trans_index = 0;

	    base.data = bdfc->bitmap;
	    base.bytes_per_line = bdfc->bytes_per_line;
	    base.width = bdfc->xmax-bdfc->xmin+1;
	    base.height = bdfc->ymax-bdfc->ymin+1;
	    box.x = j*fv->cbw; box.width = fv->cbw;
	    box.y = i*fv->cbh+fv->lab_height+1; box.height = box.width+1;
	    GDrawPushClip(pixmap,&box,&old2);
	    if ( !fv->b.sf->onlybitmaps && fv->show!=fv->filled &&
		    sc->layers[fv->b.active_layer].splines==NULL && sc->layers[fv->b.active_layer].refs==NULL &&
		    !sc->widthset &&
		    !(bdfc->xmax<=0 && bdfc->xmin==0 && bdfc->ymax<=0 && bdfc->ymax==0) ) {
		/* If we have a bitmap but no outline character... */
		GRect b;
		b.x = box.x+1; b.y = box.y+1; b.width = box.width-2; b.height = box.height-2;
		GDrawDrawRect(pixmap,&b,0x008000);
		++b.x; ++b.y; b.width -= 2; b.height -= 2;
		GDrawDrawRect(pixmap,&b,0x008000);
	    }
	    /* I assume that the bitmap image matches the bounding*/
	    /*  box. In some bitmap fonts the bitmap has white space on the*/
	    /*  right. This can throw off the centering algorithem */
	    if ( fv->magnify>1 ) {
		GDrawDrawImageMagnified(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->magnify*(fv->show->ascent-bdfc->ymax),
			fv->magnify*base.width,fv->magnify*base.height);
	    } else if ( (GDrawHasCairo(pixmap)&gc_alpha) && base.image_type==it_index ) {
		GDrawDrawGlyph(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->show->ascent-bdfc->ymax);
	    } else
		GDrawDrawImage(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->show->ascent-bdfc->ymax);
	    if ( fv->showhmetrics ) {
		int x1, x0 = j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2- bdfc->xmin*fv->magnify;
		/* Draw advance width & horizontal origin */
		if ( fv->showhmetrics&fvm_origin )
		    GDrawDrawLine(pixmap,x0,i*fv->cbh+fv->lab_height+yorg-3,x0,
			    i*fv->cbh+fv->lab_height+yorg+2,METRICS_ORIGIN);
		x1 = x0 + fv->magnify*bdfc->width;
		if ( fv->showhmetrics&fvm_advanceat )
		    GDrawDrawLine(pixmap,x1,i*fv->cbh+fv->lab_height+1,x1,
			    (i+1)*fv->cbh-1,METRICS_ADVANCE);
		if ( fv->showhmetrics&fvm_advanceto )
		    GDrawDrawLine(pixmap,x0,(i+1)*fv->cbh-2,x1,
			    (i+1)*fv->cbh-2,METRICS_ADVANCE);
	    }
	    if ( fv->showvmetrics ) {
		int x0 = j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2- bdfc->xmin*fv->magnify
			+ fv->magnify*fv->show->pixelsize/2;
		int y0 = i*fv->cbh+fv->lab_height+yorg;
		int yvw = y0 + fv->magnify*sc->vwidth*fv->show->pixelsize/em;
		if ( fv->showvmetrics&fvm_baseline )
		    GDrawDrawLine(pixmap,x0,i*fv->cbh+fv->lab_height+1,x0,
			    (i+1)*fv->cbh-1,METRICS_BASELINE);
		if ( fv->showvmetrics&fvm_advanceat )
		    GDrawDrawLine(pixmap,j*fv->cbw,yvw,(j+1)*fv->cbw,
			    yvw,METRICS_ADVANCE);
		if ( fv->showvmetrics&fvm_advanceto )
		    GDrawDrawLine(pixmap,j*fv->cbw+2,y0,j*fv->cbw+2,
			    yvw,METRICS_ADVANCE);
		if ( fv->showvmetrics&fvm_origin )
		    GDrawDrawLine(pixmap,x0-3,i*fv->cbh+fv->lab_height+yorg,x0+2,i*fv->cbh+fv->lab_height+yorg,METRICS_ORIGIN);
	    }
	    GDrawPopClip(pixmap,&old2);
	    if ( !fv->show->piecemeal ) BDFCharFree( bdfc );
	}
    }
}
static void FVDrawGlyph(GWindow pixmap, FontView *fv, int index, int forcebg ) {
    GRect box, old2;
    int feat_gid;
    SplineChar *sc;
    struct _GImage base;
    GImage gi;
    GClut clut;
    int i,j;
    int em = fv->b.sf->ascent+fv->b.sf->descent;
    int yorg = fv->magnify*(fv->show->ascent);

    i = index / fv->colcnt;
    j = index - i*fv->colcnt;
    i -= fv->rowoff;

    if ( index<fv->b.map->enccount && (fv->b.selected[index] || forcebg)) {
	box.x = j*fv->cbw+1; box.width = fv->cbw-1;
	box.y = i*fv->cbh+fv->lab_height+1; box.height = fv->cbw;
	GDrawFillRect(pixmap,&box,fv->b.selected[index] ? fvselcol : view_bgcol );
    }
    feat_gid = FeatureTrans(fv,index);
    sc = feat_gid!=-1 ? fv->b.sf->glyphs[feat_gid]: NULL;
    if ( !SCWorthOutputting(sc) ) {
	int x = j*fv->cbw+1, xend = x+fv->cbw-2;
	int y = i*fv->cbh+fv->lab_height+1, yend = y+fv->cbw-1;
	GDrawDrawLine(pixmap,x,y,xend,yend,fvemtpyslotfgcol);
	GDrawDrawLine(pixmap,x,yend,xend,y,fvemtpyslotfgcol);
    }
    if ( sc!=NULL ) {
	BDFChar *bdfc;

	if ( fv->show!=NULL && fv->show->piecemeal &&
		feat_gid!=-1 &&
		(feat_gid>=fv->show->glyphcnt || fv->show->glyphs[feat_gid]==NULL) &&
		fv->b.sf->glyphs[feat_gid]!=NULL )
	    BDFPieceMeal(fv->show,feat_gid);

	if ( fv->show!=NULL && feat_gid!=-1 &&
		feat_gid < fv->show->glyphcnt &&
		fv->show->glyphs[feat_gid]==NULL &&
		SCWorthOutputting(fv->b.sf->glyphs[feat_gid]) ) {
	     
	    box.x = j*fv->cbw+1; box.width = fv->cbw-2;
	    box.y = i*fv->cbh+fv->lab_height+2; box.height = box.width+1;
	    GDrawDrawRect(pixmap,&box,0xff0000);
	    ++box.x; ++box.y; box.width -= 2; box.height -= 2;
	    GDrawDrawRect(pixmap,&box,0xff0000);
 
	} else if ( fv->show!=NULL && feat_gid<fv->show->glyphcnt && feat_gid!=-1 &&
		fv->show->glyphs[feat_gid]!=NULL ) {
	     
	     
	     
	     
	    bdfc = fv->show->piecemeal ?
		fv->show->glyphs[feat_gid] : BDFGetMergedChar( fv->show->glyphs[feat_gid] );

	    memset(&gi,'\0',sizeof(gi));
	    memset(&base,'\0',sizeof(base));
	    if ( bdfc->byte_data ) {
		gi.u.image = &base;
		base.image_type = it_index;
		if ( !fv->b.selected[index] )
		    base.clut = fv->show->clut;
		else {
		    int bgr=((fvselcol>>16)&0xff), bgg=((fvselcol>>8)&0xff), bgb= (fvselcol&0xff);
		    int fgr=((fvselfgcol>>16)&0xff), fgg=((fvselfgcol>>8)&0xff), fgb= (fvselfgcol&0xff);
		    int i;
		    memset(&clut,'\0',sizeof(clut));
		    base.clut = &clut;
		    clut.clut_len = fv->show->clut->clut_len;
		    for ( i=0; i<clut.clut_len; ++i ) {
			clut.clut[i] =
				COLOR_CREATE( bgr + (i*(fgr-bgr))/(clut.clut_len-1),
						bgg + (i*(fgg-bgg))/(clut.clut_len-1),
						bgb + (i*(fgb-bgb))/(clut.clut_len-1));
		    }
		}
		GDrawSetDither(NULL, false);	 
	    } else {
		memset(&clut,'\0',sizeof(clut));
		gi.u.image = &base;
		base.image_type = it_mono;
		base.clut = &clut;
		clut.clut_len = 2;
		clut.clut[0] = fv->b.selected[index] ? fvselcol : view_bgcol ;
		clut.clut[1] = fv->b.selected[index] ? fvselfgcol : 0 ;
	    }
	    base.trans = 0;
	    base.clut->trans_index = 0;

	    base.data = bdfc->bitmap;
	    base.bytes_per_line = bdfc->bytes_per_line;
	    base.width = bdfc->xmax-bdfc->xmin+1;
	    base.height = bdfc->ymax-bdfc->ymin+1;
	    box.x = j*fv->cbw; box.width = fv->cbw;
	    box.y = i*fv->cbh+fv->lab_height+1; box.height = box.width+1;
	    GDrawPushClip(pixmap,&box,&old2);
	    if ( !fv->b.sf->onlybitmaps && fv->show!=fv->filled &&
		    sc->layers[fv->b.active_layer].splines==NULL && sc->layers[fv->b.active_layer].refs==NULL &&
		    !sc->widthset &&
		    !(bdfc->xmax<=0 && bdfc->xmin==0 && bdfc->ymax<=0 && bdfc->ymax==0) ) {
		 
		GRect b;
		b.x = box.x+1; b.y = box.y+1; b.width = box.width-2; b.height = box.height-2;
		GDrawDrawRect(pixmap,&b,0x008000);
		++b.x; ++b.y; b.width -= 2; b.height -= 2;
		GDrawDrawRect(pixmap,&b,0x008000);
	    }
	     
	     
	     
	    if ( fv->magnify>1 ) {
		GDrawDrawImageMagnified(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->magnify*(fv->show->ascent-bdfc->ymax),
			fv->magnify*base.width,fv->magnify*base.height);
	    } else if ( (GDrawHasCairo(pixmap)&gc_alpha) && base.image_type==it_index ) {
		GDrawDrawGlyph(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->show->ascent-bdfc->ymax);
	    } else
		GDrawDrawImage(pixmap,&gi,NULL,
			j*fv->cbw+(fv->cbw-1-base.width)/2,
			i*fv->cbh+fv->lab_height+1+fv->show->ascent-bdfc->ymax);
	    if ( fv->showhmetrics ) {
		int x1, x0 = j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2- bdfc->xmin*fv->magnify;
		 
		if ( fv->showhmetrics&fvm_origin )
		    GDrawDrawLine(pixmap,x0,i*fv->cbh+fv->lab_height+yorg-3,x0,
			    i*fv->cbh+fv->lab_height+yorg+2,METRICS_ORIGIN);
		x1 = x0 + fv->magnify*bdfc->width;
		if ( fv->showhmetrics&fvm_advanceat )
		    GDrawDrawLine(pixmap,x1,i*fv->cbh+fv->lab_height+1,x1,
			    (i+1)*fv->cbh-1,METRICS_ADVANCE);
		if ( fv->showhmetrics&fvm_advanceto )
		    GDrawDrawLine(pixmap,x0,(i+1)*fv->cbh-2,x1,
			    (i+1)*fv->cbh-2,METRICS_ADVANCE);
	    }
	    if ( fv->showvmetrics ) {
		int x0 = j*fv->cbw+(fv->cbw-1-fv->magnify*base.width)/2- bdfc->xmin*fv->magnify
			+ fv->magnify*fv->show->pixelsize/2;
		int y0 = i*fv->cbh+fv->lab_height+yorg;
		int yvw = y0 + fv->magnify*sc->vwidth*fv->show->pixelsize/em;
		if ( fv->showvmetrics&fvm_baseline )
		    GDrawDrawLine(pixmap,x0,i*fv->cbh+fv->lab_height+1,x0,
			    (i+1)*fv->cbh-1,METRICS_BASELINE);
		if ( fv->showvmetrics&fvm_advanceat )
		    GDrawDrawLine(pixmap,j*fv->cbw,yvw,(j+1)*fv->cbw,
			    yvw,METRICS_ADVANCE);
		if ( fv->showvmetrics&fvm_advanceto )
		    GDrawDrawLine(pixmap,j*fv->cbw+2,y0,j*fv->cbw+2,
			    yvw,METRICS_ADVANCE);
		if ( fv->showvmetrics&fvm_origin )
		    GDrawDrawLine(pixmap,x0-3,i*fv->cbh+fv->lab_height+yorg,x0+2,i*fv->cbh+fv->lab_height+yorg,METRICS_ORIGIN);
	    }
	    GDrawPopClip(pixmap,&old2);
	    if ( !fv->show->piecemeal ) BDFCharFree( bdfc );
	}
    }
}