Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
fltk
fltk-1.3.2-add_ability_to_convert_a_Fl_Pixmap_i...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fltk-1.3.2-add_ability_to_convert_a_Fl_Pixmap_into_a_Fl_RGB_Image.patch of Package fltk
Add ability to convert a Fl_Pixmap into a Fl_RGB_Image. This is very convenient as a lot of other functions only accept a Fl_RGB_Image. Adding this functionality also required a bit of spring cleaning in the the drawing routines. STR #2659. Index: src/ps_image.cxx =================================================================== --- src/ps_image.cxx.orig +++ src/ps_image.cxx @@ -185,72 +185,38 @@ static inline uchar swap_byte(const ucha extern uchar **fl_mask_bitmap; +struct callback_data { + const uchar *data; + int D, LD; +}; -void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) { - double x = ix, y = iy, w = iw, h = ih; - if (D<3){ //mono - draw_image_mono(data, ix, iy, iw, ih, D, LD); - return; - } +static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) { + struct callback_data *cb_data; + const uchar *curdata; + cb_data = (struct callback_data*)data; + curdata = cb_data->data + x*cb_data->D + y*cb_data->LD; - int i,j, k; + memcpy(buf, curdata, w*cb_data->D); +} - fprintf(output,"save\n"); - const char * interpol; - if (lang_level_>1){ - if (interpolate_) - interpol="true"; - else - interpol="false"; - if (mask && lang_level_>2) - fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol); - else - fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol); - } else - fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih); +void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) { + if (D<3){ //mono + draw_image_mono(data, ix, iy, iw, ih, D, LD); + return; + } + struct callback_data cb_data; if (!LD) LD = iw*D; - uchar *curmask=mask; - - for (j=0; j<ih;j++){ - if (mask){ - - for (k=0;k<my/ih;k++){ - for (i=0; i<((mx+7)/8);i++){ - if (!(i%80)) fprintf(output, "\n"); - fprintf(output, "%.2x",swap_byte(*curmask)); - curmask++; - } - fprintf(output,"\n"); - } - } - const uchar *curdata=data+j*LD; - for (i=0 ; i<iw ; i++) { - uchar r = curdata[0]; - uchar g = curdata[1]; - uchar b = curdata[2]; - if (lang_level_<3 && D>3) { //can do mixing using bg_* colors) - unsigned int a2 = curdata[3]; //must be int - unsigned int a = 255-a2; - r = (a2 * r + bg_r * a)/255; - g = (a2 * g + bg_g * a)/255; - b = (a2 * b + bg_b * a)/255; - } - if (!(i%40)) fprintf(output, "\n"); - fprintf(output, "%.2x%.2x%.2x", r, g, b); - curdata +=D; - } - fprintf(output,"\n"); - - } - - fprintf(output," >\nrestore\n" ); + cb_data.data = data; + cb_data.D = D; + cb_data.LD = LD; + draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, D); } void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D) { @@ -325,6 +291,14 @@ void Fl_PostScript_Graphics_Driver::draw uchar g = curdata[1]; uchar b = curdata[2]; + if (lang_level_<3 && D>3) { //can do mixing using bg_* colors) + unsigned int a2 = curdata[3]; //must be int + unsigned int a = 255-a2; + r = (a2 * r + bg_r * a)/255; + g = (a2 * g + bg_g * a)/255; + b = (a2 * b + bg_b * a)/255; + } + if (!(i%40)) fputs("\n", output); fprintf(output, "%.2x%.2x%.2x", r, g, b); Index: src/Fl_Image.cxx =================================================================== --- src/Fl_Image.cxx.orig +++ src/Fl_Image.cxx @@ -165,7 +165,22 @@ Fl_Image::measure(const Fl_Label *lo, / // size_t Fl_RGB_Image::max_size_ = ~((size_t)0); -/** The destructor free all memory and server resources that are used by the image. */ +int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg); + +/** The constructor creates a new RGBA image from the specified Fl_Pixmap. + + The RGBA image is built fully opaque except for the transparent area + of the pixmap that is assigned the \par bg color with full transparency */ +Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg): + Fl_Image(pxm->w(), pxm->h(), 4), id_(0), mask_(0) +{ + array = new uchar[w() * h() * d()]; + alloc_array = 1; + fl_convert_pixmap(pxm->data(), (uchar*)array, bg); + data((const char **)&array, 1); +} + +/** The destructor frees all memory and server resources that are used by the image. */ Fl_RGB_Image::~Fl_RGB_Image() { uncache(); if (alloc_array) delete[] (uchar *)array; Index: src/fl_draw_pixmap.cxx =================================================================== --- src/fl_draw_pixmap.cxx.orig +++ src/fl_draw_pixmap.cxx @@ -58,99 +58,6 @@ int fl_measure_pixmap(const char * const return 1; } -#ifdef U64 - -// The callback from fl_draw_image to get a row of data passes this: -struct pixmap_data { - int w, h; - const uchar*const* data; - union { - U64 colors[256]; - U64* byte1[256]; - }; -}; - -// callback for 1 byte per pixel: -static void cb1(void*v, int x, int y, int w, uchar* buf) { - pixmap_data& d = *(pixmap_data*)v; - const uchar* p = d.data[y]+x; - U64* q = (U64*)buf; - for (int X=w; X>0; X-=2, p += 2) { - if (X>1) { -# if WORDS_BIGENDIAN - *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]]; -# else - *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]]; -# endif - } else { -# if WORDS_BIGENDIAN - *q++ = d.colors[p[0]]<<32; -# else - *q++ = d.colors[p[0]]; -# endif - } - } -} - -// callback for 2 bytes per pixel: -static void cb2(void*v, int x, int y, int w, uchar* buf) { - pixmap_data& d = *(pixmap_data*)v; - const uchar* p = d.data[y]+2*x; - U64* q = (U64*)buf; - for (int X=w; X>0; X-=2) { - U64* colors = d.byte1[*p++]; - int index = *p++; - if (X>1) { - U64* colors1 = d.byte1[*p++]; - int index1 = *p++; -# if WORDS_BIGENDIAN - *q++ = (colors[index]<<32) | colors1[index1]; -# else - *q++ = (colors1[index1]<<32) | colors[index]; -# endif - } else { -# if WORDS_BIGENDIAN - *q++ = colors[index]<<32; -# else - *q++ = colors[index]; -# endif - } - } -} - -#else // U32 - -// The callback from fl_draw_image to get a row of data passes this: -struct pixmap_data { - int w, h; - const uchar*const* data; - union { - U32 colors[256]; - U32* byte1[256]; - }; -}; - -// callback for 1 byte per pixel: -static void cb1(void*v, int x, int y, int w, uchar* buf) { - pixmap_data& d = *(pixmap_data*)v; - const uchar* p = d.data[y]+x; - U32* q = (U32*)buf; - for (int X=w; X--;) *q++ = d.colors[*p++]; -} - -// callback for 2 bytes per pixel: -static void cb2(void*v, int x, int y, int w, uchar* buf) { - pixmap_data& d = *(pixmap_data*)v; - const uchar* p = d.data[y]+2*x; - U32* q = (U32*)buf; - for (int X=w; X--;) { - U32* colors = d.byte1[*p++]; - *q++ = colors[*p++]; - } -} - -#endif // U64 else U32 - uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here /** @@ -200,15 +107,19 @@ static void make_unused_color(uchar &r, } #endif -/** - Draw XPM image data, with the top-left corner at the given position. - \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) - */ -int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { - pixmap_data d; - if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0; +int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) { + int w, h; const uchar*const* data = (const uchar*const*)(cdata+1); int transparent_index = -1; + + if (!fl_measure_pixmap(cdata, w, h)) + return 0; + + if ((chars_per_pixel < 1) || (chars_per_pixel > 2)) + return 0; + + uchar colors[1<<(chars_per_pixel*8)][4]; + #ifdef WIN32 uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color color_count = 0; @@ -221,13 +132,7 @@ int fl_draw_pixmap(const char*const* cda // if first color is ' ' it is transparent (put it later to make // it not be transparent): if (*p == ' ') { - uchar* c = (uchar*)&d.colors[(int)' ']; -#ifdef U64 - *(U64*)c = 0; -# if WORDS_BIGENDIAN - c += 4; -# endif -#endif + uchar* c = colors[(int)' ']; transparent_index = ' '; Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; #ifdef WIN32 @@ -238,13 +143,7 @@ int fl_draw_pixmap(const char*const* cda } // read all the rest of the colors: for (int i=0; i < ncolors; i++) { - uchar* c = (uchar*)&d.colors[*p++]; -#ifdef U64 - *(U64*)c = 0; -# if WORDS_BIGENDIAN - c += 4; -# endif -#endif + uchar* c = colors[*p++]; #ifdef WIN32 used_colors[3*color_count] = *p; used_colors[3*color_count+1] = *(p+1); @@ -254,32 +153,17 @@ int fl_draw_pixmap(const char*const* cda *c++ = *p++; *c++ = *p++; *c++ = *p++; -#ifdef __APPLE_QUARTZ__ *c = 255; -#else - *c = 0; -#endif } } else { // normal XPM colormap with names - if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1)); for (int i=0; i<ncolors; i++) { const uchar *p = *data++; // the first 1 or 2 characters are the color index: int ind = *p++; uchar* c; - if (chars_per_pixel>1) { -#ifdef U64 - U64* colors = d.byte1[ind]; - if (!colors) colors = d.byte1[ind] = new U64[256]; -#else - U32* colors = d.byte1[ind]; - if (!colors) colors = d.byte1[ind] = new U32[256]; -#endif - c = (uchar*)&colors[*p]; + if (chars_per_pixel>1) ind = (ind<<8)|*p++; - } else { - c = (uchar *)&d.colors[ind]; - } + c = colors[ind]; // look for "c word", or last word if none: const uchar *previous_word = p; for (;;) { @@ -292,16 +176,8 @@ int fl_draw_pixmap(const char*const* cda previous_word = p; while (*p && !isspace(*p)) p++; } -#ifdef U64 - *(U64*)c = 0; -# if WORDS_BIGENDIAN - c += 4; -# endif -#endif -#ifdef __APPLE_QUARTZ__ - c[3] = 255; -#endif int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]); + c[3] = 255; if (parse) { #ifdef WIN32 used_colors[3*color_count] = c[0]; @@ -314,9 +190,7 @@ int fl_draw_pixmap(const char*const* cda // assume "None" or "#transparent" for any errors // "bg" should be transparent... Fl::get_color(bg, c[0], c[1], c[2]); -#ifdef __APPLE_QUARTZ__ c[3] = 0; -#endif transparent_index = ind; #ifdef WIN32 transparent_c = c; @@ -324,7 +198,6 @@ int fl_draw_pixmap(const char*const* cda } } } - d.data = data; #ifdef WIN32 if (transparent_c) { make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); @@ -334,77 +207,77 @@ int fl_draw_pixmap(const char*const* cda make_unused_color(r, g, b); } #endif - -#ifdef __APPLE_QUARTZ__ - if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) { - U32 *array = new U32[d.w * d.h], *q = array; - for (int Y = 0; Y < d.h; Y++) { - const uchar* p = data[Y]; - if (chars_per_pixel <= 1) { - for (int X = 0; X < d.w; X++) { - *q++ = d.colors[*p++]; - } - } else { - for (int X = 0; X < d.w; X++) { - U32* colors = (U32*)d.byte1[*p++]; - *q++ = colors[*p++]; - } + + U32 *q = (U32*)out; + for (int Y = 0; Y < h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + for (int X = 0; X < w; X++) + memcpy(q++, colors[*p++], 4); + } else { + for (int X = 0; X < w; X++) { + int ind = (*p++)<<8; + ind |= *p++; + memcpy(q++, colors[ind], 4); } } - Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 4); + } + + return 1; +} + +/** + Draw XPM image data, with the top-left corner at the given position. + \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) + */ +int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { + int w, h; + + if (!fl_measure_pixmap(cdata, w, h)) + return 0; + + uchar buffer[w*h*4]; + + if (!fl_convert_pixmap(cdata, buffer, bg)) + return 0; + + // FIXME: Hack until fl_draw_image() supports alpha properly +#ifdef __APPLE_QUARTZ__ + if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) { + Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4); + rgb->draw(x, y); delete rgb; - delete[] array; - } - else { + } else { #endif // __APPLE_QUARTZ__ - // build the mask bitmap used by Fl_Pixmap: - if (fl_mask_bitmap && transparent_index >= 0) { - int W = (d.w+7)/8; - uchar* bitmap = new uchar[W * d.h]; + if (fl_mask_bitmap) { + int W = (w+7)/8; + uchar* bitmap = new uchar[W * h]; *fl_mask_bitmap = bitmap; - for (int Y = 0; Y < d.h; Y++) { - const uchar* p = data[Y]; - if (chars_per_pixel <= 1) { - int dw = d.w; - for (int X = 0; X < W; X++) { - uchar b = (dw-->0 && *p++ != transparent_index); - if (dw-->0 && *p++ != transparent_index) b |= 2; - if (dw-->0 && *p++ != transparent_index) b |= 4; - if (dw-->0 && *p++ != transparent_index) b |= 8; - if (dw-->0 && *p++ != transparent_index) b |= 16; - if (dw-->0 && *p++ != transparent_index) b |= 32; - if (dw-->0 && *p++ != transparent_index) b |= 64; - if (dw-->0 && *p++ != transparent_index) b |= 128; + + const uchar *p = &buffer[3]; + uchar b = 0; + for (int Y = 0; Y < h; Y++) { + b = 0; + for (int X = 0, bit = 1; X < w; X++, p += 4) { + if (*p > 127) + b |= bit; + bit <<= 1; + if (bit > 0x80 || X == w-1) { *bitmap++ = b; + bit = 1; + b = 0; } - } else { - uchar b = 0, bit = 1; - for (int X = 0; X < d.w; X++) { - int ind = *p++; - ind = (ind<<8) | (*p++); - if (ind != transparent_index) b |= bit; - - if (bit < 128) bit <<= 1; - else { - *bitmap++ = b; - b = 0; - bit = 1; - } - } - - if (bit > 1) *bitmap++ = b; } - } + } // for Y } - fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4); + fl_draw_image(buffer, x, y, w, h, 4); #ifdef __APPLE_QUARTZ__ } #endif - if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i]; return 1; } Index: FL/Fl_Image.H =================================================================== --- FL/Fl_Image.H.orig +++ FL/Fl_Image.H @@ -26,6 +26,7 @@ #include <stdlib.h> class Fl_Widget; +class Fl_Pixmap; struct Fl_Menu_Item; struct Fl_Label; @@ -203,6 +204,7 @@ public: */ Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) : Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);} + Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg=FL_GRAY); virtual ~Fl_RGB_Image(); virtual Fl_Image *copy(int W, int H); Fl_Image *copy() { return copy(w(), h()); }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor