diff options
Diffstat (limited to 'generic/tkFont.c')
-rw-r--r-- | generic/tkFont.c | 810 |
1 files changed, 593 insertions, 217 deletions
diff --git a/generic/tkFont.c b/generic/tkFont.c index 1a6474f..32d0589 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -163,7 +163,7 @@ static const TkStateMap xlfdSetwidthMap[] = { * configuring a set of font attributes. */ -static const char *fontOpt[] = { +static const char *const fontOpt[] = { "-family", "-size", "-weight", @@ -188,27 +188,27 @@ static const char *fontOpt[] = { * the alias list are also automatically tried. */ -static char *timesAliases[] = { +static const char *const timesAliases[] = { "Times", /* Unix. */ "Times New Roman", /* Windows. */ "New York", /* Mac. */ NULL }; -static char *helveticaAliases[] = { +static const char *const helveticaAliases[] = { "Helvetica", /* Unix. */ "Arial", /* Windows. */ "Geneva", /* Mac. */ NULL }; -static char *courierAliases[] = { +static const char *const courierAliases[] = { "Courier", /* Unix and Mac. */ "Courier New", /* Windows. */ NULL }; -static char *minchoAliases[] = { +static const char *const minchoAliases[] = { "mincho", /* Unix. */ "\357\274\255\357\274\263 \346\230\216\346\234\235", /* Windows (MS mincho). */ @@ -217,7 +217,7 @@ static char *minchoAliases[] = { NULL }; -static char *gothicAliases[] = { +static const char *const gothicAliases[] = { "gothic", /* Unix. */ "\357\274\255\357\274\263 \343\202\264\343\202\267\343\203\203\343\202\257", /* Windows (MS goshikku). */ @@ -226,7 +226,7 @@ static char *gothicAliases[] = { NULL }; -static char *dingbatsAliases[] = { +static const char *const dingbatsAliases[] = { "dingbats", "zapfdingbats", "itc zapfdingbats", /* Unix. */ /* Windows. */ @@ -234,7 +234,7 @@ static char *dingbatsAliases[] = { NULL }; -static char **fontAliases[] = { +static const char *const *const fontAliases[] = { timesAliases, helveticaAliases, courierAliases, @@ -250,7 +250,7 @@ static char **fontAliases[] = { * be examined also. */ -static char *systemClass[] = { +static const char *const systemClass[] = { "fixed", /* Unix. */ /* Windows. */ "chicago", "osaka", "sistemny", @@ -258,7 +258,7 @@ static char *systemClass[] = { NULL }; -static char *serifClass[] = { +static const char *const serifClass[] = { "times", "palatino", "mincho", /* All platforms. */ "song ti", /* Unix. */ @@ -268,7 +268,7 @@ static char *serifClass[] = { NULL }; -static char *sansClass[] = { +static const char *const sansClass[] = { "helvetica", "gothic", /* All platforms. */ /* Unix. */ "ms sans serif", "traditional arabic", @@ -277,7 +277,7 @@ static char *sansClass[] = { NULL }; -static char *monoClass[] = { +static const char *const monoClass[] = { "courier", "gothic", /* All platforms. */ "fangsong ti", /* Unix. */ "simplified arabic fixed", /* Windows. */ @@ -285,11 +285,11 @@ static char *monoClass[] = { NULL }; -static char *symbolClass[] = { +static const char *const symbolClass[] = { "symbol", "dingbats", "wingdings", NULL }; -static char **fontFallbacks[] = { +static const char *const *const fontFallbacks[] = { systemClass, serifClass, sansClass, @@ -304,7 +304,7 @@ static char **fontFallbacks[] = { * found, all font families in the system are examined. */ -static char *globalFontClass[] = { +static const char *const globalFontClass[] = { "symbol", /* All platforms. */ /* Unix. */ "lucida sans unicode", /* Windows. */ @@ -325,6 +325,7 @@ static int ConfigAttributesObj(Tcl_Interp *interp, TkFontAttributes *faPtr); static void DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); static int FieldSpecified(const char *field); +static void FreeFontObj(Tcl_Obj *objPtr); static void FreeFontObjProc(Tcl_Obj *objPtr); static int GetAttributeInfoObj(Tcl_Interp *interp, const TkFontAttributes *faPtr, Tcl_Obj *objPtr); @@ -345,7 +346,7 @@ static void UpdateDependentFonts(TkFontInfo *fiPtr, * font object points to the TkFont structure for the font, or NULL. */ -Tcl_ObjType tkFontObjType = { +const Tcl_ObjType tkFontObjType = { "font", /* name */ FreeFontObjProc, /* freeIntRepProc */ DupFontObjProc, /* dupIntRepProc */ @@ -376,9 +377,8 @@ void TkFontPkgInit( TkMainInfo *mainPtr) /* The application being created. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ckalloc(sizeof(TkFontInfo)); - fiPtr = (TkFontInfo *) ckalloc(sizeof(TkFontInfo)); Tcl_InitHashTable(&fiPtr->fontCache, TCL_STRING_KEYS); Tcl_InitHashTable(&fiPtr->namedTable, TCL_STRING_KEYS); fiPtr->mainPtr = mainPtr; @@ -410,14 +410,11 @@ void TkFontPkgFree( TkMainInfo *mainPtr) /* The application being deleted. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = mainPtr->fontInfoPtr; Tcl_HashEntry *hPtr, *searchPtr; Tcl_HashSearch search; - int fontsLeft; + int fontsLeft = 0; - fiPtr = mainPtr->fontInfoPtr; - - fontsLeft = 0; for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); searchPtr != NULL; searchPtr = Tcl_NextHashEntry(&search)) { @@ -438,14 +435,14 @@ TkFontPkgFree( hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (hPtr != NULL) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree(Tcl_GetHashValue(hPtr)); hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fiPtr->namedTable); if (fiPtr->updatePending != 0) { - Tcl_CancelIdleCall(TheWorldHasChanged, (ClientData) fiPtr); + Tcl_CancelIdleCall(TheWorldHasChanged, fiPtr); } - ckfree((char *) fiPtr); + ckfree(fiPtr); } /* @@ -473,9 +470,9 @@ Tk_FontObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int index; - Tk_Window tkwin; - TkFontInfo *fiPtr; - static const char *optionStrings[] = { + Tk_Window tkwin = clientData; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; + static const char *const optionStrings[] = { "actual", "configure", "create", "delete", "families", "measure", "metrics", "names", NULL @@ -485,9 +482,6 @@ Tk_FontObjCmd( FONT_FAMILIES, FONT_MEASURE, FONT_METRICS, FONT_NAMES }; - tkwin = (Tk_Window) clientData; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); return TCL_ERROR; @@ -528,7 +522,7 @@ Tk_FontObjCmd( s = Tcl_GetString(objv[n]); if (s[0] == '-' && s[1] != '-') { optPtr = objv[n]; - ++n; + n++; } else { optPtr = NULL; } @@ -540,7 +534,7 @@ Tk_FontObjCmd( if (n < objc) { if (!strcmp(Tcl_GetString(objv[n]), "--")) { - ++n; + n++; } } @@ -550,7 +544,7 @@ Tk_FontObjCmd( if (n < objc) { charPtr = objv[n]; - ++n; + n++; } /* @@ -606,20 +600,20 @@ Tk_FontObjCmd( } case FONT_CONFIGURE: { int result; - char *string; + const char *string; Tcl_Obj *objPtr; NamedFont *nfPtr; Tcl_HashEntry *namedHashPtr; if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?"); + Tcl_WrongNumArgs(interp, 2, objv, "fontname ?-option value ...?"); return TCL_ERROR; } string = Tcl_GetString(objv[2]); namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); nfPtr = NULL; /* lint. */ if (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); } if ((namedHashPtr == NULL) || (nfPtr->deletePending != 0)) { Tcl_AppendResult(interp, "named font \"", string, @@ -639,13 +633,12 @@ Tk_FontObjCmd( return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); } case FONT_CREATE: { - int skip, i; - char *name; + int skip = 3, i; + const char *name; char buf[16 + TCL_INTEGER_SPACE]; TkFontAttributes fa; Tcl_HashEntry *namedHashPtr; - skip = 3; if (objc < 3) { name = NULL; } else { @@ -682,7 +675,7 @@ Tk_FontObjCmd( } case FONT_DELETE: { int i, result = TCL_OK; - char *string; + const char *string; /* * Delete the named font. If there are still widgets using this font, @@ -700,9 +693,8 @@ Tk_FontObjCmd( return result; } case FONT_FAMILIES: { - int skip; + int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); - skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); if (skip < 0) { return TCL_ERROR; } @@ -714,10 +706,9 @@ Tk_FontObjCmd( break; } case FONT_MEASURE: { - char *string; + const char *string; Tk_Font tkfont; int length = 0, skip = 0; - Tcl_Obj *resultPtr; if (objc > 4) { skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); @@ -726,7 +717,8 @@ Tk_FontObjCmd( } } if (objc - skip != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "font ?-displayof window? text"); + Tcl_WrongNumArgs(interp, 2, objv, + "font ?-displayof window? text"); return TCL_ERROR; } tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); @@ -734,8 +726,8 @@ Tk_FontObjCmd( return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[3 + skip], &length); - resultPtr = Tcl_GetObjResult(interp); - Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length)); + Tcl_SetObjResult(interp, + Tcl_NewIntObj(Tk_TextWidth(tkfont, string, length))); Tk_FreeFont(tkfont); break; } @@ -743,7 +735,7 @@ Tk_FontObjCmd( Tk_Font tkfont; int skip, index, i; const TkFontMetrics *fmPtr; - static const char *switches[] = { + static const char *const switches[] = { "-ascent", "-descent", "-linespace", "-fixed", NULL }; @@ -764,12 +756,10 @@ Tk_FontObjCmd( objv += skip; fmPtr = GetFontMetrics(tkfont); if (objc == 3) { - char buf[64 + TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "-ascent %d -descent %d -linespace %d -fixed %d", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-ascent %d -descent %d -linespace %d -fixed %d", fmPtr->ascent, fmPtr->descent, - fmPtr->ascent + fmPtr->descent, fmPtr->fixed); - Tcl_AppendResult(interp, buf, NULL); + fmPtr->ascent + fmPtr->descent, fmPtr->fixed)); } else { if (Tcl_GetIndexFromObj(interp, objv[3], switches, "metric", 0, &index) != TCL_OK) { @@ -783,33 +773,35 @@ Tk_FontObjCmd( case 2: i = fmPtr->ascent + fmPtr->descent; break; case 3: i = fmPtr->fixed; break; } - Tcl_SetIntObj(Tcl_GetObjResult(interp), i); + Tcl_SetObjResult(interp, Tcl_NewIntObj(i)); } Tk_FreeFont(tkfont); break; } case FONT_NAMES: { - char *string; - NamedFont *nfPtr; Tcl_HashSearch search; Tcl_HashEntry *namedHashPtr; - Tcl_Obj *strPtr, *resultPtr; + Tcl_Obj *resultPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "names"); return TCL_ERROR; } - resultPtr = Tcl_GetObjResult(interp); + resultPtr = Tcl_NewObj(); namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + NamedFont *nfPtr = Tcl_GetHashValue(namedHashPtr); + if (nfPtr->deletePending == 0) { - string = Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr); - strPtr = Tcl_NewStringObj(string, -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); + char *string = Tcl_GetHashKey(&fiPtr->namedTable, + namedHashPtr); + + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(string, -1)); } namedHashPtr = Tcl_NextHashEntry(&search); } + Tcl_SetObjResult(interp, resultPtr); break; } } @@ -844,9 +836,8 @@ UpdateDependentFonts( Tcl_HashEntry *cacheHashPtr; Tcl_HashSearch search; TkFont *fontPtr; - NamedFont *nfPtr; + NamedFont *nfPtr = Tcl_GetHashValue(namedHashPtr); - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount == 0) { /* * Well nobody's using this named font, so don't have to tell any @@ -858,13 +849,13 @@ UpdateDependentFonts( cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); while (cacheHashPtr != NULL) { - for (fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + for (fontPtr = Tcl_GetHashValue(cacheHashPtr); fontPtr != NULL; fontPtr = fontPtr->nextPtr) { if (fontPtr->namedHashPtr == namedHashPtr) { TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa); if (fiPtr->updatePending == 0) { fiPtr->updatePending = 1; - Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData) fiPtr); + Tcl_DoWhenIdle(TheWorldHasChanged, fiPtr); } } } @@ -876,11 +867,9 @@ static void TheWorldHasChanged( ClientData clientData) /* Info about application's fonts. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = clientData; - fiPtr = (TkFontInfo *) clientData; fiPtr->updatePending = 0; - RecomputeWidgets(fiPtr->mainPtr->winPtr); } @@ -888,10 +877,11 @@ static void RecomputeWidgets( TkWindow *winPtr) /* Window to which command is sent. */ { - Tk_ClassWorldChangedProc *proc; - proc = Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc); + Tk_ClassWorldChangedProc *proc = + Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc); + if (proc != NULL) { - (*proc)(winPtr->instanceData); + proc(winPtr->instanceData); } /* @@ -949,17 +939,14 @@ TkCreateNamedFont( const char *name, /* Name for the new named font. */ TkFontAttributes *faPtr) /* Attributes for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *namedHashPtr; int isNew; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &isNew); - if (!isNew) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); if (nfPtr->deletePending == 0) { if (interp) { Tcl_AppendResult(interp, "named font \"", name, @@ -980,7 +967,7 @@ TkCreateNamedFont( return TCL_OK; } - nfPtr = (NamedFont *) ckalloc(sizeof(NamedFont)); + nfPtr = ckalloc(sizeof(NamedFont)); nfPtr->deletePending = 0; Tcl_SetHashValue(namedHashPtr, nfPtr); nfPtr->fa = *faPtr; @@ -1004,14 +991,12 @@ int TkDeleteNamedFont( Tcl_Interp *interp, /* Interp for error return (can be NULL). */ Tk_Window tkwin, /* A window associated with interp. */ - CONST char *name) /* Name for the new named font. */ + const char *name) /* Name for the new named font. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; NamedFont *nfPtr; Tcl_HashEntry *namedHashPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, name); if (namedHashPtr == NULL) { if (interp) { @@ -1020,12 +1005,12 @@ TkDeleteNamedFont( } return TCL_ERROR; } - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount != 0) { nfPtr->deletePending = 1; } else { Tcl_DeleteHashEntry(namedHashPtr); - ckfree((char *) nfPtr); + ckfree(nfPtr); } return TCL_OK; } @@ -1062,7 +1047,7 @@ Tk_GetFont( Tk_Font tkfont; Tcl_Obj *strPtr; - strPtr = Tcl_NewStringObj((char *) string, -1); + strPtr = Tcl_NewStringObj(string, -1); Tcl_IncrRefCount(strPtr); tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr); Tcl_DecrRefCount(strPtr); @@ -1098,19 +1083,17 @@ Tk_AllocFontFromObj( Tcl_Obj *objPtr) /* Object describing font, as: named font, * native format, or parseable string. */ { - TkFontInfo *fiPtr; + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; Tcl_HashEntry *cacheHashPtr, *namedHashPtr; TkFont *fontPtr, *firstFontPtr, *oldFontPtr; int isNew, descent; NamedFont *nfPtr; - fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; if (objPtr->typePtr != &tkFontObjType) { SetFontFromAny(interp, objPtr); } - oldFontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; - + oldFontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (oldFontPtr != NULL) { if (oldFontPtr->resourceRefCount == 0) { /* @@ -1118,7 +1101,7 @@ Tk_AllocFontFromObj( * longer in use. Clear the reference. */ - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); oldFontPtr = NULL; } else if (Tk_Screen(tkwin) == oldFontPtr->screen) { oldFontPtr->resourceRefCount++; @@ -1134,18 +1117,18 @@ Tk_AllocFontFromObj( isNew = 0; if (oldFontPtr != NULL) { cacheHashPtr = oldFontPtr->cacheHashPtr; - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); } else { cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr), &isNew); } - firstFontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + firstFontPtr = Tcl_GetHashValue(cacheHashPtr); for (fontPtr = firstFontPtr; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) { if (Tk_Screen(tkwin) == fontPtr->screen) { fontPtr->resourceRefCount++; fontPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; return (Tk_Font) fontPtr; } } @@ -1161,7 +1144,7 @@ Tk_AllocFontFromObj( * Construct a font based on a named font. */ - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + nfPtr = Tcl_GetHashValue(namedHashPtr); nfPtr->refCount++; fontPtr = TkpGetFontFromAttributes(NULL, tkwin, &nfPtr->fa); @@ -1253,7 +1236,7 @@ Tk_AllocFontFromObj( } } - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; return (Tk_Font) fontPtr; } @@ -1278,7 +1261,8 @@ Tk_AllocFontFromObj( Tk_Font Tk_GetFontFromObj( - Tk_Window tkwin, /* The window that the font will be used in. */ + Tk_Window tkwin, /* The window that the font will be used + * in. */ Tcl_Obj *objPtr) /* The object from which to get the font. */ { TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; @@ -1289,8 +1273,7 @@ Tk_GetFontFromObj( SetFontFromAny(NULL, objPtr); } - fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; - + fontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (fontPtr != NULL) { if (fontPtr->resourceRefCount == 0) { /* @@ -1298,7 +1281,7 @@ Tk_GetFontFromObj( * longer in use. Clear the reference. */ - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); fontPtr = NULL; } else if (Tk_Screen(tkwin) == fontPtr->screen) { return (Tk_Font) fontPtr; @@ -1312,16 +1295,16 @@ Tk_GetFontFromObj( if (fontPtr != NULL) { hashPtr = fontPtr->cacheHashPtr; - FreeFontObjProc(objPtr); + FreeFontObj(objPtr); } else { hashPtr = Tcl_FindHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr)); } if (hashPtr != NULL) { - for (fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); fontPtr != NULL; + for (fontPtr = Tcl_GetHashValue(hashPtr); fontPtr != NULL; fontPtr = fontPtr->nextPtr) { if (Tk_Screen(tkwin) == fontPtr->screen) { fontPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + objPtr->internalRep.twoPtrValue.ptr1 = fontPtr; return (Tk_Font) fontPtr; } } @@ -1363,7 +1346,7 @@ SetFontFromAny( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkFontObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -1394,9 +1377,8 @@ const char * Tk_NameOfFont( Tk_Font tkfont) /* Font whose name is desired. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->cacheHashPtr->key.string; } @@ -1421,13 +1403,12 @@ void Tk_FreeFont( Tk_Font tkfont) /* Font to be released. */ { - TkFont *fontPtr, *prevPtr; + TkFont *fontPtr = (TkFont *) tkfont, *prevPtr; NamedFont *nfPtr; - if (tkfont == NULL) { + if (fontPtr == NULL) { return; } - fontPtr = (TkFont *) tkfont; fontPtr->resourceRefCount--; if (fontPtr->resourceRefCount > 0) { return; @@ -1438,15 +1419,15 @@ Tk_FreeFont( * the named font and free it if no-one else is using it. */ - nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr); + nfPtr = Tcl_GetHashValue(fontPtr->namedHashPtr); nfPtr->refCount--; if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) { Tcl_DeleteHashEntry(fontPtr->namedHashPtr); - ckfree((char *) nfPtr); + ckfree(nfPtr); } } - prevPtr = (TkFont *) Tcl_GetHashValue(fontPtr->cacheHashPtr); + prevPtr = Tcl_GetHashValue(fontPtr->cacheHashPtr); if (prevPtr == fontPtr) { if (fontPtr->nextPtr == NULL) { Tcl_DeleteHashEntry(fontPtr->cacheHashPtr); @@ -1462,7 +1443,7 @@ Tk_FreeFont( TkpDeleteFont(fontPtr); if (fontPtr->objRefCount == 0) { - ckfree((char *) fontPtr); + ckfree(fontPtr); } } @@ -1496,7 +1477,7 @@ Tk_FreeFontFromObj( /* *--------------------------------------------------------------------------- * - * FreeFontObjProc -- + * FreeFontObjProc, FreeFontObj -- * * This proc is called to release an object reference to a font. Called * when the object's internal rep is released or when the cached fontPtr @@ -1516,12 +1497,20 @@ static void FreeFontObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkFont *fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; + FreeFontObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeFontObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkFont *fontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (fontPtr != NULL) { fontPtr->objRefCount--; if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) { - ckfree((char *) fontPtr); + ckfree(fontPtr); objPtr->internalRep.twoPtrValue.ptr1 = NULL; } } @@ -1550,10 +1539,10 @@ DupFontObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkFont *fontPtr = (TkFont *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkFont *fontPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) fontPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = fontPtr; if (fontPtr != NULL) { fontPtr->objRefCount++; @@ -1584,9 +1573,8 @@ Tk_FontId( Tk_Font tkfont) /* Font that is going to be selected into * GC. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; return fontPtr->fid; } @@ -1617,9 +1605,8 @@ Tk_GetFontMetrics( Tk_FontMetrics *fmPtr) /* Pointer to structure in which font metrics * for tkfont will be stored. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; - fontPtr = (TkFont *) tkfont; fmPtr->ascent = fontPtr->fm.ascent; fmPtr->descent = fontPtr->fm.descent; fmPtr->linespace = fontPtr->fm.ascent + fontPtr->fm.descent; @@ -1659,13 +1646,12 @@ Tk_PostscriptFontName( * which the name of the Postscript font that * corresponds to tkfont will be appended. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; Tk_Uid family, weightString, slantString; char *src, *dest; int upper, len; len = Tcl_DStringLength(dsPtr); - fontPtr = (TkFont *) tkfont; /* * Convert the case-insensitive Tk_Font family name to the case-sensitive @@ -1891,19 +1877,17 @@ TkUnderlineCharsInContext( int lastByte) /* Index of first byte after the last * character. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; int startX, endX; - fontPtr = (TkFont *) tkfont; - TkpMeasureCharsInContext(tkfont, string, numBytes, 0, firstByte, -1, 0, &startX); TkpMeasureCharsInContext(tkfont, string, numBytes, 0, lastByte, -1, 0, &endX); XFillRectangle(display, drawable, gc, x + startX, - y + fontPtr->underlinePos, (unsigned int) (endX - startX), - (unsigned int) fontPtr->underlineHeight); + y + fontPtr->underlinePos, (unsigned) (endX - startX), + (unsigned) fontPtr->underlineHeight); } /* @@ -1954,7 +1938,7 @@ Tk_ComputeTextLayout( int *widthPtr, /* Filled with width of string. */ int *heightPtr) /* Filled with height of string. */ { - TkFont *fontPtr; + TkFont *fontPtr = (TkFont *) tkfont; const char *start, *end, *special; int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight; int baseline, height, curX, newX, maxWidth, *lineLengths; @@ -1965,7 +1949,6 @@ Tk_ComputeTextLayout( Tcl_DStringInit(&lineBuffer); - fontPtr = (TkFont *) tkfont; if ((fontPtr == NULL) || (string == NULL)) { if (widthPtr != NULL) { *widthPtr = 0; @@ -1989,8 +1972,8 @@ Tk_ComputeTextLayout( maxChunks = 1; - layoutPtr = (TextLayout *) - ckalloc(sizeof(TextLayout) + (maxChunks-1) * sizeof(LayoutChunk)); + layoutPtr = ckalloc(sizeof(TextLayout) + + (maxChunks-1) * sizeof(LayoutChunk)); layoutPtr->tkfont = tkfont; layoutPtr->string = string; layoutPtr->numChunks = 0; @@ -2243,11 +2226,10 @@ void Tk_FreeTextLayout( Tk_TextLayout textLayout) /* The text layout to be released. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) textLayout; - layoutPtr = (TextLayout *) textLayout; if (layoutPtr != NULL) { - ckfree((char *) layoutPtr); + ckfree(layoutPtr); } } @@ -2275,7 +2257,8 @@ void Tk_DrawTextLayout( Display *display, /* Display on which to draw. */ Drawable drawable, /* Window or pixmap in which to draw. */ - GC gc, /* Graphics context to use for drawing text. */ + GC gc, /* Graphics context to use for drawing + * text. */ Tk_TextLayout layout, /* Layout information, from a previous call to * Tk_ComputeTextLayout(). */ int x, int y, /* Upper-left hand corner of rectangle in @@ -2287,13 +2270,11 @@ Tk_DrawTextLayout( * draw from the given text item. A number < 0 * means to draw all characters. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; int i, numDisplayChars, drawX; - const char *firstByte; - const char *lastByte; + const char *firstByte, *lastByte; LayoutChunk *chunkPtr; - layoutPtr = (TextLayout *) layout; if (layoutPtr == NULL) { return; } @@ -2318,9 +2299,78 @@ Tk_DrawTextLayout( numDisplayChars = lastChar; } lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); - Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, - firstByte, lastByte - firstByte, - x + chunkPtr->x + drawX, y + chunkPtr->y); + Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte, + lastByte - firstByte, x+chunkPtr->x+drawX, y+chunkPtr->y); + } + firstChar -= chunkPtr->numChars; + lastChar -= chunkPtr->numChars; + if (lastChar <= 0) { + break; + } + chunkPtr++; + } +} + +void +TkDrawAngledTextLayout( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context to use for drawing + * text. */ + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + double angle, + int firstChar, /* The index of the first character to draw + * from the given text item. 0 specfies the + * beginning. */ + int lastChar) /* The index just after the last character to + * draw from the given text item. A number < 0 + * means to draw all characters. */ +{ + TextLayout *layoutPtr = (TextLayout *) layout; + int i, numDisplayChars, drawX; + const char *firstByte, *lastByte; + LayoutChunk *chunkPtr; + double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0); + + if (layoutPtr == NULL) { + return; + } + + if (lastChar < 0) { + lastChar = 100000000; + } + chunkPtr = layoutPtr->chunks; + for (i = 0; i < layoutPtr->numChunks; i++) { + numDisplayChars = chunkPtr->numDisplayChars; + if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) { + double dx, dy; + + if (firstChar <= 0) { + drawX = 0; + firstChar = 0; + firstByte = chunkPtr->start; + } else { + firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar); + Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start, + firstByte - chunkPtr->start, -1, 0, &drawX); + } + if (lastChar < numDisplayChars) { + numDisplayChars = lastChar; + } + lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); + dx = cosA * (chunkPtr->x + drawX) + sinA * (chunkPtr->y); + dy = -sinA * (chunkPtr->x + drawX) + cosA * (chunkPtr->y); + if (angle == 0.0) { + Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, + firstByte, lastByte - firstByte, + (int)(x + dx), (int)(y + dy)); + } else { + TkDrawAngledChars(display, drawable, gc, layoutPtr->tkfont, + firstByte, lastByte - firstByte, x+dx, y+dy, angle); + } } firstChar -= chunkPtr->numChars; lastChar -= chunkPtr->numChars; @@ -2366,18 +2416,79 @@ Tk_UnderlineTextLayout( int underline) /* Index of the single character to underline, * or -1 for no underline. */ { - TextLayout *layoutPtr; - TkFont *fontPtr; int xx, yy, width, height; if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0) && (width != 0)) { - layoutPtr = (TextLayout *) layout; - fontPtr = (TkFont *) layoutPtr->tkfont; + TextLayout *layoutPtr = (TextLayout *) layout; + TkFont *fontPtr = (TkFont *) layoutPtr->tkfont; XFillRectangle(display, drawable, gc, x + xx, y + yy + fontPtr->fm.ascent + fontPtr->underlinePos, - (unsigned int) width, (unsigned int) fontPtr->underlineHeight); + (unsigned) width, (unsigned) fontPtr->underlineHeight); + } +} + +void +TkUnderlineAngledTextLayout( + Display *display, /* Display on which to draw. */ + Drawable drawable, /* Window or pixmap in which to draw. */ + GC gc, /* Graphics context to use for drawing + * text. */ + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + double angle, + int underline) /* Index of the single character to underline, + * or -1 for no underline. */ +{ + int xx, yy, width, height; + + if (angle == 0.0) { + Tk_UnderlineTextLayout(display, drawable, gc, layout, x,y, underline); + return; + } + + if ((Tk_CharBbox(layout, underline, &xx, &yy, &width, &height) != 0) + && (width != 0)) { + TextLayout *layoutPtr = (TextLayout *) layout; + TkFont *fontPtr = (TkFont *) layoutPtr->tkfont; + double sinA = sin(angle*PI/180), cosA = cos(angle*PI/180); + double dy = yy + fontPtr->fm.ascent + fontPtr->underlinePos; + XPoint points[5]; + + /* + * Note that we're careful to only round a double value once, which + * minimizes roundoff errors. + */ + + points[0].x = x + ROUND16(xx*cosA + dy*sinA); + points[0].y = y + ROUND16(dy*cosA - xx*sinA); + points[1].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA); + points[1].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA); + if (fontPtr->underlineHeight == 1) { + /* + * Thin underlines look better when rotated when drawn as a line + * rather than a rectangle; the rasterizer copes better. + */ + + XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin); + } else { + points[2].x = x + ROUND16(xx*cosA + dy*sinA + width*cosA + + fontPtr->underlineHeight*sinA); + points[2].y = y + ROUND16(dy*cosA - xx*sinA - width*sinA + + fontPtr->underlineHeight*cosA); + points[3].x = x + ROUND16(xx*cosA + dy*sinA + + fontPtr->underlineHeight*sinA); + points[3].y = y + ROUND16(dy*cosA - xx*sinA + + fontPtr->underlineHeight*cosA); + points[4].x = points[0].x; + points[4].y = points[0].y; + XFillPolygon(display, drawable, gc, points, 5, Complex, + CoordModeOrigin); + XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin); + } } } @@ -2421,7 +2532,7 @@ Tk_PointToChar( * to the upper-left corner of the text * layout. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr, *lastPtr; TkFont *fontPtr; int i, n, dummy, baseline, pos, numChars; @@ -2439,7 +2550,6 @@ Tk_PointToChar( * Find which line contains the point. */ - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; lastPtr = chunkPtr = layoutPtr->chunks; numChars = 0; @@ -2486,8 +2596,7 @@ Tk_PointToChar( return numChars; } n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start, - chunkPtr->numBytes, x - chunkPtr->x, - 0, &dummy); + chunkPtr->numBytes, x - chunkPtr->x, 0, &dummy); return numChars + Tcl_NumUtfChars(chunkPtr->start, n); } numChars += chunkPtr->numChars; @@ -2570,7 +2679,7 @@ Tk_CharBbox( * bounding box for the character specified by * index, if non-NULL. */ { - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; int i, x = 0, w; Tk_Font tkfont; @@ -2581,7 +2690,6 @@ Tk_CharBbox( return 0; } - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; tkfont = layoutPtr->tkfont; fontPtr = (TkFont *) tkfont; @@ -2682,11 +2790,10 @@ Tk_DistanceToTextLayout( * (in pixels). */ { int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; - TextLayout *layoutPtr; TkFont *fontPtr; - layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; ascent = fontPtr->fm.ascent; descent = fontPtr->fm.descent; @@ -2770,7 +2877,7 @@ Tk_IntersectTextLayout( * rectangular area, in pixels. */ { int result, i, x1, y1, x2, y2; - TextLayout *layoutPtr; + TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr; TkFont *fontPtr; int left, top, right, bottom; @@ -2782,7 +2889,6 @@ Tk_IntersectTextLayout( * and see if they were all inside or all outside. */ - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; fontPtr = (TkFont *) layoutPtr->tkfont; @@ -2793,10 +2899,11 @@ Tk_IntersectTextLayout( result = 0; for (i = 0; i < layoutPtr->numChunks; i++) { - if (chunkPtr->start[0] == '\n') { + if ((chunkPtr->start[0] == '\n') || (chunkPtr->numBytes==0)) { /* - * Newline characters are not counted when computing area - * intersection (but tab characters would still be considered). + * Newline characters and empty chunks are not counted when + * computing area intersection (but tab characters would still be + * considered). */ chunkPtr++; @@ -2830,6 +2937,263 @@ Tk_IntersectTextLayout( /* *--------------------------------------------------------------------------- * + * TkIntersectAngledTextLayout -- + * + * Determines whether a text layout that has been turned by an angle + * about its top-left coordinae lies entirely inside, entirely outside, + * or overlaps a given rectangle. Non-displaying space characters that + * occur at the end of individual lines in the text layout are ignored + * for intersection calculations. + * + * Results: + * The return value is -1 if the text layout is entirely outside of the + * rectangle, 0 if it overlaps, and 1 if it is entirely inside of the + * rectangle. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +static inline int +PointInQuadrilateral( + double qx[], + double qy[], + double x, + double y) +{ + int i; + + for (i=0 ; i<4 ; i++) { + double sideDX = qx[(i+1)%4] - qx[i]; + double sideDY = qy[(i+1)%4] - qy[i]; + double dx = x - qx[i]; + double dy = y - qy[i]; + + if (sideDX*dy < sideDY*dx) { + return 0; + } + } + return 1; +} + +static inline int +sign( + double value) +{ + return (value < 0.0) ? -1 : (value > 0.0) ? 1 : 0; +} + +static inline int +SidesIntersect( + double ax1, double ay1, double ax2, double ay2, + double bx1, double by1, double bx2, double by2) +{ +#if 0 +/* http://www.freelunchdesign.com/cgi-bin/codwiki.pl?DiscussionTopics/CollideMeUpBaby */ + + double a1, b1, c1, a2, b2, c2, r1, r2, r3, r4, denom; + + a1 = ay2 - ay1; + b1 = ax1 - ax2; + c1 = (ax2 * ay1) - (ax1 * ay2); + r3 = (a1 * bx1) + (b1 * by1) + c1; + r4 = (a1 * bx2) + (b1 * by2) + c1; + if ((r3 != 0.0) && (r4 != 0.0) && (r3*r4 > 0.0)) { + return 0; + } + + a2 = by2 - by1; + b2 = bx1 - bx2; + c2 = (bx2 * by1) - (bx1 * by2); + r1 = (a2 * ax1) + (b2 * ay1) + c2; + r2 = (a2 * ax2) + (b2 * ay2) + c2; + if ((r1 != 0.0) && (r2 != 0.0) && (r1*r2 > 0.0)) { + return 0; + } + + denom = (a1 * b2) - (a2 * b1); + return (denom != 0.0); +#else + /* + * A more efficient version. Two line segments intersect if, when seen + * from the perspective of one line, the two endpoints of the other + * segment lie on opposite sides of the line, and vice versa. "Lie on + * opposite sides" is computed by taking the cross products and seeing if + * they are of opposite signs. + */ + + double dx, dy, dx1, dy1; + + dx = ax2 - ax1; + dy = ay2 - ay1; + dx1 = bx1 - ax1; + dy1 = by1 - ay1; + if ((dx*dy1-dy*dx1 > 0.0) == (dx*(by2-ay1)-dy*(bx2-ax1) > 0.0)) { + return 0; + } + dx = bx2 - bx1; + dy = by2 - by1; + if ((dy*dx1-dx*dy1 > 0.0) == (dx*(ay2-by1)-dy*(ax2-bx1) > 0.0)) { + return 0; + } + return 1; +#endif +} + +int +TkIntersectAngledTextLayout( + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, int y, /* Upper-left hand corner, in pixels, of + * rectangular area to compare with text + * layout. Coordinates are with respect to the + * upper-left hand corner of the text layout + * itself. */ + int width, int height, /* The width and height of the above + * rectangular area, in pixels. */ + double angle) +{ + int i, x1, y1, x2, y2; + TextLayout *layoutPtr; + LayoutChunk *chunkPtr; + TkFont *fontPtr; + double c = cos(angle * PI/180.0), s = sin(angle * PI/180.0); + double rx[4], ry[4]; + + if (angle == 0.0) { + return Tk_IntersectTextLayout(layout, x, y, width, height); + } + + /* + * Compute the coordinates of the rectangle, rotated into text layout + * space. + */ + + rx[0] = x*c - y*s; + ry[0] = y*c + x*s; + rx[1] = (x+width)*c - y*s; + ry[1] = y*c + (x+width)*s; + rx[2] = (x+width)*c - (y+height)*s; + ry[2] = (y+height)*c + (x+width)*s; + rx[3] = x*c - (y+height)*s; + ry[3] = (y+height)*c + x*s; + + /* + * Want to know if all chunks are inside the rectangle, or if there is any + * overlap. First, we check to see if all chunks are inside; if and only + * if they are, we're in the "inside" case. + */ + + layoutPtr = (TextLayout *) layout; + chunkPtr = layoutPtr->chunks; + fontPtr = (TkFont *) layoutPtr->tkfont; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - fontPtr->fm.ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + fontPtr->fm.descent; + if ( !PointInQuadrilateral(rx, ry, x1, y1) || + !PointInQuadrilateral(rx, ry, x2, y1) || + !PointInQuadrilateral(rx, ry, x2, y2) || + !PointInQuadrilateral(rx, ry, x1, y2)) { + goto notInside; + } + } + return 1; + + /* + * Next, check to see if all the points of the rectangle are inside a + * single chunk; if they are, we're in an "overlap" case. + */ + + notInside: + chunkPtr = layoutPtr->chunks; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + double cx[4], cy[4]; + + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + cx[0] = cx[3] = chunkPtr->x; + cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent; + cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth; + cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent; + if ( !PointInQuadrilateral(cx, cy, rx[0], ry[0]) || + !PointInQuadrilateral(cx, cy, rx[1], ry[1]) || + !PointInQuadrilateral(cx, cy, rx[2], ry[2]) || + !PointInQuadrilateral(cx, cy, rx[3], ry[3])) { + goto notReverseInside; + } + } + return 0; + + /* + * If we're overlapping now, we must be partially in and out of at least + * one chunk. If that is the case, there must be one line segment of the + * rectangle that is touching or crossing a line segment of a chunk. + */ + + notReverseInside: + chunkPtr = layoutPtr->chunks; + + for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) { + int j; + + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - fontPtr->fm.ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + fontPtr->fm.descent; + + for (j=0 ; j<4 ; j++) { + int k = (j+1) % 4; + + if ( SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y1, x2,y1) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y1, x2,y2) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x2,y2, x1,y2) || + SidesIntersect(rx[j],ry[j], rx[k],ry[k], x1,y2, x1,y1)) { + return 0; + } + } + } + + /* + * They must be wholly non-overlapping. + */ + + return -1; +} + +/* + *--------------------------------------------------------------------------- + * * Tk_TextLayoutToPostscript -- * * Outputs the contents of a text layout in Postscript format. The set of @@ -2870,16 +3234,14 @@ Tk_TextLayoutToPostscript( Tcl_Interp *interp, /* Filled with Postscript code. */ Tk_TextLayout layout) /* The layout to be rendered. */ { + TextLayout *layoutPtr = (TextLayout *) layout; #define MAXUSE 128 - char buf[MAXUSE+30], uindex[5] = "\0\0\0\0", one_char[5]; + char buf[MAXUSE+30]; LayoutChunk *chunkPtr; - int i, j, used, c, baseline, charsize; + int i, j, used, baseline, charsize; Tcl_UniChar ch; - const char *p, *last_p, *glyphname; - TextLayout *layoutPtr; - int bytecount=0; + const char *p, *glyphname; - layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; baseline = chunkPtr->y; used = 0; @@ -2903,54 +3265,66 @@ Tk_TextLayoutToPostscript( p = chunkPtr->start; for (j = 0; j < chunkPtr->numDisplayChars; j++) { /* - * INTL: For now we just treat the characters as binary data - * and display the lower byte. Eventually this should be - * revised to handle international postscript fonts. + * INTL: We only handle symbols that have an encoding as a + * flyph from the standard set defined by Adobe. The rest get + * punted. Eventually this should be revised to handle more + * sophsticiated international postscript fonts. */ - last_p = p; - p += (charsize = Tcl_UtfToUniChar(p,&ch)); - Tcl_UtfToExternal(interp, NULL, last_p, charsize, 0, NULL, - one_char, 4, NULL, &bytecount, NULL); - if (bytecount == 1) { - c = UCHAR(one_char[0]); - /* c = UCHAR( ch & 0xFF) */; - if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) - || (c >= UCHAR(0x7f))) { - /* - * Tricky point: the "03" is necessary in the sprintf - * below, so that a full three digits of octal are - * always generated. Without the "03", a number - * following this sequence could be interpreted by - * Postscript as part of this sequence. - */ + charsize = Tcl_UtfToUniChar(p, &ch); + p += charsize; - sprintf(buf + used, "\\%03o", c); - used += 4; - } else { - buf[used++] = c; - } + if ((ch == '(') || (ch == ')') || (ch == '\\') + || (ch < 0x20)) { + /* + * Tricky point: the "03" is necessary in the sprintf + * below, so that a full three digits of octal are always + * generated. Without the "03", a number following this + * sequence could be interpreted by Postscript as part of + * this sequence. + */ + + sprintf(buf + used, "\\%03o", ch); + used += 4; + } else if (ch <= 0x7f) { + /* + * Normal ASCII character. + */ + + buf[used++] = (char) ch; } else { + char uindex[5]; + /* - * This character doesn't belong to system character set. - * So, we must use full glyph name. + * This character doesn't belong to the ASCII character + * set, so we use the full glyph name. */ sprintf(uindex, "%04X", ch); /* endianness? */ - glyphname = Tcl_GetVar2(interp,"::tk::psglyphs",uindex,0); + glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, + 0); if (glyphname) { - if (used > 0 && buf [used-1] == '(') { - --used; + if (used > 0 && buf[used-1] == '(') { + used--; } else { buf[used++] = ')'; } buf[used++] = '/'; - while ((*glyphname) && (used < (MAXUSE+27))) { - buf[used++] = *glyphname++ ; + while ((*glyphname) && (used < MAXUSE+27)) { + buf[used++] = *glyphname++; } buf[used++] = '('; - } + } else { + /* + * No known mapping for the character into the space + * of PostScript glyphs. Ignore it. :-( + */ +#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT + fprintf(stderr, "Warning: no mapping to PostScript " + "glyphs for \\u%04x\n", ch); +#endif + } } if (used >= MAXUSE) { buf[used] = '\0'; @@ -3011,7 +3385,7 @@ ConfigAttributesObj( { int i, n, index; Tcl_Obj *optionPtr, *valuePtr; - char *value; + const char *value; for (i = 0; i < objc; i += 2) { optionPtr = objv[i]; @@ -3110,9 +3484,7 @@ GetAttributeInfoObj( { int i, index, start, end; const char *str; - Tcl_Obj *optionPtr, *valuePtr, *resultPtr; - - resultPtr = Tcl_GetObjResult(interp); + Tcl_Obj *valuePtr, *resultPtr = NULL; start = 0; end = FONT_NUMFIELDS; @@ -3126,6 +3498,9 @@ GetAttributeInfoObj( } valuePtr = NULL; + if (objPtr == NULL) { + resultPtr = Tcl_NewObj(); + } for (i = start; i < end; i++) { switch (i) { case FONT_FAMILY: @@ -3159,10 +3534,11 @@ GetAttributeInfoObj( Tcl_SetObjResult(interp, valuePtr); return TCL_OK; } - optionPtr = Tcl_NewStringObj(fontOpt[i], -1); - Tcl_ListObjAppendElement(NULL, resultPtr, optionPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, + Tcl_NewStringObj(fontOpt[i], -1)); Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr); } + Tcl_SetObjResult(interp, resultPtr); return TCL_OK; } @@ -3204,7 +3580,7 @@ ParseFontNameObj( char *dash; int objc, result, i, n; Tcl_Obj **objv; - char *string; + const char *string; TkInitFontAttributes(faPtr); @@ -3367,7 +3743,7 @@ NewChunk( if (layoutPtr->numChunks == maxChunks) { maxChunks *= 2; s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk)); - layoutPtr = (TextLayout *) ckrealloc((char *) layoutPtr, s); + layoutPtr = ckrealloc(layoutPtr, s); *layoutPtrPtr = layoutPtr; *maxPtr = maxChunks; @@ -3439,7 +3815,7 @@ TkFontParseXLFD( } Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, (char *) str, -1); + Tcl_DStringAppend(&ds, str, -1); src = Tcl_DStringValue(&ds); field[0] = src; @@ -3710,7 +4086,7 @@ TkFontGetPoints( *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetAliasList( const char *faceName) /* Font name to test for aliases. */ { @@ -3743,7 +4119,7 @@ TkFontGetAliasList( *------------------------------------------------------------------------- */ -char *** +const char *const *const * TkFontGetFallbacks(void) { return fontFallbacks; @@ -3768,7 +4144,7 @@ TkFontGetFallbacks(void) *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetGlobalClass(void) { return globalFontClass; @@ -3791,7 +4167,7 @@ TkFontGetGlobalClass(void) *------------------------------------------------------------------------- */ -char ** +const char *const * TkFontGetSymbolClass(void) { return symbolClass; @@ -3819,7 +4195,7 @@ Tcl_Obj * TkDebugFont( Tk_Window tkwin, /* The window in which the font will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { TkFont *fontPtr; Tcl_HashEntry *hashPtr; @@ -3829,7 +4205,7 @@ TkDebugFont( hashPtr = Tcl_FindHashEntry( &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name); if (hashPtr != NULL) { - fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); + fontPtr = Tcl_GetHashValue(hashPtr); if (fontPtr == NULL) { Tcl_Panic("TkDebugFont found empty hash table entry"); } @@ -3875,7 +4251,7 @@ TkFontGetFirstTextLayout( LayoutChunk *chunkPtr; int numBytesInChunk; - layoutPtr = (TextLayout *)layout; + layoutPtr = (TextLayout *) layout; if ((layoutPtr==NULL) || (layoutPtr->numChunks==0) || (layoutPtr->chunks->numDisplayChars <= 0)) { dst[0] = '\0'; |