// stest1.c  - test slides for screen size and aspect ratio
// 
// gcc -o stest1 stest1.c -lm -lgd ; ./stest1

#define NAME     "stest"
#define NFRAMES  9
#define FNT      "DejaVuMonoSans"
#define FRWIDE   15
#define F90      1.570796327

#include <gd.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>


//-----------------------------------
int main() {
    
   char       txt[80]              ;
   FILE       *pngout;             ; // output file
   gdImagePtr im                   ; // working image
   gdPoint    pt                   ;
   gdPoint    poly[10]             ;
   int        white, black, gray   ;
   int        i                    ;
   int        frame                ;
   int        nest                 ;
   int        xsize, ysize         ;
   int        xcent, ycent         ;
   int        xcenm, ycenm         ;
   int        xnest, ynest         ;
   int        x ,  y               ;
   int        x0,  y0              ;
   int        x1,  y1              ;
   int        xf,  yf              ;
   int        brect[8]             ;

   // sizes -----------------------
   int   axsize[NFRAMES], aysize[NFRAMES];

         axsize[0]=  512; aysize[0]=  384;
         axsize[1]=  800; aysize[1]=  600;
         axsize[2]=  880; aysize[2]=  660;
         axsize[3]= 1024; aysize[3]=  768;
         axsize[4]= 1280; aysize[4]=  960;
         axsize[5]= 1400; aysize[5]= 1050;
         axsize[6]= 1600; aysize[6]= 1200;
         axsize[7]= 1920; aysize[7]= 1440;
         axsize[8]= 2048; aysize[8]= 1536;
   
   for( frame=0 ; frame < NFRAMES ; frame++ ) {
      xsize = axsize[frame];
      ysize = aysize[frame];
      xcent = xsize/2 ;
      ycent = ysize/2 ;
      xcenm = xcent-1 ;
      ycenm = ycent-1 ;

      im     = gdImageCreateTrueColor(xsize, ysize);

      white   = gdImageColorAllocate (im, 255, 255, 255);
      black   = gdImageColorAllocate (im,   0,   0,   0);
   
      // moire grid ---------------------------------------------
      for( y=0 ; y < ysize ; y +=2 ) {
         for( x = 0 ; x < xsize ; x +=2 ) {
            gdImageSetPixel( im, x  , y  , white ) ;
            gdImageSetPixel( im, x+1, y  , black ) ;
            gdImageSetPixel( im, x  , y+1, black ) ;
            gdImageSetPixel( im, x+1, y+1, white ) ;
      }  }
      // gray scale ----------------------------------------------
      for( i=0 ; i<256 ; i++ ) {
         gray = gdImageColorAllocate (im, i, i, i);
         x = xcent+i-128;
         gdImageLine( im, x, ycent+20, x, ycent+140, gray );
      }
      // label ---------------------------------------------------
      sprintf( txt, "%4dx%4d", xsize, ysize );

      // scale it
      gdImageStringFT(NULL, &brect[0],     0, FNT, 40, 0.0, 0, 0, txt );

      x = xcent-(brect[0]+brect[2])/2 ;
      y = ycent-(brect[1]+brect[3])/2 ;
      
      // print it above centerline 
      gdImageStringFT( im,  &brect[0], black, FNT, 40, 0.0, x, y, txt );

      // nested boxes with sizes and arrows ----------------------

      for( nest = frame ; nest >=0 ; nest-- ) {
         xnest = axsize[nest]/2;
         ynest = aysize[nest]/2;

         // label ---------------------------------------------------
         sprintf( txt, " %4dx%4d  ", xnest*2, ynest*2 );

         // left border  UL LR
         gdImageFilledRectangle( im, xcent-xnest,        ycent-ynest,
                                     xcent+FRWIDE-xnest, ycenm+ynest, white );
         
         // left arrow
         poly[0].x=xcent-xnest        ; poly[0].y=ycent        ;
         poly[1].x=xcent+FRWIDE-xnest ; poly[1].y=ycent+FRWIDE ;
	 poly[2].x=xcent+FRWIDE-xnest ; poly[2].y=ycent-FRWIDE ;
	 gdImageFilledPolygon ( im, poly, 3, black );

         // right
         gdImageFilledRectangle( im, xcenm+xnest-FRWIDE, ycent-ynest,
                                     xcenm+xnest       , ycenm+ynest, white );
         // right arrow
         poly[0].x=xcenm+xnest        ; poly[0].y=ycent        ;
         poly[1].x=xcenm+xnest-FRWIDE ; poly[1].y=ycent+FRWIDE ;
         poly[2].x=xcenm+xnest-FRWIDE ; poly[2].y=ycent-FRWIDE ;
         gdImageFilledPolygon ( im, poly, 3, black );

         // top
         gdImageFilledRectangle( im, xcent-xnest, ycent-ynest,
                                     xcenm+xnest, ycent+FRWIDE-ynest, white );
         // top arrow
         poly[0].x=xcent        ; poly[0].y=ycent-ynest  ;
         poly[1].x=xcent+FRWIDE ; poly[1].y=ycent+FRWIDE-ynest ;
         poly[2].x=xcent-FRWIDE ; poly[2].y=ycent+FRWIDE-ynest ;
         gdImageFilledPolygon ( im, poly, 3, black );

         // top labels
         gdImageStringFT(NULL, &brect[0], 0, FNT, 14, 0.0, 0, 0, txt );
         gdImageStringFT( im,  &brect[0], black, FNT, 14, 0.0,
             xcent-xnest-brect[6], ycent-ynest-brect[7], txt );
         gdImageStringFT(NULL, &brect[0], 0, FNT, 14, 0.0, 0, 0, txt );
         gdImageStringFT( im,  &brect[0], black, FNT, 14, 0.0,
             xcenm+xnest-brect[4], ycent-ynest-brect[7], txt );

         // bottom
         gdImageFilledRectangle( im, xcent-xnest, ycenm+ynest-FRWIDE,
                                     xcenm+xnest, ycenm+ynest, white );
         // bottom arrow
         poly[0].x=xcent        ; poly[0].y=ycenm+ynest  ;
         poly[1].x=xcent+FRWIDE ; poly[1].y=ycenm+ynest-FRWIDE ;
         poly[2].x=xcent-FRWIDE ; poly[2].y=ycenm+ynest-FRWIDE ;
         gdImageFilledPolygon ( im, poly, 3, black );

         // bottom labels
         gdImageStringFT(NULL, &brect[0], 0, FNT, 14, 0.0, 0, 0, txt );
         gdImageStringFT( im,  &brect[0], black, FNT, 14, 0.0,
             xcent-xnest-brect[6], ycenm+ynest-brect[1], txt );
         gdImageStringFT(NULL, &brect[0], 0, FNT, 14, 0.0, 0, 0, txt );
         gdImageStringFT( im,  &brect[0], black, FNT, 14, 0.0,
             xcenm+xnest-brect[4], ycenm+ynest-brect[1], txt );

      }

      sprintf( txt, "%s%04d.png", NAME, xsize );
      pngout = fopen( txt, "wb");
      gdImagePngEx( im, pngout, 1 );
      gdImageDestroy(im);
      fclose(pngout);
   }
   return 0 ;
}
