1 /*  Part of XPCE --- The SWI-Prolog GUI toolkit
2 
3     Author:        Jan Wielemaker and Anjo Anjewierden
4     E-mail:        jan@swi.psy.uva.nl
5     WWW:           http://www.swi.psy.uva.nl/projects/xpce/
6     Copyright (c)  1985-2002, University of Amsterdam
7     All rights reserved.
8 
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions
11     are met:
12 
13     1. Redistributions of source code must retain the above copyright
14        notice, this list of conditions and the following disclaimer.
15 
16     2. Redistributions in binary form must reproduce the above copyright
17        notice, this list of conditions and the following disclaimer in
18        the documentation and/or other materials provided with the
19        distribution.
20 
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32     POSSIBILITY OF SUCH DAMAGE.
33 */
34 
35 #include <h/kernel.h>
36 #include <h/graphics.h>
37 #include <h/unix.h>
38 
39 static status	imageBitmap(BitmapObj bm, Image image);
40 static status	transparentBitmap(BitmapObj bm, BoolObj transparent);
41 
42 static status
initialiseBitmap(BitmapObj b,Image image,BoolObj transparent)43 initialiseBitmap(BitmapObj b, Image image, BoolObj transparent)
44 { if ( isDefault(image) )
45     TRY(image = newObject(ClassImage, NIL, EAV));
46   if ( isDefault(transparent) )
47     transparent = OFF;
48 
49   initialiseGraphical(b, ZERO, ZERO, image->size->w, image->size->h);
50 
51   assign(b, pen, ZERO);
52   assign(b, transparent, transparent);
53   assign(b, image, image);
54   if ( image->access == NAME_both && isNil(image->bitmap) )
55     assign(image, bitmap, b);
56   updateSolidBitmap(b);
57 
58   succeed;
59 }
60 
61 
62 static status
unlinkBitmap(BitmapObj bm)63 unlinkBitmap(BitmapObj bm)
64 { if ( notNil(bm->image) && bm->image->bitmap == bm )
65     assign(bm->image, bitmap, NIL);
66 
67   return unlinkGraphical((Graphical) bm);
68 }
69 
70 
71 static BitmapObj
getConvertBitmap(Class class,Name name)72 getConvertBitmap(Class class, Name name)
73 { Image im;
74 
75   if ( (im = getConvertImage(ClassImage, (Any) name)) != FAIL )
76     answer(answerObject(ClassBitmap, im, EAV));
77 
78   fail;
79 }
80 
81 
82 static status
RedrawAreaBitmap(BitmapObj b,Area a)83 RedrawAreaBitmap(BitmapObj b, Area a)
84 { int x, y, w, h;
85 
86   initialiseDeviceGraphical(b, &x, &y, &w, &h);
87   if ( notNil(b->image) )
88     r_image(b->image, 0, 0, x, y, w, h, b->transparent);
89 
90   if ( b->pen != ZERO )
91   { r_thickness(valInt(b->pen));
92     r_dash(b->texture);
93     r_box(x, y, w, h, 0, NIL);
94   }
95 
96   return RedrawAreaGraphical(b, a);
97 }
98 
99 
100 static status
geometryBitmap(BitmapObj b,Int x,Int y,Int w,Int h)101 geometryBitmap(BitmapObj b, Int x, Int y, Int w, Int h)
102 { return geometryGraphical(b, x, y, DEFAULT, DEFAULT);
103 }
104 
105 
106 static BitmapObj
getCopyBitmap(BitmapObj bm)107 getCopyBitmap(BitmapObj bm)
108 { BitmapObj copy = answerObject(ClassBitmap, EAV);
109 
110   copyGraphical(copy, bm);
111   imageBitmap(copy, bm->image);
112 
113   answer(copy);
114 }
115 
116 
117 static status
imageBitmap(BitmapObj bm,Image image)118 imageBitmap(BitmapObj bm, Image image)
119 { if ( bm->image != image )
120   { if ( (notNil(bm->image) && notNil(bm->image->mask)) ||
121 	 notNil(image->mask) )
122       clearFlag(bm, F_SOLID);
123 
124     CHANGING_GRAPHICAL(bm,
125       addRefObj(bm);			/* avoid drop-out */
126       assign(bm, image, image);
127       sizeArea(bm->area, image->size);
128       if ( image->access == NAME_both && isNil(image->bitmap) )
129 	assign(image, bitmap, bm);
130       delRefObj(bm);
131       changedEntireImageGraphical(bm));
132 
133     updateSolidBitmap(bm);
134   }
135 
136   succeed;
137 }
138 
139 
140 status
updateSolidBitmap(BitmapObj bm)141 updateSolidBitmap(BitmapObj bm)
142 { if ( notNil(bm->image->mask) || bm->transparent == ON )
143     clearFlag(bm, F_SOLID);
144   else
145     setFlag(bm, F_SOLID);
146 
147   succeed;
148 }
149 
150 
151 static status
transparentBitmap(BitmapObj bm,BoolObj transparent)152 transparentBitmap(BitmapObj bm, BoolObj transparent)
153 { CHANGING_GRAPHICAL(bm,
154 		     assign(bm, transparent, transparent);
155 		     if ( transparent == OFF )
156 		       setFlag(bm, F_SOLID);
157 		     else
158 		       clearFlag(bm, F_SOLID);
159 		     changedEntireImageGraphical(bm));
160 
161   succeed;
162 }
163 
164 
165 static status
redrawBitmap(BitmapObj bm,Area a)166 redrawBitmap(BitmapObj bm, Area a)
167 { CHANGING_GRAPHICAL(bm, sizeArea(bm->area, bm->image->size));
168 
169   return redrawGraphical((Graphical) bm, DEFAULT);
170 }
171 
172 
173 static status
loadBitmap(BitmapObj bm,FileObj file,CharArray path)174 loadBitmap(BitmapObj bm, FileObj file, CharArray path)
175 { Image image;
176 
177   if ( isDefault(path) )
178     TRY( path = getClassVariableValueClass(ClassImage, NAME_path));
179 
180   TRY(findFile(file, path, NAME_read));
181 
182   TRY(image = newObject(ClassImage, file->name, EAV));
183 
184   return imageBitmap(bm, image);
185 }
186 
187 
188 		/********************************
189 		*     BACKWARD COMPATIBILITY    *
190 		********************************/
191 
192 
193 static status
storeBitmap(BitmapObj bm,FileObj file)194 storeBitmap(BitmapObj bm, FileObj file)
195 { return storeSlotsObject(bm, file);
196 }
197 
198 
199 static status
loadFdBitmap(BitmapObj bm,IOSTREAM * fd,ClassDef def)200 loadFdBitmap(BitmapObj bm, IOSTREAM *fd, ClassDef def)
201 { TRY(loadSlotsObject(bm, fd, def));
202 
203   if ( restoreVersion < 7 )
204   { if ( restoreVersion == 1 )
205     { Image image = newObject(ClassImage, EAV);
206 
207       ws_load_old_image(image, fd);
208       assign(bm, image, image);
209     } else if ( restoreVersion <= 5 )
210     { assign(bm, image, newObject(ClassImage, EAV));
211       assign(bm, pen, ZERO);
212       assign(bm, request_compute, NIL);
213 
214       switch( Sgetc(fd) )
215       { case 'O':				/* no image */
216 	  setSize(bm->image->size, ZERO, ZERO);
217 	  break;
218 	case 'X':
219 	  loadXImage(bm->image, fd);
220       }
221     }
222 
223     if ( isNil(bm->texture) )
224       assign(bm, texture, NAME_none);
225     if ( isNil(bm->colour) )
226       assign(bm, colour, DEFAULT);
227     if ( isNil(bm->inverted) )
228       assign(bm, inverted, OFF);
229     if ( isNil(bm->transparent) )
230       assign(bm, transparent, OFF);
231   }
232 
233   updateSolidBitmap(bm);
234 
235   succeed;
236 }
237 
238 
239 static Chain
getContainsBitmap(BitmapObj bm)240 getContainsBitmap(BitmapObj bm)
241 { answer(answerObject(ClassChain, bm->image, EAV));
242 }
243 
244 
245 		 /*******************************
246 		 *	 CLASS DECLARATION	*
247 		 *******************************/
248 
249 /* Type declarations */
250 
251 static char *T_load[] =
252         { "file", "path=[char_array]" };
253 static char *T_initialise[] =
254         { "image=[image]", "transparent=[bool]" };
255 static char *T_geometry[] =
256         { "x=[int]", "y=[int]", "width=[int]", "height=[int]" };
257 
258 /* Instance Variables */
259 
260 static vardecl var_bitmap[] =
261 { SV(NAME_image, "image", IV_GET|IV_STORE, imageBitmap,
262      NAME_appearance, "The pixel collection managed"),
263   SV(NAME_transparent, "bool", IV_GET|IV_STORE, transparentBitmap,
264      NAME_appearance, "When @on, 0-pixels are not painted")
265 };
266 
267 /* Send Methods */
268 
269 static senddecl send_bitmap[] =
270 { SM(NAME_geometry, 4, T_geometry, geometryBitmap,
271      DEFAULT, "Bitmaps can only be moved"),
272   SM(NAME_initialise, 2, T_initialise, initialiseBitmap,
273      DEFAULT, "Create from image"),
274   SM(NAME_unlink, 0, NULL, unlinkBitmap,
275      DEFAULT, "Unlink from <-image"),
276   SM(NAME_redraw, 1, "[area]", redrawBitmap,
277      NAME_change, "Update size and repaint indicated area"),
278   SM(NAME_load, 2, T_load, loadBitmap,
279      NAME_file, "Load file (in path) into bitmap"),
280   SM(NAME_DrawPostScript, 1, "{head,body}", drawPostScriptBitmap,
281      NAME_postscript, "Create PostScript")
282 };
283 
284 /* Get Methods */
285 
286 static getdecl get_bitmap[] =
287 { GM(NAME_contains, 0, "chain", NULL, getContainsBitmap,
288      DEFAULT, "New chain with <-image"),
289   GM(NAME_convert, 1, "bitmap", "name", getConvertBitmap,
290      DEFAULT, "Convert image-names"),
291   GM(NAME_copy, 0, "bitmap", NULL, getCopyBitmap,
292      NAME_copy, "Make a copy that shares the image")
293 };
294 
295 /* Resources */
296 
297 #define rc_bitmap NULL
298 /*
299 static classvardecl rc_bitmap[] =
300 {
301 };
302 */
303 
304 /* Class Declaration */
305 
306 static Name bitmap_termnames[] = { NAME_image };
307 
308 ClassDecl(bitmap_decls,
309           var_bitmap, send_bitmap, get_bitmap, rc_bitmap,
310           1, bitmap_termnames,
311           "$Rev$");
312 
313 
314 
315 status
makeClassBitmap(Class class)316 makeClassBitmap(Class class)
317 { declareClass(class, &bitmap_decls);
318 
319   solidClass(class, ON);
320   setRedrawFunctionClass(class, RedrawAreaBitmap);
321   setLoadStoreFunctionClass(class, loadFdBitmap, storeBitmap);
322   cloneStyleVariableClass(class, NAME_image, NAME_reference);
323   delegateClass(class, NAME_image);
324 
325   succeed;
326 }
327 
328