1 #!/usr/bin/rdmd @cmdfile
2 module iupmain;
3 
4 import core.stdc.config : c_ulong, c_long;
5 import core.stdc.stdlib;
6 import core.stdc.stdio;
7 //#include <memory.h>
8 import core.stdc.string;
9 
10 import std.string : toStringz;
11 import std.stdio; 
12 
13 import iup.iup;
14 
15 /*
16 
17 Simple Draw Application
18 
19   Shows the same picture on several canvas. Used to quick test the CD library and
20   to demonstrate the use of CD library functions.
21 
22   This module uses only the CD library, there is another module to initialize the Window and its menus.
23 
24 */
25 
26 import cd.cd;
27 import cd.cdcgm;
28 import cd.cddgn;
29 import cd.cddxf;
30 import cd.cdclipbd;
31 import cd.cdemf;
32 import cd.cdimage;
33 import cd.cdirgb;
34 import cd.cdmf;
35 import cd.cdprint;
36 import cd.cdps;
37 import cd.cdpdf;
38 import cd.cdsvg;
39 import cd.cdwmf;
40 import cd.cdiup;
41 import cd.cddbuf;
42 import cd.cddebug;
43 import cd.wd;
44 import cd.cdgdiplus;
45 
46 version(USE_OPENGL)
47 {
48 import cd.cdgl;
49 import iup.iupgl;
50 
51 // For core API functions.
52 import derelict.opengl3.gl3;
53 import derelict.opengl3.gl;
54 }
55 
56 /* Global variables */
57 
58 cdCanvas *winCanvas = null;        /* The window drawing canvas */
59 char* winData = null;
60 cdCanvas *dbCanvas = null;        /* The double buffer canvas */
61 cdCanvas *curCanvas = null;        /* The current canvas */
62 
63 int clipping = CD_CLIPOFF;                     /* Clipping flag, same as the CD */
64 int write_mode = CD_REPLACE;                   /* Write Mode flag, same as the CD */
65 int contextplus = 0;
66 int simple_draw = 0;
67 int use_transform = 0;
68 int simulate = 0;
69 int use_opengl = 0;
70 
71 enum {DRAW_ALL, DRAW_TEXTFONTS, DRAW_TEXTALIGN, DRAW_TEST};
72 
73 enum STYLE_SIZE = 10; /* A small pattern and stipple size */
74 c_long[STYLE_SIZE*STYLE_SIZE] pattern;          /* Pattern buffer */
75 ubyte[STYLE_SIZE*STYLE_SIZE] stipple; /* Stipple buffer */
76 
77 enum IMAGE_SIZE = 100;
78 ubyte[IMAGE_SIZE*IMAGE_SIZE] red;       /* Red image buffer */
79 ubyte[IMAGE_SIZE*IMAGE_SIZE] green;     /* Green image buffer */
80 ubyte[IMAGE_SIZE*IMAGE_SIZE] blue;      /* Blue image buffer */
81 ubyte[IMAGE_SIZE*IMAGE_SIZE] alpha;     /* Alpha image buffer */
82 
83 
84 /* Prototype of the function that makes the drawing independent of canvas. */
85 void SimpleDraw(cdCanvas* canvas);
86 
87 void SimpleInitAlpha(int width, int height, ubyte* _alpha)
88 {
89   int c, l;
90   /* initialize the alpha image buffer with a degrade from transparent to opaque */
91   for (l = 0; l < height; l++)
92     for (c = 0; c < width; c++)
93       _alpha[l*width + c] = cast(ubyte)((c*255)/(width-1));
94 }
95 
96 void SimpleCreateCanvasWindow()
97 {
98   /* creates the canvas based in an existing window */
99   if (contextplus) cdUseContextPlus(1);
100   winCanvas = cdCreateCanvas(CD_IUP, winData);
101   if (contextplus) cdUseContextPlus(0);
102   curCanvas = winCanvas;
103 }
104 
105 void SimpleCreateCanvas(char* data)
106 {
107   int c, l;
108 
109   memset(pattern.ptr, 0xFF, STYLE_SIZE*STYLE_SIZE*4);
110 
111   pattern[11] = CD_RED;   /*------------*/
112   pattern[21] = CD_RED;   /*  0123456789*/               
113   pattern[31] = CD_RED;   /*            */               
114   pattern[41] = CD_RED;   /*9 WWWWWWWWWW*/               
115   pattern[51] = CD_RED;   /*8 WWWWGGGGGW*/               
116   pattern[12] = CD_RED;   /*7 WWWGGGGGBW*/                                         
117   pattern[22] = CD_RED;   /*6 WWGGGGGBBW*/                                         
118   pattern[32] = CD_RED;   /*5 WrrrrrBBBW*/                                         
119   pattern[42] = CD_RED;   /*4 WrrrrrBBBW*/                                         
120   pattern[52] = CD_RED;   /*3 WrrrrrBBWW*/                                         
121   pattern[13] = CD_RED;   /*2 WrrrrrBWWW*/                                         
122   pattern[23] = CD_RED;   /*1 WrrrrrWWWW*/                                         
123   pattern[33] = CD_RED;   /*0 WWWWWWWWWW*/                                         
124   pattern[43] = CD_RED;   /*------------*/                                         
125   pattern[53] = CD_RED;                                            
126   pattern[14] = CD_RED;   pattern[15] = CD_RED;
127   pattern[24] = CD_RED;   pattern[25] = CD_RED;
128   pattern[34] = CD_RED;   pattern[35] = CD_RED;
129   pattern[44] = CD_RED;   pattern[45] = CD_RED;
130   pattern[54] = CD_RED;   pattern[55] = CD_RED;
131   
132   pattern[26] = CD_BLUE;  pattern[37] = CD_BLUE;
133   pattern[36] = CD_BLUE;  pattern[47] = CD_BLUE;
134   pattern[46] = CD_BLUE;  pattern[57] = CD_BLUE;
135   pattern[56] = CD_BLUE;  pattern[67] = CD_BLUE;
136   
137   pattern[48] = CD_BLUE;  pattern[62] = CD_GREEN;
138   pattern[58] = CD_BLUE;  pattern[63] = CD_GREEN;
139   pattern[68] = CD_BLUE;  pattern[64] = CD_GREEN;
140   pattern[78] = CD_BLUE;  pattern[65] = CD_GREEN;
141                                pattern[66] = CD_GREEN;
142 
143   pattern[73] = CD_GREEN; pattern[84] = CD_GREEN;
144   pattern[74] = CD_GREEN; pattern[85] = CD_GREEN;
145   pattern[75] = CD_GREEN; pattern[86] = CD_GREEN;
146   pattern[76] = CD_GREEN; pattern[87] = CD_GREEN;
147   pattern[77] = CD_GREEN; pattern[88] = CD_GREEN;
148 
149   /* initialize the stipple buffer with cross pattern */
150   for (l = 0; l < STYLE_SIZE; l++)
151     for (c = 0; c < STYLE_SIZE; c++)
152       stipple[l*STYLE_SIZE + c] = (c % 4) == 0? 1: 0;
153 
154   SimpleInitAlpha(IMAGE_SIZE, IMAGE_SIZE, alpha.ptr);
155 
156   winData = data;
157   SimpleCreateCanvasWindow();
158   SimpleDrawWindow();
159 }
160 
161 int SimpleTransform()
162 {
163   use_transform = !use_transform;
164   SimpleDraw(curCanvas);
165   return 0;
166 }
167 
168 int SimpleContextPlus()
169 {
170 //#ifdef USE_CONTEXTPLUS
171   contextplus = !contextplus;
172   SimpleKillCanvas();
173   SimpleCreateCanvasWindow();
174   SimpleDraw(curCanvas);
175 //#endif
176   return 0;
177 }
178 
179 void PlayCanvasDriver(cdContext* ctx, char* StrData)
180 {
181   int w, h;
182   cdCanvasActivate(curCanvas);
183   cdCanvasBackground(curCanvas, CD_WHITE);
184   cdCanvasClear(curCanvas);
185   cdCanvasGetSize(curCanvas, &w, &h, null, null);
186   cdCanvasPlay(curCanvas, ctx, 100, w-100, 100, h-100, StrData);
187 //  cdCanvasPlay(curCanvas, ctx, 0, 0, 0, 0, StrData);
188 }
189 
190 int SimplePlayClipboard()
191 {
192   PlayCanvasDriver(CD_CLIPBOARD, null);
193   return 0;
194 }
195 
196 int SimplePlayCGMBin()
197 {
198   PlayCanvasDriver(CD_CGM, "simple_b.cgm".dup.ptr);
199   return 0;
200 }
201 
202 int SimplePlayCGMText()
203 {
204   PlayCanvasDriver(CD_CGM, "simple_t.cgm".dup.ptr);
205   return 0;
206 }
207 
208 int SimplePlayMetafile()
209 {
210   PlayCanvasDriver(CD_METAFILE, "simple.mf".dup.ptr);
211   return 0;
212 }
213 
214 int SimplePlayWMF()
215 {
216   PlayCanvasDriver(CD_WMF, "simple.wmf".dup.ptr);
217   return 0;
218 }
219 
220 int SimplePlayEMF()
221 {
222   PlayCanvasDriver(CD_EMF, "simple.emf".dup.ptr);
223   return 0;
224 }
225 
226 int SimpleRepaint()
227 {
228   SimpleDraw(curCanvas);
229   return 0;
230 }
231 
232 int SimpleDrawWindow()
233 {
234   use_opengl = 0;
235   curCanvas = winCanvas;
236   SimpleDraw(curCanvas);
237   return 0;
238 }
239 
240 void DrawCanvasDriver(cdContext* ctx, char* StrData)
241 {
242   cdCanvas* tmpCanvas = cdCreateCanvas(ctx, StrData);
243   if (tmpCanvas == null) 
244   {
245     printf("CreateCanvas(%s) - Failed!\n", StrData);
246     return;
247   }
248   printf("CreateCanvas(%s)\n", StrData);
249   SimpleDraw(tmpCanvas);
250   cdKillCanvas(tmpCanvas);
251   printf("KillCanvas()\n");
252 }
253 
254 void DrawCanvasDriverSize(cdContext* ctx, char* name, int pixels)
255 {
256   char[100] StrData;
257   int w, h;
258   double w_mm, h_mm;
259   cdCanvasGetSize(curCanvas, &w, &h, &w_mm, &h_mm);
260   if (pixels == 1)
261     sprintf(StrData.ptr, "%s %dx%d", name, w, h);
262   else if (pixels == 2)
263     sprintf(StrData.ptr, "%s -w%g -h%g -s%g", name, w_mm, h_mm, (cast(double)w/w_mm)*25.4);
264   else
265     sprintf(StrData.ptr, "%s %gx%g %g", name, w_mm, h_mm, cast(double)w/w_mm);
266   DrawCanvasDriver(ctx, StrData.ptr);
267 }
268 
269 void DrawCanvasDriverSizeParam(cdContext* ctx, char* param)
270 {
271   char[100] StrData;
272   int w, h;
273   cdCanvasGetSize(curCanvas, &w, &h, null, null);
274   sprintf(StrData.ptr, "%dx%d %s", w, h, param);
275   DrawCanvasDriver(ctx, StrData.ptr);
276 }
277 
278 int SimpleDrawDebug()
279 {
280   DrawCanvasDriverSize(CD_DEBUG, "simple_debug.txt".dup.ptr, 0);
281   return 0;
282 }
283 
284 int SimpleDrawCGMText()
285 {
286   DrawCanvasDriverSize(CD_CGM, "simple_t.cgm -t".dup.ptr, 0);
287   return 0;
288 }
289 
290 int SimpleDrawCGMBin()
291 {
292   DrawCanvasDriverSize(CD_CGM, "simple_b.cgm".dup.ptr, 0);
293   return 0;
294 }
295 
296 int SimpleDrawDXF()
297 {
298   DrawCanvasDriverSize(CD_DXF, "simple.dxf".dup.ptr, 0);
299   return 0;
300 }
301 
302 int SimpleDrawDGN()
303 {
304   DrawCanvasDriverSize(CD_DGN, "simple.dgn".dup.ptr, 0);
305   return 0;
306 }
307 
308 int SimpleDrawEMF()
309 {
310   if (contextplus) cdUseContextPlus(1);
311   DrawCanvasDriverSize(CD_EMF, "simple.emf".dup.ptr, 1);
312   if (contextplus) cdUseContextPlus(0);
313   return 0;
314 }
315 
316 int SimpleDrawMetafile()
317 {
318   DrawCanvasDriverSize(CD_METAFILE, "simple.mf".dup.ptr, 0);
319   return 0;
320 }
321 
322 int SimpleDrawPS()
323 {
324   DrawCanvasDriverSize(CD_PS, "simple.ps -l0 -r0 -t0 -b0".dup.ptr, 2);
325   return 0;
326 }
327 
328 int SimpleDrawSVG()
329 {
330   DrawCanvasDriverSize(CD_SVG, "simple.svg".dup.ptr, 0);
331   return 0;
332 }
333 
334 int SimpleDrawPDF()
335 {
336   DrawCanvasDriverSize(CD_PDF, "simple.pdf".dup.ptr, 2);
337   return 0;
338 }
339 
340 int SimpleDrawEPS()
341 {
342   DrawCanvasDriverSize(CD_PS, "simple.eps -e".dup.ptr, 2);
343   return 0;
344 }
345 
346 int SimpleDrawWMF()
347 {
348   DrawCanvasDriverSize(CD_WMF, "simple.wmf".dup.ptr, 1);
349   return 0;
350 }
351 
352 int SimpleDrawPrint()
353 {
354   if (contextplus) cdUseContextPlus(1);
355   DrawCanvasDriver(CD_PRINTER, "simple print".dup.ptr);
356   if (contextplus) cdUseContextPlus(0);
357   return 0;
358 }
359 
360 int SimpleDrawPrintDialog()
361 {
362   if (contextplus) cdUseContextPlus(1);
363   DrawCanvasDriver(CD_PRINTER, "simple -d".dup.ptr);   /* show dialog */
364   if (contextplus) cdUseContextPlus(0);
365   return 0;
366 }
367 
368 int SimpleDrawClipboardBitmap()
369 {
370   if (contextplus) cdUseContextPlus(1);
371   DrawCanvasDriverSizeParam(CD_CLIPBOARD, "-b".dup.ptr);
372   if (contextplus) cdUseContextPlus(0);
373   return 0;
374 }
375 
376 int SimpleDrawClipboardMetafile()
377 {
378   if (contextplus) cdUseContextPlus(1);
379   DrawCanvasDriverSizeParam(CD_CLIPBOARD, "-m".dup.ptr);
380   if (contextplus) cdUseContextPlus(0);
381   return 0;
382 }
383 
384 int SimpleDrawClipboardEMF()
385 {
386   if (contextplus) cdUseContextPlus(1);
387   DrawCanvasDriverSizeParam(CD_CLIPBOARD, "".dup.ptr);
388   if (contextplus) cdUseContextPlus(0);
389   return 0;
390 }
391 
392 int SimpleReplace()
393 {
394   write_mode = CD_REPLACE;
395   SimpleDraw(curCanvas);
396   return 0;
397 }
398 
399 int SimpleXor()
400 {
401   write_mode = CD_XOR;
402   SimpleDraw(curCanvas);
403   return 0;
404 }
405 
406 int SimpleNotXor()
407 {
408   write_mode = CD_NOT_XOR;
409   SimpleDraw(curCanvas);
410   return 0;
411 }
412 
413 int SimpleClippingOff()
414 {
415   clipping = CD_CLIPOFF;
416   SimpleDraw(curCanvas);
417   return 0;
418 }
419 
420 int SimpleClippingArea()
421 {
422   clipping = CD_CLIPAREA;
423   SimpleDraw(curCanvas);
424   return 0;
425 }
426 
427 int SimpleClippingPolygon()
428 {
429   clipping = CD_CLIPPOLYGON;
430   SimpleDraw(curCanvas);
431   return 0;
432 }
433 
434 int SimpleClippingRegion()
435 {
436   clipping = CD_CLIPREGION;
437   SimpleDraw(curCanvas);
438   return 0;
439 }
440 
441 int SimpleAll()
442 {
443   simple_draw = DRAW_ALL;
444   SimpleDraw(curCanvas);
445   return 0;
446 }
447 
448 int SimpleTextAlign()
449 {
450   simple_draw = DRAW_TEXTALIGN;
451   SimpleDraw(curCanvas);
452   return 0;
453 }
454 
455 int SimpleTextFonts()
456 {
457   simple_draw = DRAW_TEXTFONTS;
458   SimpleDraw(curCanvas);
459   return 0;
460 }
461 
462 int SimpleTest()
463 {
464   simple_draw = DRAW_TEST;
465   SimpleDraw(curCanvas);
466   return 0;
467 }
468 
469 void* CreateImageRGBA(int w, int h)
470 {
471   void* myImage;
472   ubyte* _alpha = cast(ubyte*)malloc(w * h);
473   SimpleInitAlpha(w, h, _alpha);
474   cdCanvasSetAttribute(curCanvas, "IMAGEALPHA", cast(char*)_alpha);
475   cdCanvasSetAttribute(curCanvas, "IMAGEFORMAT".toStringz, "32".dup.ptr);    // afetara� o proximo cdCreateImage
476   myImage = cdCanvasCreateImage(curCanvas, w, h);
477   cdCanvasSetAttribute(curCanvas, "IMAGEFORMAT", null);    // remove o atributo para nao afetar outros cdCreateImage
478   return myImage;
479 }
480 
481 int SimpleDrawImage()
482 {
483   use_opengl = 0;
484   if (dbCanvas) cdKillCanvas(dbCanvas);
485 
486   if (contextplus) cdUseContextPlus(1);
487   dbCanvas = cdCreateCanvas(CD_DBUFFER, winCanvas);
488   if (contextplus) cdUseContextPlus(0);
489 
490   curCanvas = dbCanvas;
491   SimpleDraw(curCanvas);
492 
493   return 0;
494 }
495 
496 int SimpleDrawImageRGB()
497 {
498   use_opengl = 0;
499   if (dbCanvas) cdKillCanvas(dbCanvas);
500 
501   if (contextplus) cdUseContextPlus(1);
502   dbCanvas = cdCreateCanvas(CD_DBUFFERRGB, winCanvas);
503   if (contextplus) cdUseContextPlus(0);
504 
505   curCanvas = dbCanvas;
506   SimpleDraw(curCanvas);
507 
508   return 0;
509 }
510 
511 version(USE_OPENGL) {
512 //#ifdef USE_OPENGL
513 int SimpleDrawGL()
514 {
515   char[100] StrData;
516   int w, h;
517   double w_mm, h_mm;
518 
519   if (use_opengl)
520     return 0;
521 
522   cdCanvasGetSize(curCanvas, &w, &h, &w_mm, &h_mm);
523 
524   sprintf(StrData.ptr, "%dx%d %g", w, h, (cast(double)w/w_mm));
525 
526   if (dbCanvas) cdKillCanvas(dbCanvas);
527 
528   dbCanvas = cdCreateCanvas(CD_GL, StrData.ptr);
529 
530   curCanvas = dbCanvas;
531   use_opengl = 1;
532   SimpleDraw(curCanvas);
533 
534   return 0;
535 }
536 //#endif
537 } // version(USE_OPENGL)
538 
539 int SimpleDrawSimulate()
540 {
541   simulate = !simulate;
542 
543   if (simulate)
544     cdCanvasSimulate(curCanvas, CD_SIM_ALL);
545   else
546     cdCanvasSimulate(curCanvas, CD_SIM_NONE);
547 
548   SimpleDraw(curCanvas);
549 
550   return 0;
551 }
552 
553 void SimpleKillCanvas()
554 {
555   if (dbCanvas)
556   {
557     cdKillCanvas(dbCanvas);
558     dbCanvas = null;
559   }
560   if (winCanvas)
561   {
562     cdKillCanvas(winCanvas);
563     winCanvas = null;
564   }
565 }
566 
567 void SimpleDrawTextFonts(cdCanvas* canvas);
568 void SimpleDrawTextAlign(cdCanvas* canvas);
569 void SimpleDrawAll(cdCanvas* canvas);
570 void SimpleDrawTest(cdCanvas* canvas);
571 
572 void SimpleDraw(cdCanvas* canvas)
573 {
574 version(USE_OPENGL)
575 {
576 //#ifdef USE_OPENGL
577   if (use_opengl)
578     SimpleUpdateSize(canvas);
579 //#endif
580 }
581   if (simple_draw == DRAW_TEXTFONTS)
582     SimpleDrawTextFonts(canvas);
583   else if (simple_draw == DRAW_TEXTALIGN)
584     SimpleDrawTextAlign(canvas);
585   else if (simple_draw == DRAW_TEST)
586     SimpleDrawTest(canvas);
587   else
588     SimpleDrawAll(canvas);
589 
590   cdCanvasFlush(canvas);
591 
592 version(USE_OPENGL)
593 {
594 //#ifdef USE_OPENGL
595   if (use_opengl)
596     SimpleFlush();
597 //#endif
598 }
599 }
600 
601 void SimpleDrawAll(cdCanvas* canvas)
602 {
603   int w, h;
604   cdCanvasGetSize(canvas, &w, &h, null, null);
605   
606   /* Clear the background to be white */
607   cdCanvasBackground(canvas, CD_WHITE);
608 //  cdBackground(CD_GREEN);
609   cdCanvasClear(canvas);
610 
611   /* Draw a reactangle and a polyline at the bottom-left area,
612      using a thick line with transparency.
613      Observe that transparency is only supported in a few drivers,
614      and line join is not supported in the IMAGERGB driver. */
615   cdCanvasLineWidth(canvas, 3);
616   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
617   cdCanvasForeground(canvas, cdEncodeAlpha(CD_DARK_MAGENTA, 128));
618   cdCanvasRect(canvas, 100, 200, 100, 200);
619 
620   cdCanvasBegin(canvas, CD_OPEN_LINES);
621   cdCanvasVertex(canvas, 300, 250);
622   cdCanvasVertex(canvas, 320, 270);
623   cdCanvasVertex(canvas, 350, 260);
624   cdCanvasVertex(canvas, 340, 200);
625   cdCanvasVertex(canvas, 310, 210);
626   cdCanvasEnd(canvas);
627   
628   /* Draw the red diagonal line with a custom line style. 
629      Observe that line styles are not supported in the IMAGERGB driver. */
630   cdCanvasForeground(canvas, CD_RED);
631   cdCanvasLineWidth(canvas, 3);
632   {
633     int[4] dashes = [20, 15, 5, 5];
634     cdCanvasLineStyleDashes(canvas, dashes.ptr, 4);
635   }
636   cdCanvasLineStyle(canvas, CD_CUSTOM);
637   cdCanvasLine(canvas, 0, 0, w-1, h-1);
638 
639   /* Draw the blue diagonal line with a pre-defined line style.
640      Observe that the pre-defined line style is dependent on the driver. */
641   cdCanvasForeground(canvas, CD_BLUE);
642   cdCanvasLineWidth(canvas, 10);
643   cdCanvasLineStyle(canvas, CD_DOTTED);
644   cdCanvasLine(canvas, 0, h-1, w-1, 0);
645 
646   switch(clipping)
647   {
648   case CD_CLIPOFF:
649     cdCanvasClip(canvas, CD_CLIPOFF);
650     break;
651   case CD_CLIPAREA:
652     /* Defines the clipping area equals the canvas area minus a 100 pixels margin. */
653     cdCanvasClipArea(canvas, 100, w - 100, 100, h - 100);
654     cdCanvasClip(canvas, CD_CLIPAREA);
655     break;
656   case CD_CLIPPOLYGON:
657     cdCanvasBegin(canvas, CD_CLIP);
658     cdCanvasVertex(canvas, 100, 100);
659     cdCanvasVertex(canvas, w - 100, 100);
660     cdCanvasVertex(canvas, w / 2, h - 100);
661     cdCanvasEnd(canvas);
662     cdCanvasClip(canvas, CD_CLIPPOLYGON);
663     break;
664   case CD_CLIPREGION:
665     cdCanvasTextAlignment(canvas, CD_CENTER);
666     cdCanvasFont(canvas, "Times", CD_BOLD, 50);
667 
668     cdCanvasBegin(canvas, CD_REGION);
669     cdCanvasRegionCombineMode(canvas, CD_UNION);
670     cdCanvasBox(canvas, 100, 200, 100, 200);
671     cdCanvasSector(canvas, w/2-50, h/2+50, 150, 150, 0, 360);
672     cdCanvasSector(canvas, w/2-50, h/2-50, 150, 150, 0, 360);
673     cdCanvasSector(canvas, w/2+50, h/2+50, 150, 150, 0, 360);
674     cdCanvasSector(canvas, w/2+50, h/2-50, 150, 150, 0, 360);
675     cdCanvasRegionCombineMode(canvas, CD_DIFFERENCE); 
676     cdCanvasText(canvas, w/2, h/2, "TEXT");
677     cdCanvasEnd(canvas);
678 //    cdCanvasOffsetRegion(canvas, -50, 50);
679     cdCanvasClip(canvas, CD_CLIPREGION);
680 
681     cdCanvasForeground(canvas, CD_DARK_RED);
682     cdCanvasBox(canvas, 0,w,0,h);
683     break;
684   default: assert(0);
685   }
686 
687   switch(write_mode)
688   {
689   case CD_REPLACE:
690     cdCanvasWriteMode(canvas, CD_REPLACE);
691     break;
692   case CD_XOR:
693     cdCanvasWriteMode(canvas, CD_XOR);
694     break;
695   case CD_NOT_XOR:
696     cdCanvasWriteMode(canvas, CD_NOT_XOR);
697     break;
698   default: assert(0);
699   }
700 
701   if (use_transform)
702   {
703     cdCanvasTransform(canvas, null);
704     cdCanvasTransformTranslate(canvas, w/2, h/2);
705     cdCanvasTransformRotate(canvas, 30);
706     cdCanvasTransformScale(canvas, 0.5, 0.5);
707     cdCanvasTransformTranslate(canvas, -w/2, -h/2);
708   }
709 
710 //  cdSetfAttribute("ROTATE", "15 %d %d", w/2, h/2);
711 
712   /* Reset line style and width */
713   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
714   cdCanvasLineWidth(canvas, 1);
715 //  cdBackOpacity(CD_TRANSPARENT); 
716                    
717   /* Draw an arc at bottom-left, and a sector at bottom-right.
718      Notice that counter-clockwise orientation of both. */
719   cdCanvasInteriorStyle(canvas, CD_SOLID);
720   cdCanvasForeground(canvas, CD_MAGENTA);
721   cdCanvasSector(canvas, w-100, 100, 100, 100, 50, 180);
722   cdCanvasForeground(canvas, CD_RED);
723   cdCanvasArc(canvas, 100, 100, 100, 100, 50, 180);
724 
725   /* Draw a solid filled rectangle at center. */
726   cdCanvasForeground(canvas, CD_YELLOW);
727   cdCanvasBox(canvas, w/2 - 100, w/2 + 100, h/2 - 100, h/2 + 100); 
728 
729   /* Prepare font for text. */
730   cdCanvasTextAlignment(canvas, CD_CENTER);
731   cdCanvasTextOrientation(canvas, 70);
732   cdCanvasFont(canvas, "Times", CD_BOLD, 24);
733 
734   /* Draw text at center, with orientation, 
735      and draw its bounding box. 
736      Notice that in some drivers the bounding box is not precise. */
737   {
738     int[8] rect;
739     cdCanvasGetTextBounds(canvas, w/2, h/2, "cdMin Draw (���)", rect.ptr);
740     cdCanvasForeground(canvas, CD_RED);
741     cdCanvasBegin(canvas, CD_CLOSED_LINES);
742     cdCanvasVertex(canvas, rect[0], rect[1]);
743     cdCanvasVertex(canvas, rect[2], rect[3]);
744     cdCanvasVertex(canvas, rect[4], rect[5]);
745     cdCanvasVertex(canvas, rect[6], rect[7]);
746     cdCanvasEnd(canvas);
747   }
748   cdCanvasForeground(canvas, CD_BLUE);
749   cdCanvasText(canvas, w/2, h/2, "cdMin Draw (���)");
750   cdCanvasTextOrientation(canvas, 0);
751 
752   /* Prepare World Coordinates */
753   wdCanvasViewport(canvas, 0,w-1,0,h-1);
754   if (w>h)
755     wdCanvasWindow(canvas, 0,cast(double)w/cast(double)h,0,1);
756   else
757     wdCanvasWindow(canvas, 0,1,0,cast(double)h/cast(double)w);
758 
759   /* Draw a filled blue rectangle in WC */
760   wdCanvasBox(canvas, 0.20, 0.30, 0.40, 0.50);
761   cdCanvasForeground(canvas, CD_RED);
762   /* Draw the diagonal of that rectangle in WC */
763   wdCanvasLine(canvas, 0.20, 0.40, 0.30, 0.50);
764 
765 //  wdVectorTextDirection(0, 0, 1, 1);
766   /* Prepare Vector Text in WC. */
767   wdCanvasVectorCharSize(canvas, 0.07);
768 
769 //  wdVectorText(0.1, 0.4, "�� ����� ����� ����� �����");
770 //  wdVectorText(0.1, 0.2, "�� ����� ����� ����� �����");
771   //{
772   //  int i;
773   //  char t[2];
774   //  char s[10];
775   //  int x = 20;
776   //  int y = 0;
777   //  t[1] = 0;
778   //  for (i = 0; i < 256; i++)
779   //  {
780   //    int dx = 90;
781   //    t[0] = (char)i;
782   //    sprintf(s, "%d", i);
783   //    cdText(x, y, s);
784   //    cdText(x+dx, y, t);
785   //    cdVectorText(x+2*dx, y, t);
786   //    
787   //    x += 3*dx + 2*dx/3;
788   //    if ((i+1) % 7 == 0)
789   //    {
790   //      x = 20;
791   //      y += 90;
792   //    }
793 
794   //  }
795   //}
796 
797   /* Draw vector text, and draw its bounding box. 
798      We also use this text to show when we are using a contextplus driver. */
799   {
800     double[8] rect;
801     cdCanvasForeground(canvas, CD_RED);
802     if (contextplus)
803       wdCanvasGetVectorTextBounds(canvas, "WDj-Plus", 0.25, 0.35, rect.ptr);
804     else
805       wdCanvasGetVectorTextBounds(canvas, "WDj", 0.25, 0.35, rect.ptr);
806     cdCanvasBegin(canvas, CD_CLOSED_LINES);
807     wdCanvasVertex(canvas, rect[0], rect[1]);
808     wdCanvasVertex(canvas, rect[2], rect[3]);
809     wdCanvasVertex(canvas, rect[4], rect[5]);
810     wdCanvasVertex(canvas, rect[6], rect[7]);
811     cdCanvasEnd(canvas);
812 
813     cdCanvasLineWidth(canvas, 2);
814     cdCanvasLineStyle(canvas, CD_CONTINUOUS);
815     if (contextplus)
816       wdCanvasVectorText(canvas, 0.25, 0.35, "WDj-Plus");
817     else
818       wdCanvasVectorText(canvas, 0.25, 0.35, "WDj");
819     cdCanvasLineWidth(canvas, 1);
820   }
821 
822   /* Draw a filled path at center-right (looks like a weird fish). 
823      Notice that in PDF the arc is necessarily a circle arc, and not an ellipse. */
824   cdCanvasForeground(canvas, CD_GREEN);
825   cdCanvasBegin(canvas, CD_PATH);
826   cdCanvasPathSet(canvas, CD_PATH_MOVETO);
827   cdCanvasVertex(canvas, w/2 + 200, h/2);
828   cdCanvasPathSet(canvas, CD_PATH_LINETO);
829   cdCanvasVertex(canvas, w/2 + 230, h/2 + 50);
830   cdCanvasPathSet(canvas, CD_PATH_LINETO);
831   cdCanvasVertex(canvas, w/2 + 250, h/2 + 50);
832   cdCanvasPathSet(canvas, CD_PATH_CURVETO);
833   cdCanvasVertex(canvas, w/2+150+150, h/2+200-50); /* control point for start */
834   cdCanvasVertex(canvas, w/2+150+180, h/2+250-50); /* control point for end */
835   cdCanvasVertex(canvas, w/2+150+180, h/2+200-50); /* end point */
836   cdCanvasPathSet(canvas, CD_PATH_CURVETO);
837   cdCanvasVertex(canvas, w/2+150+180, h/2+150-50); 
838   cdCanvasVertex(canvas, w/2+150+150, h/2+100-50); 
839   cdCanvasVertex(canvas, w/2+150+300, h/2+100-50); 
840   cdCanvasPathSet(canvas, CD_PATH_LINETO);
841   cdCanvasVertex(canvas, w/2+150+300, h/2-50);
842   cdCanvasPathSet(canvas, CD_PATH_ARC);
843   cdCanvasVertex(canvas, w/2+300, h/2);  /* center */
844   cdCanvasVertex(canvas, 200, 100);  /* width, height */
845   cdCanvasVertex(canvas, -30*1000, -170*1000);  /* start angle, end angle (degrees / 1000) */
846 //  cdCanvasPathSet(canvas, CD_PATH_CLOSE);
847 //  cdCanvasPathSet(canvas, CD_PATH_STROKE);
848   cdCanvasPathSet(canvas, CD_PATH_FILL);
849 //  cdCanvasPathSet(canvas, CD_PATH_FILLSTROKE);
850   cdCanvasEnd(canvas);
851 
852   /* Draw 3 pixels at center left. */
853   cdCanvasPixel(canvas, 10, h/2+0, CD_RED);
854   cdCanvasPixel(canvas, 11, h/2+1, CD_GREEN);
855   cdCanvasPixel(canvas, 12, h/2+2, CD_BLUE);
856 
857   /* Draw 4 mark types, distributed near each corner.  */
858   cdCanvasForeground(canvas, CD_RED);
859   cdCanvasMarkSize(canvas, 30);
860   cdCanvasMarkType(canvas, CD_PLUS);
861   cdCanvasMark(canvas, 200, 200);
862   cdCanvasMarkType(canvas, CD_CIRCLE);
863   cdCanvasMark(canvas, w - 200, 200);
864   cdCanvasMarkType(canvas, CD_HOLLOW_CIRCLE);
865   cdCanvasMark(canvas, 200, h - 200);
866   cdCanvasMarkType(canvas, CD_DIAMOND);
867   cdCanvasMark(canvas, w - 200, h - 200);
868 
869   /* Draw all the line style possibilities at bottom. 
870      Notice that they have some small differences between drivers. */
871   cdCanvasLineWidth(canvas, 1);
872   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
873   cdCanvasLine(canvas, 0, 10, w, 10);
874   cdCanvasLineStyle(canvas, CD_DASHED);
875   cdCanvasLine(canvas, 0, 20, w, 20);
876   cdCanvasLineStyle(canvas, CD_DOTTED);
877   cdCanvasLine(canvas, 0, 30, w, 30);
878   cdCanvasLineStyle(canvas, CD_DASH_DOT);
879   cdCanvasLine(canvas, 0, 40, w, 40);
880   cdCanvasLineStyle(canvas, CD_DASH_DOT_DOT);
881   cdCanvasLine(canvas, 0, 50, w, 50);
882 
883   /* Draw all the hatch style possibilities in the top-left corner.
884      Notice that they have some small differences between drivers. */
885   cdCanvasHatch(canvas, CD_VERTICAL); 
886   cdCanvasBox(canvas, 0, 50, h - 60, h);
887   cdCanvasHatch(canvas, CD_FDIAGONAL); 
888   cdCanvasBox(canvas, 50, 100, h - 60, h);
889   cdCanvasHatch(canvas, CD_BDIAGONAL); 
890   cdCanvasBox(canvas, 100, 150, h - 60, h);
891   cdCanvasHatch(canvas, CD_CROSS); 
892   cdCanvasBox(canvas, 150, 200, h - 60, h);
893   cdCanvasHatch(canvas, CD_HORIZONTAL); 
894   cdCanvasBox(canvas, 200, 250, h - 60, h);
895   cdCanvasHatch(canvas, CD_DIAGCROSS); 
896   cdCanvasBox(canvas, 250, 300, h - 60, h);
897 
898   /* Draw 4 regions, in diamond shape,
899      at top, bottom, left, right, 
900      using different interior styles. */
901 
902   /* At top, not filled polygon, notice that the last line style is used. */
903   cdCanvasBegin(canvas, CD_CLOSED_LINES);
904   cdCanvasVertex(canvas, w/2, h - 100); 
905   cdCanvasVertex(canvas, w/2 + 50, h - 150); 
906   cdCanvasVertex(canvas, w/2, h - 200); 
907   cdCanvasVertex(canvas, w/2 - 50, h - 150); 
908   cdCanvasEnd(canvas);
909 
910   /* At left, hatch filled polygon */
911   cdCanvasHatch(canvas, CD_DIAGCROSS); 
912   cdCanvasBegin(canvas, CD_FILL);
913   cdCanvasVertex(canvas, 100, h/2); 
914   cdCanvasVertex(canvas, 150, h/2 + 50); 
915   cdCanvasVertex(canvas, 200, h/2); 
916   cdCanvasVertex(canvas, 150, h/2 - 50); 
917   cdCanvasEnd(canvas);
918 
919   /* At right, pattern filled polygon */
920   cdCanvasPattern(canvas, STYLE_SIZE, STYLE_SIZE, pattern.ptr);
921   cdCanvasBegin(canvas, CD_FILL);
922   cdCanvasVertex(canvas, w - 100, h/2); 
923   cdCanvasVertex(canvas, w - 150, h/2 + 50); 
924   cdCanvasVertex(canvas, w - 200, h/2); 
925   cdCanvasVertex(canvas, w - 150, h/2 - 50); 
926   cdCanvasEnd(canvas);
927   
928   /* At bottom, stipple filled polygon */
929   cdCanvasStipple(canvas, STYLE_SIZE, STYLE_SIZE, stipple.ptr);
930   cdCanvasBegin(canvas, CD_FILL);
931   cdCanvasVertex(canvas, w/2, 100); 
932   cdCanvasVertex(canvas, w/2 + 50, 150); 
933   cdCanvasVertex(canvas, w/2, 200); 
934   cdCanvasVertex(canvas, w/2 - 50, 150); 
935   cdCanvasEnd(canvas);
936 
937   /* Draw two beziers at bottom-left */
938   cdCanvasBegin(canvas, CD_BEZIER);
939   cdCanvasVertex(canvas, 100, 100); 
940   cdCanvasVertex(canvas, 150, 200); 
941   cdCanvasVertex(canvas, 180, 250); 
942   cdCanvasVertex(canvas, 180, 200); 
943   cdCanvasVertex(canvas, 180, 150); 
944   cdCanvasVertex(canvas, 150, 100); 
945   cdCanvasVertex(canvas, 300, 100); 
946   cdCanvasEnd(canvas);
947 
948   /* Initialize the image buffer contents */
949 //#define IMAGE_SIZE 16
950   memset(red.ptr, 0xFF, IMAGE_SIZE*IMAGE_SIZE/2);
951   memset(green.ptr, 0x5F, IMAGE_SIZE*IMAGE_SIZE/2);
952   memset(blue.ptr, 0x5F, IMAGE_SIZE*IMAGE_SIZE/2);
953   memset(red.ptr+IMAGE_SIZE*IMAGE_SIZE/2, 0x5F, IMAGE_SIZE*IMAGE_SIZE/2);
954   memset(green.ptr+IMAGE_SIZE*IMAGE_SIZE/2, 0x8F, IMAGE_SIZE*IMAGE_SIZE/2);
955   memset(blue.ptr+IMAGE_SIZE*IMAGE_SIZE/2, 0x5F, IMAGE_SIZE*IMAGE_SIZE/2);
956   memset(red.ptr+IMAGE_SIZE*(IMAGE_SIZE-1), 0, IMAGE_SIZE);
957   memset(green.ptr+IMAGE_SIZE*(IMAGE_SIZE-1), 0, IMAGE_SIZE);
958   memset(blue.ptr+IMAGE_SIZE*(IMAGE_SIZE-1), 0, IMAGE_SIZE);
959   memset(red.ptr, 0, IMAGE_SIZE);
960   memset(green.ptr, 0, IMAGE_SIZE);
961   memset(blue.ptr, 0, IMAGE_SIZE);
962   {
963     int i, offset;
964     for (i = 0; i < IMAGE_SIZE; i++)
965     {
966       offset = i*IMAGE_SIZE;
967       red[offset] = 0;
968       green[offset] = 0;
969       blue[offset] = 0;
970       red[offset+IMAGE_SIZE-1] = 0;
971       green[offset+IMAGE_SIZE-1] = 0;
972       blue[offset+IMAGE_SIZE-1] = 0;
973     }
974   }
975 
976   //cdSetAttribute("ANTIALIAS", "0");
977 //  cdGetImageRGB(red, green, blue, w/2 - 50, h/2-50, 100, 100);
978 //  cdPutImageRectRGB(14, 13, red, green, blue, -20, -15, 649, 603, 0, 13, 0, 12);
979 //  cdPutImageRectRGB(16, 16, red, green, blue, 10, 10, 608, 608, 5, 10, 5, 10);
980 //  cdPutImageRectRGB(16, 16, red, green, blue, 10, 10, 64, 64, 5, 10, 5, 10);
981 
982 //  cdPutImageRGB(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, 100, h - 200, IMAGE_SIZE, IMAGE_SIZE);
983 //  cdPutImageRGBA(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, alpha, 100, h - 200, IMAGE_SIZE, IMAGE_SIZE);
984 //  cdPutImageRGB(IMAGE_SIZE, IMAGE_SIZE, red, green, blue, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE);
985   /* Draw the image on the top-right corner but increasing its actual size, and uses its full area */
986   cdCanvasPutImageRectRGBA(canvas, IMAGE_SIZE, IMAGE_SIZE, red.ptr, green.ptr, blue.ptr, alpha.ptr, w - 400, h - 310, 3*IMAGE_SIZE, 3*IMAGE_SIZE, 0, 0, 0, 0);
987 
988   cdCanvasSetAttribute(canvas, "ROTATE", null);
989   if (use_transform)
990     cdCanvasTransform(canvas, null);
991   cdCanvasClip(canvas, CD_CLIPOFF);
992 
993   /* Adds a new page, or 
994      flushes the file, or
995      flushes the screen, or
996      swap the double buffer. */
997   cdCanvasFlush(canvas);
998 }
999 
1000 void DrawVectorTextBox(cdCanvas* canvas, int x, int y, char* text)
1001 {
1002   int[8] rect;
1003   int draw_box;
1004 
1005   cdCanvasLineWidth(canvas, 1);
1006   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
1007 
1008   draw_box = 0;
1009   if (draw_box)
1010   {
1011     int xmin, xmax, ymin, ymax;
1012     cdCanvasGetVectorTextBox(canvas, x, y, text, &xmin, &xmax, &ymin, &ymax);
1013     cdCanvasForeground(canvas, CD_GREEN);
1014     cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
1015 
1016     if (cdCanvasTextOrientation(canvas, CD_QUERY) == 0)
1017     {
1018       cdCanvasForeground(canvas, CD_RED);
1019       cdCanvasLine(canvas, xmin, y, xmax, y);
1020     }
1021   }
1022   else
1023   {
1024     /* bounding box */
1025     cdCanvasGetVectorTextBounds(canvas, text, x, y, rect.ptr);
1026     cdCanvasForeground(canvas, CD_GREEN);
1027     cdCanvasBegin(canvas, CD_CLOSED_LINES);
1028     cdCanvasVertex(canvas, rect[0], rect[1]);
1029     cdCanvasVertex(canvas, rect[2], rect[3]);
1030     cdCanvasVertex(canvas, rect[4], rect[5]);
1031     cdCanvasVertex(canvas, rect[6], rect[7]);
1032     cdCanvasEnd(canvas);
1033   }
1034 
1035   /* reference point */
1036   cdCanvasForeground(canvas, CD_BLUE);
1037   cdCanvasMarkType(canvas, CD_PLUS);
1038   cdCanvasMarkSize(canvas, 30);
1039   cdCanvasMark(canvas, x, y);
1040 
1041   cdCanvasForeground(canvas, CD_BLACK);
1042   cdCanvasVectorText(canvas, x, y, text);
1043 }
1044 
1045 void DrawTextBox(cdCanvas* canvas, int x, int y, char* text)
1046 {
1047   int[8] rect;
1048   int draw_box;
1049 
1050   cdCanvasLineWidth(canvas, 1);
1051   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
1052 
1053   draw_box = 0;
1054   if (draw_box)
1055   {
1056     int xmin, xmax, ymin, ymax;
1057     cdCanvasGetTextBox(canvas, x, y, text, &xmin, &xmax, &ymin, &ymax);
1058     cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
1059 
1060     if (cdCanvasTextOrientation(canvas, CD_QUERY) == 0)
1061     {
1062       cdCanvasForeground(canvas, CD_RED);
1063       cdCanvasLine(canvas, xmin, y, xmax, y);
1064     }
1065   }
1066   else
1067   {
1068     /* bounding box */
1069     cdCanvasGetTextBounds(canvas, x, y, text, rect.ptr);
1070     cdCanvasForeground(canvas, CD_GREEN);
1071     cdCanvasBegin(canvas, CD_CLOSED_LINES);
1072     cdCanvasVertex(canvas, rect[0], rect[1]);
1073     cdCanvasVertex(canvas, rect[2], rect[3]);
1074     cdCanvasVertex(canvas, rect[4], rect[5]);
1075     cdCanvasVertex(canvas, rect[6], rect[7]);
1076     cdCanvasEnd(canvas);
1077   }
1078 
1079   /* reference point */
1080   cdCanvasForeground(canvas, CD_BLUE);
1081   cdCanvasMarkType(canvas, CD_PLUS);
1082   cdCanvasMarkSize(canvas, 30);
1083   cdCanvasMark(canvas, x, y);
1084 
1085   cdCanvasForeground(canvas, CD_BLACK);
1086   cdCanvasText(canvas, x, y, text);
1087 }
1088 
1089 void SimpleDrawTextAlign(cdCanvas* canvas)
1090 {
1091   int w, h, i, xoff, yoff, use_vector;
1092 
1093   int[12] text_aligment = [
1094     CD_NORTH,
1095     CD_SOUTH,
1096     CD_EAST,
1097     CD_WEST,
1098     CD_NORTH_EAST,
1099     CD_NORTH_WEST,
1100     CD_SOUTH_EAST,
1101     CD_SOUTH_WEST,
1102     CD_CENTER,
1103     CD_BASE_CENTER,
1104     CD_BASE_RIGHT,
1105     CD_BASE_LEFT
1106   ];
1107 
1108 version(all) {
1109   char*[] text_aligment_str = [
1110   "North (�yj)\nSecond Line (�yj)".dup.ptr,
1111   "South (�yj)\nSecond Line (�yj)".dup.ptr,
1112   "East (�yj)\nSecond Line (�yj)".dup.ptr,
1113   "West (�yj)\nSecond Line (�yj)".dup.ptr,
1114   "North East (�yj)\nSecond Line (�yj)".dup.ptr,
1115   "North West (�yj)\nSecond Line (�yj)".dup.ptr,
1116   "South East (�yj)\nSecond Line (�yj)".dup.ptr,
1117   "South West (�yj)\nSecond Line (�yj)".dup.ptr,
1118   "Center (�yj)\nSecond Line (�yj)".dup.ptr,
1119   "Base Center (�yj)\nSecond Line (�yj)".dup.ptr,
1120   "Base Right (�yj)\nSecond Line (�yj)".dup.ptr,
1121   "Base Left (�yj)\nSecond Line (�yj)".dup.ptr
1122   ];
1123 }
1124 else {
1125   char*[] text_aligment_str = [
1126   "North (�yj)",
1127   "South (�yj)",
1128   "East (�yj)",
1129   "West (�yj)",
1130   "North East (�yj)",
1131   "North West (�yj)",
1132   "South East (�yj)",
1133   "South West (�yj)",
1134   "Center (�yj)",
1135   "Base Center (�yj)",
1136   "Base Right (�yj)",
1137   "Base Left (�yj)"
1138   ];
1139 }
1140 
1141   cdCanvasGetSize(canvas, &w, &h, null, null);
1142 
1143   cdCanvasBackground(canvas, CD_WHITE);
1144   cdCanvasClear(canvas);
1145 
1146   use_vector = 0;
1147 
1148 version(none) {
1149   if (use_vector)
1150     cdCanvasVectorTextDirection(canvas, 0, 0, 1, 1);
1151   else
1152     cdCanvasTextOrientation(canvas, 45);
1153 }
1154 
1155   xoff = w/4;
1156   yoff = h/7;
1157 
1158   if (use_vector)
1159     cdCanvasVectorCharSize(canvas, 30);
1160   else
1161   {
1162     //cdCanvasFont(canvas, "Times", CD_PLAIN, 14);
1163     cdCanvasFont(canvas, "Helvetica", CD_PLAIN, 24);
1164   }
1165 
1166   for (i = 0; i < 12; i++)
1167   {
1168     cdCanvasTextAlignment(canvas, text_aligment[i]);
1169     if (i < 6)
1170     {
1171       if (use_vector)
1172         DrawVectorTextBox(canvas, xoff, yoff*(i+1), text_aligment_str[i]);
1173       else
1174         DrawTextBox(canvas, xoff, yoff*(i+1), text_aligment_str[i]);
1175     }
1176     else
1177     {
1178       if (use_vector)
1179         DrawVectorTextBox(canvas, 3*xoff, yoff*(i-5), text_aligment_str[i]);
1180       else
1181         DrawTextBox(canvas, 3*xoff, yoff*(i-5), text_aligment_str[i]);
1182     }
1183   }
1184 }
1185 
1186 void DrawTextFont(cdCanvas* canvas, const(char)* font, int size, int xoff, int yoff, char* text)
1187 {
1188   cdCanvasFont(canvas, font, CD_PLAIN, size);
1189   DrawTextBox(canvas, xoff, yoff, text);
1190 
1191   cdCanvasFont(canvas, font, CD_BOLD, size);
1192   DrawTextBox(canvas, 2*xoff, yoff, text);
1193 
1194   cdCanvasFont(canvas, font, CD_ITALIC, size);
1195   DrawTextBox(canvas, 3*xoff, yoff, text);
1196 
1197   cdCanvasFont(canvas, font, CD_BOLD_ITALIC, size);
1198   DrawTextBox(canvas, 4*xoff, yoff, text);
1199 }
1200 
1201 void SimpleDrawTextFonts(cdCanvas* canvas)
1202 {
1203   int xoff, yoff, size;
1204 
1205   cdCanvasBackground(canvas, CD_WHITE);
1206   cdCanvasClear(canvas);
1207 
1208   xoff = 470;
1209   yoff = 150;
1210   size = -30;
1211 
1212   cdCanvasTextAlignment(canvas, CD_CENTER);
1213 
1214   DrawTextFont(canvas, "Courier", size, xoff, yoff, "Courier".dup.ptr);
1215   DrawTextFont(canvas, "Times", size, xoff, 2*yoff, "Times Roman".dup.ptr);
1216   DrawTextFont(canvas, "Helvetica", size, xoff, 3*yoff, "Helvetica".dup.ptr);
1217   DrawTextFont(canvas, "System", size, xoff, 4*yoff, "System".dup.ptr);
1218 
1219   {
1220 //    static char native[50] = "Tecmedia, -60";
1221 //    static char native[50] = "-*-helvetica-medium-r-*-*-8-*";
1222 //    static char native[50] = "Edwardian Script ITC, 24";
1223 //    cdSetAttribute("ADDFONTMAP","Edwardian Script ITC=ITCEDSCR");
1224 
1225 //    char native[50] = "Book Antiqua, 24";
1226 //    cdSetAttribute("ADDFONTMAP", "Book Antiqua=BKANT");
1227 
1228 //    cdNativeFont("-d");
1229 //    cdNativeFont(native);
1230 //    DrawTextBox(xoff, yoff, native);
1231 //    DrawTextBox(xoff, yoff, "The quick brown fox.");
1232   }
1233 
1234   //cdNativeFont("Tecmedia, 36");
1235 
1236   //cdSetAttribute("ADDFONTMAP", "WingDings=WingDing");
1237   //cdNativeFont("WingDings, 36");
1238 
1239   //cdText(500, 50, "X");
1240   //cdText(500, 50, "abcdefghijklmnopqrstuvwxyz");
1241   //cdText(500, 150, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
1242   //cdText(500, 250, "1234567890");
1243   //cdText(500, 350, "'\"!@#$%�&*()_+-=[]^/;.,");
1244 
1245   //cdFont(CD_COURIER, 0, 22);
1246   //cdText(10, 60, "abcdefghijklmnopqrstuvwxyz");
1247   //cdText(10, 160, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
1248   //cdText(10, 260, "1234567890");
1249   //cdText(500, 360, "'\"!@#$%�&*()_+-=[]^/;.,");
1250 }
1251 
1252 void SimpleDrawTest(cdCanvas* canvas)
1253 //void SimpleDrawMainTest(cdCanvas* canvas)
1254 {
1255   c_long[16] pattern;  /* 4x4 pattern */
1256   int w, h;
1257   int xmin, xmax, ymin, ymax;
1258 
1259 /* notice that if we are not using world coordinates 
1260    it is harder to position all the objetcs we want. */
1261   cdCanvasGetSize(canvas, &w, &h, null, null);
1262 
1263   cdCanvasBackground(canvas, CD_WHITE);
1264   cdCanvasClear(canvas);
1265 
1266 /* pattern initialization */
1267   pattern[0]  = CD_RED;    pattern[1]  = CD_RED;    /* first line */
1268   pattern[2]  = CD_YELLOW; pattern[3]  = CD_YELLOW;
1269   pattern[4]  = CD_RED;    pattern[5]  = CD_RED;    /* second line */
1270   pattern[6]  = CD_YELLOW; pattern[7]  = CD_YELLOW;
1271   pattern[8]  = CD_YELLOW; pattern[9]  = CD_YELLOW; /* third line */
1272   pattern[10] = CD_YELLOW; pattern[11] = CD_YELLOW;
1273   pattern[12] = CD_YELLOW; pattern[13] = CD_YELLOW; /* fourth line */
1274   pattern[14] = CD_YELLOW; pattern[15] = CD_YELLOW;
1275 
1276 /* set the line attributes */
1277   cdCanvasLineWidth(canvas, 4);
1278   cdCanvasLineStyle(canvas, CD_CONTINUOUS);
1279 
1280 /* in the center draw a pattern pizza 
1281    with a slice mising */
1282   cdCanvasPattern(canvas, 4, 4, pattern.ptr);
1283   cdCanvasSector(canvas, w/2, h/2, w/2, h/2, 45, 0);
1284 /* draws a dark red border */
1285   cdCanvasForeground(canvas, CD_DARK_RED);
1286   cdCanvasInteriorStyle(canvas, CD_HOLLOW);
1287   cdCanvasSector(canvas, w/2, h/2, w/2, h/2, 45, 0);
1288 
1289 /* on the left a red hash diamond */
1290 /* notice the the default back opacity is transparent
1291    and the pattern of the sector will still be visible
1292    inside the hatch where the two objects intersect */
1293   cdCanvasForeground(canvas, CD_RED);
1294   cdCanvasHatch(canvas, CD_DIAGCROSS); 
1295   cdCanvasBegin(canvas, CD_FILL);
1296   cdCanvasVertex(canvas, w/4, h/4); 
1297   cdCanvasVertex(canvas, w/2-w/8, h/2); 
1298   cdCanvasVertex(canvas, w/4, 3*h/4); 
1299   cdCanvasVertex(canvas, w/8, h/2); 
1300   cdCanvasEnd(canvas);
1301 
1302 /* draws a blue roof.*/
1303   cdCanvasForeground(canvas, CD_BLUE);
1304   cdCanvasLine(canvas, w/8, h/2, w/4, 3*h/4);
1305   cdCanvasLine(canvas, w/4, 3*h/4, w/2-w/8, h/2);
1306 
1307 /* draws a dashed ribbon on the right 
1308    with a custom color */
1309   cdCanvasForeground(canvas, cdEncodeColor(100, 25, 200));
1310   cdCanvasLineStyle(canvas, CD_DASH_DOT);
1311   cdCanvasBegin(canvas, CD_BEZIER);
1312   cdCanvasVertex(canvas, 3*w/4-20, h/2-50); 
1313   cdCanvasVertex(canvas, 3*w/4+150, 3*h/4-50); 
1314   cdCanvasVertex(canvas, 3*w/4-150, 3*h/4-50); 
1315   cdCanvasVertex(canvas, 3*w/4+20, h/2-50); 
1316   cdCanvasEnd(canvas);
1317 
1318   cdCanvasFont(canvas, "Helvetica", CD_BOLD, 40);
1319   cdCanvasTextAlignment(canvas, CD_CENTER);
1320   cdCanvasText(canvas, w/2, h/4-50, "Canvas Draw");
1321   cdCanvasGetTextBox(canvas, w/2, h/4-50, "Canvas Draw", &xmin, &xmax, &ymin, &ymax);
1322   cdCanvasRect(canvas, xmin, xmax, ymin, ymax);
1323 }
1324 
1325 version(none) {
1326 //#
1327 void draw_wd()
1328 {
1329   char* text;
1330   double x, y;
1331   double[8] rect;
1332 
1333   cdBackground(CD_WHITE);
1334   cdClear();
1335   cdLineStyle(CD_CONTINUOUS);
1336   cdLineWidth(1);
1337 
1338 //  wdVectorTextDirection(0, 0, 1, 1);
1339   cdTextAlignment(CD_NORTH_WEST);
1340 
1341 //  text = "Vector Text";
1342   text = "Vector Text\nSecond Line\nThird Line";
1343   x = 0.25;
1344   y = 0.40;
1345 
1346   cdForeground(CD_BLACK);
1347   wdLine(0, 0, 1, 1);
1348   wdLine(0, 1, 1, 0);
1349 
1350   cdForeground(CD_GREEN);
1351   cdMarkType(CD_STAR);
1352   wdMark(x, y);
1353 
1354   cdForeground(CD_BLUE);
1355   wdVectorCharSize(0.1);
1356   wdVectorText(x, y, text);
1357 
1358   cdForeground(CD_RED);
1359   wdGetVectorTextBounds(text, x, y, rect);
1360   cdBegin(CD_CLOSED_LINES);
1361   wdVertex(rect[0], rect[1]);
1362   wdVertex(rect[2], rect[3]);
1363   wdVertex(rect[4], rect[5]);
1364   wdVertex(rect[6], rect[7]);
1365   cdEnd();
1366 }
1367 
1368 //void SimpleDrawTest(cdCanvas* canvas)
1369 void SimpleDrawTestHardCopy(cdCanvas* canvas)
1370 {
1371   int w, h;
1372   cdGetCanvasSize(&w, &h, 0, 0);
1373   
1374   wdViewport(0,w-1,0,h-1);
1375   if (w>h)
1376     wdWindow(0,cast(double)w/cast(double)h,0,1);
1377   else
1378     wdWindow(0,1,0,cast(double)h/cast(double)w);
1379 
1380   draw_wd();
1381 
1382   //wdHardcopy(CD_CLIPBOARD, "800x600", cdActiveCanvas(), draw_wd );
1383 }
1384 
1385 //void SimpleDrawTest(cdCanvas* canvas)
1386 void SimpleDrawTestImageRGB(cdCanvas* canvas)
1387 {
1388   int size = 2048*2048;
1389   ubyte* red, green, blue;
1390   cdCanvas* canvas = cdCreateCanvas(CD_IMAGERGB, "2048x2048");
1391   cdActivate(canvas);
1392 
1393   red = calloc(size, 1);
1394   green = calloc(size, 1);
1395   blue = calloc(size, 1);
1396 
1397   cdPutImageRectRGB(2048, 2048, red, green, blue, 0, 3, 2048, 2017, 0, 2047, 3, 2020);
1398 
1399   free(red);
1400   free(green);
1401   free(blue);
1402 
1403   cdKillCanvas(canvas);
1404 }
1405 
1406 //void SimpleDrawTest(cdCanvas* canvas)
1407 void SimpleDrawVectorFont(cdCanvas* canvas)
1408 {
1409   cdBackground(CD_WHITE);
1410   cdClear();
1411   cdLineStyle(CD_CONTINUOUS);
1412   cdLineWidth(1);
1413 
1414 //  wdVectorText(0.1, 0.4, "���� ����� ����� ����� �����");
1415 //  wdVectorText(0.1, 0.2, "���� ����� ����� ����� ����� ");
1416   cdVectorFont("../etc/vectorfont26.txt"); /* original Simplex II */
1417   {
1418     int i;
1419     char[2] t;
1420     char[10] s;
1421     int x = 10;
1422     int y = 600;
1423     t[1] = 0;
1424   cdFont(CD_COURIER, CD_BOLD, 14);
1425   cdVectorCharSize(25);
1426     for (i = 128; i < 256; i++)
1427     {
1428       int dx = 30;
1429       t[0] = cast(char)i;
1430       sprintf(s, "%3d", i);
1431       cdForeground(CD_DARK_RED);
1432       cdText(x, y, s);
1433 //      cdText(x+dx, y, t);
1434       cdForeground(CD_BLACK);
1435       cdVectorText(x+2*dx-10, y, t);
1436       
1437       x += 3*dx;
1438       if ((i+1) % 8 == 0)
1439       {
1440         x = 10;
1441         y -= 30;
1442       }
1443     }
1444   //cdFont(CD_TIMES_ROMAN, CD_PLAIN, 24);
1445   //cdVectorCharSize(24);
1446   //  for (i = 192; i < 256; i++)
1447   //  {
1448   //    int dx = 92;
1449   //    t[0] = (char)i;
1450   //    sprintf(s, "%d", i);
1451   //    cdText(x, y, s);
1452   //    cdText(x+dx, y, t);
1453   //    cdVectorText(x+2*dx, y, t);
1454   //    
1455   //    x += 3*dx + 2*dx/3;
1456   //    if ((i+1) % 4 == 0)
1457   //    {
1458   //      x = 30;
1459   //      y += 52;
1460   //    }
1461   //  }
1462   }
1463 }
1464 
1465 //void SimpleDrawTest(cdCanvas* canvas)
1466 void SimpleDrawPoly(cdCanvas* canvas)
1467 {
1468   int w, h;
1469   cdGetCanvasSize(&w, &h, 0, 0);
1470 
1471   cdBackground(CD_WHITE);
1472   cdClear();
1473 
1474   //cdSetAttribute("ANTIALIAS", "0");
1475   cdForeground(cdEncodeAlpha(cdEncodeColor(255, 0, 0), 100));
1476 
1477   cdfCanvasArc(cdActiveCanvas(), 255, 255, 100, 100, 0, 360);
1478 
1479   cdLine(0, 0, 200, 200);
1480 
1481   cdBegin(CD_BEZIER);
1482   cdVertex(100, 100); 
1483   cdVertex(150, 200); 
1484   cdVertex(180, 250); 
1485   cdVertex(180, 200); 
1486   cdVertex(180, 150); 
1487   cdVertex(150, 100); 
1488   cdVertex(300, 100); 
1489   cdEnd();
1490 
1491 
1492   cdEnd();
1493 }
1494 }
1495 
1496 
1497 version(none) {
1498 //#ifdef USE_OPENGL
1499 //#ifdef WIN32
1500 //#include <windows.h>
1501 //#endif
1502 
1503 //#include <GL/gl.h>
1504 //#include <GL/glu.h>
1505 //#endif
1506 }
1507 
1508 int cmdExit() nothrow
1509 {
1510   return IUP_CLOSE;
1511 }
1512 
1513 //void simple_loadled ();
1514 
1515 version(USE_OPENGL)
1516 {
1517 //#ifdef USE_OPENGL
1518 /* USE_OPENGL - add to linker:
1519 cdgl
1520 iupgl
1521 ftgl
1522 glu32
1523 opengl32
1524 */
1525 
1526 void SimpleUpdateSize(cdCanvas* cnv)
1527 {
1528   Ihandle* canvas = IupGetHandle("SimpleCanvas");
1529   int w = IupGetInt(canvas, "RASTERSIZE");
1530   int h = IupGetInt2(canvas, "RASTERSIZE");
1531   IupGLMakeCurrent(canvas);
1532 
1533   glMatrixMode(GL_PROJECTION);
1534   glLoadIdentity();
1535 //  gluOrtho2D(0, w, 0, h);
1536 
1537   glMatrixMode(GL_MODELVIEW);
1538   glLoadIdentity();
1539 
1540   if (cnv)
1541   {
1542     char[100] StrData;
1543     sprintf(StrData.ptr, "%dx%d", w, h);  /* no need to update resolution */
1544     cdCanvasSetAttribute(cnv, "SIZE", StrData.ptr);
1545   }
1546 }
1547 
1548 void SimpleFlush()
1549 {
1550   IupGLSwapBuffers(IupGetHandle("SimpleCanvas"));
1551 }
1552 //#endif
1553 } // version(USE_OPENGL)
1554 
1555 int main(string[] args) { // C: int main(int argc, char** argv)
1556     // Load OpenGL versions 1.0 and 1.1.
1557 //    DerelictGL3.load();
1558     
1559 	int rv;
1560 	{
1561 		char*[] args_carray;
1562 		foreach (s; args)
1563 			args_carray ~= cast(char*) s.toStringz;
1564 
1565 		debug  writeln("APP_NAME: ", args[0]);
1566 		int argc = cast(int) args.length;
1567 		char** argv = args_carray.ptr;
1568 		char* error = null;
1569 
1570 		/* Initialization of IUP */
1571 		IupOpen(&argc, &argv);
1572 	}
1573 
1574 // Create an OpenGL context with another library (like SDL 2 or GLFW 3)
1575 //#ifdef USE_CONTEXTPLUS
1576   cdInitContextPlus();
1577 //#endif
1578 version(USE_OPENGL) {
1579 //#ifdef USE_OPENGL
1580   // Load versions 1.2+ and all supported ARB and EXT extensions.
1581   DerelictGL.reload();
1582   // Now OpenGL functions can be called.
1583   IupGLCanvasOpen();
1584 //#endif
1585 } // version(USE_OPENGL)
1586 
1587 //  simple_loadled();
1588 
1589 	char* error = null;
1590 	if ((error = IupLoad("simple.led")) != null) {
1591 		IupMessage("LED Fehler", error);
1592 		exit(EXIT_FAILURE);
1593 	}
1594 
1595 version(USE_OPENGL)
1596 {
1597 //#ifdef USE_OPENGL
1598   {
1599     Ihandle* dialog = IupGetHandle("SimpleDialog");
1600     Ihandle* canvas = IupGetHandle("SimpleCanvas");
1601     IupDestroy(canvas);
1602     canvas = IupGLCanvas("SimpleRepaint");
1603 //    DerelictGL.reload();
1604     IupSetHandle("SimpleCanvas", canvas);
1605     IupAppend(dialog, canvas);
1606   }
1607 //#endif
1608 } // version(USE_OPENGL)
1609   IupSetAttribute(IupGetHandle("SimpleDialog"), "PLACEMENT", "MAXIMIZED");
1610   IupShow(IupGetHandle("SimpleDialog"));
1611 
1612   SimpleCreateCanvas(cast(char*)IupGetHandle("SimpleCanvas"));
1613 
1614   IupSetFunction("cmdExit", cast(Icallback) &cmdExit);
1615 
1616   IupSetFunction("SimplePlayClipboard", cast(Icallback) &SimplePlayClipboard);
1617   IupSetFunction("SimplePlayCGMText", cast(Icallback) &SimplePlayCGMText);
1618   IupSetFunction("SimplePlayCGMBin", cast(Icallback) &SimplePlayCGMBin);
1619   IupSetFunction("SimplePlayMetafile", cast(Icallback) &SimplePlayMetafile);
1620   IupSetFunction("SimplePlayWMF", cast(Icallback) &SimplePlayWMF);
1621   IupSetFunction("SimplePlayEMF", cast(Icallback) &SimplePlayEMF);
1622 
1623   IupSetFunction("SimpleDrawDebug", cast(Icallback) &SimpleDrawDebug);
1624   IupSetFunction("SimpleDrawWindow", cast(Icallback) &SimpleDrawWindow);
1625   IupSetFunction("SimpleDrawCGMText", cast(Icallback) &SimpleDrawCGMText);
1626   IupSetFunction("SimpleDrawCGMBin", cast(Icallback) &SimpleDrawCGMBin);
1627   IupSetFunction("SimpleDrawDXF", cast(Icallback) &SimpleDrawDXF);
1628   IupSetFunction("SimpleDrawDGN", cast(Icallback) &SimpleDrawDGN);
1629   IupSetFunction("SimpleDrawEMF", cast(Icallback) &SimpleDrawEMF);
1630   IupSetFunction("SimpleDrawMetafile", cast(Icallback) &SimpleDrawMetafile);
1631   IupSetFunction("SimpleDrawPDF", cast(Icallback) &SimpleDrawPDF);
1632   IupSetFunction("SimpleDrawPS", cast(Icallback) &SimpleDrawPS);
1633   IupSetFunction("SimpleDrawEPS", cast(Icallback) &SimpleDrawEPS);
1634   IupSetFunction("SimpleDrawSVG", cast(Icallback) &SimpleDrawSVG);
1635   IupSetFunction("SimpleDrawWMF", cast(Icallback) &SimpleDrawWMF);
1636   IupSetFunction("SimpleDrawPrint", cast(Icallback) &SimpleDrawPrint);
1637   IupSetFunction("SimpleDrawPrintDialog", cast(Icallback) &SimpleDrawPrintDialog);
1638   IupSetFunction("SimpleDrawClipboardBitmap", cast(Icallback) &SimpleDrawClipboardBitmap);
1639   IupSetFunction("SimpleDrawClipboardMetafile", cast(Icallback) &SimpleDrawClipboardMetafile);
1640   IupSetFunction("SimpleDrawClipboardEMF", cast(Icallback) &SimpleDrawClipboardEMF);
1641   IupSetFunction("SimpleDrawImage", cast(Icallback) &SimpleDrawImage);
1642   IupSetFunction("SimpleDrawImageRGB", cast(Icallback) &SimpleDrawImageRGB);
1643   IupSetFunction("SimpleDrawSimulate", cast(Icallback) &SimpleDrawSimulate);
1644 
1645 version(USE_OPENGL)
1646 {
1647 //#ifdef USE_OPENGL
1648   IupSetFunction("SimpleDrawGL", cast(Icallback) &SimpleDrawGL);
1649 //#endif
1650 }
1651 
1652   IupSetFunction("SimpleNotXor", cast(Icallback) &SimpleNotXor);
1653   IupSetFunction("SimpleXor", cast(Icallback) &SimpleXor);
1654   IupSetFunction("SimpleReplace", cast(Icallback) &SimpleReplace);
1655   IupSetFunction("SimpleClippingOff", cast(Icallback) &SimpleClippingOff);
1656   IupSetFunction("SimpleClippingArea", cast(Icallback) &SimpleClippingArea);
1657   IupSetFunction("SimpleClippingPolygon", cast(Icallback) &SimpleClippingPolygon);
1658   IupSetFunction("SimpleClippingRegion", cast(Icallback) &SimpleClippingRegion);
1659   IupSetFunction("SimpleContextPlus", cast(Icallback) &SimpleContextPlus);
1660   IupSetFunction("SimpleTransform", cast(Icallback) &SimpleTransform);
1661 
1662   IupSetFunction("SimpleAll", cast(Icallback) &SimpleAll);
1663   IupSetFunction("SimpleTextAlign", cast(Icallback) &SimpleTextAlign);
1664   IupSetFunction("SimpleTextFonts", cast(Icallback) &SimpleTextFonts);
1665   IupSetFunction("SimpleTest", cast(Icallback) &SimpleTest);
1666 
1667   IupSetFunction("SimpleRepaint", cast(Icallback) &SimpleRepaint);
1668 
1669   SimpleDrawWindow();
1670 
1671 version(USE_OPENGL)
1672 {
1673 //#ifdef USE_OPENGL
1674   SimpleUpdateSize(null);
1675   IupUpdate(IupGetHandle("SimpleCanvas"));
1676 //#endif
1677 }
1678 
1679   IupMainLoop();
1680 
1681   SimpleKillCanvas();
1682 
1683   IupClose();
1684 
1685   return EXIT_SUCCESS;
1686 }