📄 image.cc
字号:
if (getVisual()->c_class == StaticGray) { ncolors = 1 << screen_depth; } else { ncolors = colors_per_channel * colors_per_channel * colors_per_channel; if (ncolors > (1 << screen_depth)) { colors_per_channel = (1 << screen_depth) / 3; ncolors = colors_per_channel * colors_per_channel * colors_per_channel; } } if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { fprintf(stderr, "BImageControl::BImageControl: invalid colormap size %d " "(%d/%d/%d) - reducing", ncolors, colors_per_channel, colors_per_channel, colors_per_channel); colors_per_channel = (1 << screen_depth) / 3; } colors = new XColor[ncolors]; if (! colors) { fprintf(stderr, "BImageControl::BImageControl: error allocating " "colormap\n"); exit(1); } int i = 0, ii, p, bits = 255 / (colors_per_channel - 1); red_bits = green_bits = blue_bits = bits; for (i = 0; i < 256; i++) red_color_table[i] = green_color_table[i] = blue_color_table[i] = i / bits; basedisplay->grab(); for (i = 0; i < ncolors; i++) { colors[i].red = (i * 0xffff) / (colors_per_channel - 1); colors[i].green = (i * 0xffff) / (colors_per_channel - 1); colors[i].blue = (i * 0xffff) / (colors_per_channel - 1); ; colors[i].flags = DoRed|DoGreen|DoBlue; if (! XAllocColor(basedisplay->getXDisplay(), getColormap(), &colors[i])) { fprintf(stderr, "couldn't alloc color %i %i %i\n", colors[i].red, colors[i].green, colors[i].blue); colors[i].flags = 0; } else colors[i].flags = DoRed|DoGreen|DoBlue; } basedisplay->ungrab(); XColor icolors[256]; int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth)); for (i = 0; i < incolors; i++) icolors[i].pixel = i; XQueryColors(basedisplay->getXDisplay(), getColormap(), icolors, incolors); for (i = 0; i < ncolors; i++) { if (! colors[i].flags) { unsigned long chk = 0xffffffff, pixel, close = 0; p = 2; while (p--) { for (ii = 0; ii < incolors; ii++) { int r = (colors[i].red - icolors[i].red) >> 8; int g = (colors[i].green - icolors[i].green) >> 8; int b = (colors[i].blue - icolors[i].blue) >> 8; pixel = (r * r) + (g * g) + (b * b); if (pixel < chk) { chk = pixel; close = ii; } colors[i].red = icolors[close].red; colors[i].green = icolors[close].green; colors[i].blue = icolors[close].blue; if (XAllocColor(basedisplay->getXDisplay(), getColormap(), &colors[i])) { colors[i].flags = DoRed|DoGreen|DoBlue; break; } } } } } break; } default: fprintf(stderr, "BImageControl::BImageControl: unsupported visual %d\n", getVisual()->c_class); exit(1); } cache = new LinkedList<Cache>;}BImageControl::~BImageControl(void) { if (sqrt_table) { delete [] sqrt_table; } if (grad_xbuffer) { delete [] grad_xbuffer; } if (grad_ybuffer) { delete [] grad_ybuffer; } if (colors) { unsigned long *pixels = new unsigned long [ncolors]; int i; for (i = 0; i < ncolors; i++) *(pixels + i) = (*(colors + i)).pixel; XFreeColors(basedisplay->getXDisplay(), getColormap(), pixels, ncolors, 0); delete [] colors; } if (cache->count()) { int i, n = cache->count(); fprintf(stderr, "BImageContol::~BImageControl: pixmap cache - " "releasing %d pixmaps\n", n); for (i = 0; i < n; i++) { Cache *tmp = cache->first(); XFreePixmap(basedisplay->getXDisplay(), tmp->pixmap); cache->remove(tmp); delete tmp; }#ifdef TIMEDCACHE if (timer) { timer->stop(); delete timer; }#endif // TIMEDCACHE } delete cache;}Pixmap BImageControl::searchCache(unsigned int width, unsigned int height, unsigned long texture, BColor *c1, BColor *c2) { if (cache->count()) { LinkedListIterator<Cache> it(cache); for (; it.current(); it++) { if ((it.current()->width == width) && (it.current()->height == height) && (it.current()->texture == texture) && (it.current()->pixel1 == c1->getPixel())) if (texture & BImage_Gradient) { if (it.current()->pixel2 == c2->getPixel()) { it.current()->count++; return it.current()->pixmap; } } else { it.current()->count++; return it.current()->pixmap; } } } return None;}Pixmap BImageControl::renderImage(unsigned int width, unsigned int height, BTexture *texture) { if (texture->getTexture() & BImage_ParentRelative) return ParentRelative; Pixmap pixmap = searchCache(width, height, texture->getTexture(), texture->getColor(), texture->getColorTo()); if (pixmap) return pixmap; BImage image(this, width, height); pixmap = image.render(texture); if (pixmap) { Cache *tmp = new Cache; tmp->pixmap = pixmap; tmp->width = width; tmp->height = height; tmp->count = 1; tmp->texture = texture->getTexture(); tmp->pixel1 = texture->getColor()->getPixel(); if (texture->getTexture() & BImage_Gradient) tmp->pixel2 = texture->getColorTo()->getPixel(); else tmp->pixel2 = 0l; cache->insert(tmp); if ((unsigned) cache->count() > cache_max) {#ifdef DEBUG fprintf(stderr, "BImageControl::renderImage: cache is large, " "forcing cleanout\n");#endif // DEBUG timeout(); } return pixmap; } return None;}void BImageControl::removeImage(Pixmap pixmap) { if (pixmap) { LinkedListIterator<Cache> it(cache); for (; it.current(); it++) { if (it.current()->pixmap == pixmap) { Cache *tmp = it.current(); if (tmp->count) { tmp->count--;#ifdef TIMEDCACHE if (! timer) timeout();#else // !TIMEDCACHE if (! tmp->count) timeout();#endif // TIMEDCACHE } return; } } }}unsigned long BImageControl::getColor(const char *colorname, unsigned char *r, unsigned char *g, unsigned char *b){ XColor color; color.pixel = 0; if (! XParseColor(basedisplay->getXDisplay(), getColormap(), colorname, &color)) { fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n", colorname); } else if (! XAllocColor(basedisplay->getXDisplay(), getColormap(), &color)) { fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n", colorname); } if (color.red == 65535) *r = 0xff; else *r = (unsigned char) (color.red / 0xff); if (color.green == 65535) *g = 0xff; else *g = (unsigned char) (color.green / 0xff); if (color.blue == 65535) *b = 0xff; else *b = (unsigned char) (color.blue / 0xff); return color.pixel;}unsigned long BImageControl::getColor(const char *colorname) { XColor color; color.pixel = 0; if (! XParseColor(basedisplay->getXDisplay(), getColormap(), colorname, &color)) { fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n", colorname); } else if (! XAllocColor(basedisplay->getXDisplay(), getColormap(), &color)) { fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n", colorname); } return color.pixel;}void BImageControl::getColorTables(unsigned char **rmt, unsigned char **gmt, unsigned char **bmt, int *roff, int *goff, int *boff, int *rbit, int *gbit, int *bbit) { if (rmt) *rmt = red_color_table; if (gmt) *gmt = green_color_table; if (bmt) *bmt = blue_color_table; if (roff) *roff = red_offset; if (goff) *goff = green_offset; if (boff) *boff = blue_offset; if (rbit) *rbit = red_bits; if (gbit) *gbit = green_bits; if (bbit) *bbit = blue_bits;}void BImageControl::getXColorTable(XColor **c, int *n) { if (c) *c = colors; if (n) *n = ncolors;}void BImageControl::getGradientBuffers(unsigned int w, unsigned int h, unsigned int **xbuf, unsigned int **ybuf){ if (w > grad_buffer_width) { if (grad_xbuffer) { delete [] grad_xbuffer; } grad_buffer_width = w; grad_xbuffer = new unsigned int[grad_buffer_width * 3]; } if (h > grad_buffer_height) { if (grad_ybuffer) { delete [] grad_ybuffer; } grad_buffer_height = h; grad_ybuffer = new unsigned int[grad_buffer_height * 3]; } *xbuf = grad_xbuffer; *ybuf = grad_ybuffer;}void BImageControl::installRootColormap(void) { basedisplay->grab(); Bool install = True; int i = 0, ncmap = 0; Colormap *cmaps = XListInstalledColormaps(basedisplay->getXDisplay(), window, &ncmap); if (cmaps) { for (i = 0; i < ncmap; i++) if (*(cmaps + i) == getColormap()) install = False; if (install) XInstallColormap(basedisplay->getXDisplay(), getColormap()); XFree(cmaps); } basedisplay->ungrab();}void BImageControl::setColorsPerChannel(int cpc) { if (cpc < 2) cpc = 2; if (cpc > 6) cpc = 6; colors_per_channel = cpc;}unsigned long BImageControl::getSqrt(unsigned int x) { if (! sqrt_table) { // build sqrt table for use with elliptic gradient sqrt_table = new unsigned long[(256 * 256 * 2) + 1]; int i = 0; for (; i < (256 * 256 * 2); i++) *(sqrt_table + i) = bsqrt(i); } return (*(sqrt_table + x));}void BImageControl::parseTexture(BTexture *texture, char *t) { if ((! texture) || (! t)) return; int t_len = strlen(t) + 1, i; char *ts = new char[t_len]; if (! ts) return; // convert to lower case for (i = 0; i < t_len; i++) *(ts + i) = tolower(*(t + i)); if (strstr(ts, "parentrelative")) { texture->setTexture(BImage_ParentRelative); } else { texture->setTexture(0); if (strstr(ts, "solid")) texture->addTexture(BImage_Solid); else if (strstr(ts, "gradient")) { texture->addTexture(BImage_Gradient); if (strstr(ts, "crossdiagonal")) texture->addTexture(BImage_CrossDiagonal); else if (strstr(ts, "rectangle")) texture->addTexture(BImage_Rectangle); else if (strstr(ts, "pyramid")) texture->addTexture(BImage_Pyramid); else if (strstr(ts, "pipecross")) texture->addTexture(BImage_PipeCross); else if (strstr(ts, "elliptic")) texture->addTexture(BImage_Elliptic); else if (strstr(ts, "diagonal")) texture->addTexture(BImage_Diagonal); else if (strstr(ts, "horizontal")) texture->addTexture(BImage_Horizontal); else if (strstr(ts, "vertical")) texture->addTexture(BImage_Vertical); else texture->addTexture(BImage_Diagonal); } else texture->addTexture(BImage_Solid); if (strstr(ts, "raised")) texture->addTexture(BImage_Raised); else if (strstr(ts, "sunken")) texture->addTexture(BImage_Sunken); else if (strstr(ts, "flat")) texture->addTexture(BImage_Flat); else texture->addTexture(BImage_Raised); if (! (texture->getTexture() & BImage_Flat)) if (strstr(ts, "bevel2")) texture->addTexture(BImage_Bevel2); else texture->addTexture(BImage_Bevel1);#ifdef INTERLACE if (strstr(ts, "interlaced")) texture->addTexture(BImage_Interlaced);#endif // INTERLACE } delete [] ts;}void BImageControl::parseColor(BColor *color, char *c) { if (! color) return; if (color->isAllocated()) { unsigned long pixel = color->getPixel(); XFreeColors(basedisplay->getXDisplay(), getColormap(), &pixel, 1, 0); color->setPixel(0l); color->setRGB(0, 0, 0); color->setAllocated(False); } if (c) { unsigned char r, g, b; color->setPixel(getColor(c, &r, &g, &b)); color->setRGB(r, g, b); color->setAllocated(True); }}void BImageControl::timeout(void) { LinkedListIterator<Cache> it(cache); for (; it.current(); it++) { Cache *tmp = it.current(); if (tmp->count <= 0) { XFreePixmap(basedisplay->getXDisplay(), tmp->pixmap); cache->remove(tmp); delete tmp; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -