DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2659
Version: 1.4-feature
Attached file "fltk-1_v2.3.x-pixmap.patch"...
Link: http://www.fltk.org/str.php?L2659
Version: 1.4-feature
diff -ur fltk-1.3.0r9619.org/src/Fl_Image.cxx fltk-1.3.0r9619/src/Fl_Image.cxx
--- fltk-1.3.0r9619.org/src/Fl_Image.cxx 2012-03-18 19:48:29.000000000
+0100
+++ fltk-1.3.0r9619/src/Fl_Image.cxx 2012-06-18 15:53:37.058387483 +0200
@@ -163,6 +163,19 @@
//
// RGB image class...
//
+
+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. */
+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 free all memory and server resources that are used by the
image. */
Fl_RGB_Image::~Fl_RGB_Image() {
uncache();
diff -ur fltk-1.3.0r9619.org/FL/Fl_Image.H fltk-1.3.0r9619/FL/Fl_Image.H
--- fltk-1.3.0r9619.org/FL/Fl_Image.H 2012-06-13 19:47:03.000000000 +0200
+++ fltk-1.3.0r9619/FL/Fl_Image.H 2012-06-18 15:53:51.176064518 +0200
@@ -25,6 +25,7 @@
# include "Enumerations.H"
class Fl_Widget;
+class Fl_Pixmap;
struct Fl_Menu_Item;
struct Fl_Label;
@@ -201,6 +202,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.0r9619.org/src/fl_draw_pixmap.cxx
fltk-1.3.0r9619/src/fl_draw_pixmap.cxx
--- fltk-1.3.0r9619.org/src/fl_draw_pixmap.cxx 2012-04-22 05:09:31.000000000
+0200
+++ fltk-1.3.0r9619/src/fl_draw_pixmap.cxx 2012-06-18 15:54:07.656854873
+0200
@@ -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;
- *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;
- }
- }
-
- if (bit > 1) *bitmap++ = b;
+ const uchar *p = &buffer[3];
+ for (int Y = 0; Y < h; Y++) {
+ int dw = w;
+ for (int X = 0; X < W; X++) {
+ uchar b = 0;
+ for (int bit = 0x01;bit <= 0x80;bit<<=1) {
+ if (dw-- < 0)
+ break;
+ if (*p > 127)
+ b |= bit;
+ p += 4;
+ }
+ *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;
}
_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev