diff options
Diffstat (limited to 'contrib/fltk/06-str2659-pixmap.patch')
-rw-r--r-- | contrib/fltk/06-str2659-pixmap.patch | 554 |
1 files changed, 554 insertions, 0 deletions
diff --git a/contrib/fltk/06-str2659-pixmap.patch b/contrib/fltk/06-str2659-pixmap.patch new file mode 100644 index 00000000..30315138 --- /dev/null +++ b/contrib/fltk/06-str2659-pixmap.patch @@ -0,0 +1,554 @@ +diff -ur fltk-1.3.2.org/FL/Fl_Image.H fltk-1.3.2/FL/Fl_Image.H +--- fltk-1.3.2.org/FL/Fl_Image.H 2012-11-09 17:02:08.000000000 +0100 ++++ fltk-1.3.2/FL/Fl_Image.H 2013-01-16 14:40:51.543230638 +0100 +@@ -26,6 +26,7 @@ + #include <stdlib.h> + + class Fl_Widget; ++class Fl_Pixmap; + struct Fl_Menu_Item; + struct Fl_Label; + +@@ -203,6 +204,7 @@ + */ + 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()); } +diff -ur fltk-1.3.2.org/src/fl_draw_pixmap.cxx fltk-1.3.2/src/fl_draw_pixmap.cxx +--- fltk-1.3.2.org/src/fl_draw_pixmap.cxx 2012-04-22 05:09:31.000000000 +0200 ++++ fltk-1.3.2/src/fl_draw_pixmap.cxx 2013-01-16 14:40:51.542230588 +0100 +@@ -58,99 +58,6 @@ + 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,34 +107,33 @@ + } + #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; + used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar)); + #endif + +- if (ncolors < 0) { // FLTK (non standard) compressed colormap ++ if (ncolors < 0) { ++ // FLTK (non standard) compressed colormap + ncolors = -ncolors; + const uchar *p = *data++; + // 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 +144,7 @@ + } + // 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,69 +154,44 @@ + *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)); ++ } else { ++ // normal XPM colormap with names + 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]; +- ind = (ind<<8)|*p++; +- } else { +- c = (uchar *)&d.colors[ind]; +- } ++ if (chars_per_pixel>1) ++ ind = (ind<<8)|*p++; ++ c = colors[ind]; + // look for "c word", or last word if none: + const uchar *previous_word = p; + for (;;) { +- while (*p && isspace(*p)) p++; +- uchar what = *p++; +- while (*p && !isspace(*p)) p++; +- while (*p && isspace(*p)) p++; +- if (!*p) {p = previous_word; break;} +- if (what == 'c') break; +- previous_word = p; +- while (*p && !isspace(*p)) p++; ++ while (*p && isspace(*p)) p++; ++ uchar what = *p++; ++ while (*p && !isspace(*p)) p++; ++ while (*p && isspace(*p)) p++; ++ if (!*p) {p = previous_word; break;} ++ if (what == 'c') break; ++ 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]; +- used_colors[3*color_count+1] = c[1]; +- used_colors[3*color_count+2] = c[2]; +- color_count++; ++ used_colors[3*color_count] = c[0]; ++ used_colors[3*color_count+1] = c[1]; ++ used_colors[3*color_count+2] = c[2]; ++ color_count++; + #endif +- } +- else { ++ } else { + // assume "None" or "#transparent" for any errors +- // "bg" should be transparent... +- Fl::get_color(bg, c[0], c[1], c[2]); +-#ifdef __APPLE_QUARTZ__ ++ // "bg" should be transparent... ++ Fl::get_color(bg, c[0], c[1], c[2]); + c[3] = 0; +-#endif + transparent_index = ind; + #ifdef WIN32 + transparent_c = c; +@@ -324,7 +199,6 @@ + } + } + } +- d.data = data; + #ifdef WIN32 + if (transparent_c) { + make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); +@@ -334,77 +208,76 @@ + make_unused_color(r, g, b); + } + #endif ++ ++ 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); ++ } ++ } ++ } + ++ 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()) { +- 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++]; +- } +- } +- } +- Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 4); ++ 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; +- } +- } 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; ++ bit = 1; ++ b = 0; + } + } +- +- if (bit > 1) *bitmap++ = b; + } +- } ++ + } + +- 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; + } + +diff -ur fltk-1.3.2.org/src/Fl_Image.cxx fltk-1.3.2/src/Fl_Image.cxx +--- fltk-1.3.2.org/src/Fl_Image.cxx 2012-11-09 17:02:08.000000000 +0100 ++++ fltk-1.3.2/src/Fl_Image.cxx 2013-01-16 14:41:38.404162795 +0100 +@@ -165,7 +165,22 @@ + // + 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; +diff -ur fltk-1.3.2.org/src/ps_image.cxx fltk-1.3.2/src/ps_image.cxx +--- fltk-1.3.2.org/src/ps_image.cxx 2011-07-19 06:49:30.000000000 +0200 ++++ fltk-1.3.2/src/ps_image.cxx 2013-01-16 14:40:51.541228080 +0100 +@@ -185,72 +185,38 @@ + + 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 @@ + 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); + |