1 /***************************************************************************
2                        plotting.cpp  -  GDL routines for plotting
3                              -------------------
4     begin                : July 22 2002
5     copyright            : (C) 2002-2011 by Marc Schellens et al.
6     email                : m_schellens@users.sf.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "includefirst.hpp"
19 #include "plotting.hpp"
20 #include "nullgdl.hpp"
21 #include <gsl/gsl_const_mksa.h> // GSL_CONST_MKSA_INCH
22 
23 namespace lib {
24 
25   using namespace std;
26 
device(EnvT * e)27   void device(EnvT* e) {
28     bool setfontpresent = false;
29     GraphicsDevice* actDevice = GraphicsDevice::GetDevice();
30     //GET functions are examined BEFORE setting functions.
31 
32     // GET_DECOMPOSED ?
33     {
34       static int get_decomposedIx = e->KeywordIx("GET_DECOMPOSED");
35       if (e->KeywordPresent(get_decomposedIx)) {
36         DLong value = actDevice->GetDecomposed();
37         if (value == -1)
38           e->Throw("Keyword GET_DECOMPOSED not allowed for call to: DEVICE");
39         else
40           e->SetKW(get_decomposedIx, new DLongGDL(value));
41       }
42     }
43 
44     //The font-related commands will not really work in graphic widgets until the plplot-related part is taken into account (PLESC font).
45     //But all the elements are there.
46     //SET_FONT?  //must be before GET_FONTNAME if in same commandline. Otherwise GET_FONTXXX will return NULL
47     {
48       static int set_fontIx = e->KeywordIx("SET_FONT");
49       if (e->KeywordPresent(set_fontIx)) {
50         setfontpresent = true;
51         DStringGDL* pattern = e->GetKWAs<DStringGDL>(set_fontIx);
52         if (!actDevice->SetFont((*pattern)[0])) e->Throw("Keyword SET_FONT not allowed for call to: DEVICE");
53       }
54     }
55     static int fontIx = e->KeywordIx("FONT"); //font is OLD keyword  for SET_FONT still accepted.
56     if (e->KeywordPresent(fontIx)) {
57       setfontpresent = true;
58       DStringGDL* pattern = e->GetKWAs<DStringGDL>(fontIx);
59       if (!actDevice->SetFont((*pattern)[0])) e->Throw("(Obsolete) Keyword FONT not allowed for call to: DEVICE");
60     }
61 
62     //GET_FONTNAMES?
63     {
64       static int get_fontnamesIx = e->KeywordIx("GET_FONTNAMES");
65       if (e->KeywordPresent(get_fontnamesIx)) {
66         if (!setfontpresent) return;
67         BaseGDL* value = actDevice->GetFontnames();
68         if (value != NULL) e->SetKW(get_fontnamesIx, value->Dup());
69         else e->SetKW(get_fontnamesIx, new DStringGDL(""));
70       }
71     }
72     //GET_FONTNUM?
73     {
74       static int get_fontnumIx = e->KeywordIx("GET_FONTNUM");
75       if (e->KeywordPresent(get_fontnumIx)) {
76         if (!setfontpresent) return;
77         DLong value = actDevice->GetFontnum();
78         e->SetKW(get_fontnumIx, new DLongGDL(value)); //will return 0
79       }
80     }
81     //GET_CURRENT_FONT?
82     {
83       static int get_current_fontIx = e->KeywordIx("GET_CURRENT_FONT");
84       if (e->KeywordPresent(get_current_fontIx)) {
85         DString value = actDevice->GetCurrentFont(); //should NOT open graphic window
86         e->SetKW(get_current_fontIx, new DStringGDL(value));
87       }
88     }
89     //GET_FONTNUM? //TODO
90 
91     // GET_GRAPHICS_FUNCTION
92     {
93       static int get_graphics_FunctionIx = e->KeywordIx("GET_GRAPHICS_FUNCTION");
94       if (e->KeywordPresent(get_graphics_FunctionIx)) {
95         DLong value = actDevice->GetGraphicsFunction(); //OPENS A WINDOW IF NONE EXIST
96         if (value == -1)
97           e->Throw("Keyword GET_GRAPHICS_FUNCTION not allowed for call to: DEVICE");
98         else
99           e->SetKW(get_graphics_FunctionIx, new DLongGDL(value));
100       }
101     }
102 
103     // GET_PAGE_SIZE ?
104     {
105       static int get_page_sizeIx = e->KeywordIx("GET_PAGE_SIZE");
106       if (e->KeywordPresent(get_page_sizeIx)) {
107         DIntGDL* value = actDevice->GetPageSize();
108         if (value == NULL)
109           e->Throw("Keyword GET_PAGE_SIZE not allowed for call to: DEVICE");
110         else
111           e->SetKW(get_page_sizeIx, value);
112       }
113     }
114 
115     // GET_PIXEL_DEPTH ?
116     {
117       static int get_pixel_depthIx = e->KeywordIx("GET_PIXEL_DEPTH");
118       if (e->KeywordPresent(get_pixel_depthIx)) {
119         DLong value = actDevice->GetPixelDepth();
120         if (value == -1)
121           e->Throw("Keyword GET_PIXEL_DEPTH not allowed for call to: DEVICE");
122         else
123           e->SetKW(get_pixel_depthIx, new DLongGDL(value));
124       }
125     }
126 
127     // GET_SCREEN_SIZE
128     {
129       static int get_screen_sizeIx = e->KeywordIx("GET_SCREEN_SIZE");
130       if (e->KeywordPresent(get_screen_sizeIx)) {
131         DLongGDL* fvalue = actDevice->GetScreenSize();
132         if (fvalue == NULL)
133           e->Throw("Keyword GET_SCREEN_SIZE not allowed for call to: DEVICE");
134         else {
135           (*fvalue)[0] = floor((*fvalue)[0]);
136           (*fvalue)[1] = floor((*fvalue)[1]);
137           e->SetKW(get_screen_sizeIx, fvalue);
138         }
139       }
140     }
141 
142     // GET_VISUAL_DEPTH ?
143     {
144       static int get_visual_depthIx = e->KeywordIx("GET_VISUAL_DEPTH");
145       if (e->KeywordPresent(get_visual_depthIx)) {
146         DLong value = actDevice->GetVisualDepth();
147         if (value == -1)
148           e->Throw("Keyword GET_VISUAL_DEPTH not allowed for call to: DEVICE");
149         else
150           e->SetKW(get_visual_depthIx, new DLongGDL(value));
151       }
152     }
153 
154     // GET_VISUAL_NAME ?
155     {
156       static int get_visual_nameIx = e->KeywordIx("GET_VISUAL_NAME");
157       if (e->KeywordPresent(get_visual_nameIx)) {
158         DString value = actDevice->GetVisualName();
159         if (value == "")
160           e->Throw("Keyword GET_VISUAL_NAME not allowed for call to: DEVICE");
161         else
162           e->SetKW(get_visual_nameIx, new DStringGDL(value));
163       }
164     }
165 
166     // GET_WINDOW_POSITION ?
167     {
168       static int get_window_positionIx = e->KeywordIx("GET_WINDOW_POSITION");
169       if (e->KeywordPresent(get_window_positionIx)) {
170         DIntGDL* value = actDevice->GetWindowPosition(); //OPENS A WINDOW IF NONE EXISTS
171         if (value == NULL)
172           e->Throw("Keyword GET_WINDOW_POSITION not allowed for call to: DEVICE");
173         else
174           e->SetKW(get_window_positionIx, value);
175       }
176     }
177 
178     // GET_WRITE_MASK ?
179     {
180       static int get_write_maskIx = e->KeywordIx("GET_WRITE_MASK");
181       if (e->KeywordPresent(get_write_maskIx)) {
182         DLong value = actDevice->GetWriteMask();
183         if (value == -1)
184           e->Throw("Keyword GET_WRITE_MASK not allowed for call to: DEVICE");
185         else
186           e->SetKW(get_write_maskIx, new DLongGDL(value));
187       }
188     }
189 
190     // WINDOW_STATE ?
191     {
192       static int window_stateIx = e->KeywordIx("WINDOW_STATE");
193       if (e->KeywordPresent(window_stateIx)) {
194         DByteGDL* value = actDevice->WindowState();
195         if (value == NULL)
196           e->Throw("Keyword WINDOW_STATE not allowed for call to: DEVICE");
197         else
198           e->SetKW(window_stateIx, value);
199       }
200     }
201 
202     // CLOSE_FILE {{{
203     {
204       static int closeFileIx = e->KeywordIx("CLOSE_FILE");
205       if (e->KeywordSet(closeFileIx)) {
206         bool success = actDevice->CloseFile();
207         if (!success)
208           e->Throw("Current device does not support keyword CLOSE_FILE.");
209       }
210     }
211 
212     // Z_BUFFERING
213     {
214       static int z_bufferingIx = e->KeywordIx("Z_BUFFERING");
215       BaseGDL* z_buffering = e->GetKW(z_bufferingIx);
216       if (z_buffering != NULL) {
217         bool success = actDevice->ZBuffering(e->KeywordSet(z_bufferingIx));
218         if (!success)
219           e->Throw("Current device does not support keyword Z_BUFFERING.");
220       }
221     }
222 
223     // SET_RESOLUTION
224     {
225       static int set_resolutionIx = e->KeywordIx("SET_RESOLUTION");
226       BaseGDL* set_resolution = e->GetKW(set_resolutionIx);
227       if (set_resolution != NULL) {
228         DLongGDL* resolution = e->GetKWAs<DLongGDL>(set_resolutionIx);
229         if (resolution->N_Elements() != 2)
230           e->Throw("Keyword array parameter SET_RESOLUTION must have 2 elements.");
231         DLong x = (*resolution)[0];
232         DLong y = (*resolution)[1];
233 
234         if (x < 0 || y < 0)
235           e->Throw("Value of Resolution is out of allowed range.");
236 
237         bool success = actDevice->SetResolution(x, y);
238         if (!success)
239           e->Throw("Current device does not support keyword SET_RESOLUTION.");
240       }
241     }
242 
243 
244     // SET_CHARACTER_SIZE
245     {
246       static int set_character_sizeIx = e->KeywordIx("SET_CHARACTER_SIZE");
247       BaseGDL* set_character_size = e->GetKW(set_character_sizeIx);
248       if (set_character_size != NULL) {
249         DLongGDL* character_size = e->GetKWAs<DLongGDL>(set_character_sizeIx);
250         if (character_size->N_Elements() != 2)
251           e->Throw("Keyword array parameter SET_CHARACTER_SIZE must have 2 elements.");
252         DLong x = (*character_size)[0];
253         DLong y = (*character_size)[1];
254 
255         if (x < 0 || y < 0)
256           e->Throw("Value of Character Size is out of allowed range.");
257 
258         bool success = actDevice->SetCharacterSize(x, y);
259         if (!success)
260           e->Throw("Current device does not support keyword SET_CHARACTER_SIZE.");
261       }
262     }
263 
264     // DECOMPOSED
265     {
266       static int decomposedIx = e->KeywordIx("DECOMPOSED");
267       BaseGDL* decomposed = e->GetKW(decomposedIx);
268       if (decomposed != NULL) {
269         bool success = actDevice->Decomposed(e->KeywordSet(decomposedIx));
270         if (!success)
271           e->Throw("Current device does not support keyword DECOMPOSED.");
272       }
273     }
274 
275     // SET_GRAPHICS_FUNCTION
276     {
277       static int set_graphicsFunctionIx = e->KeywordIx("SET_GRAPHICS_FUNCTION");
278       BaseGDL* set_gfunction = e->GetKW(set_graphicsFunctionIx);
279       if (set_gfunction != NULL) {
280         DLongGDL* gfunction = e->GetKWAs<DLongGDL>(set_graphicsFunctionIx);
281         bool success = actDevice->SetGraphicsFunction((*gfunction)[0]);
282         if (!success)
283           e->Throw("Current device does not support keyword SET_GRAPHICS_FUNCTION.");
284       }
285     }
286     // RETAIN
287     {
288       static int valIx = e->KeywordIx("RETAIN");
289       BaseGDL* res = e->GetKW(valIx);
290       if (res != NULL) {
291         DLongGDL* val = e->GetKWAs<DLongGDL>(valIx);
292         bool success = actDevice->SetBackingStore((*val)[0]);
293         if (!success)
294           e->Throw("Current device does not support keyword RETAIN.");
295       }
296     }
297     // ************************ CURSORS ***********************
298     // CURSOR_STANDARD
299     {
300       static int cursorStandardIx = e->KeywordIx("CURSOR_STANDARD");
301       BaseGDL* res = e->GetKW(cursorStandardIx);
302       if (res != NULL) {
303         DLongGDL* val = e->GetKWAs<DLongGDL>(cursorStandardIx);
304         bool success = actDevice->CursorStandard((*val)[0]);
305         if (!success)
306           e->Throw("Current device does not support keyword CURSOR_STANDARD.");
307       }
308     }
309     // CURSOR_CROSSHAIR
310     {
311       static int valIx = e->KeywordIx("CURSOR_CROSSHAIR");
312       BaseGDL* res = e->GetKW(valIx);
313       if (res != NULL) {
314         bool success = actDevice->CursorCrosshair();
315         if (!success)
316           e->Throw("Current device does not support keyword CURSOR_CROSSHAIR.");
317       }
318     }
319     // CURSOR_ORIGINAL (WARNING: SAME CODE AS  CURSOR_CROSSHAIR!)
320     {
321       static int valIx = e->KeywordIx("CURSOR_ORIGINAL");
322       BaseGDL* res = e->GetKW(valIx);
323       if (res != NULL) {
324         bool success = actDevice->CursorCrosshair(true);
325         if (!success)
326           e->Throw("Current device does not support keyword CURSOR_ORIGINAL.");
327       }
328     }
329     // CURSOR_IMAGE Must be a 16 line by 16 colums bitmap, contained in a 16 short int vector.
330     // it comes with CURSOR_MASK and CURSOR_XY
331     {
332       static int cursorImageIx = e->KeywordIx("CURSOR_IMAGE");
333       BaseGDL* what = e->GetKW(cursorImageIx);
334       if (what != NULL) {
335         DIntGDL* val = e->GetKWAs<DIntGDL>(cursorImageIx);
336         if (val->N_Elements() != 16) e->Throw("Keyword array parameter CURSOR_IMAGE must have 16 elements.");
337         char* imagegdl = (char*) val->DataAddr();
338         char* image=imagegdl;
339         if (!BigEndian()) {
340           image=(char*)(malloc(64)); //be large
341           char k = 0;
342           for (int i = 0; i < 31; i += 2) {
343             k = imagegdl[i];
344             image[i] = imagegdl[i + 1];
345             image[i + 1] = k;
346           }
347         }
348         char* maskgdl = NULL;
349         char* mask = NULL;
350         // it comes with CURSOR_MASK
351         static int cursorMaskIx = e->KeywordIx("CURSOR_MASK");
352         if (e->KeywordPresent(cursorMaskIx)) {
353           DIntGDL* msk = e->GetKWAs<DIntGDL>(cursorMaskIx);
354           if (msk->N_Elements() != 16) e->Throw("Keyword array parameter CURSOR_MASK must have 16 elements.");
355           maskgdl = (char*) msk->DataAddr();
356           mask=maskgdl;
357           if (!BigEndian()) {
358             mask=(char*)malloc(64);
359             char k = 0;
360             for (int i = 0; i < 32; i += 2) {
361               k = maskgdl[i];
362               mask[i] = maskgdl[i + 1];
363               mask[i + 1] = k;
364             }
365           }
366         }
367         int x = 7;
368         int y = 7;
369         // it comes with CURSOR_XY
370         static int cursorXYIx = e->KeywordIx("CURSOR_XY");
371         if (e->KeywordPresent(cursorXYIx)) {
372           DIntGDL* cxy = e->GetKWAs<DIntGDL>(cursorXYIx);
373           if (cxy->N_Elements() != 2) e->Throw("Keyword array parameter CURSOR_XY must have 2 elements.");
374           x = (*cxy)[0]; x=max(0,min(x,15)); x=15-x; //wx direction
375           y = (*cxy)[1]; y=max(0,min(y,15));
376         }
377 
378         bool success = actDevice->CursorImage(image, x, y, mask);
379         if (!BigEndian()) {
380           free(image);
381           if (mask!=NULL) free(mask);
382         }
383         if (!success)
384           e->Throw("Current device does not support keyword CURSOR_IMAGE.");
385       }
386     }
387     // FILENAME
388     {
389       static int fileNameIx = e->KeywordIx("FILENAME");
390       BaseGDL* fileName = e->GetKW(fileNameIx);
391       if (fileName != NULL) {
392         DString fName;
393         e->AssureStringScalarKW(fileNameIx, fName);
394         if (fName == "")
395           e->Throw("Null filename not allowed.");
396         WordExp(fName);
397         bool success = actDevice->SetFileName(fName);
398         if (!success)
399           e->Throw("Current device does not support keyword FILENAME.");
400       }
401     }
402 
403     // LANDSCAPE and PORTRAIT need to be executed before XSIZE, YSIZE, XOFFSET and YOFFSET!
404     {
405       static int portraitIx = e->KeywordIx("PORTRAIT");
406       static int landscapeIx = e->KeywordIx("LANDSCAPE");
407       //IDL consider the value of the first typed of the two options, if both are present.
408       //I dunoo how to do that with GDL parsing.
409       if (e->KeywordSet(portraitIx) && e->KeywordSet(landscapeIx))
410         Warning("Warning: both PORTRAIT and LANDSCAPE specified!");
411 
412       // LANDSCAPE
413       {
414         BaseGDL* landscapeKW = e->GetKW(landscapeIx);
415         if (landscapeKW != NULL) {
416           DLong isLandscape;
417           e->AssureLongScalarKW(landscapeIx, isLandscape);
418           if (isLandscape == 0) {
419             bool success = actDevice->SetPortrait();
420             if (!success) e->Throw("Current device does not support keyword LANDSCAPE");
421           } else {
422             bool success = actDevice->SetLandscape();
423             if (!success) e->Throw("Current device does not support keyword LANDSCAPE");
424           }
425         }
426       }
427 
428       // PORTRAIT
429       {
430         BaseGDL* portraitKW = e->GetKW(portraitIx);
431         if (portraitKW != NULL) {
432           DLong isPortrait;
433           e->AssureLongScalarKW(portraitIx, isPortrait);
434           if (isPortrait == 0) {
435             bool success = actDevice->SetLandscape();
436             if (!success) e->Throw("Current device does not support keyword PORTRAIT");
437           } else {
438             bool success = actDevice->SetPortrait();
439             if (!success) e->Throw("Current device does not support keyword PORTRAIT");
440           }
441         }
442       }
443     }
444 
445     {
446       static int inchesIx = e->KeywordIx("INCHES");
447       // XOFFSET
448       {
449         static int xOffsetIx = e->KeywordIx("XOFFSET");
450         BaseGDL* xOffsetKW = e->GetKW(xOffsetIx);
451         if (xOffsetKW != NULL) {
452           DFloat xOffsetValue;
453           e->AssureFloatScalarKW(xOffsetIx, xOffsetValue);
454           bool success = actDevice->SetXOffset(xOffsetValue
455             * (e->KeywordSet(inchesIx) ? 100. * GSL_CONST_MKSA_INCH : 1.)
456             );
457           if (!success)
458             e->Throw("Current device does not support keyword XOFFSET.");
459         }
460       }
461 
462       // YOFFSET
463       {
464         static int yOffsetIx = e->KeywordIx("YOFFSET");
465         BaseGDL* yOffsetKW = e->GetKW(yOffsetIx);
466         if (yOffsetKW != NULL) {
467           DFloat yOffsetValue;
468           e->AssureFloatScalarKW(yOffsetIx, yOffsetValue);
469           bool success = actDevice->SetYOffset(yOffsetValue
470             * (e->KeywordSet(inchesIx) ? 100. * GSL_CONST_MKSA_INCH : 1.)
471             );
472           if (!success)
473             e->Throw("Current device does not support keyword YOFFSET.");
474         }
475       }
476 
477       // XSIZE
478       {
479         static int xSizeIx = e->KeywordIx("XSIZE");
480         BaseGDL* xSizeKW = e->GetKW(xSizeIx);
481         if (xSizeKW != NULL) {
482           DFloat xSizeValue;
483           e->AssureFloatScalarKW(xSizeIx, xSizeValue);
484           bool success = actDevice->SetXPageSize(xSizeValue
485             * (e->KeywordSet(inchesIx) ? 100. * GSL_CONST_MKSA_INCH : 1.)
486             );
487           if (!success)
488             e->Throw("Current device does not support keyword XSIZE.");
489         }
490       }
491 
492       // YSIZE
493       {
494         static int ySizeIx = e->KeywordIx("YSIZE");
495         BaseGDL* ySizeKW = e->GetKW(ySizeIx);
496         if (ySizeKW != NULL) {
497           DFloat ySizeValue;
498           e->AssureFloatScalarKW(ySizeIx, ySizeValue);
499           bool success = actDevice->SetYPageSize(ySizeValue
500             * (e->KeywordSet(inchesIx) ? 100. * GSL_CONST_MKSA_INCH : 1.)
501             );
502           if (!success)
503             e->Throw("Current device does not support keyword YSIZE.");
504         }
505       }
506     }
507 
508     // SCALE_FACTOR
509     {
510       static int scaleIx = e->KeywordIx("SCALE_FACTOR");
511       BaseGDL* scaleKW = e->GetKW(scaleIx);
512       if (scaleKW != NULL) {
513         DFloat scaleValue;
514         e->AssureFloatScalarKW(scaleIx, scaleValue);
515         bool success = actDevice->SetScale(scaleValue);
516         if (!success)
517           e->Throw("Current device does not support keyword SCALE.");
518       }
519     }
520 
521     // COLOR
522     {
523       // TODO: turn off with COLOR=0?
524       static int colorIx = e->KeywordIx("COLOR");
525       BaseGDL* colorKW = e->GetKW(colorIx);
526       if (colorKW != NULL) {
527         DLong colorValue;
528         e->AssureLongScalarKW(colorIx, colorValue);
529         bool success = actDevice->SetColor(colorValue);
530         if (!success) e->Throw("Current device does not support keyword COLOR.");
531       }
532     }
533 
534     // ENCAPSULATED
535     {
536       static int encapsulatedIx = e->KeywordIx("ENCAPSULATED");
537       BaseGDL* encapsulatedKW = e->GetKW(encapsulatedIx);
538       if (encapsulatedKW != NULL) {
539         bool success;
540         if ((*e->GetKWAs<DIntGDL>(encapsulatedIx))[0] == 0)
541           success = actDevice->SetEncapsulated(false);
542         else
543           success = actDevice->SetEncapsulated(true);
544         if (!success) e->Throw("Current device does not support keyword ENCAPSULATED.");
545       }
546     }
547     //BITS_PER_PIXEL
548     {
549       static int bppIx = e->KeywordIx("BITS_PER_PIXEL");
550       BaseGDL* bppKW = e->GetKW(bppIx);
551       if (bppKW != NULL) {
552         bool success;
553 
554         success = actDevice->SetBPP((*e->GetKWAs<DIntGDL>(bppIx))[0]);
555         if (!success) e->Throw("Current device does not support keyword BITS_PER_PIXEL.");
556       }
557     }
558     // COPY
559     {
560       static int copyIx = e->KeywordIx("COPY");
561       if (e->KeywordPresent(copyIx)) {
562         DLongGDL* parameters = e->GetKWAs<DLongGDL>(copyIx);
563         if (parameters->N_Elements() > 7 || parameters->N_Elements() < 6)
564           e->Throw("Keyword array parameter COPY must have from 6 to 7 elements.");
565         // WRONG!! device number may also be a gui number in some cases... HAVING TWO X11-like GRAPHIC DEVICES IS NOT GOOD AT ALL! FIXME!
566         if (parameters->N_Elements() == 7) {
567           if (!actDevice->WState((*parameters)[6])) e->Throw("Window number " + i2s((*parameters)[6]) + " out of range or no more windows or known bug with widgets");
568         }
569         bool doesTheCopy = actDevice->CopyRegion(parameters);
570         if (!doesTheCopy) e->Throw("Keyword COPY not allowed for call to: DEVICE");
571       }
572     }
573     // SET_PIXEL_DEPTH ?
574     {
575       static int set_pixel_depthIx = e->KeywordIx("SET_PIXEL_DEPTH");
576       if (e->KeywordPresent(set_pixel_depthIx)) {
577         BaseGDL* depthKW = e->GetKW(set_pixel_depthIx);
578         if (depthKW != NULL) {
579           bool success = actDevice->SetPixelDepth((*e->GetKWAs<DIntGDL>(set_pixel_depthIx))[0]);
580           if (!success) e->Throw("Keyword SET_PIXEL_DEPTH not allowed for call to: DEVICE");
581         }
582       }
583     }
584   }
585 
586 } // namespace
587 
588