📄 fl_draw_image.cxx
字号:
}static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2]));}static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24));}static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32(unsigned(*from) * 0x1010100U);}static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32(*from * 0x10101U);}static voidcolor32_converter(const uchar *from, uchar *to, int w, int delta) { INNARDS32( (from[0]<<fl_redshift)+(from[1]<<fl_greenshift)+(from[2]<<fl_blueshift));}static voidmono32_converter(const uchar *from,uchar *to,int w, int delta) { INNARDS32( (*from << fl_redshift)+(*from << fl_greenshift)+(*from << fl_blueshift));}////////////////////////////////////////////////////////////////static void figure_out_visual() { static XPixmapFormatValues *pfvlist; static int FL_NUM_pfv; if (!pfvlist) pfvlist = XListPixmapFormats(fl_display,&FL_NUM_pfv); XPixmapFormatValues *pfv; for (pfv = pfvlist; pfv < pfvlist+FL_NUM_pfv; pfv++) if (pfv->depth == fl_visual->depth) break; i.format = ZPixmap; i.byte_order = ImageByteOrder(fl_display);//i.bitmap_unit = 8;//i.bitmap_bit_order = MSBFirst;//i.bitmap_pad = 8; i.depth = fl_visual->depth; i.bits_per_pixel = pfv->bits_per_pixel; if (i.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error else bytes_per_pixel = i.bits_per_pixel/8; unsigned int n = pfv->scanline_pad/8; if (pfv->scanline_pad & 7 || (n&(n-1))) Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad); if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE); scanline_add = n-1; scanline_mask = -n;#if USE_COLORMAP if (bytes_per_pixel == 1) { converter = color8_converter; mono_converter = mono8_converter; return; } if (!fl_visual->red_mask) Fl::fatal("Can't do %d bits_per_pixel colormap",i.bits_per_pixel);#endif // otherwise it is a TrueColor visual: fl_xpixel(0,0,0); // setup fl_redmask, etc, in fl_color.C int rs = fl_redshift; int gs = fl_greenshift; int bs = fl_blueshift; switch (bytes_per_pixel) { case 2: // All 16-bit TrueColor visuals are supported on any machine with // 24 or more bits per integer.#ifdef U16 ::i.byte_order = WORDS_BIGENDIAN;#else ::i.byte_order = 1;#endif if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) { converter = c565_converter; mono_converter = m565_converter; } else { converter = color16_converter; mono_converter = mono16_converter; } break; case 3: if (::i.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;} if (rs == 0 && gs == 8 && bs == 16) { converter = rgb_converter; mono_converter = rrr_converter; } else if (rs == 16 && gs == 8 && bs == 0) { converter = bgr_converter; mono_converter = rrr_converter; } else { Fl::fatal("Can't do arbitrary 24bit color"); } break; case 4: if ((::i.byte_order!=0) != WORDS_BIGENDIAN) {rs = 24-rs; gs = 24-gs; bs = 24-bs;} if (rs == 0 && gs == 8 && bs == 16) { converter = xbgr_converter; mono_converter = xrrr_converter; } else if (rs == 24 && gs == 16 && bs == 8) { converter = rgbx_converter; mono_converter = rrrx_converter; } else if (rs == 8 && gs == 16 && bs == 24) { converter = bgrx_converter; mono_converter = rrrx_converter; } else if (rs == 16 && gs == 8 && bs == 0) { converter = xrgb_converter; mono_converter = xrrr_converter; } else { ::i.byte_order = WORDS_BIGENDIAN; converter = color32_converter; mono_converter = mono32_converter; } break; default: Fl::fatal("Can't do %d bits_per_pixel",i.bits_per_pixel); }}#endif#define MAXBUFFER 0x40000 // 256kstatic void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int mono, Fl_Draw_Image_Cb cb, void* userdata){#ifndef NANO_X //tanghao if (!linedelta) linedelta = W*delta; int dx, dy, w, h; fl_clip_box(X,Y,W,H,dx,dy,w,h); if (w<=0 || h<=0) return; dx -= X; dy -= Y; if (!bytes_per_pixel) figure_out_visual(); i.width = w; i.height = h; void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter; if (mono) conv = mono_converter; // See if the data is already in the right format. Unfortunately // some 32-bit x servers (XFree86) care about the unknown 8 bits // and they must be zero. I can't confirm this for user-supplied // data, so the 32-bit shortcut is disabled... // This can set bytes_per_line negative if image is bottom-to-top // I tested it on Linux, but it may fail on other Xlib implementations: if (buf && (#if 0 // set this to 1 to allow 32-bit shortcut delta == 4 &&#if WORDS_BIGENDIAN conv == rgbx_converter#else conv == xbgr_converter#endif ||#endif conv == rgb_converter && delta==3 ) && !(linedelta&scanline_add)) { i.data = (char *)(buf+delta*dx+linedelta*dy); i.bytes_per_line = linedelta; } else { int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE); int blocking = h; static STORETYPE *buffer; // our storage, always word aligned static long buffer_size; {int size = linesize*h; if (size > MAXBUFFER) { size = MAXBUFFER; blocking = MAXBUFFER/linesize; } if (size > buffer_size) { delete[] buffer; buffer_size = size; buffer = new STORETYPE[size]; }} i.data = (char *)buffer; i.bytes_per_line = linesize*sizeof(STORETYPE); if (buf) { buf += delta*dx+linedelta*dy; for (int j=0; j<h; ) { STORETYPE *to = buffer; int k; for (k = 0; j<h && k<blocking; k++, j++) { conv(buf, (uchar*)to, w, delta); buf += linedelta; to += linesize; }#ifndef NANO_X //tanghao XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);#endif //tanghao } } else {#ifdef __GNUC__ STORETYPE linebuf[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];#else STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];#endif for (int j=0; j<h; ) { STORETYPE *to = buffer; int k; for (k = 0; j<h && k<blocking; k++, j++) { cb(userdata, dx, dy+j, w, (uchar*)linebuf); conv((uchar*)linebuf, (uchar*)to, w, delta); to += linesize; }#ifndef NANO_X XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);#endif //tanghao }#ifndef __GNUC__ delete[] linebuf;#endif } }#else if (linedelta == 0) linedelta = W*delta; if (buf) { bool flip_h = ( delta < 0); if (flip_h) delta = - delta; bool flip_v = (linedelta < 0); if (flip_v) linedelta = -linedelta; if (delta >= 1) { GR_WINDOW_ID id = fl_window; GR_GC_ID gc = GrNewGC(); U32 prev_fg = (U32) -1; GR_POINT plist[1000]; int pcnt = 0; for ( int y = 0; y < H; ++y ) { const uchar * pixel = buf; buf += linedelta; for ( int x = 0; x < W; ++x ) { U32 fg; // calculate the foreground color if (delta >= 3) // presume it's RGB... fg = GR_RGB(pixel[0],pixel[1],pixel[2]); else // presume it's greyscale fg = GR_RGB(pixel[0],pixel[0],pixel[0]); // if the foreground color changed, dump any queued pixels remaining // for the old color, then change the color if (fg != prev_fg) { if (pcnt) { GrPoints(id,gc,pcnt,plist); pcnt = 0; } GrSetGCForeground(gc,fg); prev_fg = fg; } // queue the next pixel value plist[pcnt].x = X+(flip_h?(W-x-1):x); plist[pcnt].y = Y+(flip_v?(H-y-1):y); pcnt++; // if we've reached the max. number of queued pixels, dump them if (pcnt == sizeof(plist)/sizeof(*plist)) { GrPoints(id,gc,pcnt,plist); pcnt = 0; } pixel += delta; } } // dump any remaining queued points if (pcnt) GrPoints(id,gc,pcnt,plist); GrDestroyGC(gc); } else { Fl::fatal("Can't do a delta value of %d",delta); } } else { int linesize = ((linedelta>0) ? linedelta : -linedelta); int blocking = H; static uchar * buffer = 0; static long buffer_size = 0; { int size = linesize*H; if (size > MAXBUFFER) { size = MAXBUFFER; blocking = MAXBUFFER/linesize; } if (size > buffer_size) { delete[] buffer; buffer_size = size; buffer = new uchar[size]; } } uchar * linebuf = new uchar[linesize]; for (int j=0; j<H; ) { uchar *to = buffer; int k; for (k = 0; j<H && k<blocking; k++, j++) { cb(userdata, X, Y+j, W, linebuf); memcpy(to,linebuf,linesize); to += linesize; } innards(buffer,X,Y+j-k,W,blocking,delta,linedelta,0,0,0); } delete [] linebuf; }#endif //tanghao}void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);}void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);}void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ innards(buf,x,y,w,h,d,l,1,0,0);}void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int x, int y, int w, int h,int d) { innards(0,x,y,w,h,d,0,1,cb,data);}void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {#ifndef NANO_X //tanghao if (fl_visual->depth > 16) { fl_color(r,g,b); fl_rectf(x,y,w,h); } else { uchar c[3]; c[0] = r; c[1] = g; c[2] = b; innards(c,x,y,w,h,0,0,0,0,0); }#else // this may need speeded up sometime, as in the above code .. jsk fl_color(r,g,b); fl_rectf(x,y,w,h);#endif //tanghao}#endif//// End of "$Id: fl_draw_image.cxx,v 1.1.1.1 2003/08/07 21:18:41 jasonk Exp $".//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -