[comp.sys.amiga] imagfunc.c - 9 of 21

crunch@well.UUCP (John Draper) (12/03/86)

/***************************** Imagfunc.c ************************************
*
*  Image editor functions for the Gadget Editor.
*
*  This module by
*  Ray R. Larson        This version: Sept. 28, 1986
*
*  This module contains the source for the  routines that support the
*  the main routine Image_Ed.
****************************************************************************/
extern char kprintstr[200]; /* work string for debugging output */
                     /* because kprintf doesn't work for me */
 
/*  The usual header files   */
#include <intuition/intuition.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/display.h>
#include <exec/memory.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <devices/narrator.h>
#include <devices/audio.h>
#include <libraries/translator.h>
 
/*------------ Graphics Macros ------------------*/
 
#include <graphics/gfxmacros.h>
 
/*------------ External function declarations ------------*/
 
extern struct ViewPort *ViewPortAddress();
extern struct Window *OpenWindow();
extern struct IntuiMessage *GetMsg();
extern void *AllocRaster();
extern struct ColorMap *GetColorMap();
extern struct Preferences *GetPrefs();
extern APTR  AllocRemember();
extern struct Remember *rememberBase;
extern struct TmpRas *InitTmpRas();
 
/*------------------- global variables -------------------*/
 
extern struct GfxBase *GfxBase;
extern struct IntuitionBase *IntuitionBase;
 
/*------------------- work rasters and bitmaps -----------*/
extern struct RastPort smallraster; /* these are in imagdcl.c */
extern struct BitMap smallbitmap;
struct TmpRas smalltmpras;
BYTE *tmprasbuf;
 
/*------------------- macro definitions ------------------*/
#define inrange(n,nl,nh) ((n >= nl) && (n <= nh) ?1:0)
#define inbox(x,y,xt,yt,xb,yb) ((inrange(x,xt,xb) && inrange(y,yt,yb)) ?1:0)
#define MIN(a,b) ((a < b) ? a:b)
#define MAX(a,b) ((a > b) ? a:b)
#define ABS(a) ((a > 0) ? a:(a * -1))
/*------------------- color table definitions ------------------*/
 
extern UWORD defaultCT[32], CTable[32];
extern struct ColorMap *cmap;
 
/**************************************************************************
* Definitions and declarations for all them gadgets
***************************************************************************/
/* image editor window dimensions */
#define WINDWIDTH  640
#define WINDHEIGHT 200
 
/* size of the image editing area */
#define FRAMETOP    11
#define FRAMELEFT    3
#define FRAMEBOT   173
#define FRAMERIGHT 401
#define FRAMEHEIGHT  FRAMEBOT-FRAMETOP
#define FRAMEWIDTH   FRAMERIGHT-FRAMELEFT
 
#define PALETTEG   1
#define MAGMINUSG  2
#define MAGPLUSG   3
#define UPDOWNG    4
#define LEFTRIGHTG 5
#define BIGEDG     6
#define RESETG     7 /* no longer used put in menu */
#define BLUECTLG   8
#define GREENCTLG  9
#define REDCTLG    10
 
/* menu items  - menu declarations are in imagmen.c */
#define PROJMEN 0
#define EDITMEN 1
#define OPTMEN  2
#define RETURNM 0
#define CANCELM 1
#define CLREDWIN 0
#define CLREDALL 1
#define RESETIMAG 2
#define RESETCOLOR 3
#define SHOWSMALL 0
#define HIDESMALL 1
 
extern struct Gadget UpDownGadg, L_R_Gadg, paletteGadg;
extern struct PropInfo UpDownProp, L_R_Prop;
 
/* The following routine allocates work bitmaps and raster ports for */
/* the image editor                                                  */
 
initrasters(width,height,depth)
   LONG width, height, depth;
   {
        SHORT i;
 
        InitRastPort(&smallraster);
 
        InitBitMap(&smallbitmap,depth,width,height);
 
        for (i=0 ; i < depth; i++)
            smallbitmap.Planes[i] =
                (PLANEPTR)AllocRaster(width+24L,height+24L);
        for (i=0 ; i < depth; i++)
            if(smallbitmap.Planes[i] == NULL)
               return(FALSE);
 
        tmprasbuf = AllocRaster(width+24L,height+24L);
        if (tmprasbuf == NULL) return(FALSE);
        smallraster.TmpRas =
            InitTmpRas(&smalltmpras,tmprasbuf,RASSIZE(width+24L,height+24L));
 
        smallraster.BitMap = &smallbitmap;
 
        return(TRUE);
    }
 
/* To erase the temporary rasters... */
FreeEdRas (width,height,depth)
      LONG width, height, depth;
     {
        SHORT i;
 
        for (i = 0 ; i < depth; i++)
            FreeRaster(smallbitmap.Planes[i], width+24L,height+24L);
 
        FreeRaster(tmprasbuf,width+24L,height+24L);
     }
 
 
/* output 'pixels' to the image editing area on the editor screen */
bigpixel(rp,mousex,mousey,magnif, max_x, max_y)
     struct RastPort *rp;
     short mousex, mousey, magnif, max_x, max_y;
     {
        LONG x,y,tx,ty,bx,by, magval;
 
        magval = (1L << magnif);
        /* clip it */
        if(inbox(mousex,mousey,FRAMELEFT,FRAMETOP,
           MIN(max_x,FRAMERIGHT-1),
           MIN(max_y,FRAMEBOT-1)) == 0) return;
 
        if (magnif)
           {
             x = ((LONG)(mousex - FRAMELEFT)) / magval;
             y = ((LONG)(mousey - FRAMETOP)) / magval;
 
             tx = (x * magval) + FRAMELEFT;
             ty = (y * magval) + FRAMETOP;
             bx = tx + (magval-1) ;
             by = ty + (magval-1) ;
 
             bx = MIN(bx,MIN(max_x+magval,FRAMERIGHT));
             by = MIN(by,MIN(max_y+magval,FRAMEBOT));
 
             RectFill(rp,tx,ty,bx,by);
           }
        else WritePixel(rp,(LONG)mousex,(LONG)mousey);
 
    }
 
 
/* The following routine writes pixels in the 'real-size' raster */
/* for the image that is off-screen.                             */
smallpixel(rp,mousex,mousey,magnif,max_x,max_y,offset_x,offset_y)
     struct RastPort *rp;
     short mousex, mousey, magnif,max_x, max_y, offset_x, offset_y;
     {
        LONG x,y,magval;
 
        magval = (1L << magnif);
        x = ((LONG)(mousex - FRAMELEFT)) / magval;
        y = ((LONG)(mousey - FRAMETOP)) / magval;
 
        if(inbox(x,y,0,0,max_x,max_y) == 0)
             return;
 
        else WritePixel(rp,x+(LONG)offset_x, y+(LONG)offset_y);
 
    }
 
/* The following routine renders lines draw with the line tool into the */
/* small image                                                          */
 
smalline(rp,basex,basey,mousex,mousey,magnif,max_x,max_y,offset_x,offset_y,pen)
     struct RastPort *rp;
     SHORT basex,basey,mousex, mousey, magnif,max_x, max_y, offset_x, offset_y;
     LONG pen;
     {
        SHORT x1,y1, x2, y2, magval;
 
        magval = 1 << magnif;
        x1 = ((basex - FRAMELEFT) / magval)+offset_x;
        y1 = ((basey - FRAMETOP) / magval)+offset_y;
        x2 = ((mousex - FRAMELEFT) / magval)+offset_x;
        y2 = ((mousey - FRAMETOP) / magval)+offset_y;
 
        if(inbox(x2,y2,0,0,max_x,max_y) == 0)
             return;
 
        im_draw_line(rp,x1,y1,x2,y2,pen,0);
    }
 
/* The following routine renders boxes draw with the box  tool into the */
/* small image                                                          */
 
smallbox(rp,basex,basey,width,height,magnif,max_x,max_y,offset_x,offset_y,pen)
     struct RastPort *rp;
     SHORT basex,basey,width,height, magnif,max_x, max_y, offset_x, offset_y;
     LONG pen;
     {
        SHORT x,y, w, h, magval;
 
        magval = 1 << magnif;
        x = ((basex - FRAMELEFT) / magval)+offset_x;
        y = ((basey - FRAMETOP) / magval)+offset_y;
        w = width / magval;
        h = height / magval;
 
        if(inbox(x+w,y+h,0,0,max_x,max_y) == 0)
             return;
 
        im_draw_box(rp,x,y,w,h,pen,0);
    }
 
/* The following routine renders filled boxes drawn with the filledbox    */
/* tool into the small raster image                                       */
 
smallrect(rp,x1,y1,x2,y2,magnif,max_x,max_y,offset_x,offset_y,pen)
     struct RastPort *rp;
     SHORT x1,y1,x2,y2,magnif,max_x, max_y, offset_x, offset_y;
     LONG pen;
     {
        SHORT x,y,topx,topy,botx,boty, magval;
 
        topx = MIN(x1,x2);
        topy = MIN(y1,y2);
        botx = MAX(x1,x2);
        boty = MAX(y1,y2);
        magval = 1 << magnif;
        topx = ((topx - FRAMELEFT) / magval)+offset_x;
        topy = ((topy - FRAMETOP) / magval)+offset_y;
        botx = ((botx - FRAMELEFT) / magval)+offset_x;
        boty = ((boty - FRAMETOP) / magval)+offset_y;
 
        if(inbox(topx,topy,0,0,max_x,max_y) == 0)
             return;
        if(inbox(botx,boty,0,0,max_x,max_y) == 0)
             return;
 
        RectFill(rp,(LONG)topx,(LONG)topy,(LONG)botx,(LONG)boty);
    }
 
 
/* The following routine renders circles draw with the circle tool into the */
/* small image                                                              */
 
smallcirc(rp,centerx,centery,radius,aspect,magnif,max_x,max_y,offset_x,offset_y,
pen)
     struct RastPort *rp;
     SHORT centerx,centery,radius,aspect, magnif,max_x, max_y, offset_x, offset_
y;
     LONG pen;
     {
        SHORT x, y, r, a, magval;
 
        magval = 1 << magnif;
        x = ((centerx - FRAMELEFT) / magval)+offset_x;
        y = ((centery - FRAMETOP) / magval)+offset_y;
        r = radius / magval;
        a = aspect / magval;
 
        if((inrange(x+r,0,max_x) == 0)||
           (inrange(x-r,0,max_x) == 0)||
           (inrange(y+a,0,max_y) == 0)||
           (inrange(y-a,0,max_y) == 0)) return;
 
        im_draw_circ(rp,x,y,r,a,pen,0);
    }
 
 
/* The following routine flood fills areas in the small raster with the   */
/* given pen color                                                        */
smallfill(rp,mousex,mousey,magnif,offset_x,offset_y)
     struct RastPort *rp;
     SHORT mousex,mousey,magnif, offset_x, offset_y;
     {
        SHORT magval;
        LONG x, y;
 
        magval = 1 << magnif;
        x = (LONG)((mousex - FRAMELEFT) / magval)+offset_x;
        y = (LONG)((mousey - FRAMETOP) / magval)+offset_y;
 
        SetDrMd(&smallraster,JAM2);
        Flood(&smallraster,1L,x,y);
    }
 
/* The following routine redraws the image in the editing window     */
/* from the off-screen raster. It is used whenever the magnification */
/* is changed or when the editing area is moved.                     */
redrawim (src_rp, dest_rp, src_x, src_y, maxsrc_x, maxsrc_y,
           dest_width, dest_height, magnif,clear)
      struct RastPort *src_rp, *dest_rp;
      SHORT src_x,src_y,maxsrc_x,maxsrc_y,dest_width,dest_height,magnif;
      SHORT clear;
      {
        register LONG pen;
        register SHORT x, y, pixoutx, pixouty, magval;
        SHORT out_width, out_height, mousex, mousey, src_width, src_height;
        SHORT n_pixwide, n_pixhigh;
        SHORT tx,ty,bx,by;
 
        /* clear the image drawing area */
        if (clear)
        {SetAPen(dest_rp,0L);
         RectFill(dest_rp,((LONG)FRAMELEFT),((LONG)FRAMETOP),
                 ((LONG)FRAMERIGHT),((LONG)FRAMEBOT));
        }
 
        /* set the output frame width and height*/
        src_width = (maxsrc_x - src_x)+1;
        src_height = (maxsrc_y - src_y)+1;
 
        if (src_width > dest_width) out_width = dest_width;
        else out_width = src_width;
        if (src_height > dest_height) out_height = dest_height;
        else out_height = src_height;
 
        magval = 1<<magnif;
 
        if (magnif) /* when the image is magnified redraw as in bigpixel */
           { n_pixwide = dest_width/magval;
             n_pixhigh = dest_height/magval;
 
             pixouty = 0;
             for( y = src_y;  y <= maxsrc_y && pixouty <= n_pixhigh; y++, pixout
y++)
                { pixoutx = 0;
                for( x = src_x; x <= maxsrc_x && pixoutx <= n_pixwide; x++, pixo
utx++)
                   { /* first, get the color for the pixel from the */
                     /* source (small) raster and use it to set the */
                     /* pen color for the editing pen               */
                     /* (the pen will be left in the last color)    */
                     pen = ReadPixel(src_rp,(LONG)x,(LONG)y);
                     if(pen != 0)
                       { SetAPen(dest_rp,pen);
 
                        /* write it into the editing frame at the right */
                        /* magnification, making each pixel in the small*/
                        /* image into a rectangle in the editor area    */
 
                         tx = ((x-src_x) * magval) + FRAMELEFT;
                         ty = ((y-src_y) * magval) + FRAMETOP;
                         bx = tx + (magval-1) ;
                         by = ty + (magval-1) ;
 
                         if( inbox(tx,ty,FRAMELEFT,FRAMETOP,
                                   FRAMERIGHT-2,FRAMEBOT-2) == 0) continue;
 
                         bx = MIN(bx,FRAMERIGHT-1);
                         by = MIN(by,FRAMEBOT-1);
 
                         RectFill(dest_rp,(LONG)tx,(LONG)ty,(LONG)bx,(LONG)by);
                        }
                    }
                 }
             }
         else /* no magnification so simply blit the image over */
             {
              if (out_width == 0) out_width = 1;
              if (out_height == 0) out_height = 1;
              ClipBlit (src_rp,(LONG)src_x,(LONG)src_y,
                        dest_rp,(LONG)FRAMELEFT,(LONG)FRAMETOP,
                        (LONG)out_width,
                        (LONG)out_height,
                        (LONG)0xc0 /* copy all planes */);
             }
 }
 
/* this routine sets the variables used for clipping the editor image */
setclip(rp,max_right,max_bot,magnif,imagewidth,imageheight)
    struct RastPort *rp;
    SHORT *max_right, *max_bot, magnif, imagewidth, imageheight;
    {
      SHORT mag_width, mag_height;
      BOOL drawright, drawbot;
 
      drawright = drawbot = FALSE;
 
      mag_width = imagewidth << magnif;
      mag_height = imageheight << magnif;
 
      if (mag_width >= (FRAMEWIDTH))
         *max_right = FRAMERIGHT;
      else { *max_right = mag_width + FRAMELEFT -1;
             drawright = TRUE;
           }
 
      if (mag_height >= (FRAMEHEIGHT))
         *max_bot = FRAMEBOT;
      else { *max_bot = mag_height + FRAMETOP -1;
             drawbot = TRUE;
           }
 
      if(drawright)/* put a complement 'frame' on the right side */
           {
             SetDrMd(rp,COMPLEMENT | JAM1);
             Move(rp,(LONG)*max_right+1,(LONG)FRAMETOP);
             Draw(rp,(LONG)*max_right+1,(LONG)MIN(*max_bot+1,FRAMEBOT));
           }
      if(drawbot) /* put a complement 'frame' at the bottom */
          {
             SetDrMd(rp,COMPLEMENT | JAM1);
             Move(rp,(LONG)FRAMELEFT,(LONG)*max_bot+1);
             Draw(rp,(LONG)MIN(*max_right+1,FRAMERIGHT),(LONG)*max_bot+1);
           }
 
      SetDrMd(rp,JAM1);
 
}
 
/* The following routine sets the image movement proportional gadget sizes */
setprops(w,magnif,imagewidth,imageheight)
    struct Window *w;
    SHORT  magnif, imagewidth, imageheight;
    {
      SHORT mag_width, mag_height;
      USHORT vdiv, vertbod, hdiv, horizbod;
      mag_width = imagewidth << magnif;
      mag_height = imageheight << magnif;
      vdiv = (mag_height / (FRAMEHEIGHT))+ 1;/* round up to next highest*/
      hdiv = (mag_width / (FRAMEWIDTH))+ 1;
      vertbod =  0xFFFF / vdiv ;
      horizbod = 0xFFFF / hdiv;
      if(vertbod == 0xFFFF) vertbod -= 0x1000;
      if(horizbod == 0xFFFF) horizbod -= 0x1000;
      UpDownProp.VertBody = vertbod; /* calc from height */
      L_R_Prop.HorizBody = horizbod; /* calc from width */
 
     RefreshGadgets(&L_R_Gadg,w,NULL);
 
}
 
/* initialize palette - this will set up a pallette for any depth of */
/* screen.                                                           */
initpalette(rp,depth)
   struct RastPort *rp;
   SHORT depth;
   {
     SHORT i, j, c_rows, n_colors, c_per_row;
     LONG x, y, bx, by, boxw, boxh, pen;
 
     n_colors = 1 << depth;
     if (n_colors > 8) c_rows = 2;
     else c_rows = 1;
 
     c_per_row = n_colors / c_rows;
 
     boxw = (LONG)paletteGadg.Width/c_per_row;
     boxh = (LONG)paletteGadg.Height/c_rows;
     pen = 0L;
     for (j = 0; j < c_rows; j++)
        {
          for (i=0; i < c_per_row; i++, pen++)
             {
               SetAPen(rp,pen);
               x = ((LONG)i * boxw) + (LONG)paletteGadg.LeftEdge ;
               y = ((LONG)j * boxh) + (LONG)paletteGadg.TopEdge ;
               bx = x + boxw -1L;
               by = y + boxh -1L;
               RectFill(rp,x,y,bx,by); /* fill in color box */
             }
         }
 
   }
 
/* The following routine converts the image from the UBYTE planes of */
/* the small raster bitmap to a USHORT array for the image structure */
 
struct Image *bitmapTOimage(bitmap,width,height,depth)
        struct BitMap *bitmap;
        SHORT width, height, depth;
        {
          struct Image *imptr;
          SHORT n_words, tot_words, i, temp;
          SHORT n_rows, bytes_per_row, byte, burnbytes, row;
          USHORT *dest;
          UBYTE *src;
 
          /* allocate a new image structure */
          imptr = (struct Image *)AllocRemember(
                  rememberBase,(LONG)sizeof(struct Image),
                  MEMF_CHIP | MEMF_CLEAR);
 
          if (imptr == NULL) return(NULL);
 
          /* initialize it */
          imptr->LeftEdge = 0;
          imptr->TopEdge = 0;
          imptr->Width = width;
          imptr->Height = height;
          imptr->Depth = depth;
          imptr->PlanePick = 0xFF;
          imptr->PlaneOnOff = 0;
          imptr->NextImage = NULL;
 
          /* how many words are needed for the image? */
          n_words = width/16;
          if (n_words % 16 != 0) n_words += 1;
          tot_words = n_words * (height * depth);
 
          /* allocate the word array */
          imptr->ImageData = (USHORT *)AllocRemember (
                     rememberBase,(LONG)(sizeof(USHORT) * tot_words),
                      MEMF_CHIP | MEMF_CLEAR);
          if(imptr->ImageData == NULL)
            { kputs("No room for image data - no image returned!");
              return(NULL);
            }
 
          /* OK, so we should have the memory for the image, so now */
          /* we scan the bitmap and move it to the ImageData area   */
 
          if (bitmap->Rows > height) n_rows = height;
          else n_rows = bitmap->Rows;
 
          if (bitmap->BytesPerRow > (n_words * 2))
             { bytes_per_row = n_words * 2;
               burnbytes = bitmap->BytesPerRow - bytes_per_row;
             }
          else
             { bytes_per_row = bitmap->BytesPerRow;
               burnbytes = 0;
             }
 
          dest = imptr->ImageData;
          for (i = 0; i < depth; i ++)
             {
               src = (UBYTE *)bitmap->Planes[i];
               for (row = 0; row < n_rows; row++)
                  { for (byte=0; byte < bytes_per_row; byte+=2)
                       { /* put pairs of bytes into single words */
                         temp = (USHORT) *src++;
                         temp = temp << 8;
                         temp |= (USHORT)*src++;
                         *dest++ = temp;
                        }
                     /* skip any 'dangling' bytes that aren't part of the */
                     /* image definition.                                 */
                     src += burnbytes;
                   }
              }
#ifdef DEBUG
 kputs("got to the end - returning bitmap pointer");
#endif
    return(imptr);
}
 
 
/* The following routine frees the memory allocated for an image */
/* Note - this is not called in the gadget editor. RRL           */
FreeImage(imptr)
    struct Image *imptr;
    {
     SHORT n_words, tot_words;
     if (imptr == NULL) return;
 
     n_words = imptr->Width/16;
     if (n_words % 16 != 0) n_words += 1;
     tot_words = n_words * (imptr->Height * imptr->Depth);
 
     FreeMem(imptr->ImageData,(LONG)(sizeof(USHORT) * tot_words));
     FreeMem(imptr,(LONG)sizeof(struct Image));
    }
 
/*========================================================================
  im_draw_box - Draws a box, given Left, Top, Width, Height, and a RastPort
  -- slightly modified from the draw_box in gt.c for the image editor -rrl
========================================================================*/
im_draw_box(rport, left, top, width, height, pen, tempbox)
struct RastPort *rport;
SHORT left, top, width, height;
BOOL tempbox;
LONG pen;
{
    long lf = (long)left;
    long tp = (long)top;
    long wd = (long)width;
    long hg = (long)height;
 
    if(tempbox)
      {
        SetDrMd(rport, COMPLEMENT);
        SetAPen(rport, 1L);
        SetBPen(rport, 0L);
      }
    else
      {
        SetDrMd(rport, JAM1);
        SetAPen(rport, pen);
      }
 
    Move(rport, lf, tp);
    Draw(rport, lf+wd, tp);
    Draw(rport, lf+wd, tp+hg);
    Draw(rport, lf,  tp+hg);
    Draw(rport, lf, tp);
}
 
/*========================================================================
  im_draw_line - Draws a line, given a pair of xy coords and a RastPort
========================================================================*/
im_draw_line(rport, x1, y1, x2, y2, pen, templine)
struct RastPort *rport;
SHORT x1, y1, x2, y2;
LONG pen;
BOOL templine;
{
    if(templine)
      {
        SetDrMd(rport, COMPLEMENT);
        SetAPen(rport, 1L);
        SetBPen(rport, 0L);
      }
    else
      {
        SetDrMd(rport, JAM1);
        SetAPen(rport, pen);
      }
    Move(rport, (LONG)x1,(LONG)y1);
    Draw(rport, (LONG)x2, (LONG)y2);
}
 
/*========================================================================
  im_draw_circ - Draws a circle, given a center xy coord
  the radius and a RastPort.
  -- based on Bresenham's algorithm, and redone from pascal to c
     using the version in the Turbo Pascal Graphics Library.
     Thanks Borland.
========================================================================*/
/* some constants for the circle algorithm */
SHORT circ[14]=
        {0,121,239,355,465,568,663,749,823,885,935,971,993,1000};
 
 
im_draw_circ(rp, x_c, y_c, radius, aspect, pen, templine)
struct RastPort *rp;
SHORT x_c, y_c, radius, aspect;
LONG pen;
BOOL templine;
{
    SHORT i,xk1,xk2,yk1,yk2;
    register SHORT xp1,yp1,xp2,yp2, x_center, y_center;
    register FLOAT xfact, yfact;
    FLOAT aspectfactor=0.45, aspectfl;
 
    if(radius == 0) return;
    x_center = x_c;
    y_center = y_c;
 
    if(templine)
      {
        SetDrMd(rp, COMPLEMENT);
        SetAPen(rp, 1L);
        SetBPen(rp, 0L);
      }
    else
      {
        SetDrMd(rp, JAM1);
        SetAPen(rp, pen);
      }
    aspectfl = ((FLOAT)aspect*2.1) / (FLOAT)radius;
    aspectfl = ABS(aspectfl) * aspectfactor;
    xfact = ABS(0.001 * (FLOAT)radius);
    yfact = xfact * aspectfl;
    if (xfact > 0.0)
      {
        xk1 = (SHORT)(circ[0] * xfact+0.5);
        yk1 = (SHORT)(circ[13] * yfact+0.5);
        for(i=1; i<14; i++)
           {
             xk2 = (SHORT)(circ[i]*xfact+0.5);
             yk2 = (SHORT)(circ[13 - i+1]*yfact+0.5);
             xp1 = x_center-xk1;
             yp1 = y_center+yk1;
             xp2 = x_center-xk2;
             yp2 = y_center+yk2;
             Move(rp, (LONG)xp1,(LONG)yp1);
             Draw(rp, (LONG)xp2, (LONG)yp2);
 
             xp1 = x_center+xk1;
             xp2 = x_center+xk2;
             Move(rp, (LONG)xp1,(LONG)yp1);
             Draw(rp, (LONG)xp2, (LONG)yp2);
 
             yp1 = y_center-yk1;
             yp2 = y_center-yk2;
             Move(rp, (LONG)xp1,(LONG)yp1+1);
             Draw(rp, (LONG)xp2, (LONG)yp2+1);
 
             xp1 = x_center-xk1;
             xp2 = x_center-xk2;
             Move(rp, (LONG)xp1,(LONG)yp1+1);
             Draw(rp, (LONG)xp2, (LONG)yp2+1);
 
             xk1 = xk2;
             yk1 = yk2;
           }
         }
        else
           WritePixel(rp,x_center,y_center);
  }