📄 tk3d.c
字号:
/* * tk3d.c -- * * This module provides procedures to draw borders in * the three-dimensional Motif style. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tk3d.c 1.60 97/01/13 17:23:10 */#include <tk3d.h>/* * Hash table to map from a border's values (color, etc.) to a * Border structure for those values. */static Tcl_HashTable borderTable;typedef struct { Tk_Uid colorName; /* Color for border. */ Colormap colormap; /* Colormap used for allocating border * colors. */ Screen *screen; /* Screen on which border will be drawn. */} BorderKey;static int initialized = 0; /* 0 means static structures haven't * been initialized yet. *//* * Forward declarations for procedures defined in this file: */static void BorderInit _ANSI_ARGS_((void));static int Intersect _ANSI_ARGS_((XPoint *a1Ptr, XPoint *a2Ptr, XPoint *b1Ptr, XPoint *b2Ptr, XPoint *iPtr));static void ShiftLine _ANSI_ARGS_((XPoint *p1Ptr, XPoint *p2Ptr, int distance, XPoint *p3Ptr));/* *-------------------------------------------------------------- * * Tk_Get3DBorder -- * * Create a data structure for displaying a 3-D border. * * Results: * The return value is a token for a data structure * describing a 3-D border. This token may be passed * to Tk_Draw3DRectangle and Tk_Free3DBorder. If an * error prevented the border from being created then * NULL is returned and an error message will be left * in interp->result. * * Side effects: * Data structures, graphics contexts, etc. are allocated. * It is the caller's responsibility to eventually call * Tk_Free3DBorder to release the resources. * *-------------------------------------------------------------- */Tk_3DBorderTk_Get3DBorder(interp, tkwin, colorName) Tcl_Interp *interp; /* Place to store an error message. */ Tk_Window tkwin; /* Token for window in which border will * be drawn. */ Tk_Uid colorName; /* String giving name of color * for window background. */{ BorderKey key; Tcl_HashEntry *hashPtr; register TkBorder *borderPtr; int new; XGCValues gcValues; if (!initialized) { BorderInit(); } /* * First, check to see if there's already a border that will work * for this request. */ key.colorName = colorName; key.colormap = Tk_Colormap(tkwin); key.screen = Tk_Screen(tkwin); hashPtr = Tcl_CreateHashEntry(&borderTable, (char *) &key, &new); if (!new) { borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); borderPtr->refCount++; } else { XColor *bgColorPtr; /* * No satisfactory border exists yet. Initialize a new one. */ bgColorPtr = Tk_GetColor(interp, tkwin, colorName); if (bgColorPtr == NULL) { Tcl_DeleteHashEntry(hashPtr); return NULL; } borderPtr = TkpGetBorder(); borderPtr->screen = Tk_Screen(tkwin); borderPtr->visual = Tk_Visual(tkwin); borderPtr->depth = Tk_Depth(tkwin); borderPtr->colormap = key.colormap; borderPtr->refCount = 1; borderPtr->bgColorPtr = bgColorPtr; borderPtr->darkColorPtr = NULL; borderPtr->lightColorPtr = NULL; borderPtr->shadow = None; borderPtr->bgGC = None; borderPtr->darkGC = None; borderPtr->lightGC = None; borderPtr->hashPtr = hashPtr; Tcl_SetHashValue(hashPtr, borderPtr); /* * Create the information for displaying the background color, * but delay the allocation of shadows until they are actually * needed for drawing. */ gcValues.foreground = borderPtr->bgColorPtr->pixel; borderPtr->bgGC = Tk_GetGC(tkwin, GCForeground, &gcValues); } return (Tk_3DBorder) borderPtr;}/* *-------------------------------------------------------------- * * Tk_Draw3DRectangle -- * * Draw a 3-D border at a given place in a given window. * * Results: * None. * * Side effects: * A 3-D border will be drawn in the indicated drawable. * The outside edges of the border will be determined by x, * y, width, and height. The inside edges of the border * will be determined by the borderWidth argument. * *-------------------------------------------------------------- */voidTk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) Tk_Window tkwin; /* Window for which border was allocated. */ Drawable drawable; /* X window or pixmap in which to draw. */ Tk_3DBorder border; /* Token for border to draw. */ int x, y, width, height; /* Outside area of region in * which border will be drawn. */ int borderWidth; /* Desired width for border, in * pixels. */ int relief; /* Type of relief: TK_RELIEF_RAISED, * TK_RELIEF_SUNKEN, TK_RELIEF_GROOVE, etc. */{ if (width < 2*borderWidth) { borderWidth = width/2; } if (height < 2*borderWidth) { borderWidth = height/2; } Tk_3DVerticalBevel(tkwin, drawable, border, x, y, borderWidth, height, 1, relief); Tk_3DVerticalBevel(tkwin, drawable, border, x+width-borderWidth, y, borderWidth, height, 0, relief); Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, borderWidth, 1, 1, 1, relief); Tk_3DHorizontalBevel(tkwin, drawable, border, x, y+height-borderWidth, width, borderWidth, 0, 0, 0, relief);}/* *-------------------------------------------------------------- * * Tk_NameOf3DBorder -- * * Given a border, return a textual string identifying the * border's color. * * Results: * The return value is the string that was used to create * the border. * * Side effects: * None. * *-------------------------------------------------------------- */char *Tk_NameOf3DBorder(border) Tk_3DBorder border; /* Token for border. */{ TkBorder *borderPtr = (TkBorder *) border; return ((BorderKey *) borderPtr->hashPtr->key.words)->colorName;}/* *-------------------------------------------------------------------- * * Tk_3DBorderColor -- * * Given a 3D border, return the X color used for the "flat" * surfaces. * * Results: * Returns the color used drawing flat surfaces with the border. * * Side effects: * None. * *-------------------------------------------------------------------- */XColor *Tk_3DBorderColor(border) Tk_3DBorder border; /* Border whose color is wanted. */{ return(((TkBorder *) border)->bgColorPtr);}/* *-------------------------------------------------------------------- * * Tk_3DBorderGC -- * * Given a 3D border, returns one of the graphics contexts used to * draw the border. * * Results: * Returns the graphics context given by the "which" argument. * * Side effects: * None. * *-------------------------------------------------------------------- */GCTk_3DBorderGC(tkwin, border, which) Tk_Window tkwin; /* Window for which border was allocated. */ Tk_3DBorder border; /* Border whose GC is wanted. */ int which; /* Selects one of the border's 3 GC's: * TK_3D_FLAT_GC, TK_3D_LIGHT_GC, or * TK_3D_DARK_GC. */{ TkBorder * borderPtr = (TkBorder *) border; if ((borderPtr->lightGC == None) && (which != TK_3D_FLAT_GC)) { TkpGetShadows(borderPtr, tkwin); } if (which == TK_3D_FLAT_GC) { return borderPtr->bgGC; } else if (which == TK_3D_LIGHT_GC) { return borderPtr->lightGC; } else if (which == TK_3D_DARK_GC){ return borderPtr->darkGC; } panic("bogus \"which\" value in Tk_3DBorderGC"); /* * The code below will never be executed, but it's needed to * keep compilers happy. */ return (GC) None;}/* *-------------------------------------------------------------- * * Tk_Free3DBorder -- * * This procedure is called when a 3D border is no longer * needed. It frees the resources associated with the * border. After this call, the caller should never again * use the "border" token. * * Results: * None. * * Side effects: * Resources are freed. * *-------------------------------------------------------------- */voidTk_Free3DBorder(border) Tk_3DBorder border; /* Token for border to be released. */{ register TkBorder *borderPtr = (TkBorder *) border; Display *display = DisplayOfScreen(borderPtr->screen); borderPtr->refCount--; if (borderPtr->refCount == 0) { TkpFreeBorder(borderPtr); if (borderPtr->bgColorPtr != NULL) { Tk_FreeColor(borderPtr->bgColorPtr); } if (borderPtr->darkColorPtr != NULL) { Tk_FreeColor(borderPtr->darkColorPtr); } if (borderPtr->lightColorPtr != NULL) { Tk_FreeColor(borderPtr->lightColorPtr); } if (borderPtr->shadow != None) { Tk_FreeBitmap(display, borderPtr->shadow); } if (borderPtr->bgGC != None) { Tk_FreeGC(display, borderPtr->bgGC); } if (borderPtr->darkGC != None) { Tk_FreeGC(display, borderPtr->darkGC); } if (borderPtr->lightGC != None) { Tk_FreeGC(display, borderPtr->lightGC); } Tcl_DeleteHashEntry(borderPtr->hashPtr); ckfree((char *) borderPtr); }}/* *---------------------------------------------------------------------- * * Tk_SetBackgroundFromBorder -- * * Change the background of a window to one appropriate for a given * 3-D border. * * Results: * None. * * Side effects: * Tkwin's background gets modified. * *---------------------------------------------------------------------- */voidTk_SetBackgroundFromBorder(tkwin, border) Tk_Window tkwin; /* Window whose background is to be set. */ Tk_3DBorder border; /* Token for border. */{ register TkBorder *borderPtr = (TkBorder *) border; Tk_SetWindowBackground(tkwin, borderPtr->bgColorPtr->pixel);}/* *---------------------------------------------------------------------- * * Tk_GetRelief -- * * Parse a relief description and return the corresponding * relief value, or an error. * * Results: * A standard Tcl return value. If all goes well then * *reliefPtr is filled in with one of the values * TK_RELIEF_RAISED, TK_RELIEF_FLAT, or TK_RELIEF_SUNKEN. * * Side effects: * None. * *---------------------------------------------------------------------- */intTk_GetRelief(interp, name, reliefPtr) Tcl_Interp *interp; /* For error messages. */ char *name; /* Name of a relief type. */ int *reliefPtr; /* Where to store converted relief. */{ char c; size_t length; c = name[0]; length = strlen(name); if ((c == 'f') && (strncmp(name, "flat", length) == 0)) { *reliefPtr = TK_RELIEF_FLAT; } else if ((c == 'g') && (strncmp(name, "groove", length) == 0) && (length >= 2)) { *reliefPtr = TK_RELIEF_GROOVE; } else if ((c == 'r') && (strncmp(name, "raised", length) == 0) && (length >= 2)) { *reliefPtr = TK_RELIEF_RAISED; } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)) { *reliefPtr = TK_RELIEF_RIDGE; } else if ((c == 's') && (strncmp(name, "solid", length) == 0)) { *reliefPtr = TK_RELIEF_SOLID; } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) { *reliefPtr = TK_RELIEF_SUNKEN; } else { sprintf(interp->result, "bad relief type \"%.50s\": must be %s", name, "flat, groove, raised, ridge, solid, or sunken"); return TCL_ERROR; } return TCL_OK;}/* *-------------------------------------------------------------- * * Tk_NameOfRelief -- * * Given a relief value, produce a string describing that * relief value. * * Results: * The return value is a static string that is equivalent * to relief. * * Side effects: * None. * *-------------------------------------------------------------- */char *Tk_NameOfRelief(relief) int relief; /* One of TK_RELIEF_FLAT, TK_RELIEF_RAISED, * or TK_RELIEF_SUNKEN. */{ if (relief == TK_RELIEF_FLAT) { return "flat"; } else if (relief == TK_RELIEF_SUNKEN) { return "sunken"; } else if (relief == TK_RELIEF_RAISED) { return "raised"; } else if (relief == TK_RELIEF_GROOVE) { return "groove"; } else if (relief == TK_RELIEF_RIDGE) { return "ridge"; } else if (relief == TK_RELIEF_SOLID) { return "solid"; } else { return "unknown relief"; }}/* *-------------------------------------------------------------- * * Tk_Draw3DPolygon -- * * Draw a border with 3-D appearance around the edge of a * given polygon. * * Results: * None. * * Side effects: * Information is drawn in "drawable" in the form of a * 3-D border borderWidth units width wide on the left * of the trajectory given by pointPtr and numPoints (or * -borderWidth units wide on the right side, if borderWidth * is negative). * *--------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -