diff options
Diffstat (limited to 'unix/tkUnixFont.c')
-rw-r--r-- | unix/tkUnixFont.c | 545 |
1 files changed, 431 insertions, 114 deletions
diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c index 897770b..b361e83 100644 --- a/unix/tkUnixFont.c +++ b/unix/tkUnixFont.c @@ -19,7 +19,7 @@ * The preferred font encodings. */ -static CONST char *encodingList[] = { +static const char *const encodingList[] = { "iso8859-1", "jis0208", "jis0212", NULL }; @@ -137,9 +137,9 @@ typedef struct UnixFont { */ typedef struct EncodingAlias { - char *realName; /* The real name of the encoding to load if + const char *realName; /* The real name of the encoding to load if * the provided name matched the pattern. */ - char *aliasPattern; /* Pattern for encoding name, of the form that + const char *aliasPattern; /* Pattern for encoding name, of the form that * is acceptable to Tcl_StringMatch. */ } EncodingAlias; @@ -205,31 +205,31 @@ static void FontPkgCleanup(ClientData clientData); static FontFamily * AllocFontFamily(Display *display, XFontStruct *fontStructPtr, int base); static SubFont * CanUseFallback(UnixFont *fontPtr, - CONST char *fallbackName, int ch, + const char *fallbackName, int ch, SubFont **fixSubFontPtrPtr); static SubFont * CanUseFallbackWithAliases(UnixFont *fontPtr, - char *fallbackName, int ch, + const char *fallbackName, int ch, Tcl_DString *nameTriedPtr, SubFont **fixSubFontPtrPtr); -static int ControlUtfProc(ClientData clientData, CONST char *src, +static int ControlUtfProc(ClientData clientData, const char *src, int srcLen, int flags, Tcl_EncodingState*statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); static XFontStruct * CreateClosestFont(Tk_Window tkwin, - CONST TkFontAttributes *faPtr, - CONST TkXLFDAttributes *xaPtr); + const TkFontAttributes *faPtr, + const TkXLFDAttributes *xaPtr); static SubFont * FindSubFontForChar(UnixFont *fontPtr, int ch, SubFont **fixSubFontPtrPtr); static void FontMapInsert(SubFont *subFontPtr, int ch); static void FontMapLoadPage(SubFont *subFontPtr, int row); static int FontMapLookup(SubFont *subFontPtr, int ch); static void FreeFontFamily(FontFamily *afPtr); -static CONST char * GetEncodingAlias(CONST char *name); +static const char * GetEncodingAlias(const char *name); static int GetFontAttributes(Display *display, XFontStruct *fontStructPtr, FontAttributes *faPtr); static XFontStruct * GetScreenFont(Display *display, FontAttributes *wantPtr, char **nameList, - int bestIdx[], unsigned int bestScore[]); + int bestIdx[], unsigned bestScore[]); static XFontStruct * GetSystemFont(Display *display); static int IdentifySymbolEncodings(FontAttributes *faPtr); static void InitFont(Tk_Window tkwin, XFontStruct *fontStructPtr, @@ -237,21 +237,21 @@ static void InitFont(Tk_Window tkwin, XFontStruct *fontStructPtr, static void InitSubFont(Display *display, XFontStruct *fontStructPtr, int base, SubFont *subFontPtr); -static char ** ListFonts(Display *display, CONST char *faceName, +static char ** ListFonts(Display *display, const char *faceName, int *numNamesPtr); -static char ** ListFontOrAlias(Display *display, CONST char*faceName, +static char ** ListFontOrAlias(Display *display, const char*faceName, int *numNamesPtr); -static unsigned int RankAttributes(FontAttributes *wantPtr, +static unsigned RankAttributes(FontAttributes *wantPtr, FontAttributes *gotPtr); static void ReleaseFont(UnixFont *fontPtr); static void ReleaseSubFont(Display *display, SubFont *subFontPtr); -static int SeenName(CONST char *name, Tcl_DString *dsPtr); +static int SeenName(const char *name, Tcl_DString *dsPtr); #ifndef WORDS_BIGENDIAN -static int Ucs2beToUtfProc(ClientData clientData, CONST char*src, +static int Ucs2beToUtfProc(ClientData clientData, const char*src, int srcLen, int flags, Tcl_EncodingState*statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); -static int UtfToUcs2beProc(ClientData clientData, CONST char*src, +static int UtfToUcs2beProc(ClientData clientData, const char*src, int srcLen, int flags, Tcl_EncodingState*statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); @@ -279,7 +279,7 @@ static void FontPkgCleanup( ClientData clientData) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->controlFamily.encoding != NULL) { @@ -318,7 +318,7 @@ void TkpFontPkgInit( TkMainInfo *mainPtr) /* The application being created. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_EncodingType type; SubFont dummy; @@ -380,7 +380,7 @@ TkpFontPkgInit( static int ControlUtfProc( ClientData clientData, /* Not used. */ - CONST char *src, /* Source string in UTF-8. */ + const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state @@ -404,9 +404,9 @@ ControlUtfProc( * correspond to the bytes stored in the * output buffer. */ { - CONST char *srcStart, *srcEnd; + const char *srcStart, *srcEnd; char *dstStart, *dstEnd; - Tcl_UniChar ch; + int ch; int result; static char hexChars[] = "0123456789abcdef"; static char mapChars[] = { @@ -427,9 +427,9 @@ ControlUtfProc( result = TCL_CONVERT_NOSPACE; break; } - src += Tcl_UtfToUniChar(src, &ch); + src += TkUtfToUniChar(src, &ch); dst[0] = '\\'; - if ((ch < sizeof(mapChars)) && (mapChars[ch] != 0)) { + if (((size_t) ch < sizeof(mapChars)) && (mapChars[ch] != 0)) { dst[1] = mapChars[ch]; dst += 2; } else if (ch < 256) { @@ -437,13 +437,21 @@ ControlUtfProc( dst[2] = hexChars[(ch >> 4) & 0xf]; dst[3] = hexChars[ch & 0xf]; dst += 4; - } else { + } else if (ch < 0x10000) { dst[1] = 'u'; dst[2] = hexChars[(ch >> 12) & 0xf]; dst[3] = hexChars[(ch >> 8) & 0xf]; dst[4] = hexChars[(ch >> 4) & 0xf]; dst[5] = hexChars[ch & 0xf]; dst += 6; + } else { + /* TODO we can do better here */ + dst[1] = 'u'; + dst[2] = 'f'; + dst[3] = 'f'; + dst[4] = 'f'; + dst[5] = 'd'; + dst += 6; } } *srcReadPtr = src - srcStart; @@ -473,7 +481,7 @@ ControlUtfProc( static int Ucs2beToUtfProc( ClientData clientData, /* Not used. */ - CONST char *src, /* Source string in Unicode. */ + const char *src, /* Source string in Unicode. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state @@ -497,7 +505,7 @@ Ucs2beToUtfProc( * correspond to the bytes stored in the * output buffer. */ { - CONST char *srcStart, *srcEnd; + const char *srcStart, *srcEnd; char *dstEnd, *dstStart; int result, numChars; @@ -556,7 +564,7 @@ static int UtfToUcs2beProc( ClientData clientData, /* TableEncodingData that specifies * encoding. */ - CONST char *src, /* Source string in UTF-8. */ + const char *src, /* Source string in UTF-8. */ int srcLen, /* Source string length in bytes. */ int flags, /* Conversion control flags. */ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state @@ -580,14 +588,14 @@ UtfToUcs2beProc( * correspond to the bytes stored in the * output buffer. */ { - CONST char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; + const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result, numChars; Tcl_UniChar ch; srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; - if ((flags & TCL_ENCODING_END) == 0) { + if (!(flags & TCL_ENCODING_END)) { srcClose -= TCL_UTF_MAX; } @@ -656,12 +664,12 @@ UtfToUcs2beProc( TkFont * TkpGetNativeFont( Tk_Window tkwin, /* For display where font will be used. */ - CONST char *name) /* Platform-specific font name. */ + const char *name) /* Platform-specific font name. */ { UnixFont *fontPtr; XFontStruct *fontStructPtr; FontAttributes fa; - CONST char *p; + const char *p; int hasSpace, dashes, hasWild; /* @@ -719,7 +727,7 @@ TkpGetNativeFont( } fontStructPtr = CreateClosestFont(tkwin, &fa.fa, &fa.xa); } - fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont)); + fontPtr = ckalloc(sizeof(UnixFont)); InitFont(tkwin, fontStructPtr, fontPtr); return (TkFont *) fontPtr; @@ -763,7 +771,7 @@ TkpGetFontFromAttributes( * will be released. If NULL, a new TkFont * structure is allocated. */ Tk_Window tkwin, /* For display where font will be used. */ - CONST TkFontAttributes *faPtr) + const TkFontAttributes *faPtr) /* Set of attributes to match. */ { UnixFont *fontPtr; @@ -775,7 +783,7 @@ TkpGetFontFromAttributes( fontPtr = (UnixFont *) tkFontPtr; if (fontPtr == NULL) { - fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont)); + fontPtr = ckalloc(sizeof(UnixFont)); } else { ReleaseFont(fontPtr); } @@ -845,8 +853,6 @@ TkpGetFontFamilies( Tcl_HashSearch search; Tcl_Obj *resultPtr, *strPtr; - resultPtr = Tcl_GetObjResult(interp); - Tcl_InitHashTable(&familyTable, TCL_STRING_KEYS); nameList = ListFonts(Tk_Display(tkwin), "*", &numNames); for (i = 0; i < numNames; i++) { @@ -874,11 +880,13 @@ TkpGetFontFamilies( XFreeFontNames(nameList); hPtr = Tcl_FirstHashEntry(&familyTable, &search); + resultPtr = Tcl_NewObj(); while (hPtr != NULL) { strPtr = Tcl_NewStringObj(Tcl_GetHashKey(&familyTable, hPtr), -1); Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); hPtr = Tcl_NextHashEntry(&search); } + Tcl_SetObjResult(interp, resultPtr); Tcl_DeleteHashTable(&familyTable); } @@ -911,7 +919,7 @@ TkpGetSubFonts( UnixFont *fontPtr; FontFamily *familyPtr; - resultPtr = Tcl_GetObjResult(interp); + resultPtr = Tcl_NewObj(); fontPtr = (UnixFont *) tkfont; for (i = 0; i < fontPtr->numSubFonts; i++) { familyPtr = fontPtr->subFontArray[i].familyPtr; @@ -922,6 +930,7 @@ TkpGetSubFonts( listPtr = Tcl_NewListObj(3, objv); Tcl_ListObjAppendElement(NULL, resultPtr, listPtr); } + Tcl_SetObjResult(interp, resultPtr); } /* @@ -945,7 +954,7 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + int c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { FontAttributes atts; @@ -958,6 +967,7 @@ TkpGetFontAttrsForChar( SubFont *thisSubFontPtr = FindSubFontForChar(fontPtr, c, &lastSubFontPtr); /* Pointer to the subfont to use for the given * character */ + GetFontAttributes(Tk_Display(tkwin), thisSubFontPtr->fontStructPtr, &atts); *faPtr = atts.fa; } @@ -986,7 +996,7 @@ TkpGetFontAttrsForChar( int Tk_MeasureChars( Tk_Font tkfont, /* Font in which characters will be drawn. */ - CONST char *source, /* UTF-8 string to be displayed. Need not be + const char *source, /* UTF-8 string to be displayed. Need not be * '\0' terminated. */ int numBytes, /* Maximum number of bytes to consider from * source string. */ @@ -1025,8 +1035,8 @@ Tk_MeasureChars( curX = 0; curByte = 0; } else if (maxLength < 0) { - CONST char *p, *end, *next; - Tcl_UniChar ch; + const char *p, *end, *next; + int ch; SubFont *thisSubFontPtr; FontFamily *familyPtr; Tcl_DString runString; @@ -1042,7 +1052,7 @@ Tk_MeasureChars( curX = 0; end = source + numBytes; for (p = source; p < end; ) { - next = p + Tcl_UtfToUniChar(p, &ch); + next = p + TkUtfToUniChar(p, &ch); thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); if (thisSubFontPtr != lastSubFontPtr) { familyPtr = lastSubFontPtr->familyPtr; @@ -1078,11 +1088,11 @@ Tk_MeasureChars( Tcl_DStringFree(&runString); curByte = numBytes; } else { - CONST char *p, *end, *next, *term; + const char *p, *end, *next, *term; int newX, termX, sawNonSpace, dstWrote; Tcl_UniChar ch; FontFamily *familyPtr; - char buf[16]; + XChar2b buf[8]; /* * How many chars will fit in the space allotted? This first version @@ -1104,14 +1114,14 @@ Tk_MeasureChars( } else { lastSubFontPtr = FindSubFontForChar(fontPtr, ch, NULL); familyPtr = lastSubFontPtr->familyPtr; - Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p, - 0, NULL, buf, sizeof(buf), NULL, &dstWrote, NULL); + Tcl_UtfToExternal(NULL, familyPtr->encoding, p, next - p, 0, NULL, + (char *)&buf[0].byte1, sizeof(buf), NULL, &dstWrote, NULL); if (familyPtr->isTwoByteFont) { newX += XTextWidth16(lastSubFontPtr->fontStructPtr, - (XChar2b *) buf, dstWrote >> 1); + buf, dstWrote >> 1); } else { - newX += XTextWidth(lastSubFontPtr->fontStructPtr, buf, - dstWrote); + newX += XTextWidth(lastSubFontPtr->fontStructPtr, + (char *)&buf[0].byte1, dstWrote); } } if (newX > maxLength) { @@ -1200,7 +1210,7 @@ Tk_MeasureChars( int TkpMeasureCharsInContext( Tk_Font tkfont, /* Font in which characters will be drawn. */ - CONST char *source, /* UTF-8 string to be displayed. Need not be + const char *source, /* UTF-8 string to be displayed. Need not be * '\0' terminated. */ int numBytes, /* Maximum number of bytes to consider from * source string in all. */ @@ -1253,7 +1263,7 @@ Tk_DrawChars( GC gc, /* Graphics context for drawing characters. */ Tk_Font tkfont, /* Font in which characters will be drawn; * must be the same as font used in GC. */ - CONST char *source, /* UTF-8 string to be displayed. Need not be + const char *source, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that @@ -1264,22 +1274,20 @@ Tk_DrawChars( int x, int y) /* Coordinates at which to place origin of * string when drawing. */ { - UnixFont *fontPtr; + UnixFont *fontPtr = (UnixFont *) tkfont; SubFont *thisSubFontPtr, *lastSubFontPtr; Tcl_DString runString; - CONST char *p, *end, *next; + const char *p, *end, *next; int xStart, needWidth, window_width, do_width; Tcl_UniChar ch; FontFamily *familyPtr; #ifdef TK_DRAW_CHAR_XWINDOW_CHECK int rx, ry; - unsigned int width, height, border_width, depth; + unsigned width, height, border_width, depth; Drawable root; #endif - fontPtr = (UnixFont *) tkfont; lastSubFontPtr = &fontPtr->subFontArray[0]; - xStart = x; #ifdef TK_DRAW_CHAR_XWINDOW_CHECK @@ -1392,7 +1400,7 @@ TkpDrawCharsInContext( GC gc, /* Graphics context for drawing characters. */ Tk_Font tkfont, /* Font in which characters will be drawn; * must be the same as font used in GC. */ - CONST char *source, /* UTF-8 string to be displayed. Need not be + const char *source, /* UTF-8 string to be displayed. Need not be * '\0' terminated. All Tk meta-characters * (tabs, control characters, and newlines) * should be stripped out of the string that @@ -1406,10 +1414,13 @@ TkpDrawCharsInContext( * whole (not just the range) string when * drawing. */ { + int widthUntilStart; + (void) numBytes; /*unused*/ + Tk_MeasureChars(tkfont, source, rangeStart, -1, 0, &widthUntilStart); Tk_DrawChars(display, drawable, gc, tkfont, source + rangeStart, - rangeLength, x, y); + rangeLength, x+widthUntilStart, y); } /* @@ -1441,9 +1452,9 @@ TkpDrawCharsInContext( static XFontStruct * CreateClosestFont( Tk_Window tkwin, /* For display where font will be used. */ - CONST TkFontAttributes *faPtr, + const TkFontAttributes *faPtr, /* Set of generic attributes to match. */ - CONST TkXLFDAttributes *xaPtr) + const TkXLFDAttributes *xaPtr) /* Set of X-specific attributes to match. */ { FontAttributes want; @@ -1451,7 +1462,7 @@ CreateClosestFont( int numNames, nameIdx, bestIdx[2]; Display *display; XFontStruct *fontStructPtr; - unsigned int bestScore[2]; + unsigned bestScore[2]; want.fa = *faPtr; want.xa = *xaPtr; @@ -1481,9 +1492,9 @@ CreateClosestFont( nameList = ListFontOrAlias(display, want.fa.family, &numNames); if (numNames == 0) { - char ***fontFallbacks; + const char *const *const *fontFallbacks; int i, j; - char *fallback; + const char *fallback; fontFallbacks = TkFontGetFallbacks(); for (i = 0; fontFallbacks[i] != NULL; i++) { @@ -1513,18 +1524,18 @@ CreateClosestFont( found: bestIdx[0] = -1; bestIdx[1] = -1; - bestScore[0] = (unsigned int) -1; - bestScore[1] = (unsigned int) -1; + bestScore[0] = (unsigned) -1; + bestScore[1] = (unsigned) -1; for (nameIdx = 0; nameIdx < numNames; nameIdx++) { FontAttributes got; int scalable; - unsigned int score; + unsigned score; if (TkFontParseXLFD(nameList[nameIdx], &got.fa, &got.xa) != TCL_OK) { continue; } IdentifySymbolEncodings(&got); - scalable = (got.fa.size == 0); + scalable = (got.fa.size == 0.0); score = RankAttributes(&want, &got); if (score < bestScore[scalable]) { bestIdx[scalable] = nameIdx; @@ -1574,7 +1585,7 @@ InitFont( UnixFont *fontPtr) /* Filled with information constructed from * the above arguments. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); unsigned long value; int minHi, maxHi, minLo, maxLo, fixed, width, limit, i, n; @@ -1631,7 +1642,7 @@ InitFont( fmPtr->fixed = fixed; fontPtr->display = display; - fontPtr->pixelSize = TkFontGetPixels(tkwin, fa.fa.size); + fontPtr->pixelSize = (int)(TkFontGetPixels(tkwin, fa.fa.size) + 0.5); fontPtr->xa = fa.xa; fontPtr->numSubFonts = 1; @@ -1648,7 +1659,7 @@ InitFont( pageMap = fontPtr->subFontArray[0].fontMap[0]; for (i = 0; i < 256; i++) { if ((minHi > 0) || (i < minLo) || (i > maxLo) - || (((pageMap[i>>3] >> (i&7)) & 1) == 0)) { + || !((pageMap[i>>3] >> (i&7)) & 1)) { n = 0; } else if (fontStructPtr->per_char == NULL) { n = fontStructPtr->max_bounds.width; @@ -1727,7 +1738,7 @@ ReleaseFont( ReleaseSubFont(fontPtr->display, &fontPtr->subFontArray[i]); } if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); + ckfree(fontPtr->subFontArray); } } @@ -1827,7 +1838,7 @@ AllocFontFamily( FontFamily *familyPtr; FontAttributes fa; Tcl_Encoding encoding; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); GetFontAttributes(display, fontStructPtr, &fa); @@ -1844,7 +1855,7 @@ AllocFontFamily( } } - familyPtr = (FontFamily *) ckalloc(sizeof(FontFamily)); + familyPtr = ckalloc(sizeof(FontFamily)); memset(familyPtr, 0, sizeof(FontFamily)); familyPtr->nextPtr = tsdPtr->fontFamilyList; tsdPtr->fontFamilyList = familyPtr; @@ -1901,7 +1912,7 @@ FreeFontFamily( FontFamily *familyPtr) /* The FontFamily to delete. */ { FontFamily **familyPtrPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); int i; @@ -1931,7 +1942,7 @@ FreeFontFamily( familyPtrPtr = &(*familyPtrPtr)->nextPtr; } - ckfree((char *) familyPtr); + ckfree(familyPtr); } /* @@ -1967,7 +1978,11 @@ FindSubFontForChar( { int i, j, k, numNames; Tk_Uid faceName; - char *fallback, **aliases, **nameList, **anyFallbacks, ***fontFallbacks; + const char *fallback; + const char *const *aliases; + char **nameList; + const char *const *anyFallbacks; + const char *const *const *fontFallbacks; SubFont *subFontPtr; Tcl_DString ds; @@ -2204,10 +2219,10 @@ FontMapLoadPage( Tcl_Encoding encoding; XFontStruct *fontStructPtr; XCharStruct *widths; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - subFontPtr->fontMap[row] = (char *) ckalloc(FONTMAP_BITSPERPAGE / 8); + subFontPtr->fontMap[row] = ckalloc(FONTMAP_BITSPERPAGE / 8); memset(subFontPtr->fontMap[row], 0, FONTMAP_BITSPERPAGE / 8); if (subFontPtr->familyPtr == &tsdPtr->controlFamily) { @@ -2285,7 +2300,7 @@ static SubFont * CanUseFallbackWithAliases( UnixFont *fontPtr, /* The font object that will own the new * screen font. */ - char *faceName, /* Desired face name for new screen font. */ + const char *faceName, /* Desired face name for new screen font. */ int ch, /* The Unicode character that the new screen * font must be able to display. */ Tcl_DString *nameTriedPtr, /* Records face names that have already been @@ -2296,7 +2311,7 @@ CanUseFallbackWithAliases( * reallocate our subfont table. */ { SubFont *subFontPtr; - char **aliases; + const char *const *aliases; int i; if (SeenName(faceName, nameTriedPtr) == 0) { @@ -2341,11 +2356,11 @@ CanUseFallbackWithAliases( static int SeenName( - CONST char *name, /* The name to check. */ + const char *name, /* The name to check. */ Tcl_DString *dsPtr) /* Contains names that have already been * seen. */ { - CONST char *seen, *end; + const char *seen, *end; seen = Tcl_DStringValue(dsPtr); end = seen + Tcl_DStringLength(dsPtr); @@ -2355,7 +2370,7 @@ SeenName( } seen += strlen(seen) + 1; } - Tcl_DStringAppend(dsPtr, (char *) name, (int) (strlen(name) + 1)); + Tcl_DStringAppend(dsPtr, name, (int) (strlen(name) + 1)); return 0; } @@ -2390,7 +2405,7 @@ static SubFont * CanUseFallback( UnixFont *fontPtr, /* The font object that will own the new * screen font. */ - CONST char *faceName, /* Desired face name for new screen font. */ + const char *faceName, /* Desired face name for new screen font. */ int ch, /* The Unicode character that the new screen * font must be able to display. */ SubFont **fixSubFontPtrPtr) /* Subfont reference to fix up if we @@ -2398,9 +2413,11 @@ CanUseFallback( { int i, nameIdx, numNames, srcLen, numEncodings, bestIdx[2]; Tk_Uid hateFoundry; - CONST char *charset, *hateCharset; - unsigned int bestScore[2]; - char **nameList, **nameListOrig, src[TCL_UTF_MAX]; + const char *charset, *hateCharset; + unsigned bestScore[2]; + char **nameList; + char **nameListOrig; + char src[TCL_UTF_MAX]; FontAttributes want, got; Display *display; SubFont subFont; @@ -2436,7 +2453,7 @@ CanUseFallback( want.xa = fontPtr->xa; want.fa.family = Tk_GetUid(faceName); - want.fa.size = -fontPtr->pixelSize; + want.fa.size = (double)-fontPtr->pixelSize; hateFoundry = NULL; hateCharset = NULL; @@ -2448,13 +2465,13 @@ CanUseFallback( retry: bestIdx[0] = -1; bestIdx[1] = -1; - bestScore[0] = (unsigned int) -1; - bestScore[1] = (unsigned int) -1; + bestScore[0] = (unsigned) -1; + bestScore[1] = (unsigned) -1; for (nameIdx = 0; nameIdx < numNames; nameIdx++) { Tcl_Encoding encoding; char dst[16]; int scalable, srcRead, dstWrote; - unsigned int score; + unsigned score; if (nameList[nameIdx] == NULL) { continue; @@ -2519,7 +2536,7 @@ CanUseFallback( * D. Rank each name and pick the best match. */ - scalable = (got.fa.size == 0); + scalable = (got.fa.size == 0.0); score = RankAttributes(&want, &got); if (score < bestScore[scalable]) { bestIdx[scalable] = nameIdx; @@ -2537,7 +2554,7 @@ CanUseFallback( * make a copy. */ - nameList = (char **) ckalloc(numNames * sizeof(char *)); + nameList = ckalloc(numNames * sizeof(char *)); memcpy(nameList, nameListOrig, numNames * sizeof(char *)); } nameList[nameIdx] = NULL; @@ -2555,7 +2572,7 @@ CanUseFallback( if (fontStructPtr == NULL) { if (nameList != nameListOrig) { - ckfree((char *) nameList); + ckfree(nameList); } XFreeFontNames(nameListOrig); return NULL; @@ -2575,16 +2592,15 @@ CanUseFallback( goto retry; } if (nameList != nameListOrig) { - ckfree((char *) nameList); + ckfree(nameList); } XFreeFontNames(nameListOrig); if (fontPtr->numSubFonts >= SUBFONT_SPACE) { SubFont *newPtr; - newPtr = (SubFont *) - ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1)); - memcpy((char *) newPtr, fontPtr->subFontArray, + newPtr = ckalloc(sizeof(SubFont) * (fontPtr->numSubFonts + 1)); + memcpy(newPtr, fontPtr->subFontArray, fontPtr->numSubFonts * sizeof(SubFont)); if (fixSubFontPtrPtr != NULL) { register SubFont *fixSubFontPtr = *fixSubFontPtrPtr; @@ -2595,7 +2611,7 @@ CanUseFallback( } } if (fontPtr->subFontArray != fontPtr->staticSubFonts) { - ckfree((char *) fontPtr->subFontArray); + ckfree(fontPtr->subFontArray); } fontPtr->subFontArray = newPtr; } @@ -2622,12 +2638,12 @@ CanUseFallback( *--------------------------------------------------------------------------- */ -static unsigned int +static unsigned RankAttributes( FontAttributes *wantPtr, /* The desired attributes. */ FontAttributes *gotPtr) /* The attributes we have to live with. */ { - unsigned int penalty; + unsigned penalty; penalty = 0; if (gotPtr->xa.foundry != wantPtr->xa.foundry) { @@ -2649,7 +2665,7 @@ RankAttributes( penalty += 1000; } - if (gotPtr->fa.size == 0) { + if (gotPtr->fa.size == 0.0) { /* * A scalable font is almost always acceptable, but the corresponding * bitmapped font would be better. @@ -2663,18 +2679,18 @@ RankAttributes( * It's worse to be too large than to be too small. */ - diff = (-gotPtr->fa.size - -wantPtr->fa.size); + diff = (int) (150 * (-gotPtr->fa.size - -wantPtr->fa.size)); if (diff > 0) { penalty += 600; } else if (diff < 0) { penalty += 150; diff = -diff; } - penalty += 150 * diff; + penalty += diff; } if (gotPtr->xa.charset != wantPtr->xa.charset) { int i; - CONST char *gotAlias, *wantAlias; + const char *gotAlias, *wantAlias; penalty += 65000; gotAlias = GetEncodingAlias(gotPtr->xa.charset); @@ -2719,7 +2735,7 @@ GetScreenFont( char **nameList, /* Array of XLFDs. */ int bestIdx[2], /* Indices into above array for XLFD of best * bitmapped and best scalable font. */ - unsigned int bestScore[2]) /* Scores of best bitmapped and best scalable + unsigned bestScore[2]) /* Scores of best bitmapped and best scalable * font. XLFD corresponding to lowest score * will be constructed. */ { @@ -2757,7 +2773,7 @@ GetScreenFont( } *str = '\0'; sprintf(buf, "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]], - -wantPtr->fa.size, rest); + (int)(-wantPtr->fa.size+0.5), rest); *str = '-'; fontStructPtr = XLoadQueryFont(display, buf); bestScore[1] = INT_MAX; @@ -2888,7 +2904,7 @@ GetFontAttributes( static char ** ListFonts( Display *display, /* Display to query. */ - CONST char *faceName, /* Desired face name, or "*" for all. */ + const char *faceName, /* Desired face name, or "*" for all. */ int *numNamesPtr) /* Filled with length of returned array, or 0 * if no names were found. */ { @@ -2901,11 +2917,12 @@ ListFonts( static char ** ListFontOrAlias( Display *display, /* Display to query. */ - CONST char *faceName, /* Desired face name, or "*" for all. */ + const char *faceName, /* Desired face name, or "*" for all. */ int *numNamesPtr) /* Filled with length of returned array, or 0 * if no names were found. */ { - char **nameList, **aliases; + char **nameList; + const char *const *aliases; int i; nameList = ListFonts(display, faceName, numNamesPtr); @@ -2954,7 +2971,8 @@ IdentifySymbolEncodings( FontAttributes *faPtr) { int i, j; - char **aliases, **symbolClass; + const char *const *aliases; + const char *const *symbolClass; symbolClass = TkFontGetSymbolClass(); for (i = 0; symbolClass[i] != NULL; i++) { @@ -2993,14 +3011,14 @@ IdentifySymbolEncodings( *--------------------------------------------------------------------------- */ -static CONST char * +static const char * GetEncodingAlias( - CONST char *name) /* The name to look up. */ + const char *name) /* The name to look up. */ { EncodingAlias *aliasPtr; for (aliasPtr = encodingAliases; aliasPtr->aliasPattern != NULL; ) { - if (Tcl_StringMatch((char *) name, aliasPtr->aliasPattern)) { + if (Tcl_StringMatch(name, aliasPtr->aliasPattern)) { return aliasPtr->realName; } aliasPtr++; @@ -3009,6 +3027,305 @@ GetEncodingAlias( } /* + *--------------------------------------------------------------------------- + * + * TkDrawAngledChars -- + * + * Draw some characters at an angle. This is awkward here because we have + * no reliable way of drawing any characters at an angle in classic X11; + * we have to draw on a Pixmap which is converted to an XImage (from + * helper function GetImageOfText), rotate the image (hokey code!) onto + * another XImage (from helper function InitDestImage), and then use the + * rotated image as a mask when drawing. This is pretty awful; improved + * versions are welcomed! + * + * Results: + * None. + * + * Side effects: + * Target drawable is updated. + * + *--------------------------------------------------------------------------- + */ + +static inline XImage * +GetImageOfText( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + Tk_Font tkfont, /* Font in which characters will be drawn. */ + const char *source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are not + * stripped out, they will be displayed as + * regular printing characters. */ + int numBytes, /* Number of bytes in string. */ + int *realWidthPtr, int *realHeightPtr) +{ + int width, height; + TkFont *fontPtr = (TkFont *) tkfont; + Pixmap bitmap; + GC bitmapGC; + XGCValues values; + XImage *image; + + (void) Tk_MeasureChars(tkfont, source, numBytes, -1, 0, &width); + height = fontPtr->fm.ascent + fontPtr->fm.descent; + + bitmap = Tk_GetPixmap(display, drawable, width, height, 1); + values.graphics_exposures = False; + values.foreground = BlackPixel(display, DefaultScreen(display)); + bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground, + &values); + XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height); + + values.font = Tk_FontId(tkfont); + values.foreground = WhitePixel(display, DefaultScreen(display)); + values.background = BlackPixel(display, DefaultScreen(display)); + XChangeGC(display, bitmapGC, GCFont|GCForeground|GCBackground, &values); + Tk_DrawChars(display, bitmap, bitmapGC, tkfont, source, numBytes, 0, + fontPtr->fm.ascent); + XFreeGC(display, bitmapGC); + + image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes, + ZPixmap); + Tk_FreePixmap(display, bitmap); + + *realWidthPtr = width; + *realHeightPtr = height; + return image; +} + +static inline XImage * +InitDestImage( + Display *display, + Drawable drawable, + int width, + int height, + Pixmap *bitmapPtr) +{ + Pixmap bitmap; + XImage *image; + GC bitmapGC; + XGCValues values; + + bitmap = Tk_GetPixmap(display, drawable, width, height, 1); + values.graphics_exposures = False; + values.foreground = BlackPixel(display, DefaultScreen(display)); + bitmapGC = XCreateGC(display, bitmap, GCGraphicsExposures|GCForeground, + &values); + XFillRectangle(display, bitmap, bitmapGC, 0, 0, width, height); + XFreeGC(display, bitmapGC); + + image = XGetImage(display, bitmap, 0, 0, width, height, AllPlanes, + ZPixmap); + *bitmapPtr = bitmap; + return image; +} + +void +TkDrawAngledChars( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context for drawing characters. */ + Tk_Font tkfont, /* Font in which characters will be drawn; + * must be the same as font used in GC. */ + const char *source, /* UTF-8 string to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are not + * stripped out, they will be displayed as + * regular printing characters. */ + int numBytes, /* Number of bytes in string. */ + double x, double y, + double angle) +{ + if (angle == 0.0) { + Tk_DrawChars(display, drawable, gc, tkfont, source, numBytes, x, y); + } else { + double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0); + int bufHeight, bufWidth, srcWidth, srcHeight, i, j, dx, dy; + Pixmap buf; + XImage *srcImage = GetImageOfText(display, drawable, tkfont, source, + numBytes, &srcWidth, &srcHeight); + XImage *dstImage; + enum {Q0=1,R1,Q1,R2,Q2,R3,Q3} quadrant; + GC bwgc, cpgc; + XGCValues values; + int ascent = ((TkFont *) tkfont)->fm.ascent; + + /* + * First, work out what quadrant we are operating in. We also handle + * the rectilinear rotations as special cases. Conceptually, there's + * also R0 (angle == 0.0) but that has been already handled as a + * special case above. + * + * R1 + * Q1 | Q0 + * | + * R2 ----+---- R0 + * | + * Q2 | Q3 + * R3 + */ + + if (angle < 90.0) { + quadrant = Q0; + } else if (angle == 90.0) { + quadrant = R1; + } else if (angle < 180.0) { + quadrant = Q1; + } else if (angle == 180.0) { + quadrant = R2; + } else if (angle < 270.0) { + quadrant = Q2; + } else if (angle == 270.0) { + quadrant = R3; + } else { + quadrant = Q3; + } + + if (srcImage == NULL) { + return; + } + bufWidth = srcWidth*fabs(cosA) + srcHeight*fabs(sinA); + bufHeight = srcHeight*fabs(cosA) + srcWidth*fabs(sinA); + dstImage = InitDestImage(display, drawable, bufWidth,bufHeight, &buf); + if (dstImage == NULL) { + Tk_FreePixmap(display, buf); + XDestroyImage(srcImage); + return; + } + + /* + * Do the rotation, setting or resetting pixels in the destination + * image dependent on whether the corresponding pixel (after rotation + * to source image space) is set. + */ + + for (i=0 ; i<srcWidth ; i++) { + for (j=0 ; j<srcHeight ; j++) { + switch (quadrant) { + case Q0: + dx = ROUND16(i*cosA + j*sinA); + dy = ROUND16(j*cosA + (srcWidth - i)*sinA); + break; + case R1: + dx = j; + dy = srcWidth - i; + break; + case Q1: + dx = ROUND16((i - srcWidth)*cosA + j*sinA); + dy = ROUND16((srcWidth-i)*sinA + (j-srcHeight)*cosA); + break; + case R2: + dx = srcWidth - i; + dy = srcHeight - j; + break; + case Q2: + dx = ROUND16((i-srcWidth)*cosA + (j-srcHeight)*sinA); + dy = ROUND16((j - srcHeight)*cosA - i*sinA); + break; + case R3: + dx = srcHeight - j; + dy = i; + break; + default: + dx = ROUND16(i*cosA + (j - srcHeight)*sinA); + dy = ROUND16(j*cosA - i*sinA); + } + + if (dx < 0 || dy < 0 || dx >= bufWidth || dy >= bufHeight) { + continue; + } + XPutPixel(dstImage, dx, dy, + XGetPixel(dstImage,dx,dy) | XGetPixel(srcImage,i,j)); + } + } + XDestroyImage(srcImage); + + /* + * Schlep the data back to the Xserver. + */ + + values.function = GXcopy; + values.foreground = WhitePixel(display, DefaultScreen(display)); + values.background = BlackPixel(display, DefaultScreen(display)); + bwgc = XCreateGC(display, buf, GCFunction|GCForeground|GCBackground, + &values); + XPutImage(display, buf, bwgc, dstImage, 0,0, 0,0, bufWidth,bufHeight); + XFreeGC(display, bwgc); + XDestroyImage(dstImage); + + /* + * Calculate where we want to draw the text. + */ + + switch (quadrant) { + case Q0: + dx = x; + dy = y - srcWidth*sinA; + break; + case R1: + dx = x; + dy = y - srcWidth; + break; + case Q1: + dx = x + srcWidth*cosA; + dy = y + srcHeight*cosA - srcWidth*sinA; + break; + case R2: + dx = x - srcWidth; + dy = y - srcHeight; + break; + case Q2: + dx = x + srcWidth*cosA + srcHeight*sinA; + dy = y + srcHeight*cosA; + break; + case R3: + dx = x - srcHeight; + dy = y; + break; + default: + dx = x + srcHeight*sinA; + dy = y; + } + + /* + * Apply a correction to deal with the fact that we aren't told to + * draw from our top-left corner but rather from the left-end of our + * baseline. + */ + + dx -= ascent*sinA; + dy -= ascent*cosA; + + /* + * Transfer the text to the screen. This is done by using it as a mask + * and then drawing through that mask with the original drawing color. + */ + + values.function = GXcopy; + values.fill_style = FillSolid; + values.clip_mask = buf; + values.clip_x_origin = dx; + values.clip_y_origin = dy; + cpgc = XCreateGC(display, drawable, + GCFunction|GCFillStyle|GCClipMask|GCClipXOrigin|GCClipYOrigin, + &values); + XCopyGC(display, gc, GCForeground, cpgc); + XFillRectangle(display, drawable, cpgc, dx, dy, bufWidth, + bufHeight); + XFreeGC(display, cpgc); + + Tk_FreePixmap(display, buf); + return; + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 |