summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixFont.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tkUnixFont.c')
-rw-r--r--unix/tkUnixFont.c475
1 files changed, 391 insertions, 84 deletions
diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c
index d97723b..62f594b 100644
--- a/unix/tkUnixFont.c
+++ b/unix/tkUnixFont.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkUnixFont.c,v 1.33 2007/02/28 09:23:30 dkf Exp $
+ * RCS: @(#) $Id: tkUnixFont.c,v 1.43 2010/12/02 11:38:29 dkf Exp $
*/
#include "tkUnixInt.h"
@@ -21,7 +21,7 @@
* The preferred font encodings.
*/
-static CONST char *encodingList[] = {
+static const char *const encodingList[] = {
"iso8859-1", "jis0208", "jis0212", NULL
};
@@ -139,9 +139,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;
@@ -207,31 +207,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,
@@ -239,21 +239,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);
@@ -281,7 +281,7 @@ static void
FontPkgCleanup(
ClientData clientData)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->controlFamily.encoding != NULL) {
@@ -320,7 +320,7 @@ void
TkpFontPkgInit(
TkMainInfo *mainPtr) /* The application being created. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_EncodingType type;
SubFont dummy;
@@ -382,7 +382,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
@@ -406,7 +406,7 @@ 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 result;
@@ -475,7 +475,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
@@ -499,7 +499,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;
@@ -558,7 +558,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
@@ -582,7 +582,7 @@ 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;
@@ -658,12 +658,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;
/*
@@ -765,7 +765,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;
@@ -847,8 +847,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++) {
@@ -876,11 +874,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);
}
@@ -913,7 +913,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;
@@ -924,6 +924,7 @@ TkpGetSubFonts(
listPtr = Tcl_NewListObj(3, objv);
Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
}
+ Tcl_SetObjResult(interp, resultPtr);
}
/*
@@ -960,6 +961,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;
}
@@ -988,7 +990,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. */
@@ -1027,7 +1029,7 @@ Tk_MeasureChars(
curX = 0;
curByte = 0;
} else if (maxLength < 0) {
- CONST char *p, *end, *next;
+ const char *p, *end, *next;
Tcl_UniChar ch;
SubFont *thisSubFontPtr;
FontFamily *familyPtr;
@@ -1080,11 +1082,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
@@ -1106,14 +1108,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) {
@@ -1202,7 +1204,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. */
@@ -1255,7 +1257,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
@@ -1266,22 +1268,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
@@ -1394,7 +1394,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
@@ -1443,9 +1443,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;
@@ -1453,7 +1453,7 @@ CreateClosestFont(
int numNames, nameIdx, bestIdx[2];
Display *display;
XFontStruct *fontStructPtr;
- unsigned int bestScore[2];
+ unsigned bestScore[2];
want.fa = *faPtr;
want.xa = *xaPtr;
@@ -1483,9 +1483,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++) {
@@ -1515,12 +1515,12 @@ 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;
@@ -1576,7 +1576,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;
@@ -1829,7 +1829,7 @@ AllocFontFamily(
FontFamily *familyPtr;
FontAttributes fa;
Tcl_Encoding encoding;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
GetFontAttributes(display, fontStructPtr, &fa);
@@ -1903,7 +1903,7 @@ FreeFontFamily(
FontFamily *familyPtr) /* The FontFamily to delete. */
{
FontFamily **familyPtrPtr;
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
int i;
@@ -1969,7 +1969,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;
@@ -2206,7 +2210,7 @@ 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);
@@ -2287,7 +2291,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
@@ -2298,7 +2302,7 @@ CanUseFallbackWithAliases(
* reallocate our subfont table. */
{
SubFont *subFontPtr;
- char **aliases;
+ const char *const *aliases;
int i;
if (SeenName(faceName, nameTriedPtr) == 0) {
@@ -2343,11 +2347,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);
@@ -2357,7 +2361,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;
}
@@ -2392,7 +2396,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
@@ -2400,9 +2404,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;
@@ -2450,13 +2456,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;
@@ -2624,12 +2630,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) {
@@ -2676,7 +2682,7 @@ RankAttributes(
}
if (gotPtr->xa.charset != wantPtr->xa.charset) {
int i;
- CONST char *gotAlias, *wantAlias;
+ const char *gotAlias, *wantAlias;
penalty += 65000;
gotAlias = GetEncodingAlias(gotPtr->xa.charset);
@@ -2721,7 +2727,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. */
{
@@ -2890,7 +2896,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. */
{
@@ -2903,11 +2909,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);
@@ -2956,7 +2963,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++) {
@@ -2995,14 +3003,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++;
@@ -3011,6 +3019,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