From d43c554ac1385f5af698356cc0ec0d452b57893f Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 13 Feb 2004 10:33:32 +0000 Subject: * (ZnGetTexFont): The font encoding is considered when loading a font. This plus a patch in the text item should lead to a correct behavior when drawing UTF8 strings (regardless of the input versus output encoding). --- generic/Image.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 97 insertions(+), 14 deletions(-) (limited to 'generic/Image.c') diff --git a/generic/Image.c b/generic/Image.c index a7498fd..1796089 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -1084,6 +1084,9 @@ typedef struct _TexFont { TexGlyphInfo *tgi; ZnTexGVI *tgvi; ZnTexGVI **lut; +#ifndef PTK + Tcl_Encoding enc; +#endif Tcl_HashEntry *hash; } TexFont; @@ -1192,7 +1195,8 @@ placeGlyph(FontInfoPtr font, FontInfoPtr SuckGlyphsFromServer(ZnWInfo *wi, - Tk_Font font) + Tk_Font font, + Tcl_Encoding enc) { Pixmap offscreen = 0; XImage *image = NULL; @@ -1200,10 +1204,11 @@ SuckGlyphsFromServer(ZnWInfo *wi, XGCValues values; unsigned int width, height, length, pixwidth; unsigned int i, j; - char str[] = " "; + char str_from[] = " "; + char str_utf[8]; unsigned char *bitmapData = NULL; unsigned int x, y; - int num_chars, spanLength=0; + int num_chars, written, spanLength=0; unsigned int charWidth=0, maxSpanLength; int grabList[MAX_GLYPHS_PER_GRAB]; unsigned int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; @@ -1232,8 +1237,11 @@ SuckGlyphsFromServer(ZnWInfo *wi, */ width = 0; for (i = 0; i < myfontinfo->num_glyphs; i++) { - *str = i + myfontinfo->min_char; - Tk_MeasureChars(font, str, 1, 0, TK_AT_LEAST_ONE, &length); + *str_from = i + myfontinfo->min_char; + Tcl_ExternalToUtf(wi->interp, enc, str_from, 1, + TCL_ENCODING_START|TCL_ENCODING_END, + NULL, str_utf, 8, NULL, &written, NULL); + Tk_MeasureChars(font, str_utf, 1, 0, TK_AT_LEAST_ONE, &length); width = MAX(width, length); } @@ -1268,8 +1276,11 @@ SuckGlyphsFromServer(ZnWInfo *wi, numToGrab = 0; for (i = 0; i < myfontinfo->num_glyphs; i++) { - *str = i + myfontinfo->min_char; - Tk_MeasureChars(font, str, 1, 0, TK_AT_LEAST_ONE, &charWidth); + *str_from = i + myfontinfo->min_char; + Tcl_ExternalToUtf(wi->interp, enc, str_from, 1, + TCL_ENCODING_START|TCL_ENCODING_END, + NULL, str_utf, 8, NULL, &written, NULL); + Tk_MeasureChars(font, str_utf, written, 0, TK_AT_LEAST_ONE, &charWidth); myfontinfo->glyph[i].width = charWidth; myfontinfo->glyph[i].height = height; @@ -1278,7 +1289,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, myfontinfo->glyph[i].advance = charWidth; myfontinfo->glyph[i].bitmap = NULL; if (charWidth != 0) { - Tk_DrawChars(wi->dpy, offscreen, xgc, font, str, 1, + Tk_DrawChars(wi->dpy, offscreen, xgc, font, str_utf, written, (int) (8*maxSpanLength*numToGrab), myfontinfo->ascent); grabList[numToGrab] = i; numToGrab++; @@ -1344,6 +1355,60 @@ SuckGlyphsFromServer(ZnWInfo *wi, return NULL; } +#ifndef PTK +Tcl_Encoding +ZnGetFontEncoding(ZnWInfo *wi, + Tk_Font tkfont) +{ +#ifdef WIN + return Tcl_GetEncoding(wi->interp, "unicode"); +#else + Tcl_Encoding enc; + XFontStruct *fs; + int count; + unsigned long prop; + char CONST *xlfd; + char *charset_lc=NULL; + char *charset, *charset_def = "iso8859-1"; + + fs = XQueryFont(wi->dpy, Tk_FontId(tkfont)); + + charset = charset_def; + xlfd = Tk_NameOfFont(tkfont); + if (XGetFontProperty(fs, XInternAtom(wi->dpy, "FONT", 0), &prop) != False) { + xlfd = charset = XGetAtomName(wi->dpy, prop); + for (count = 0; count < 13; count++) { + charset = strchr(charset, '-'); + if (!charset) { + charset = charset_def; + goto getenc; + } + charset++; + } + /* Get a lower case string */ + charset_lc = ZnMalloc(sizeof(charset)+1); + for (count = strlen(charset)-1; count >= 0; count--) { + charset_lc[count] = tolower(charset[count]); + } + charset = charset_lc; + } + + getenc: + enc = Tcl_GetEncoding(wi->interp, charset); + if (charset_lc) { + ZnFree(charset_lc); + } + if (!enc) { + ZnWarning("Unable to find encoding for font "); + ZnWarning(xlfd); + ZnWarning("\n"); + } + + return enc; +#endif +} +#endif + /* ********************************************************************************** * @@ -1392,10 +1457,13 @@ ZnGetTexFont(ZnWInfo *wi, /* Get a local reference to the font, it will be deallocated * when no further references on this TexFont exist. */ txf->tkfont = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(font)); +#ifndef PTK + txf->enc = ZnGetFontEncoding(wi, txf->tkfont); +#endif /*printf("Chargement de la texture pour la fonte %s\n", ZnNameOfTexFont(tfi));*/ - fontinfo = SuckGlyphsFromServer(wi, txf->tkfont); + fontinfo = SuckGlyphsFromServer(wi, txf->tkfont, txf->enc); if (fontinfo == NULL) { goto error; } @@ -1619,18 +1687,20 @@ ZnGetTexFont(ZnWInfo *wi, ZnFree(txf->teximage); txf->teximage = NULL; } + Tcl_FreeEncoding(txf->enc); + Tk_FreeFont(txf->tkfont); ZnFree(txf); ZnWarning("Cannot load font texture for font "); ZnWarning(Tk_NameOfFont(font)); ZnWarning("\n"); return 0; } - + memset(txf->lut, 0, txf->range * sizeof(ZnTexGVI *)); for (i = 0; i < txf->num_glyphs; i++) { txf->lut[txf->tgi[i].c - txf->min_glyph] = &txf->tgvi[i]; } - + for (i = 0; i < fontinfo->num_glyphs; i++) { if (fontinfo->glyph[i].bitmap) ZnFree(fontinfo->glyph[i].bitmap); @@ -1638,12 +1708,12 @@ ZnGetTexFont(ZnWInfo *wi, ZnFree(fontinfo); ZnFree(glist); ZnFree(glist2); - + entry = Tcl_CreateHashEntry(&font_textures, (char *) font, &new); Tcl_SetHashValue(entry, (ClientData) txf); txf->hash = entry; } - + /* * Now locate the texture obj in the texture list for this widget. */ @@ -1658,7 +1728,6 @@ ZnGetTexFont(ZnWInfo *wi, */ tfi = ZnMalloc(sizeof(TexFontInfo)); if (tfi == NULL) { - ZnFree(txf); return NULL; } tfi->refcount = 1; @@ -1782,6 +1851,7 @@ ZnFreeTexFont(ZnTexFontInfo tfi) ZnFree(txf->tgvi); ZnFree(txf->lut); ZnFree(txf->teximage); + Tcl_FreeEncoding(txf->enc); Tcl_DeleteHashEntry(txf->hash); ZnFree(txf); } @@ -1813,6 +1883,19 @@ ZnCharInTexFont(ZnTexFontInfo tfi, /* ********************************************************************************** * + * ZnTexFontEncoding -- + * + ********************************************************************************** + */ +Tcl_Encoding +ZnTexFontEncoding(ZnTexFontInfo tfi) +{ + return ((TexFontInfo *) tfi)->txf->enc; +} + +/* + ********************************************************************************** + * * ZnTexFontGVI -- * ********************************************************************************** -- cgit v1.1