1 /********************************************************************************
2 * *
3 * Image Test *
4 * *
5 ********************************************************************************/
6 #include "fx.h"
7 #ifdef HAVE_PNG_H
8 #include "FXPNGImage.h"
9 #endif
10 #ifdef HAVE_JPEG_H
11 #include "FXJPGImage.h"
12 #endif
13 #ifdef HAVE_TIFF_H
14 #include "FXTIFImage.h"
15 #endif
16 #include "FXICOImage.h"
17 #include "FXTGAImage.h"
18 #include "FXRGBImage.h"
19
20 #include "FXGradientBar.h"
21
22
23 FXColor grey_ramp[512*50]; // Created images
24 FXColor red_ramp[512*50];
25 FXColor green_ramp[512*50];
26 FXColor blue_ramp[512*50];
27
28
29 // Event Handler Object
30 class ImageWindow : public FXMainWindow {
31
32 // Macro for class hierarchy declarations
33 FXDECLARE(ImageWindow)
34
35 private:
36
37 FXCanvas *canvas; // Canvas to draw into
38 FXColorWell *backwell; // Color Well for background
39 FXColorWell *borderwell; // Color Well for border
40 FXColorWell *textwell; // Color Well for text
41 FXImage *grey;
42 FXImage *red;
43 FXImage *green;
44 FXImage *blue;
45 FXImage *grey_nodither;
46 FXImage *red_nodither;
47 FXImage *green_nodither;
48 FXImage *blue_nodither;
49 FXImage *picture; // Complete picture
50 FXFont *font; // Font for text
51
52 protected:
ImageWindow()53 ImageWindow(){}
54
55 public:
56
57 // Message handlers
58 long onCanvasRepaint(FXObject*,FXSelector,void*);
59 long onCmdWell(FXObject*,FXSelector,void*);
60 long onCmdRestore(FXObject*,FXSelector,void*);
61
62 public:
63
64 // Messages for our class
65 enum{
66 ID_CANVAS=FXMainWindow::ID_LAST,
67 ID_WELL,
68 ID_RESTORE,
69 ID_LAST
70 };
71
72 public:
73
74 // ImageWindow constructor
75 ImageWindow(FXApp* a);
76
77 // Initialize
78 virtual void create();
79
80 // ImageWindow destructor
81 virtual ~ImageWindow();
82 };
83
84
85
86 // Message Map for the Scribble App class
87 FXDEFMAP(ImageWindow) ImageWindowMap[]={
88
89 //____Message_Type______________ID_______________Message_Handler___
90 FXMAPFUNC(SEL_PAINT, ImageWindow::ID_CANVAS, ImageWindow::onCanvasRepaint),
91 FXMAPFUNC(SEL_COMMAND, ImageWindow::ID_WELL, ImageWindow::onCmdWell),
92 FXMAPFUNC(SEL_COMMAND, ImageWindow::ID_RESTORE, ImageWindow::onCmdRestore),
93 };
94
95
96
97 // Macro for the ScribbleApp class hierarchy implementation
FXIMPLEMENT(ImageWindow,FXMainWindow,ImageWindowMap,ARRAYNUMBER (ImageWindowMap))98 FXIMPLEMENT(ImageWindow,FXMainWindow,ImageWindowMap,ARRAYNUMBER(ImageWindowMap))
99
100
101
102 // Construct ImageWindow
103 ImageWindow::ImageWindow(FXApp* a):FXMainWindow(a,"Image Application",NULL,NULL,DECOR_ALL,0,0,800,600){
104 FXint x,y;
105 FXVerticalFrame *canvasFrame;
106 FXVerticalFrame *buttonFrame;
107 FXHorizontalFrame *contents;
108
109 FXColorDialog *colordlg=new FXColorDialog(this,"Color Dialog");
110
111 FXHorizontalFrame *hf=new FXHorizontalFrame(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
112
113 //new FXGradientBar(this,NULL,0,GRADIENTBAR_VERTICAL|GRADIENTBAR_CONTROLS_LEFT|FRAME_SUNKEN|LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y,0,0,0,0, 15,15,15,15);
114 new FXGradientBar(this,NULL,0,GRADIENTBAR_VERTICAL|GRADIENTBAR_CONTROLS_LEFT|GRADIENTBAR_CONTROLS_RIGHT|FRAME_SUNKEN|LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y,0,0,0,0, 15,15,15,15);
115 //new FXGradientBar(this,NULL,0,GRADIENTBAR_VERTICAL|GRADIENTBAR_CONTROLS_RIGHT|FRAME_SUNKEN|LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y,0,0,0,0, 15,15,15,15);
116 //new FXGradientBar(this,NULL,0,GRADIENTBAR_VERTICAL|FRAME_SUNKEN|LAYOUT_SIDE_LEFT|LAYOUT_FILL_Y,0,0,0,0, 15,15,15,15);
117
118 //new FXGradientBar(this,NULL,0,GRADIENTBAR_HORIZONTAL|GRADIENTBAR_CONTROLS_BOTTOM|FRAME_SUNKEN|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0, 15,15,15,15);
119 FXGradientBar *gb=new FXGradientBar(this,NULL,0,GRADIENTBAR_HORIZONTAL|GRADIENTBAR_CONTROLS_TOP|GRADIENTBAR_CONTROLS_BOTTOM|FRAME_SUNKEN|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0, 15,15,15,15);
120 //new FXGradientBar(this,NULL,0,GRADIENTBAR_HORIZONTAL|GRADIENTBAR_CONTROLS_TOP|GRADIENTBAR_CONTROLS_BOTTOM|FRAME_SUNKEN|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0, 15,15,15,15);
121 //new FXGradientBar(this,NULL,0,GRADIENTBAR_HORIZONTAL|FRAME_SUNKEN|LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X,0,0,0,0, 15,15,15,15);
122
123
124 new FXRadioButton(hf,"Linear blend",gb,FXGradientBar::ID_BLEND_LINEAR,LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
125 new FXRadioButton(hf,"Power law blend",gb,FXGradientBar::ID_BLEND_POWER,LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
126 new FXRadioButton(hf,"Sine blend",gb,FXGradientBar::ID_BLEND_SINE,LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
127 new FXRadioButton(hf,"Increasing blend",gb,FXGradientBar::ID_BLEND_INCREASING,LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
128 new FXRadioButton(hf,"Decreasing blend",gb,FXGradientBar::ID_BLEND_DECREASING,LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
129 new FXColorWell(hf,FXRGB(0,0,0),gb,FXGradientBar::ID_LOWER_COLOR,LAYOUT_CENTER_Y);
130 new FXColorWell(hf,FXRGB(0,0,0),gb,FXGradientBar::ID_UPPER_COLOR,LAYOUT_CENTER_Y);
131 new FXButton(hf,"Recenter",NULL,gb,FXGradientBar::ID_RECENTER,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
132 new FXButton(hf,"Split",NULL,gb,FXGradientBar::ID_SPLIT,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
133 new FXButton(hf,"Merge",NULL,gb,FXGradientBar::ID_MERGE,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
134 new FXButton(hf,"Uniform",NULL,gb,FXGradientBar::ID_UNIFORM,FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|ICON_BEFORE_TEXT);
135
136 contents=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
137
138 // LEFT pane to contain the canvas
139 canvasFrame=new FXVerticalFrame(contents,FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
140
141 // Label above the canvas
142 new FXLabel(canvasFrame,"Canvas Frame",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
143
144 new FXRuler(canvasFrame,NULL,0,RULER_MARKERS|RULER_NUMBERS|RULER_ARROW|RULER_TICKS_CENTER|LAYOUT_FILL_X);
145
146 // Horizontal divider line
147 new FXHorizontalSeparator(canvasFrame,SEPARATOR_GROOVE|LAYOUT_FILL_X);
148
149 // Drawing canvas
150 canvas=new FXCanvas(canvasFrame,this,ID_CANVAS,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT);
151
152
153 // RIGHT pane for the buttons
154 buttonFrame=new FXVerticalFrame(contents,FRAME_SUNKEN|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
155
156 // Label above the buttons
157 new FXLabel(buttonFrame,"Button Frame",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
158
159 // Horizontal divider line
160 new FXHorizontalSeparator(buttonFrame,SEPARATOR_RIDGE|LAYOUT_FILL_X);
161
162 new FXLabel(buttonFrame,"&Background\nColor well",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
163 backwell=new FXColorWell(buttonFrame,FXRGB(255,255,255),this,ID_WELL,LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,0,0,100,30);
164
165 new FXLabel(buttonFrame,"B&order\nColor well",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
166 borderwell=new FXColorWell(buttonFrame,FXRGB(0,0,0),this,ID_WELL,LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,0,0,100,30);
167
168 new FXLabel(buttonFrame,"&Text\nColor well",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
169 textwell=new FXColorWell(buttonFrame,FXRGB(0,0,0),this,ID_WELL,LAYOUT_CENTER_X|LAYOUT_TOP|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,0,0,100,30);
170
171 // Button to draw
172 new FXButton(buttonFrame,"&Colors...\tPop the color dialog",NULL,colordlg,FXWindow::ID_SHOW,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,5,5);
173
174 // Button to draw
175 new FXButton(buttonFrame,"Save Image...\tRead back image and save to file",NULL,this,ID_RESTORE,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,5,5);
176
177 // Exit button
178 new FXButton(buttonFrame,"E&xit\tQuit ImageApp",NULL,getApp(),FXApp::ID_QUIT,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,5,5);
179
180 // Create images with dithering
181 grey=new FXImage(getApp(),grey_ramp,IMAGE_DITHER|IMAGE_SHMI|IMAGE_SHMP,512,50);
182 red=new FXImage(getApp(),red_ramp,IMAGE_DITHER|IMAGE_SHMI|IMAGE_SHMP,512,50);
183 green=new FXImage(getApp(),green_ramp,IMAGE_DITHER|IMAGE_SHMI|IMAGE_SHMP,512,50);
184 blue=new FXImage(getApp(),blue_ramp,IMAGE_DITHER|IMAGE_SHMI|IMAGE_SHMP,512,50);
185
186 // Create image with nearest color instead of dithering
187 grey_nodither=new FXImage(getApp(),grey_ramp,IMAGE_NEAREST|IMAGE_SHMI|IMAGE_SHMP,512,50);
188 red_nodither=new FXImage(getApp(),red_ramp,IMAGE_NEAREST|IMAGE_SHMI|IMAGE_SHMP,512,50);
189 green_nodither=new FXImage(getApp(),green_ramp,IMAGE_NEAREST|IMAGE_SHMI|IMAGE_SHMP,512,50);
190 blue_nodither=new FXImage(getApp(),blue_ramp,IMAGE_NEAREST|IMAGE_SHMI|IMAGE_SHMP,512,50);
191
192 // Result image
193 // picture=new FXBMPImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
194 // picture=new FXXPMImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
195 // picture=new FXGIFImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
196 // picture=new FXPNGImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
197 // picture=new FXRGBImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
198 // picture=new FXPCXImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
199 // picture=new FXTGAImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
200 // picture=new FXICOImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,64,64);
201 // picture=new FXJPGImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
202 // picture=new FXTIFImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
203 picture=new FXGIFImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,850,600);
204
205 // Fill the ramps
206 for(x=0; x<512; x++){
207 for(y=0; y<50; y++){
208 grey_ramp[y*512+x]=FXRGB(x/2,x/2,x/2);
209 }
210 for(y=0; y<50; y++){
211 red_ramp[y*512+x]=FXRGB(x/2,0,0);
212 }
213 for(y=0; y<50; y++){
214 green_ramp[y*512+x]=FXRGB(0,x/2,0);
215 }
216 for(y=0; y<50; y++){
217 blue_ramp[y*512+x]=FXRGB(0,0,x/2);
218 }
219 }
220
221 // Make font
222 font=new FXFont(getApp(),"times",36,FXFont::Bold);
223
224 // Make a tip
225 new FXToolTip(getApp());
226 }
227
228
229 // Destroy ImageWindow
~ImageWindow()230 ImageWindow::~ImageWindow(){
231 delete grey;
232 delete red;
233 delete green;
234 delete blue;
235 delete grey_nodither;
236 delete red_nodither;
237 delete green_nodither;
238 delete blue_nodither;
239 delete picture;
240 delete font;
241 }
242
243
244 // Create and initialize
create()245 void ImageWindow::create(){
246
247 // Create the windows
248 FXMainWindow::create();
249
250 // Create images
251 grey->create();
252 red->create();
253 green->create();
254 blue->create();
255 grey_nodither->create();
256 red_nodither->create();
257 green_nodither->create();
258 blue_nodither->create();
259
260 picture->create();
261
262 // Font too
263 font->create();
264
265 // Make it appear
266 show(PLACEMENT_SCREEN);
267
268 // First time repaint
269 canvas->update();
270
271 }
272
273
274 // Handle the clear message
onCanvasRepaint(FXObject *,FXSelector,void * ptr)275 long ImageWindow::onCanvasRepaint(FXObject*,FXSelector,void* ptr){
276 FXEvent *event=(FXEvent*)ptr;
277 FXuint pat;
278
279 // We caused a redraw, so redo it all
280 if(event->synthetic){
281 FXDCWindow dc(picture);
282
283 // Erase the canvas, color comes from well
284 dc.setForeground(backwell->getRGBA());
285
286 dc.fillRectangle(0,0,picture->getWidth(),picture->getHeight());
287
288 // Draw images
289 dc.drawImage(grey,10,10);
290 dc.drawImage(grey_nodither,10,60);
291 dc.drawImage(red,10,130);
292 dc.drawImage(red_nodither,10,180);
293 dc.drawImage(green,10,250);
294 dc.drawImage(green_nodither,10,300);
295 dc.drawImage(blue,10,370);
296 dc.drawImage(blue_nodither,10,420);
297
298 // Draw patterns
299 dc.setFillStyle(FILL_OPAQUESTIPPLED);
300 dc.setForeground(FXRGB(0,0,0));
301 dc.setBackground(FXRGB(255,255,255));
302 for(pat=STIPPLE_0; pat<=STIPPLE_16; pat+=1){
303 dc.setStipple((FXStipplePattern)pat);
304 dc.fillRectangle(10+(512*pat)/17,490,31,50);
305 }
306 dc.setFillStyle(FILL_SOLID);
307
308 // Draw borders
309 dc.setForeground(borderwell->getRGBA());
310 dc.drawRectangle(10,10,512,50);
311 dc.drawRectangle(10,60,512,50);
312
313 dc.drawRectangle(10,130,512,50);
314 dc.drawRectangle(10,180,512,50);
315
316 dc.drawRectangle(10,250,512,50);
317 dc.drawRectangle(10,300,512,50);
318
319 dc.drawRectangle(10,370,512,50);
320 dc.drawRectangle(10,420,512,50);
321
322 dc.drawRectangle(10,490,512,50);
323
324 // Draw text
325 dc.setFont(font);
326 dc.setForeground(textwell->getRGBA());
327 dc.drawText(540,60,"Grey",4);
328 dc.drawText(540,180,"Red",3);
329 dc.drawText(540,300,"Green",5);
330 dc.drawText(540,420,"Blue",4);
331 dc.drawText(540,540,"Patterns",8);
332 }
333
334 // Now repaint the screen
335 FXDCWindow sdc(canvas,event);
336
337 // Clear whole thing
338 sdc.setForeground(backwell->getRGBA());
339 sdc.fillRectangle(0,0,canvas->getWidth(),canvas->getHeight());
340
341 // Draw using drawImage, which is simple
342 //sdc.drawImage(picture,0,0);
343
344 // Or use drawArea, which is more flexible
345 sdc.drawArea(picture,0,0,picture->getWidth(),picture->getHeight(),0,0);
346
347 return 1;
348 }
349
350
351 // Color well got changed
onCmdWell(FXObject *,FXSelector,void *)352 long ImageWindow::onCmdWell(FXObject*,FXSelector,void*){
353 canvas->update();
354 return 1;
355 }
356
357
358 // Restore image from off-screen pixmap
onCmdRestore(FXObject *,FXSelector,void *)359 long ImageWindow::onCmdRestore(FXObject*,FXSelector,void*){
360 FXFileDialog savedialog(this,"Save BMP");
361 savedialog.setDirectory(".");
362 if(savedialog.execute()){
363 FXFileStream outfile;
364 if(outfile.open(savedialog.getFilename(),FXStreamSave)){
365 picture->restore();
366 picture->savePixels(outfile);
367 outfile.close();
368 }
369 }
370 return 1;
371 }
372
373
374 // Here we begin
main(int argc,char * argv[])375 int main(int argc,char *argv[]){
376
377 // Make application
378 FXApp application("Image","FoxText");
379
380 // Start app
381 application.init(argc,argv);
382
383 // Make window
384 new ImageWindow(&application);
385
386 // Create the application's windows
387 application.create();
388
389 // Run the application
390 return application.run();
391 }
392
393
394
395
396