You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
7.6KB

  1. //
  2. // "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. // Pixmap label support for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2010 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. #include <FL/Fl.H>
  28. #include <FL/Fl_Widget.H>
  29. #include "Fl_Type.h"
  30. #include "Fluid_Image.h"
  31. #include "../src/flstring.h"
  32. #include <stdio.h>
  33. #include <errno.h>
  34. #include <stdlib.h>
  35. #include <FL/filename.H>
  36. extern void goto_source_dir(); // in fluid.C
  37. extern void leave_source_dir(); // in fluid.C
  38. void Fluid_Image::image(Fl_Widget *o) {
  39. if (o->window() != o) o->image(img);
  40. }
  41. void Fluid_Image::deimage(Fl_Widget *o) {
  42. if (o->window() != o) o->deimage(img);
  43. }
  44. static int pixmap_header_written = 0;
  45. static int bitmap_header_written = 0;
  46. static int image_header_written = 0;
  47. static int jpeg_header_written = 0;
  48. void Fluid_Image::write_static() {
  49. if (!img) return;
  50. if (img->count() > 1) {
  51. // Write Pixmap data...
  52. write_c("\n");
  53. if (pixmap_header_written != write_number) {
  54. write_c("#include <FL/Fl_Pixmap.H>\n");
  55. pixmap_header_written = write_number;
  56. }
  57. write_c("static const char *%s[] = {\n",
  58. unique_id(this, "idata", fl_filename_name(name()), 0));
  59. write_cstring(img->data()[0], strlen(img->data()[0]));
  60. int i;
  61. int ncolors, chars_per_color;
  62. sscanf(img->data()[0], "%*d%*d%d%d", &ncolors, &chars_per_color);
  63. if (ncolors < 0) {
  64. write_c(",\n");
  65. write_cstring(img->data()[1], ncolors * -4);
  66. i = 2;
  67. } else {
  68. for (i = 1; i <= ncolors; i ++) {
  69. write_c(",\n");
  70. write_cstring(img->data()[i], strlen(img->data()[i]));
  71. }
  72. }
  73. for (; i < img->count(); i ++) {
  74. write_c(",\n");
  75. write_cstring(img->data()[i], img->w() * chars_per_color);
  76. }
  77. write_c("\n};\n");
  78. write_c("static Fl_Pixmap %s(%s);\n",
  79. unique_id(this, "image", fl_filename_name(name()), 0),
  80. unique_id(this, "idata", fl_filename_name(name()), 0));
  81. } else if (img->d() == 0) {
  82. // Write Bitmap data...
  83. write_c("\n");
  84. if (bitmap_header_written != write_number) {
  85. write_c("#include <FL/Fl_Bitmap.H>\n");
  86. bitmap_header_written = write_number;
  87. }
  88. write_c("static unsigned char %s[] =\n",
  89. unique_id(this, "idata", fl_filename_name(name()), 0));
  90. write_cdata(img->data()[0], ((img->w() + 7) / 8) * img->h());
  91. write_c(";\n");
  92. write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
  93. unique_id(this, "image", fl_filename_name(name()), 0),
  94. unique_id(this, "idata", fl_filename_name(name()), 0),
  95. img->w(), img->h());
  96. } else if (strcmp(fl_filename_ext(name()), ".jpg")==0) {
  97. // Write jpeg image data...
  98. write_c("\n");
  99. if (jpeg_header_written != write_number) {
  100. write_c("#include <FL/Fl_JPEG_Image.H>\n");
  101. jpeg_header_written = write_number;
  102. }
  103. write_c("static unsigned char %s[] =\n",
  104. unique_id(this, "idata", fl_filename_name(name()), 0));
  105. FILE *f = fl_fopen(name(), "rb");
  106. if (!f) {
  107. // message = "Can't include binary file. Can't open";
  108. } else {
  109. fseek(f, 0, SEEK_END);
  110. size_t nData = ftell(f);
  111. fseek(f, 0, SEEK_SET);
  112. if (nData) {
  113. char *data = (char*)calloc(nData, 1);
  114. if (fread(data, nData, 1, f)==0) { /* ignore */ }
  115. write_cdata(data, nData);
  116. free(data);
  117. }
  118. fclose(f);
  119. }
  120. write_c(";\n");
  121. write_c("static Fl_JPEG_Image %s(\"%s\", %s);\n",
  122. unique_id(this, "image", fl_filename_name(name()), 0),
  123. fl_filename_name(name()),
  124. unique_id(this, "idata", fl_filename_name(name()), 0));
  125. } else {
  126. // Write image data...
  127. write_c("\n");
  128. if (image_header_written != write_number) {
  129. write_c("#include <FL/Fl_Image.H>\n");
  130. image_header_written = write_number;
  131. }
  132. write_c("static unsigned char %s[] =\n",
  133. unique_id(this, "idata", fl_filename_name(name()), 0));
  134. write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
  135. write_c(";\n");
  136. write_c("static Fl_RGB_Image %s(%s, %d, %d, %d, %d);\n",
  137. unique_id(this, "image", fl_filename_name(name()), 0),
  138. unique_id(this, "idata", fl_filename_name(name()), 0),
  139. img->w(), img->h(), img->d(), img->ld());
  140. }
  141. }
  142. void Fluid_Image::write_code(const char *var, int inactive) {
  143. if (!img) return;
  144. write_c("%s%s->%s(%s);\n", indent(), var, inactive ? "deimage" : "image",
  145. unique_id(this, "image", fl_filename_name(name()), 0));
  146. }
  147. ////////////////////////////////////////////////////////////////
  148. static Fluid_Image** images = 0; // sorted list
  149. static int numimages = 0;
  150. static int tablesize = 0;
  151. Fluid_Image* Fluid_Image::find(const char *iname) {
  152. if (!iname || !*iname) return 0;
  153. // first search to see if it exists already:
  154. int a = 0;
  155. int b = numimages;
  156. while (a < b) {
  157. int c = (a+b)/2;
  158. int i = strcmp(iname,images[c]->name_);
  159. if (i < 0) b = c;
  160. else if (i > 0) a = c+1;
  161. else return images[c];
  162. }
  163. // no, so now see if the file exists:
  164. goto_source_dir();
  165. FILE *f = fl_fopen(iname,"rb");
  166. if (!f) {
  167. read_error("%s : %s",iname,strerror(errno));
  168. leave_source_dir();
  169. return 0;
  170. }
  171. fclose(f);
  172. Fluid_Image *ret = new Fluid_Image(iname);
  173. if (!ret->img || !ret->img->w() || !ret->img->h()) {
  174. delete ret;
  175. ret = 0;
  176. read_error("%s : unrecognized image format", iname);
  177. }
  178. leave_source_dir();
  179. if (!ret) return 0;
  180. // make a new entry in the table:
  181. numimages++;
  182. if (numimages > tablesize) {
  183. tablesize = tablesize ? 2*tablesize : 16;
  184. if (images) images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
  185. else images = (Fluid_Image**)malloc(tablesize*sizeof(Fluid_Image*));
  186. }
  187. for (b = numimages-1; b > a; b--) images[b] = images[b-1];
  188. images[a] = ret;
  189. return ret;
  190. }
  191. Fluid_Image::Fluid_Image(const char *iname) {
  192. name_ = strdup(iname);
  193. written = 0;
  194. refcount = 0;
  195. img = Fl_Shared_Image::get(iname);
  196. }
  197. void Fluid_Image::increment() {
  198. ++refcount;
  199. }
  200. void Fluid_Image::decrement() {
  201. --refcount;
  202. if (refcount > 0) return;
  203. delete this;
  204. }
  205. Fluid_Image::~Fluid_Image() {
  206. int a;
  207. if (images) {
  208. for (a = 0;; a++) if (images[a] == this) break;
  209. numimages--;
  210. for (; a < numimages; a++) images[a] = images[a+1];
  211. }
  212. if (img) img->release();
  213. free((void*)name_);
  214. }
  215. ////////////////////////////////////////////////////////////////
  216. #include <FL/Fl_File_Chooser.H>
  217. const char *ui_find_image_name;
  218. Fluid_Image *ui_find_image(const char *oldname) {
  219. goto_source_dir();
  220. fl_file_chooser_ok_label("Use Image");
  221. const char *name = fl_file_chooser("Image?","Image Files (*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm})",oldname,1);
  222. fl_file_chooser_ok_label(NULL);
  223. ui_find_image_name = name;
  224. Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
  225. leave_source_dir();
  226. return ret;
  227. }
  228. //
  229. // End of "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
  230. //