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