commit 7818fcd49753f4fd5b5b9e91613c42da9bca6f28 Author: Anders Kaseorg Date: Fri Sep 26 07:16:32 2008 -0400 Support multibyte character sets in zwgc zephyrgrams. Signed-off-by: Anders Kaseorg diff --git a/zwgc/X_fonts.c b/zwgc/X_fonts.c index 496a3bf..7ec4465 100644 --- a/zwgc/X_fonts.c +++ b/zwgc/X_fonts.c @@ -35,13 +35,12 @@ static const char rcsid_X_fonts_c[] = "$Id: X_fonts.c,v 1.6 1999-01-22 23:20:08 #include "zwgc.h" /* - * font_dict - Lookup cache for fonts (the value pointers are XFontStruct *'s) + * font_dict - Lookup cache for fonts (the value pointers are XFontSet's) */ static pointer_dictionary family_dict = NULL; static pointer_dictionary fontname_dict = NULL; static pointer_dictionary fontst_dict = NULL; -static pointer_dictionary fidst_dict = NULL; /* * {face,size}_to_string - lookup tables for converting {face,size} int @@ -122,89 +121,38 @@ static char *get_specific_fontname(family,size,face) } } -/* fast function to convert Font to hex. Return value - * is on the heap and must be freed. I'm cheating in - * that I know that Font us really an unsigned long. */ - -static char hexdigits[] = {"0123456789ABCDEF"}; -static char *Font_to_hex(num) - Font num; -{ - char *temp; - int i; - - temp=(char *) malloc((sizeof(Font)<<1)+2); - - for (i=0;i<((sizeof(Font)<<1)+1);i++) - temp[i] = hexdigits[(num>>(i*4))&0x0f]; - temp[i] = '\0'; - - return(temp); -} - -void add_fid(font) - XFontStruct *font; -{ - - char *fidstr; - pointer_dictionary_binding *binding; - int exists; - - if (!fidst_dict) - fidst_dict = pointer_dictionary_Create(37); - fidstr=Font_to_hex(font->fid); - binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists); - free(fidstr); - - if (!exists) - binding->value=(pointer) font; -} - -/* requires that the font already be cached. */ -XFontStruct *get_fontst_from_fid(fid) - Font fid; -{ - char *fidstr; - pointer_dictionary_binding *binding; - int exists; - - fidstr=Font_to_hex(fid); - - binding = pointer_dictionary_Define(fidst_dict,fidstr,&exists); - free(fidstr); -#ifdef DEBUG - if (exists) { - return((XFontStruct *) binding->value); - } else { - printf("Font fid=0x%s not cached. Oops.\n",fidstr); - abort(); - } -#else - return((XFontStruct *) binding->value); -#endif -} - -static XFontStruct *get_fontst(dpy,fontname) +static XFontSet get_fontst(dpy,fontname) Display *dpy; char *fontname; { pointer_dictionary_binding *binding; int exists; - XFontStruct *fontst; + XFontSet fontst; if (!fontst_dict) fontst_dict = pointer_dictionary_Create(37); binding = pointer_dictionary_Define(fontst_dict,fontname,&exists); if (exists) { - return((XFontStruct *) binding->value); + return((XFontSet) binding->value); } else { - fontst=XLoadQueryFont(dpy,fontname); + char **missing_list; + int missing_count; + char *def_string; + fontst = XCreateFontSet(dpy, fontname, &missing_list, &missing_count, + &def_string); + if (missing_count != 0) { + int i; + fprintf(stderr, "warning: missing charsets:"); + for (i=0;ivalue=(pointer) fontst; - add_fid(fontst); } return(fontst); /* If resource returns NULL, return NULL also */ } } @@ -223,7 +171,7 @@ static char *get_fontname(family,size,face) return(fontname); } -static XFontStruct *complete_get_fontst(dpy,style,substyle,size,face) +static XFontSet complete_get_fontst(dpy,style,substyle,size,face) Display *dpy; string style; string substyle; @@ -231,7 +179,7 @@ static XFontStruct *complete_get_fontst(dpy,style,substyle,size,face) int face; { char *family,*fontname; - XFontStruct *fontst; + XFontSet fontst; if (family=get_family(style,substyle)) if (fontname=get_fontname(family,size,face)) @@ -242,14 +190,14 @@ static XFontStruct *complete_get_fontst(dpy,style,substyle,size,face) } /* - * XFontStruct *get_font(string style, substyle; int size, face) + * XFontSet get_font(string style, substyle; int size, face) * Requires: size is one of SMALL_SIZE, MEDIUM_SIZE, LARGE_SIZE and * face is one of ROMAN_FACE, BOLD_FACE, ITALIC_FACE, * BOLDITALIC_FACE. * Effects: unknown */ -XFontStruct *get_font(dpy,style,substyle,size,face) +XFontSet get_font(dpy,style,substyle,size,face) Display *dpy; string style; string substyle; @@ -257,7 +205,7 @@ XFontStruct *get_font(dpy,style,substyle,size,face) int face; { char *family,*fontname; - XFontStruct *fontst; + XFontSet fontst; if (size == SPECIAL_SIZE) { /* attempt to process @font explicitly */ diff --git a/zwgc/X_fonts.h b/zwgc/X_fonts.h index 36a3a7b..5b57d60 100644 --- a/zwgc/X_fonts.h +++ b/zwgc/X_fonts.h @@ -31,7 +31,7 @@ #define LARGE_SIZE 2 /* - * XFontStruct *get_font(string family; int size, face) + * XFontSet get_font(string family; int size, face) * Requires: size is one of SMALL_SIZE, MEDIUM_SIZE, LARGE_SIZE and * face is one of ROMAN_FACE, BOLD_FACE, ITALIC_FACE, * BOLDITALIC_FACE. @@ -41,7 +41,6 @@ * specified by default.medium.roman is used. <<<>>> */ -extern XFontStruct *get_font(); -extern XFontStruct *get_fontst_from_fid(); +extern XFontSet get_font(); #endif diff --git a/zwgc/X_gram.c b/zwgc/X_gram.c index 0fc1c68..50b993e 100644 --- a/zwgc/X_gram.c +++ b/zwgc/X_gram.c @@ -407,7 +407,7 @@ void x_gram_draw(dpy, w, gram, region) GC gc; XGCValues gcvals; xblock *xb; - XTextItem text; + XmbTextItem text; int startblock,endblock,startpixel,endpixel; #define SetFG(fg) \ @@ -485,8 +485,8 @@ void x_gram_draw(dpy, w, gram, region) text.chars=gram->text+xb->strindex; text.nchars=xb->strlen; text.delta=0; - text.font=xb->fid; - XDrawText(dpy,w,gc,xb->x,xb->y,&text,1); + text.font_set=xb->font; + Xutf8DrawText(dpy,w,gc,xb->x,xb->y,&text,1); } } diff --git a/zwgc/X_gram.h b/zwgc/X_gram.h index 604bcfc..c131a80 100644 --- a/zwgc/X_gram.h +++ b/zwgc/X_gram.h @@ -22,7 +22,7 @@ typedef struct _xblock { unsigned long fgcolor; - Font fid; + XFontSet font; int x,y; int x1,y1,x2,y2; /* bounds of block. used for cut and paste. */ int strindex; @@ -41,7 +41,7 @@ typedef struct _x_gram { typedef struct _xauxblock { int align; - XFontStruct *font; + XFontSet font; char *str; int len; int width; diff --git a/zwgc/main.c b/zwgc/main.c index e624755..8c7faa2 100644 --- a/zwgc/main.c +++ b/zwgc/main.c @@ -23,6 +23,7 @@ static const char rcsid_main_c[] = "$Id: main.c,v 1.39 2004-06-24 02:27:34 ghuds #include #include #include +#include #include #include @@ -226,6 +227,7 @@ int main(argc, argv) int status; #endif + setlocale(LC_ALL, ""); progname = argv[0]; /* diff --git a/zwgc/xmark.c b/zwgc/xmark.c index 8b7f97e..99bf772 100644 --- a/zwgc/xmark.c +++ b/zwgc/xmark.c @@ -49,7 +49,7 @@ void xmarkSetBound(gram,x,y,which) int which; { int i,xofs,yofs; - XFontStruct *font; + XFontSet font; xblock *xb; unsigned char *s; @@ -106,6 +106,8 @@ void xmarkSetBound(gram,x,y,which) for (yofs=xb->y1;(inumblocks) && (xb->y1 == yofs);i++,xb++) { if (x <= xb->x2) { + int num_chars; + XRectangle *ink, *logical; markblock[which]=i; xofs=xb->x1; @@ -113,18 +115,24 @@ void xmarkSetBound(gram,x,y,which) markchar[which]=0; RETURN; } - font=get_fontst_from_fid(xb->fid); - for (i=0,s=(unsigned char *)((gram->text)+(xb->strindex)); - xofsstrlen; - i++,s++) { - /* if font->per_char is NULL, then we should use min_bounds */ - short usewidth = font->per_char ? font->per_char[*s - font->min_char_or_byte2].width : font->min_bounds.width; - if (x <= (xofs+=usewidth)) { + font=xb->font; + Xutf8TextPerCharExtents(font, gram->text+xb->strindex, xb->strlen, + NULL, NULL, -1, &num_chars, NULL, NULL); + ink = malloc(num_chars * sizeof(XRectangle)); + logical = malloc(num_chars * sizeof(XRectangle)); + Xutf8TextPerCharExtents(font, gram->text+xb->strindex, xb->strlen, + ink, logical, num_chars, &num_chars, NULL, NULL); + for (i=0;ix1 - usewidth; + markpixel[which]=xofs + logical[i].x - xb->x1; + free(ink); + free(logical); RETURN; } } + free(ink); + free(logical); } } diff --git a/zwgc/xshow.c b/zwgc/xshow.c index 552a634..9a71fea 100644 --- a/zwgc/xshow.c +++ b/zwgc/xshow.c @@ -151,6 +151,7 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines, length of the longest line and the total number of characters. */ for (line=0; lineascent; - descent = auxblocks[block].font->descent; + fse = XExtentsOfFontSet(auxblocks[block].font); + ascent = -fse->max_logical_extent.y; + descent = fse->max_logical_extent.y+fse->max_logical_extent.height; if (ascent>maxascent) maxascent = ascent; if (descent>maxdescent) @@ -218,7 +221,7 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines, /* XXX implicit assumption that a line must have at least one block, so that there is indeed a reasonable font in auxblocks[0].font */ - width = lsize*2+csize+XTextWidth(auxblocks[0].font," ",1); + width = lsize*2+csize+Xutf8TextEscapement(auxblocks[0].font," ",1); break; case 4: @@ -226,16 +229,16 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines, break; case 5: - width = lsize+rsize+XTextWidth(auxblocks[0].font, " ", 1); + width = lsize+rsize+Xutf8TextEscapement(auxblocks[0].font, " ", 1); break; case 6: - width = csize+rsize*2+XTextWidth(auxblocks[0].font, " ", 1); + width = csize+rsize*2+Xutf8TextEscapement(auxblocks[0].font, " ", 1); break; case 7: width = max(lsize,rsize)*2+csize+ - XTextWidth(auxblocks[0].font," ",1)*2; + Xutf8TextEscapement(auxblocks[0].font," ",1)*2; break; } if (width>maxwidth) @@ -258,7 +261,7 @@ void fixup_and_draw(dpy, style, auxblocks, blocks, num, lines, numlines, without it. */ for (i=0; ifid; + blocks[block].font = auxblocks[block].font; switch (auxblocks[block].align) { case LEFTALIGN: blocks[block].x = lofs; @@ -360,7 +363,8 @@ void xshow(dpy, desc, numstr, numnl) int numstr; int numnl; { - XFontStruct *font; + XFontSet font; + XFontSetExtents *fse; xmode_stack modes = xmode_stack_create(); xmode curmode; xlinedesc *lines; @@ -507,8 +511,10 @@ void xshow(dpy, desc, numstr, numnl) lines[line].startblock = linestart; lines[line].numblock = nextblock-linestart; font = MODE_TO_FONT(dpy,style,&curmode); - lines[line].ascent = font->ascent; - lines[line].descent = font->descent; + fse = XExtentsOfFontSet(font); + lines[line].ascent = -fse->max_logical_extent.y; + lines[line].descent = + fse->max_logical_extent.y+fse->max_logical_extent.height; line++; linestart = nextblock; break; diff --git a/zwgc/xshow.h b/zwgc/xshow.h index 2dbd381..64bbb66 100644 --- a/zwgc/xshow.h +++ b/zwgc/xshow.h @@ -21,7 +21,7 @@ typedef struct _xblock { unsigned long fgcolor; - Font fid; + XFontSet font; int x,y; int x1,y1,x2,y2; /* bounds of block. used for cut and paste. */ int strindex; @@ -38,7 +38,7 @@ typedef struct _xwin { typedef struct _xauxblock { int align; - XFontStruct *font; + XFontSet font; char *str; int len; int width;