summaryrefslogtreecommitdiff
path: root/src/Fl_Pixmap.cxx
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2001-11-19 01:06:45 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>2001-11-19 01:06:45 +0000
commit1acc39c5d8d5b3db88abfd008699dadb8aade2b9 (patch)
treec35a486fc713b48c85286ce42291aa88e6652e7e /src/Fl_Pixmap.cxx
parent681ded73c20af217254a8dfb7838b612b17b126c (diff)
OK, lots of changes to the Fl_Image, Fl_Bitmap, Fl_Pixmap, and Fl_RGB_Image
classes: new copy(), copy(w,h), desaturate(), color_average(), and inactive() methods, alloc_xyz member for copied data, etc. Updated test programs to use inactive() and copy() methods to create inactive images for the test buttons, plus the inactive button to toggle it... Added start of separate image classes, a la 2.0, for various image formats. FLUID will also be updated for it... git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1703 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Pixmap.cxx')
-rw-r--r--src/Fl_Pixmap.cxx317
1 files changed, 315 insertions, 2 deletions
diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx
index cf3b65465..67a584238 100644
--- a/src/Fl_Pixmap.cxx
+++ b/src/Fl_Pixmap.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.3 2001/11/18 20:52:28 easysw Exp $"
+// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.4 2001/11/19 01:06:45 easysw Exp $"
//
// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
//
@@ -38,6 +38,8 @@
#include <FL/Fl_Pixmap.H>
#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.cxx to store mask
void fl_restore_clip(); // in fl_rect.cxx
@@ -172,6 +174,7 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
Fl_Pixmap::~Fl_Pixmap() {
if (id) fl_delete_offscreen(id);
if (mask) fl_delete_bitmask(mask);
+ delete_data();
}
void Fl_Pixmap::label(Fl_Widget* w) {
@@ -181,6 +184,316 @@ void Fl_Pixmap::label(Fl_Widget* w) {
void Fl_Pixmap::label(Fl_Menu_Item* m) {
}
+void Fl_Pixmap::copy_data() {
+ if (alloc_data) return;
+
+ char **new_data, // New data array
+ **new_row; // Current row in image
+ int i, // Looping var
+ ncolors, // Number of colors in image
+ chars_per_pixel,// Characters per color
+ chars_per_line; // Characters per line
+
+ // Figure out how many colors there are, and how big they are...
+ sscanf(data[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+ chars_per_line = chars_per_pixel * w() + 1;
+
+ // Allocate memory for the new array...
+ new_data = new char *[h() + ncolors + 1];
+ new_data[0] = new char[strlen(data[0]) + 1];
+ strcpy(new_data[0], data[0]);
+
+ // Copy colors...
+ if (ncolors < 0) {
+ // Copy FLTK colormap values...
+ ncolors = -ncolors;
+ for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+ *new_row = new char[4];
+ memcpy(*new_row, data[i + 1], 4);
+ }
+ } else {
+ // Copy standard XPM colormap values...
+ for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+ *new_row = new char[strlen(data[i + 1]) + 1];
+ strcpy(*new_row, data[i + 1]);
+ }
+ }
+
+ // Copy image data...
+ for (i = 0; i < h(); i ++, new_row ++) {
+ *new_row = new char[chars_per_line];
+ memcpy(*new_row, data[i + ncolors + 1], chars_per_line);
+ }
+
+ // Update pointers...
+ data = new_data;
+ alloc_data = 1;
+}
+
+Fl_Image *Fl_Pixmap::copy(int W, int H) {
+ // Optimize the simple copy where the width and height are the same...
+ if (W == w() && H == h()) return new Fl_Pixmap(data);
+
+ // OK, need to resize the image data; allocate memory and
+ Fl_Pixmap *new_image; // New pixmap
+ char **new_data, // New array for image data
+ **new_row, // Pointer to row in image data
+ *new_ptr, // Pointer into new array
+ new_info[255]; // New information line
+ const char *old_ptr; // Pointer into old array
+ int i, // Looping var
+ c, // Channel number
+ sy, // Source coordinate
+ dx, dy, // Destination coordinates
+ xerr, yerr, // X & Y errors
+ xmod, ymod, // X & Y moduli
+ xstep, ystep; // X & Y step increments
+ int ncolors, // Number of colors in image
+ chars_per_pixel,// Characters per color
+ chars_per_line; // Characters per line
+
+ // Figure out how many colors there are, and how big they are...
+ sscanf(data[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+ chars_per_line = chars_per_pixel * W + 1;
+
+ sprintf(new_info, "%d %d %d %d", W, H, ncolors, chars_per_pixel);
+
+ // Figure out Bresenheim step/modulus values...
+ xmod = w() % W;
+ xstep = (w() / W) * chars_per_pixel;
+ ymod = h() % H;
+ ystep = h() / H;
+
+ // Allocate memory for the new array...
+ new_data = new char *[H + ncolors + 1];
+ new_data[0] = new char[strlen(new_info) + 1];
+ strcpy(new_data[0], new_info);
+
+ // Copy colors...
+ if (ncolors < 0) {
+ // Copy FLTK colormap values...
+ ncolors = -ncolors;
+ for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+ *new_row = new char[4];
+ memcpy(*new_row, data[i + 1], 4);
+ }
+ } else {
+ // Copy standard XPM colormap values...
+ for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) {
+ *new_row = new char[strlen(data[i + 1]) + 1];
+ strcpy(*new_row, data[i + 1]);
+ }
+ }
+
+ // Copy image data...
+ for (i = 0; i < h(); i ++, new_row ++) {
+ *new_row = new char[chars_per_line];
+ memcpy(*new_row, data[i + ncolors + 1], chars_per_line);
+ }
+ // Scale the image using a nearest-neighbor algorithm...
+ for (dy = h(), sy = 0, yerr = H / 2; dy > 0; dy --, new_row ++) {
+ *new_row = new char[chars_per_line];
+ new_ptr = *new_row;
+
+ for (dx = w(), xerr = W / 2, old_ptr = data[sy + ncolors + 1];
+ dx > 0;
+ dx --) {
+ for (c = 0; c < chars_per_pixel; c ++) *new_ptr++ = old_ptr[c];
+
+ old_ptr += xstep;
+ xerr -= xmod;
+
+ if (xerr <= 0) {
+ xerr += W;
+ old_ptr += chars_per_pixel;
+ }
+ }
+
+ *new_ptr = '\0';
+ sy += ystep;
+ yerr -= ymod;
+ if (yerr <= 0) {
+ yerr += H;
+ sy ++;
+ }
+ }
+
+ new_image = new Fl_Pixmap((const char * const *)data);
+ new_image->alloc_data = 1;
+
+ return new_image;
+}
+
+void Fl_Pixmap::color_average(Fl_Color c, float i) {
+ // Delete any existing pixmap/mask objects...
+ if (id) {
+ fl_delete_offscreen(id);
+ id = 0;
+ }
+
+ if (mask) {
+ fl_delete_bitmask(mask);
+ mask = 0;
+ }
+
+ // Allocate memory as needed...
+ copy_data();
+
+ // Get the color to blend with...
+ uchar r, g, b;
+ unsigned ia, ir, ig, ib;
+
+ Fl::get_color(c, r, g, b);
+ if (i < 0.0f) i = 0.0f;
+ else if (i > 1.0f) i = 1.0f;
+
+ ia = (unsigned)(256 * i);
+ ir = r * (256 - ia);
+ ig = g * (256 - ia);
+ ib = b * (256 - ia);
+
+ // Update the colormap to do the blend...
+ char line[255]; // New colormap line
+ int color, // Looping var
+ ncolors, // Number of colors in image
+ chars_per_pixel;// Characters per color
+
+
+ sscanf(data[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+
+ if (ncolors < 0) {
+ // Update FLTK colormap...
+ ncolors = -ncolors;
+ for (color = 0; color < ncolors; color ++) {
+ ((char *)data[color + 1])[1] = (ia * data[color + 1][1] + ir) >> 8;
+ ((char *)data[color + 1])[2] = (ia * data[color + 1][2] + ig) >> 8;
+ ((char *)data[color + 1])[3] = (ia * data[color + 1][3] + ib) >> 8;
+ }
+ } else {
+ // Update standard XPM colormap...
+ for (color = 0; color < ncolors; color ++) {
+ // look for "c word", or last word if none:
+ const char *p = data[color + 1] + chars_per_pixel + 1;
+ const char *previous_word = p;
+ for (;;) {
+ while (*p && isspace(*p)) p++;
+ char 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 WIN32
+ if (fl_parse_color(p, r, g, b) {
+#else
+ XColor x;
+ if (XParseColor(fl_display, fl_colormap, p, &x)) {
+ r = x.red>>8;
+ g = x.green>>8;
+ b = x.blue>>8;
+#endif
+
+ r = (ia * r + ir) >> 8;
+ g = (ia * g + ig) >> 8;
+ b = (ia * b + ib) >> 8;
+
+ if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X",
+ data[color + 1][0],
+ data[color + 1][1], r, g, b);
+ else sprintf(line, "%c c #%02X%02X%02X", data[color + 1][0], r, g, b);
+
+ delete[] data[color + 1];
+ ((char **)data)[color + 1] = new char[strlen(line) + 1];
+ strcpy((char *)data[color + 1], line);
+ }
+ }
+ }
+}
+
+void Fl_Pixmap::delete_data() {
+ if (alloc_data) {
+ for (int i = 0; data[i]; i ++) delete[] data[i];
+ delete[] data;
+ }
+}
+
+void Fl_Pixmap::desaturate() {
+ // Delete any existing pixmap/mask objects...
+ if (id) {
+ fl_delete_offscreen(id);
+ id = 0;
+ }
+
+ if (mask) {
+ fl_delete_bitmask(mask);
+ mask = 0;
+ }
+
+ // Allocate memory as needed...
+ copy_data();
+
+ // Update the colormap to grayscale...
+ char line[255]; // New colormap line
+ int i, // Looping var
+ ncolors, // Number of colors in image
+ chars_per_pixel;// Characters per color
+ uchar r, g, b;
+
+ sscanf(data[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel);
+
+ if (ncolors < 0) {
+ // Update FLTK colormap...
+ ncolors = -ncolors;
+ for (i = 0; i < ncolors; i ++) {
+ g = (data[i + 1][1] * 31 + data[i + 1][2] * 61 + data[i + 1][3] * 8) / 100;
+ ((char *)data[i + 1])[1] =
+ ((char *)data[i + 1])[2] =
+ ((char *)data[i + 1])[3] = g;
+ }
+ } else {
+ // Update standard XPM colormap...
+ for (i = 0; i < ncolors; i ++) {
+ // look for "c word", or last word if none:
+ const char *p = data[i + 1] + chars_per_pixel + 1;
+ const char *previous_word = p;
+ for (;;) {
+ while (*p && isspace(*p)) p++;
+ char 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 WIN32
+ if (fl_parse_color(p, r, g, b) {
+#else
+ XColor x;
+ if (XParseColor(fl_display, fl_colormap, p, &x)) {
+ r = x.red>>8;
+ g = x.green>>8;
+ b = x.blue>>8;
+#endif
+
+ g = (r * 31 + g * 61 + b * 8) / 100;
+
+ if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", data[i + 1][0],
+ data[i + 1][1], g, g, g);
+ else sprintf(line, "%c c #%02X%02X%02X", data[i + 1][0], g, g, g);
+
+ delete[] data[i + 1];
+ ((char **)data)[i + 1] = new char[strlen(line) + 1];
+ strcpy((char *)data[i + 1], line);
+ }
+ }
+ }
+}
+
//
-// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.3 2001/11/18 20:52:28 easysw Exp $".
+// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.4 2001/11/19 01:06:45 easysw Exp $".
//