📄 tkimgbmap.c
字号:
if (instancePtr->bg != NULL) { Tk_FreeColor(instancePtr->bg); } instancePtr->bg = colorPtr; colorPtr = Tk_GetColor(masterPtr->interp, instancePtr->tkwin, masterPtr->fgUid); if (colorPtr == NULL) { goto error; } if (instancePtr->fg != NULL) { Tk_FreeColor(instancePtr->fg); } instancePtr->fg = colorPtr; if (instancePtr->bitmap != None) { Tk_FreePixmap(Tk_Display(instancePtr->tkwin), instancePtr->bitmap); instancePtr->bitmap = None; } if (masterPtr->data != NULL) { instancePtr->bitmap = XCreateBitmapFromData( Tk_Display(instancePtr->tkwin), RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)), masterPtr->data, (unsigned) masterPtr->width, (unsigned) masterPtr->height); } if (instancePtr->mask != None) { Tk_FreePixmap(Tk_Display(instancePtr->tkwin), instancePtr->mask); instancePtr->mask = None; } if (masterPtr->maskData != NULL) { instancePtr->mask = XCreateBitmapFromData( Tk_Display(instancePtr->tkwin), RootWindowOfScreen(Tk_Screen(instancePtr->tkwin)), masterPtr->maskData, (unsigned) masterPtr->width, (unsigned) masterPtr->height); } if (masterPtr->data != NULL) { gcValues.foreground = instancePtr->fg->pixel; gcValues.graphics_exposures = False; mask = GCForeground|GCGraphicsExposures; if (instancePtr->bg != NULL) { gcValues.background = instancePtr->bg->pixel; mask |= GCBackground; if (instancePtr->mask != None) { gcValues.clip_mask = instancePtr->mask; mask |= GCClipMask; } } else { gcValues.clip_mask = instancePtr->bitmap; mask |= GCClipMask; } gc = Tk_GetGC(instancePtr->tkwin, mask, &gcValues); } else { gc = None; } if (instancePtr->gc != None) { Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc); } instancePtr->gc = gc; return; error: /* * An error occurred: clear the graphics context in the instance to * make it clear that this instance cannot be displayed. Then report * the error. */ if (instancePtr->gc != None) { Tk_FreeGC(Tk_Display(instancePtr->tkwin), instancePtr->gc); } instancePtr->gc = None; Tcl_AddErrorInfo(masterPtr->interp, "\n (while configuring image \""); Tcl_AddErrorInfo(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster)); Tcl_AddErrorInfo(masterPtr->interp, "\")"); Tcl_BackgroundError(masterPtr->interp);}/* *---------------------------------------------------------------------- * * TkGetBitmapData -- * * Given a file name or ASCII string, this procedure parses the * file or string contents to produce binary data for a bitmap. * * Results: * If the bitmap description was parsed successfully then the * return value is a malloc-ed array containing the bitmap data. * The dimensions of the data are stored in *widthPtr and * *heightPtr. *hotXPtr and *hotYPtr are set to the bitmap * hotspot if one is defined, otherwise they are set to -1, -1. * If an error occurred, NULL is returned and an error message is * left in interp->result. * * Side effects: * A bitmap is created. * *---------------------------------------------------------------------- */char *TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr, hotXPtr, hotYPtr) Tcl_Interp *interp; /* For reporting errors, or NULL. */ char *string; /* String describing bitmap. May * be NULL. */ char *fileName; /* Name of file containing bitmap * description. Used only if string * is NULL. Must not be NULL if * string is NULL. */ int *widthPtr, *heightPtr; /* Dimensions of bitmap get returned * here. */ int *hotXPtr, *hotYPtr; /* Position of hot spot or -1,-1. */{ int width, height, numBytes, hotX, hotY; char *p, *end, *expandedFileName; ParseInfo pi; char *data = NULL; Tcl_DString buffer; pi.string = string; if (string == NULL) { if ((interp != NULL) && Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't get bitmap data from a file in a", " safe interpreter", (char *) NULL); return NULL; } expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer); if (expandedFileName == NULL) { return NULL; } pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0); Tcl_DStringFree(&buffer); if (pi.chan == NULL) { if (interp != NULL) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "couldn't read bitmap file \"", fileName, "\": ", Tcl_PosixError(interp), (char *) NULL); } return NULL; } } else { pi.chan = NULL; } /* * Parse the lines that define the dimensions of the bitmap, * plus the first line that defines the bitmap data (it declares * the name of a data variable but doesn't include any actual * data). These lines look something like the following: * * #define foo_width 16 * #define foo_height 16 * #define foo_x_hot 3 * #define foo_y_hot 3 * static char foo_bits[] = { * * The x_hot and y_hot lines may or may not be present. It's * important to check for "char" in the last line, in order to * reject old X10-style bitmaps that used shorts. */ width = 0; height = 0; hotX = -1; hotY = -1; while (1) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } if ((pi.wordLength >= 6) && (pi.word[pi.wordLength-6] == '_') && (strcmp(pi.word+pi.wordLength-6, "_width") == 0)) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } width = strtol(pi.word, &end, 0); if ((end == pi.word) || (*end != 0)) { goto error; } } else if ((pi.wordLength >= 7) && (pi.word[pi.wordLength-7] == '_') && (strcmp(pi.word+pi.wordLength-7, "_height") == 0)) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } height = strtol(pi.word, &end, 0); if ((end == pi.word) || (*end != 0)) { goto error; } } else if ((pi.wordLength >= 6) && (pi.word[pi.wordLength-6] == '_') && (strcmp(pi.word+pi.wordLength-6, "_x_hot") == 0)) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } hotX = strtol(pi.word, &end, 0); if ((end == pi.word) || (*end != 0)) { goto error; } } else if ((pi.wordLength >= 6) && (pi.word[pi.wordLength-6] == '_') && (strcmp(pi.word+pi.wordLength-6, "_y_hot") == 0)) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } hotY = strtol(pi.word, &end, 0); if ((end == pi.word) || (*end != 0)) { goto error; } } else if ((pi.word[0] == 'c') && (strcmp(pi.word, "char") == 0)) { while (1) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } if ((pi.word[0] == '{') && (pi.word[1] == 0)) { goto getData; } } } else if ((pi.word[0] == '{') && (pi.word[1] == 0)) { if (interp != NULL) { Tcl_AppendResult(interp, "format error in bitmap data; ", "looks like it's an obsolete X10 bitmap file", (char *) NULL); } goto errorCleanup; } } /* * Now we've read everything but the data. Allocate an array * and read in the data. */ getData: if ((width <= 0) || (height <= 0)) { goto error; } numBytes = ((width+7)/8) * height; data = (char *) ckalloc((unsigned) numBytes); for (p = data; numBytes > 0; p++, numBytes--) { if (NextBitmapWord(&pi) != TCL_OK) { goto error; } *p = (char) strtol(pi.word, &end, 0); if (end == pi.word) { goto error; } } /* * All done. Clean up and return. */ if (pi.chan != NULL) { Tcl_Close(NULL, pi.chan); } *widthPtr = width; *heightPtr = height; *hotXPtr = hotX; *hotYPtr = hotY; return data; error: if (interp != NULL) { interp->result = "format error in bitmap data"; } errorCleanup: if (data != NULL) { ckfree(data); } if (pi.chan != NULL) { Tcl_Close(NULL, pi.chan); } return NULL;}/* *---------------------------------------------------------------------- * * NextBitmapWord -- * * This procedure retrieves the next word of information (stuff * between commas or white space) from a bitmap description. * * Results: * Returns TCL_OK if all went well. In this case the next word, * and its length, will be availble in *parseInfoPtr. If the end * of the bitmap description was reached then TCL_ERROR is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */static intNextBitmapWord(parseInfoPtr) ParseInfo *parseInfoPtr; /* Describes what we're reading * and where we are in it. */{ char *src, *dst; int c; parseInfoPtr->wordLength = 0; dst = parseInfoPtr->word; if (parseInfoPtr->string != NULL) { for (src = parseInfoPtr->string; isspace(UCHAR(*src)) || (*src == ','); src++) { if (*src == 0) { return TCL_ERROR; } } for ( ; !isspace(UCHAR(*src)) && (*src != ',') && (*src != 0); src++) { *dst = *src; dst++; parseInfoPtr->wordLength++; if (parseInfoPtr->wordLength > MAX_WORD_LENGTH) { return TCL_ERROR; } } parseInfoPtr->string = src; } else { for (c = GetByte(parseInfoPtr->chan); isspace(UCHAR(c)) || (c == ','); c = GetByte(parseInfoPtr->chan)) { if (c == EOF) { return TCL_ERROR; } } for ( ; !isspace(UCHAR(c)) && (c != ',') && (c != EOF); c = GetByte(parseInfoPtr->chan)) { *dst = c; dst++; parseInfoPtr->wordLength++; if (parseInfoPtr->wordLength > MAX_WORD_LENGTH) { return TCL_ERROR; } } } if (parseInfoPtr->wordLength == 0) { return TCL_ERROR; } parseInfoPtr->word[parseInfoPtr->wordLength] = 0; return TCL_OK;}/* *-------------------------------------------------------------- * * ImgBmapCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to an image managed by this module. * See the user documentation for details on what it does. * * Results:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -