bool grTkLoadFont() { Tk_Window tkwind; int i; char *s; char *unable = "Unable to load font"; static char *fontnames[4] = { TK_FONT_SMALL, TK_FONT_MEDIUM, TK_FONT_LARGE, TK_FONT_XLARGE }; static char *optionnames[4] = { "small", "medium", "large", "xlarge"}; tkwind = Tk_MainWindow(magicinterp); for (i = 0; i < 4; i++) { s = XGetDefault(grXdpy, "magic", optionnames[i]); if (s) fontnames[i] = s; if ((grTkFonts[i] = Tk_GetFont(magicinterp, tkwind, fontnames[i])) == NULL) { TxError("%s %s\n", unable, fontnames[i]); if ((grTkFonts[i] = Tk_GetFont(magicinterp, tkwind, TK_DEFAULT_FONT)) == NULL) { TxError("%s %s\n", unable, TK_DEFAULT_FONT); return FALSE; } } } return TRUE; }
static int win_choose_font (ClientData cd, Tcl_Interp *interp, int argc, char **argv) { char *deffont; Tk_Window parent; int i, oldMode; CHOOSEFONT cf; LOGFONT lf; HDC hdc; HFONT hfont; char facebuf[LF_FACESIZE]; TEXTMETRIC tm; int pointsize; char *s; Tcl_DString resultStr; /* used to translate result in UTF8 in Tcl/Tk8.1 */ deffont = NULL; parent = Tk_MainWindow (interp); for (i = 1; i < argc; i += 2) { if (i + 1 >= argc) { Tcl_ResetResult (interp); Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), "value for \"", argv[i], "\" missing", (char *) NULL); return TCL_ERROR; } if (strcmp (argv[i], "-default") == 0) deffont = argv[i + 1]; else if (strcmp (argv[i], "-parent") == 0) { parent = Tk_NameToWindow (interp, argv[i + 1], Tk_MainWindow (interp)); if (parent == NULL) return TCL_ERROR; } else { Tcl_ResetResult (interp); Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), "unknown option \"", argv[i], "\"", (char *) NULL); return TCL_ERROR; } } memset (&cf, 0, sizeof (CHOOSEFONT)); cf.lStructSize = sizeof (CHOOSEFONT); if (Tk_WindowId (parent) == None) Tk_MakeWindowExist (parent); cf.hwndOwner = Tk_GetHWND (Tk_WindowId (parent)); cf.lpLogFont = &lf; cf.Flags = CF_SCREENFONTS | CF_FORCEFONTEXIST; memset (&lf, 0, sizeof (LOGFONT)); if (deffont != NULL) { Tk_Font tkfont; const TkFontAttributes *fa; tkfont = Tk_GetFont (interp, parent, deffont); if (tkfont == NULL) return TCL_ERROR; cf.Flags |= CF_INITTOLOGFONTSTRUCT; /* In order to initialize LOGFONT, we need to extract the real font attributes from the Tk internal font information. */ fa = &((TkFont *) tkfont)->fa; /* This code is taken from TkpGetFontFromAttributes. It converts a TkFontAttributes structure into a LOGFONT structure. */ #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) lf.lfHeight = - fa->size; #else lf.lfHeight = - fa->pointsize; #endif if (lf.lfHeight < 0) lf.lfHeight = MulDiv (lf.lfHeight, 254 * WidthOfScreen (Tk_Screen (parent)), 720 * WidthMMOfScreen (Tk_Screen (parent))); lf.lfWeight = fa->weight == TK_FW_NORMAL ? FW_NORMAL : FW_BOLD; lf.lfItalic = fa->slant; lf.lfUnderline = fa->underline; lf.lfStrikeOut = fa->overstrike; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; if (fa->family == NULL) lf.lfFaceName[0] = '\0'; else strncpy (lf.lfFaceName, fa->family, sizeof (lf.lfFaceName)); Tk_FreeFont (tkfont); } oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); if (! ChooseFont (&cf)) { DWORD code; code = CommDlgExtendedError (); if (code == 0) { /* The user pressed cancel. */ Tcl_ResetResult (interp); return TCL_OK; } else { char buf[200]; sprintf (buf, "Windows common dialog error 0x%lx", (unsigned long) code); Tcl_ResetResult (interp); #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, buf, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, buf, -1); #endif Tcl_AppendStringsToObj (Tcl_GetObjResult (interp), Tcl_DStringValue(&resultStr), (char *) NULL); Tcl_DStringFree(&resultStr); return TCL_ERROR; } } Tcl_SetServiceMode(oldMode); /* We now have a LOGFONT structure. We store it into a device context, and then extract enough information to build a Tk font specification. With luck, when Tk interprets the font specification it will wind up with the font that the user expects to see. Some of this code is taken from AllocFont. */ hfont = CreateFontIndirect (&lf); if (hfont == NULL) { /* This should be impossible. */ #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "CreateFontIndirect failed on chosen font", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, "CreateFontIndirect failed on chosen font", -1); #endif Tcl_SetResult (interp, Tcl_DStringValue(&resultStr), TCL_STATIC); Tcl_DStringFree(&resultStr); return TCL_ERROR; } hdc = GetDC (cf.hwndOwner); hfont = SelectObject (hdc, hfont); GetTextFace (hdc, sizeof (facebuf), facebuf); GetTextMetrics (hdc, &tm); Tcl_ResetResult (interp); #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, facebuf, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr,facebuf,-1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); pointsize = MulDiv (tm.tmHeight - tm.tmInternalLeading, 720 * WidthMMOfScreen (Tk_Screen (parent)), 254 * WidthOfScreen (Tk_Screen (parent))); if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewIntObj (pointsize)) != TCL_OK) { return TCL_ERROR; } if (tm.tmWeight > FW_MEDIUM) s = "bold"; else s = "normal"; #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, s, -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); if (tm.tmItalic) s = "italic"; else s = "roman"; #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, s, -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, s, -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); if (tm.tmUnderlined) { #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "underline", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr,"underline",-1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); } if (tm.tmStruckOut) { #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1) Tcl_ExternalToUtfDString(NULL, "overstrike", -1, &resultStr); #else Tcl_InitDString(&resultStr); Tcl_DStingAppend(&resultStr, "overstrike", -1); #endif if (Tcl_ListObjAppendElement (interp, Tcl_GetObjResult (interp), Tcl_NewStringObj (Tcl_DStringValue(&resultStr), -1)) != TCL_OK) { Tcl_DStringFree(&resultStr); return TCL_ERROR; } Tcl_DStringFree(&resultStr); } hfont = SelectObject (hdc, hfont); ReleaseDC (cf.hwndOwner, hdc); DeleteObject (hfont); return TCL_OK; }
callGraphConsts::callGraphConsts(Tcl_Interp *interp, Tk_Window theTkWindow) { display = Tk_Display(theTkWindow); // needed in destructor textColor = Tk_GetColor(interp, theTkWindow, Tk_GetUid("black")); assert(textColor); // Root Item FontStruct's: Tk_Uid rootItemFontName = Tk_GetOption( theTkWindow, "listRootItemFont", "Font" ); assert( rootItemFontName != NULL ); rootItemFontStruct = Tk_GetFont( interp, theTkWindow, rootItemFontName ); Tk_Uid rootItemItalicFontName = Tk_GetOption( theTkWindow, "listRootItemEmphFont", "Font" ); assert( rootItemItalicFontName != NULL ); rootItemItalicFontStruct = Tk_GetFont( interp, theTkWindow, rootItemItalicFontName ); // Root Item Text GCs: XGCValues values; values.foreground = textColor->pixel; values.font = Tk_FontId(rootItemFontStruct); rootItemTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(rootItemTextGC); values.font = Tk_FontId(rootItemItalicFontStruct); values.foreground = textColor->pixel; rootItemShadowTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(rootItemShadowTextGC); // Listbox FontStruct's: Tk_Uid listboxItemFontName = Tk_GetOption( theTkWindow, "listItemFont", "Font" ); assert( listboxItemFontName ); listboxItemFontStruct = Tk_GetFont(interp, theTkWindow, listboxItemFontName ); Tk_Uid listboxItemItalicFontName = Tk_GetOption( theTkWindow, "listItemEmphFont", "Font" ); assert( listboxItemItalicFontName ); listboxItemItalicFontStruct = Tk_GetFont(interp, theTkWindow, listboxItemItalicFontName ); // Listbox Item Text GCs: values.foreground = textColor->pixel; values.font = Tk_FontId(listboxItemFontStruct); listboxItemGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(listboxItemGC); values.font = Tk_FontId(listboxItemItalicFontStruct); values.foreground = textColor->pixel; listboxItemShadowTextGC = Tk_GetGC(theTkWindow, GCForeground | GCFont, &values); assert(listboxItemShadowTextGC); rootItemTk3DBordersByStyle.resize(2); //Color for non-recursive nodes rootItemTk3DBordersByStyle[0] = Tk_Get3DBorder(interp, theTkWindow, Tk_GetUid("gray")); assert(rootItemTk3DBordersByStyle[0]); //Color for recursive nodes rootItemTk3DBordersByStyle[1] = Tk_Get3DBorder(interp, theTkWindow, Tk_GetUid("#60c0a0")); //green assert(rootItemTk3DBordersByStyle[1]); listboxItemTk3DBordersByStyle = rootItemTk3DBordersByStyle; // 3D borders for listbox: // It seems reasonable to use the exact same colors for shg listbox items: //listboxScrollbarBorder = rootItemBorder; }
static int DoConfig( Tcl_Interp *interp, /* Interpreter for error reporting. */ Tk_Window tkwin, /* Window containing widget (needed to set up * X resources). */ Tk_ConfigSpec *specPtr, /* Specifier to apply. */ Tk_Uid value, /* Value to use to fill in widgRec. */ int valueIsUid, /* Non-zero means value is a Tk_Uid; zero * means it's an ordinary string. */ char *widgRec) /* Record whose fields are to be modified. * Values must be properly initialized. */ { char *ptr; Tk_Uid uid; int nullValue; nullValue = 0; if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { nullValue = 1; } do { ptr = widgRec + specPtr->offset; switch (specPtr->type) { case TK_CONFIG_BOOLEAN: if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_INT: if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_DOUBLE: if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_STRING: { char *oldStr, *newStr; if (nullValue) { newStr = NULL; } else { newStr = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(newStr, value); } oldStr = *((char **) ptr); if (oldStr != NULL) { ckfree(oldStr); } *((char **) ptr) = newStr; break; } case TK_CONFIG_UID: if (nullValue) { *((Tk_Uid *) ptr) = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); *((Tk_Uid *) ptr) = uid; } break; case TK_CONFIG_COLOR: { XColor *newPtr, *oldPtr; if (nullValue) { newPtr = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newPtr = Tk_GetColor(interp, tkwin, uid); if (newPtr == NULL) { return TCL_ERROR; } } oldPtr = *((XColor **) ptr); if (oldPtr != NULL) { Tk_FreeColor(oldPtr); } *((XColor **) ptr) = newPtr; break; } case TK_CONFIG_FONT: { Tk_Font newFont; if (nullValue) { newFont = NULL; } else { newFont = Tk_GetFont(interp, tkwin, value); if (newFont == NULL) { return TCL_ERROR; } } Tk_FreeFont(*((Tk_Font *) ptr)); *((Tk_Font *) ptr) = newFont; break; } case TK_CONFIG_BITMAP: { Pixmap newBmp, oldBmp; if (nullValue) { newBmp = None; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newBmp = Tk_GetBitmap(interp, tkwin, uid); if (newBmp == None) { return TCL_ERROR; } } oldBmp = *((Pixmap *) ptr); if (oldBmp != None) { Tk_FreeBitmap(Tk_Display(tkwin), oldBmp); } *((Pixmap *) ptr) = newBmp; break; } case TK_CONFIG_BORDER: { Tk_3DBorder newBorder, oldBorder; if (nullValue) { newBorder = NULL; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newBorder = Tk_Get3DBorder(interp, tkwin, uid); if (newBorder == NULL) { return TCL_ERROR; } } oldBorder = *((Tk_3DBorder *) ptr); if (oldBorder != NULL) { Tk_Free3DBorder(oldBorder); } *((Tk_3DBorder *) ptr) = newBorder; break; } case TK_CONFIG_RELIEF: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_CURSOR: case TK_CONFIG_ACTIVE_CURSOR: { Tk_Cursor newCursor, oldCursor; if (nullValue) { newCursor = None; } else { uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); newCursor = Tk_GetCursor(interp, tkwin, uid); if (newCursor == None) { return TCL_ERROR; } } oldCursor = *((Tk_Cursor *) ptr); if (oldCursor != None) { Tk_FreeCursor(Tk_Display(tkwin), oldCursor); } *((Tk_Cursor *) ptr) = newCursor; if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) { Tk_DefineCursor(tkwin, newCursor); } break; } case TK_CONFIG_JUSTIFY: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_ANCHOR: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_CAP_STYLE: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_JOIN_STYLE: uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_PIXELS: if (Tk_GetPixels(interp, tkwin, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_MM: if (Tk_GetScreenMM(interp, tkwin, value, (double*)ptr) != TCL_OK) { return TCL_ERROR; } break; case TK_CONFIG_WINDOW: { Tk_Window tkwin2; if (nullValue) { tkwin2 = NULL; } else { tkwin2 = Tk_NameToWindow(interp, value, tkwin); if (tkwin2 == NULL) { return TCL_ERROR; } } *((Tk_Window *) ptr) = tkwin2; break; } case TK_CONFIG_CUSTOM: if ((*specPtr->customPtr->parseProc)( specPtr->customPtr->clientData, interp, tkwin, value, widgRec, specPtr->offset) != TCL_OK) { return TCL_ERROR; } break; default: { char buf[64 + TCL_INTEGER_SPACE]; sprintf(buf, "bad config table: unknown type %d", specPtr->type); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } } specPtr++; } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); return TCL_OK; }
static void imfsample_display(ClientData cldata) { char *str; int row, col, namex, namey, n, sx, sy, update = FALSE, done; Imfsample *imfsample = (Imfsample *) cldata; Display *dpy = imfsample->display; Tk_Window tkwin = imfsample->tkwin; GC gc; Pixmap pm = None; Drawable d; Tk_Font tkfont; int winwidth = Tk_Width(Tk_Parent(tkwin)); int winheight = Tk_Height(Tk_Parent(tkwin)); char tclbuf[100]; int rslt; imfsample->update_pending = 0; if (!Tk_IsMapped(tkwin)) { return; } /* Check if we need to redraw the entire imfsample. */ if (imfsample->imfapp) { if (imfsample->oldfirst != imfsample->firstvisrow || imfsample->redraw) { imfsample->oldfirst = imfsample->firstvisrow; update = TRUE; } } /* Create a pixmap for double-buffering if necessary. */ if (imfsample->double_buffer) { update = TRUE; pm = Tk_GetPixmap(imfsample->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), DefaultDepthOfScreen(Tk_Screen(tkwin))); d = pm; } else { d = Tk_WindowId(tkwin); } if (black_color == NULL) { black_color = Tk_GetColor(interp, tkwin, Tk_GetUid("black")); } if (white_color == NULL) { white_color = Tk_GetColor(interp, tkwin, Tk_GetUid("white")); } if (black_border == NULL) { black_border = Tk_Get3DBorder(interp, tkwin, "black"); } if (white_border == NULL) { white_border = Tk_Get3DBorder(interp, tkwin, "white"); } /* Collect GC and font for subsequent work. */ gc = imfsample->gc; XSetClipMask(dpy, gc, None); if (imfsample->show_names) { #ifdef WIN32 tkfont = Tk_GetFont(interp, tkwin, "-family arial -size 8"); #elif defined (MAC) tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 11"); #else tkfont = Tk_GetFont(interp, tkwin, "-family helvetica -size 12"); #endif XSetFont(imfsample->display, gc, Tk_FontId(tkfont)); } /* Redraw the entire widget background/border, but not if we are just updating the selected image. */ if (imfsample->selected == imfsample->previous /* Always redraw if we have only one image (e.g. closeups). */ || (imfsample->numimages == 1 && imfsample->selected == -1) || update) { done = FALSE; if (imfsample->with_terrain >= 0 /* Terrain tiles are not supported on Windows yet. */ && use_clip_mask) { ImageFamily *timf = imfsample->imf_list[imfsample->with_terrain]; Image *timg; TkImage *tkimg; timg = best_image(timf, 64, 64); if (timg) { tkimg = (TkImage *) timg->hook; if (tkimg && tkimg->colr) { XSetFillStyle(dpy, gc, FillTiled); XSetTile(dpy, gc, tkimg->colr); XFillRectangle(dpy, d, gc, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin)); done = TRUE; } } } if (!done) { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), imfsample->border_width, imfsample->relief); } } #if 0 for (i = 0; i < imfsample->numimages; i++) { if (imf_interp_hook) imfsample->imf_list[i] = (*imf_interp_hook)(imfsample->imf_list[i], NULL, TRUE); } #endif /* Tweak the default item width/height to something better. */ if (imfsample->iheight == 0) { imfsample->iheight = 32; if (imfsample->numimages == 1) imfsample->iheight = imfsample->height; } if (imfsample->iwidth == 0) { imfsample->iwidth = 32; if (imfsample->numimages == 1) imfsample->iwidth = imfsample->width; } imfsample->eltw = imfsample->iwidth; if (imfsample->show_grid) imfsample->eltw += 2; else imfsample->eltw += 2 * imfsample->pad; if (imfsample->show_names && !imfsample->show_grid) imfsample->eltw += 80; imfsample->elth = imfsample->iheight; if (imfsample->show_grid) imfsample->elth += 2; else imfsample->elth += 2 * imfsample->pad; /* Fix a lower bound on the vertical spacing. */ /* (should be determined by choice of app font) */ if (imfsample->elth < 10 && !imfsample->show_grid) imfsample->elth = 10; /* Compute and save the number of columns to use. */ imfsample->cols = winwidth / imfsample->eltw; if (imfsample->cols <= 0) imfsample->cols = 1; /* We can get a little wider spacing by recalculating the element width. */ if (imfsample->show_names && !imfsample->show_grid) imfsample->eltw = (winwidth - 10) / imfsample->cols; imfsample->rows = imfsample->numimages / imfsample->cols; /* Account for a last partial row. */ if (imfsample->rows * imfsample->cols < imfsample->numimages) ++(imfsample->rows); /* Compute the number of visible rows. It would be time-consuming to render all the images, so try to do only the visible ones. */ imfsample->numvisrows = winheight / imfsample->elth; if (imfsample->numvisrows > imfsample->rows) imfsample->numvisrows = imfsample->rows; if (imfsample->numvisrows < 1) imfsample->numvisrows = min(1, imfsample->rows); if (imfsample->firstvisrow + imfsample->numvisrows > imfsample->rows) imfsample->firstvisrow = imfsample->rows - imfsample->numvisrows; /* Imfapp-specific code that adjusts the canvas content to fit a resized window and also sets the canvas scrollregion correctly. */ if (imfsample->imfapp && imfsample->redraw) { imfsample->width = Tk_Width(Tk_Parent(tkwin)); imfsample->height = imfsample->rows * imfsample->elth + 7; Tk_GeometryRequest(tkwin, imfsample->width, imfsample->height); /* There must be a better way to do this ... */ sprintf(tclbuf, ".images.canvas configure -scrollregion [ list 0 0 0 %d ]", imfsample->height); rslt = Tcl_Eval(interp, tclbuf); if (rslt == TCL_ERROR) { fprintf(stderr, "Error: %s\n", Tcl_GetStringResult(interp)); } /* Force a redraw of the scrollbar if the window was resized. */ if (imfsample->numimages) { sprintf(tclbuf, ".images.canvas.content yview scroll 0 units"); } else { sprintf(tclbuf, ".images.scroll set 0 1"); } rslt = Tcl_Eval(interp, tclbuf); if (rslt == TCL_ERROR) { fprintf(stderr, "Error: %s\n", Tcl_GetStringResult(interp)); } } /* Now iterate through all the images we want to draw. */ for (row = imfsample->firstvisrow; row <= (imfsample->firstvisrow + imfsample->numvisrows); ++row) { if (row < 0) continue; for (col = 0; col < imfsample->cols; ++col) { n = row * imfsample->cols + col; if (n >= imfsample->numimages) break; sx = col * imfsample->eltw; sy = (row - imfsample->firstvisrow) * imfsample->elth; /* Erase the old selected imf if we picked a new one. */ if (n == imfsample->previous && n != imfsample->selected) { done = FALSE; if (imfsample->with_terrain >= 0 /* Terrain tiles are not supported on Windows yet. */ && use_clip_mask) { ImageFamily *timf = imfsample->imf_list[imfsample->with_terrain]; Image *timg; TkImage *tkimg; timg = best_image(timf, 64, 64); if (timg) { tkimg = (TkImage *) timg->hook; if (tkimg && tkimg->colr) { XSetFillStyle(dpy, gc, FillTiled); XSetTile(dpy, gc, tkimg->colr); if (imfsample->show_grid) { XFillRectangle(dpy, d, gc, sx, sy + 2, imfsample->eltw, imfsample->elth); } else { XFillRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw, imfsample->elth); } done = TRUE; } } } if (!done) { if (imfsample->show_grid) { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, sx, sy + 2, imfsample->eltw, imfsample->elth, imfsample->border_width, imfsample->relief); } else { Tk_Fill3DRectangle(tkwin, d, imfsample->bg_border, sx, sy + 7, imfsample->eltw, imfsample->elth, imfsample->border_width, imfsample->relief); } } } /* Just draw the old erased image if we selected a new one, else draw every image. */ if (imfsample->selected == imfsample->previous || n == imfsample->previous || update) { if (imfsample->show_grid) { Tk_Fill3DRectangle(tkwin, d, imfsample->cu_border, sx + 2, sy + 2, imfsample->iwidth, imfsample->iheight, imfsample->border_width, imfsample->relief); draw_one_main_image(imfsample, d, gc, imfsample->imf_list[n], sx + 2, sy + 2, imfsample->iwidth, imfsample->iheight); } else { draw_one_main_image(imfsample, d, gc, imfsample->imf_list[n], sx + imfsample->pad, sy + imfsample->pad, imfsample->iwidth, imfsample->iheight); } if (imfsample->show_names && !imfsample->show_grid) { namex = sx + 5; namey = sy + imfsample->elth + 3; XSetClipMask(dpy, gc, None); XSetFillStyle(dpy, gc, FillSolid); XSetForeground(dpy, gc, Tk_3DBorderColor( imfsample->fg_border)->pixel); str = imfsample->imf_list[n]->name; Tk_DrawChars(dpy, d, gc, tkfont, str, strlen(str), namex, namey); } } /* Box the selected imf. */ if (n == imfsample->selected) { XSetClipMask(dpy, gc, None); XSetFillStyle(dpy, gc, FillSolid); XSetForeground(dpy, gc, Tk_3DBorderColor(imfsample->fg_border)->pixel); if (imfsample->show_grid) { /* A rectangle on the Mac is 1 pixel smaller in both directions. */ #ifdef MAC XDrawRectangle(dpy, d, gc, sx + 2, sy + 2, imfsample->eltw - 2, imfsample->elth - 2); #else XDrawRectangle(dpy, d, gc, sx + 2, sy + 2, imfsample->eltw - 3, imfsample->elth - 3); #endif } else { #ifdef MAC XDrawRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw, imfsample->elth); #else XDrawRectangle(dpy, d, gc, sx, sy + 7, imfsample->eltw - 1, imfsample->elth - 1); #endif } } } } /* Reset the old selected image to the new one if it exists. */ if (imfsample->selected != -1) { imfsample->previous = imfsample->selected; } /* Reset the redraw flag. */ imfsample->redraw = FALSE; /* If double-buffered, copy to the screen and release the pixmap. */ if (imfsample->double_buffer) { XCopyArea(imfsample->display, pm, Tk_WindowId(tkwin), imfsample->copygc, 0, 0, (unsigned) winwidth, (unsigned) winheight, 0, 0); Tk_FreePixmap(imfsample->display, pm); } if (imfsample->show_names) { Tk_FreeFont(tkfont); } /* In theory this shouldn't be necessary, but in practice the interface widgets (esp. the progress bar fill color) are affected by the last value of the foreground left over from drawing, so set to a consistent value. */ /* (Note that as of 2000-09-16, some color errors persist, so this might not really be necessary -sts) */ XSetForeground(imfsample->display, imfsample->gc, black_color->pixel); XSetBackground(imfsample->display, imfsample->gc, white_color->pixel); XSetForeground(imfsample->display, imfsample->copygc, black_color->pixel); XSetBackground(imfsample->display, imfsample->copygc, white_color->pixel); }