fltk  1.3.5-source
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X.
  Fossies Dox: fltk-1.3.5-source.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

fl_draw_pixmap.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // Pixmap drawing code for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2012 by Bill Spitzak and others.
7 //
8 // This library is free software. Distribution and use rights are outlined in
9 // the file "COPYING" which should have been included with this file. If this
10 // file is missing or damaged, see the license at:
11 //
12 // http://www.fltk.org/COPYING.php
13 //
14 // Please report all bugs and problems on the following page:
15 //
16 // http://www.fltk.org/str.php
17 //
18 
19 // NOTE: I believe many of the following comments (between the dash markers)
20 // are no longer accurate:
21 // --------------------------------------------------------------------
22 // Implemented without using the xpm library (which I can't use because
23 // it interferes with the color cube used by fl_draw_image).
24 // Current implementation is cheap and slow, and works best on a full-color
25 // display. Transparency is not handled, and colors are dithered to
26 // the color cube. Color index is achieved by adding the id
27 // characters together! Also mallocs a lot of temporary memory!
28 // Notice that there is no pixmap file interface. This is on purpose,
29 // as I want to discourage programs that require support files to work.
30 // All data needed by a program ui should be compiled in!!!
31 // --------------------------------------------------------------------
32 // The above comments were checked in as r2, and much has changed since then;
33 // transparency added, color cube not required, etc. -erco Oct 20 2013
34 
35 #include <FL/Fl.H>
36 #include <FL/fl_draw.H>
37 #include <FL/x.H>
38 #include <stdio.h>
39 #include "flstring.h"
40 
42 
52 int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h) {
53  return fl_measure_pixmap((const char*const*)data,w,h);
54 }
55 
60 int fl_measure_pixmap(const char * const *cdata, int &w, int &h) {
61  int i = sscanf(cdata[0],"%d%d%d%d",&w,&h,&ncolors,&chars_per_pixel);
62  if (i<4 || w<=0 || h<=0 ||
63  (chars_per_pixel!=1 && chars_per_pixel!=2) ) return w=0;
64  return 1;
65 }
66 
67 uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
68 
78 int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) {
79  return fl_draw_pixmap((const char*const*)data,x,y,bg);
80 }
81 
82 #ifdef WIN32
83 // to compute an unused color to be used for the pixmap background
84 FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color
85 static int color_count; // # of non-transparent colors used in pixmap
86 typedef struct { uchar r; uchar g; uchar b; } UsedColor;
87 static UsedColor *used_colors;
88 
89 // Makes an RGB triplet different from all the colors used in the pixmap
90 // and compute win_pixmap_bg_color from this triplet
91 static void make_unused_color(uchar &r, uchar &g, uchar &b) {
92  int i;
93  r = 2; g = 3; b = 4;
94  while (1) {
95  for ( i=0; i<color_count; i++ )
96  if ( used_colors[i].r == r &&
97  used_colors[i].g == g &&
98  used_colors[i].b == b )
99  break;
100  if (i >= color_count) {
101  free((void*)used_colors); used_colors = NULL;
102  win_pixmap_bg_color = RGB(r, g, b);
103  return;
104  }
105  if (r < 255) {
106  r++;
107  } else {
108  r = 0;
109  if (g < 255) {
110  g++;
111  } else {
112  g = 0;
113  b++;
114  }
115  }
116  }
117 }
118 #endif
119 
120 int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
121  int w, h;
122  const uchar*const* data = (const uchar*const*)(cdata+1);
123 
124  if (!fl_measure_pixmap(cdata, w, h))
125  return 0;
126 
127  if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
128  return 0;
129 
130  typedef uchar uchar4[4];
131  uchar4 *colors = new uchar4[1<<(chars_per_pixel*8)];
132 
133 #ifdef WIN32
134  uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
135  color_count = 0;
136  used_colors = (UsedColor*)malloc(abs(ncolors) * sizeof(UsedColor));
137 #endif
138 
139  if (ncolors < 0) { // FLTK (non standard) compressed colormap
140  ncolors = -ncolors;
141  const uchar *p = *data++;
142  // if first color is ' ' it is transparent (put it later to make
143  // it not be transparent):
144  if (*p == ' ') {
145  uchar* c = colors[(int)' '];
146  Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
147 #ifdef WIN32
148  transparent_c = c;
149 #endif
150  p += 4;
151  ncolors--;
152  }
153  // read all the rest of the colors:
154  for (int i=0; i < ncolors; i++) {
155  uchar* c = colors[*p++];
156 #ifdef WIN32
157  used_colors[color_count].r = *(p+0);
158  used_colors[color_count].g = *(p+1);
159  used_colors[color_count].b = *(p+2);
160  color_count++;
161 #endif
162  *c++ = *p++;
163  *c++ = *p++;
164  *c++ = *p++;
165  *c = 255;
166  }
167  } else { // normal XPM colormap with names
168  for (int i=0; i<ncolors; i++) {
169  const uchar *p = *data++;
170  // the first 1 or 2 characters are the color index:
171  int ind = *p++;
172  uchar* c;
173  if (chars_per_pixel>1)
174  ind = (ind<<8)|*p++;
175  c = colors[ind];
176  // look for "c word", or last word if none:
177  const uchar *previous_word = p;
178  for (;;) {
179  while (*p && isspace(*p)) p++;
180  uchar what = *p++;
181  while (*p && !isspace(*p)) p++;
182  while (*p && isspace(*p)) p++;
183  if (!*p) {p = previous_word; break;}
184  if (what == 'c') break;
185  previous_word = p;
186  while (*p && !isspace(*p)) p++;
187  }
188  int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
189  c[3] = 255;
190  if (parse) {
191 #ifdef WIN32
192  used_colors[color_count].r = c[0];
193  used_colors[color_count].g = c[1];
194  used_colors[color_count].b = c[2];
195  color_count++;
196 #endif
197  } else {
198  // assume "None" or "#transparent" for any errors
199  // "bg" should be transparent...
200  Fl::get_color(bg, c[0], c[1], c[2]);
201  c[3] = 0;
202 #ifdef WIN32
203  transparent_c = c;
204 #endif
205  } // if parse
206  } // for ncolors
207  } // if ncolors
208 #ifdef WIN32
209  if (transparent_c) {
210  make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
211  } else {
212  uchar r, g, b;
213  make_unused_color(r, g, b);
214  }
215 #endif
216 
217  U32 *q = (U32*)out;
218  for (int Y = 0; Y < h; Y++) {
219  const uchar* p = data[Y];
220  if (chars_per_pixel <= 1) {
221  for (int X = 0; X < w; X++)
222  memcpy(q++, colors[*p++], 4);
223  } else {
224  for (int X = 0; X < w; X++) {
225  int ind = (*p++)<<8;
226  ind |= *p++;
227  memcpy(q++, colors[ind], 4);
228  }
229  }
230  }
231  delete[] colors;
232  return 1;
233 }
234 
239 int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
240  int w, h;
241 
242  if (!fl_measure_pixmap(cdata, w, h))
243  return 0;
244 
245  uchar *buffer = new uchar[w*h*4];
246 
247  if (!fl_convert_pixmap(cdata, buffer, bg)) {
248  delete[] buffer;
249  return 0;
250  }
251 
252  // FIXME: Hack until fl_draw_image() supports alpha properly
253 #ifdef __APPLE_QUARTZ__
255  Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4);
256  rgb->alloc_array = 1;
257  rgb->draw(x, y);
258  delete rgb;
259  return 1;
260  } else {
261 #endif // __APPLE_QUARTZ__
262  // build the mask bitmap used by Fl_Pixmap:
263  if (fl_mask_bitmap) {
264  int W = (w+7)/8;
265  uchar* bitmap = new uchar[W * h];
266  *fl_mask_bitmap = bitmap;
267  const uchar *p = &buffer[3];
268  uchar b = 0;
269  for (int Y = 0; Y < h; Y++) {
270  b = 0;
271  for (int X = 0, bit = 1; X < w; X++, p += 4) {
272  if (*p > 127)
273  b |= bit;
274  bit <<= 1;
275  if (bit > 0x80 || X == w-1) {
276  *bitmap++ = b;
277  bit = 1;
278  b = 0;
279  }
280  } // if chars_per_pixel
281  } // for Y
282  }
283 
284  fl_draw_image(buffer, x, y, w, h, 4);
285 
286 #ifdef __APPLE_QUARTZ__
287  }
288 #endif
289  delete[] buffer;
290  return 1;
291 }
292 
293 //
294 // End of "$Id$".
295 //
Fl.H
Fl_Color
unsigned int Fl_Color
Definition: Enumerations.H:934
chars_per_pixel
static int chars_per_pixel
Definition: fl_draw_pixmap.cxx:41
ncolors
static int ncolors
Definition: fl_draw_pixmap.cxx:41
x.H
free
void free()
fl_convert_pixmap
int fl_convert_pixmap(const char *const *cdata, uchar *out, Fl_Color bg)
Definition: fl_draw_pixmap.cxx:120
NULL
#define NULL
Definition: forms.H:34
b
long b
Definition: jpegint.h:397
FL_EXPORT
#define FL_EXPORT
Definition: Fl_Export.H:35
Fl_Display_Device::display_device
static Fl_Display_Device * display_device()
Definition: Fl_Device.cxx:83
fl_draw_image
void fl_draw_image(const uchar *buf, int X, int Y, int W, int H, int D=3, int L=0)
Definition: fl_draw.H:685
buffer
static char * buffer
Definition: file.cxx:215
p
static menustate * p
Definition: Fl_Menu.cxx:606
Fl::get_color
static unsigned get_color(Fl_Color i)
Definition: fl_color.cxx:359
Fl_RGB_Image::alloc_array
int alloc_array
Definition: Fl_Image.H:215
fl_measure_pixmap
int fl_measure_pixmap(char *const *data, int &w, int &h)
Definition: fl_draw_pixmap.cxx:52
fl_draw.H
utility header to pull drawing functions together
fl_parse_color
int fl_parse_color(const char *p, uchar &r, uchar &g, uchar &b)
Definition: Fl_get_system_colors.cxx:122
Fl_Surface_Device::surface
static Fl_Surface_Device * surface()
Definition: Fl_Device.H:574
U32
#define U32
Definition: config.h:201
Fl_RGB_Image::draw
virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0)
Definition: Fl_Image.cxx:651
fl_draw_pixmap
int fl_draw_pixmap(char *const *data, int x, int y, Fl_Color bg)
Definition: fl_draw_pixmap.cxx:78
x
int x
Definition: test.c:73
y
int y
Definition: test.c:74
malloc
voidp malloc()
Y
static int Y
Definition: Fl_Tooltip.cxx:76
flstring.h
fl_mask_bitmap
uchar ** fl_mask_bitmap
Definition: fl_draw_pixmap.cxx:67
uchar
unsigned char uchar
Definition: fl_types.h:30
Fl_RGB_Image
Definition: Fl_Image.H:202