📄 tkwincolor.c
字号:
register WinColor *winColPtr = (WinColor *) colorPtr; if (winColPtr->info.magic == COLOR_MAGIC) { return winColPtr->index; } return -1;}/* *---------------------------------------------------------------------- * * XAllocColor -- * * Find the closest available color to the specified XColor. * * Results: * Updates the color argument and returns 1 on success. Otherwise * returns 0. * * Side effects: * Allocates a new color in the palette. * *---------------------------------------------------------------------- */intXAllocColor(display, colormap, color) Display* display; Colormap colormap; XColor* color;{ TkWinColormap *cmap = (TkWinColormap *) colormap; PALETTEENTRY entry, closeEntry; HDC dc = GetDC(NULL); entry.peRed = (color->red) >> 8; entry.peGreen = (color->green) >> 8; entry.peBlue = (color->blue) >> 8; entry.peFlags = 0; if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE); UINT newPixel, closePixel; int new, refCount; Tcl_HashEntry *entryPtr; UINT index; /* * Find the nearest existing palette entry. */ newPixel = RGB(entry.peRed, entry.peGreen, entry.peBlue); index = GetNearestPaletteIndex(cmap->palette, newPixel); GetPaletteEntries(cmap->palette, index, 1, &closeEntry); closePixel = RGB(closeEntry.peRed, closeEntry.peGreen, closeEntry.peBlue); /* * If this is not a duplicate, allocate a new entry. Note that * we may get values for index that are above the current size * of the palette. This happens because we don't shrink the size of * the palette object when we deallocate colors so there may be * stale values that match in the upper slots. We should ignore * those values and just put the new color in as if the colors * had not matched. */ if ((index >= cmap->size) || (newPixel != closePixel)) { if (cmap->size == sizePalette) { color->red = closeEntry.peRed << 8; color->green = closeEntry.peGreen << 8; color->blue = closeEntry.peBlue << 8; entry = closeEntry; if (index >= cmap->size) { OutputDebugString("XAllocColor: Colormap is bigger than we thought"); } } else { cmap->size++; ResizePalette(cmap->palette, cmap->size); SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry); } } color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue); entryPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char *) color->pixel, &new); if (new) { refCount = 1; } else { refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1; } Tcl_SetHashValue(entryPtr, (ClientData)refCount); } else { /* * Determine what color will actually be used on non-colormap systems. */ color->pixel = GetNearestColor(dc, RGB(entry.peRed, entry.peGreen, entry.peBlue)); color->red = (GetRValue(color->pixel) << 8); color->green = (GetGValue(color->pixel) << 8); color->blue = (GetBValue(color->pixel) << 8); } ReleaseDC(NULL, dc); return 1;}/* *---------------------------------------------------------------------- * * XFreeColors -- * * Deallocate a block of colors. * * Results: * None. * * Side effects: * Removes entries for the current palette and compacts the * remaining set. * *---------------------------------------------------------------------- */voidXFreeColors(display, colormap, pixels, npixels, planes) Display* display; Colormap colormap; unsigned long* pixels; int npixels; unsigned long planes;{ TkWinColormap *cmap = (TkWinColormap *) colormap; COLORREF cref; UINT count, index, refCount; int i; PALETTEENTRY entry, *entries; Tcl_HashEntry *entryPtr; HDC dc = GetDC(NULL); /* * We don't have to do anything for non-palette devices. */ if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) { /* * This is really slow for large values of npixels. */ for (i = 0; i < npixels; i++) { entryPtr = Tcl_FindHashEntry(&cmap->refCounts, (char *) pixels[i]); if (!entryPtr) { panic("Tried to free a color that isn't allocated."); } refCount = (int) Tcl_GetHashValue(entryPtr) - 1; if (refCount == 0) { cref = pixels[i] & 0x00ffffff; index = GetNearestPaletteIndex(cmap->palette, cref); GetPaletteEntries(cmap->palette, index, 1, &entry); if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) { count = cmap->size - index; entries = (PALETTEENTRY *) ckalloc(sizeof(PALETTEENTRY) * count); GetPaletteEntries(cmap->palette, index+1, count, entries); SetPaletteEntries(cmap->palette, index, count, entries); ckfree((char *) entries); cmap->size--; } else { panic("Tried to free a color that isn't allocated."); } Tcl_DeleteHashEntry(entryPtr); } else { Tcl_SetHashValue(entryPtr, (ClientData)refCount); } } } ReleaseDC(NULL, dc);}/* *---------------------------------------------------------------------- * * XCreateColormap -- * * Allocate a new colormap. * * Results: * Returns a newly allocated colormap. * * Side effects: * Allocates an empty palette and color list. * *---------------------------------------------------------------------- */ColormapXCreateColormap(display, w, visual, alloc) Display* display; Window w; Visual* visual; int alloc;{ char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; LOGPALETTE *logPalettePtr; PALETTEENTRY *entryPtr; TkWinColormap *cmap; Tcl_HashEntry *hashPtr; int new; UINT i; HPALETTE sysPal; /* * Allocate a starting palette with all of the reserved colors. */ logPalettePtr = (LOGPALETTE *) logPalBuf; logPalettePtr->palVersion = 0x300; sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256, logPalettePtr->palPalEntry); cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap)); cmap->size = logPalettePtr->palNumEntries; cmap->stale = 0; cmap->palette = CreatePalette(logPalettePtr); /* * Add hash entries for each of the static colors. */ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS); for (i = 0; i < logPalettePtr->palNumEntries; i++) { entryPtr = logPalettePtr->palPalEntry + i; hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char*) PALETTERGB( entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue), &new); Tcl_SetHashValue(hashPtr, (ClientData)1); } return (Colormap)cmap;}/* *---------------------------------------------------------------------- * * XFreeColormap -- * * Frees the resources associated with the given colormap. * * Results: * None. * * Side effects: * Deletes the palette associated with the colormap. Note that * the palette must not be selected into a device context when * this occurs. * *---------------------------------------------------------------------- */voidXFreeColormap(display, colormap) Display* display; Colormap colormap;{ TkWinColormap *cmap = (TkWinColormap *) colormap; if (!DeleteObject(cmap->palette)) { panic("Unable to free colormap, palette is still selected."); } Tcl_DeleteHashTable(&cmap->refCounts); ckfree((char *) cmap);}/* *---------------------------------------------------------------------- * * TkWinSelectPalette -- * * This function sets up the specified device context with a * given palette. If the palette is stale, it realizes it in * the background unless the palette is the current global * palette. * * Results: * Returns the previous palette selected into the device context. * * Side effects: * May change the system palette. * *---------------------------------------------------------------------- */HPALETTETkWinSelectPalette(dc, colormap) HDC dc; Colormap colormap;{ TkWinColormap *cmap = (TkWinColormap *) colormap; HPALETTE oldPalette; oldPalette = SelectPalette(dc, cmap->palette, (cmap->palette == TkWinGetSystemPalette()) ? FALSE : TRUE); RealizePalette(dc); return oldPalette;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -