/*-> h.DrawFile1 */
/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the "DrawFile" library for rendering RISCOS Draw files from applications *
 * in C. It may be used freely in the creation of programs for Archimedes.  *
 * It should be used with Acorn's C Compiler Release 2 or later.            *
 *                                                                          *
 * No support can be given to programmers using this code and, while we     *
 * believe that it is correct, no correspondence can be entered into        *
 * concerning behaviour or bugs.                                            *
 *                                                                          *
 * Upgrades of this code may or may not appear, and while every effort will *
 * be made to keep such upgrades upwards compatible, no guarantees can be   *
 * given.                                                                   *
 ***************************************************************************/

/* -> h.DrawFile1 : general internal header for DrawFile module
 *
 * History:
 * Version 0.0: 22 Nov 88, DAHE: created
 * Version 0.1: 23 Nov 88, DAHE: first working version
 * Version 0.2: 15 Feb 89, DAHE: merged with stubs of other Draw headers
 *
 * Intended only to be included by the DrawFile code itself, not by clients
 * of the module.
 *
 * Header defining object types and some functions - normally to be included
 * before DrawLevel0 and DrawLevel1, if they are present.
 */

/* Macros for setting errors */
#define DrawFile_Error(Code, Location) {error->type=DrawOwnError; \
 error->err.draw.code=Code;error->err.draw.location=Location;}

#define DrawFile_OSError(error, Err) \
  {error->type=DrawOSError;error->err.os=Err;}

/*============================================================================*/

/* The following part of the file is extracted from h.draw. */


#define majorformatversionstamp 201
#define minorformatversionstamp 0

/* Macros for converting between units, for text */
#define draw_pointsToDraw(pp)  ((pp) * 640)
#define draw_pointsToFont(pp)  ((pp) * 1000)
#define draw_drawToFont(xx)    ((25 * (xx)) / 16)
#define draw_fontToDraw(xx)    ((16 * (xx)) / 25)
#define draw_fontToOS(xx)      ((xx) / 400)

#define TRANSPARENT 0xFFFFFFFF  /* Special, all other colours are */

/* Draw module SWI numbers */
#define Draw_Fill          0x00060702     /* XDraw_Fill        */
#define Draw_Stroke        0x00060704     /* XDraw_Stroke      */


typedef int draw_sizetyp;
typedef struct { int x0,y0, x1,y1; } draw_bboxtyp;
typedef int draw_coltyp;
typedef int draw_pathwidth;   /* 1 word */


typedef enum
{ join_mitred   = 0,
  join_round    = 1,
  join_bevelled = 2
} draw_jointyp;

typedef enum
{ cap_butt     = 0,
  cap_round    = 1,
  cap_square   = 2,
  cap_triangle = 3
} draw_captyp;

typedef enum
{ wind_nonzero = 0,
  wind_evenodd = 1
} draw_windtyp;

typedef enum
{ dash_absent  = 0,
  dash_present = 1
} draw_dashtyp;

#define packmask_join     0x03
#define packmask_endcap   0x0C
#define packmask_startcap 0x30
#define packmask_windrule 0x40
#define packmask_dashed   0x80
#define packshft_join        0
#define packshft_endcap      2
#define packshft_startcap    4
#define packshft_windrule    6
#define packshft_dashed      7


typedef struct
{ unsigned char joincapwind;       /* 1 byte  */ /* bit 0..1 join         */
                                                 /* bit 2..3 end cap      */
                                                 /* bit 4..5 start cap    */
                                                 /* bit 6    winding rule */
                                                 /* bit 7    dashed       */
  unsigned char reserved8;         /* 1 byte  */
  unsigned char tricapwid;         /* 1 byte  */ /* 1/16th of line width */
  unsigned char tricaphei;         /* 1 byte  */ /* 1/16th of line width */
} draw_pathstyle;


typedef char draw_fontref;    /* 1 byte */


typedef struct
{ draw_fontref fontref;             /* 1 byte  */
  char         reserved8;           /* 1 byte  */
  short        reserved16;          /* 2 bytes */
} draw_textstyle;   /* 1 word */

typedef unsigned int draw_fontsize;  /* 4 bytes, unsigned */

typedef int coord;

typedef struct
{ int typeface;     /* index into fontname table */
  int typesizex;
  int typesizey;
  draw_coltyp textcolour;    /* text colour RGB */
  draw_coltyp background;    /* hint for anti-aliased printing RGB */
} fontrec;

typedef enum
{ draw_OBJFONTLIST = 0,
  draw_OBJTEXT     = 1,
  draw_OBJPATH     = 2,
/*draw_OBJRECT     = 3,*/
/*draw_OBJELLI     = 4,*/
  draw_OBJSPRITE   = 5,
  draw_OBJGROUP    = 6,
  draw_OBJTAGG     = 7, 
  draw_OBJTEXTAREA = 9,
  draw_OBJTEXTCOL  = 10
} draw_tagtyp;

typedef struct { int x,y; } draw_objcoord;

/* ------------------------------------------------------------------------- */
/*                                                                           */
/* File header                                                               */
/*                                                                           */

typedef struct
{ char title[4];
  int  majorstamp;
  int  minorstamp;
  char progident[12];
  draw_bboxtyp   bbox;      /* 4 words */
} draw_fileheader;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* General header for graphic objects - on other objects, tag & size exist   */
/*                                      other fields are unused and may not  */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */
  draw_sizetyp   size;      /* 1 word  */
  draw_bboxtyp   bbox;      /* 4 words */
} draw_objhdr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A font list                                                               */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */
  draw_sizetyp   size;      /* 1 word  */
} draw_fontliststrhdr;

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */
  draw_sizetyp   size;      /* 1 word  */

  draw_fontref   fontref;
  char           fontname[1];   /* String, null terminated */
} draw_fontliststr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A line of text                                                            */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  draw_coltyp    textcolour; /* 1 word  */
  draw_coltyp    background; /* 1 word  */
  draw_textstyle textstyle;  /* 1 word  */
  draw_fontsize  fsizex;     /* 1 word, unsigned */
  draw_fontsize  fsizey;     /* 1 word, unsigned */
  draw_objcoord  coord;      /* 2 words */
} draw_textstrhdr;

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  draw_coltyp    textcolour; /* 1 word  */
  draw_coltyp    background; /* 1 word  */
  draw_textstyle textstyle;  /* 1 word  */
  draw_fontsize  fsizex;     /* 1 word, unsigned */
  draw_fontsize  fsizey;     /* 1 word, unsigned */
  draw_objcoord  coord;      /* 2 words */

  char           text[1];   /* String, null terminated */
} draw_textstr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* Elements within a path                                                    */
/*                                                                           */

typedef enum
 { Draw_PathTERM  = 0,     /* end of path                                   */
   Draw_PathMOVE  = 2,     /* move to (x,y), starts new subpath             */
   Draw_PathLINE  = 8,     /* line to (x,y)                                 */
   Draw_PathCURVE = 6,     /* bezier curve to (x3,y3) with 2 control points */
   Draw_PathCLOSE = 5      /* close current subpath with a line             */
} draw_path_tagvalue;


typedef struct
{ unsigned char tag;          /* 1 byte  */   /* of draw_path_tagvalue */
  char          reserved8;    /* 1 byte  */
  short         reserved16;   /* 2 bytes */
} draw_path_tagtype;


typedef struct { draw_path_tagtype tag; int x,y; } path_movestr;

typedef struct { draw_path_tagtype tag; int x,y; } path_linestr;

typedef struct { draw_path_tagtype tag; int x1,y1;
                                        int x2,y2; int x3,y3; } path_curvestr;

typedef struct { draw_path_tagtype tag; } path_closestr;

typedef struct { draw_path_tagtype tag; } path_termstr;

typedef union           /* Use ONLY for space checking purposes */
{ path_movestr a;path_linestr b;path_curvestr c;path_closestr d;path_termstr e;
} largest_path_str;


typedef union
{ path_movestr  *move;
  path_linestr  *line;
  path_curvestr *curve;
  path_closestr *close;
  path_termstr  *term;

  char *bytep;
  int  *wordp;
} path_eleptr;



/* ------------------------------------------------------------------------- */
/*                                                                           */
/* Optional dashpattern                                                      */
/*                                                                           */

typedef struct
{ int dashstart;       /* 1 word */           /* distance into pattern */
  int dashcount;       /* 1 word */           /* number of elements    */
} draw_dashstrhdr;

typedef struct
{ int dashstart;       /* 1 word */           /* distance into pattern */
  int dashcount;       /* 1 word */           /* number of elements    */
  int dashelements[6]; /* dashcount words */  /* elements of pattern   */
} draw_dashstr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* Unpacked joint,start cap,end cap structure - as fed to draw_stroke etc    */
/*                                                                           */

typedef struct
{ char join;
  char endcap;
  char startcap;
  char reserved;  /* must be zero */
  int  mitrelimit;
  short endtricapwid;
  short endtricaphei;
  short starttricapwid;
  short starttricaphei;
} draw_jointspec;


typedef struct
{ draw_pathwidth linewidth;
  draw_coltyp    linecolour;
  draw_coltyp    fillcolour;

  draw_dashstr* pattern;
  draw_jointyp  join;       /* 1 byte  */
  draw_captyp   endcap;     /* 1 byte  */
  draw_captyp   startcap;   /* 1 byte  */
  draw_windtyp  windrule;   /* 1 byte  */
  int           tricapwid;
  int           tricaphei;
} pathrec;



/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A path                                                                    */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  draw_coltyp    fillcolour; /* 1 word  */
  draw_coltyp    pathcolour; /* 1 word  */
  draw_pathwidth pathwidth;  /* 1 word  */
  draw_pathstyle pathstyle;  /* 1 word  */
} draw_pathstrhdr;

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  draw_coltyp    fillcolour; /* 1 word  */
  draw_coltyp    pathcolour; /* 1 word  */
  draw_pathwidth pathwidth;  /* 1 word  */
  draw_pathstyle pathstyle;  /* 1 word  */

  draw_dashstr data;      /* optional dash pattern, then path elements */
 int PATH;
} draw_pathstr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A rectangle T.B.A                                                         */
/*                                                                           */


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* An ellipse T.B.A                                                          */
/*                                                                           */


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A sprite                                                                  */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */  /* NB fileIO_xxx routines assume  */
  draw_sizetyp   size;      /* 1 word  */  /*    a draw_spristrhdr is all    */
  draw_bboxtyp   bbox;      /* 4 words */  /*    that needs adding to change */
} draw_spristrhdr;

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */
  draw_sizetyp   size;      /* 1 word  */
  draw_bboxtyp   bbox;      /* 4 words */
  sprite_header  sprite;
  int            palette[1]; /* depends on sprite.mode (or not present) */
} draw_spristr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A grouping                                                                */
/*                                                                           */

typedef struct { char ch[12]; } draw_groupnametyp;  /* 12 bytes */

typedef struct
{ draw_tagtyp       tag;   /* 1 word   */
  draw_sizetyp      size;  /* 1 word   */
  draw_bboxtyp      bbox;  /* 4 words  */
  draw_groupnametyp name;  /* 12 bytes */
} draw_groustr;

/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A tagged object T.B.A                                                     */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */  /* NB fileIO_xxx routines assume  */
  draw_sizetyp   size;      /* 1 word  */  /*    a draw_spristrhdr is all    */
  draw_bboxtyp   bbox;      /* 4 words */  /*    that needs adding to change */
} draw_taggstrhdr;

typedef struct
{ draw_tagtyp    tag;       /* 1 word  */
  draw_sizetyp   size;      /* 1 word  */
  draw_bboxtyp   bbox;      /* 4 words */
} draw_taggstr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A text column                                                             */
/*                                                                           */
/* These only appear nested within a text area                               */

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
} draw_textcolhdr;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A text area object (new style)                                            */
/*                                                                           */
/*                                                                           */

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  draw_textcolhdr column;    /* Hook for pointing to text columns */
} draw_textareastrhdr;

typedef struct
{ draw_tagtyp    tag;        /* 1 word  */
  draw_sizetyp   size;       /* 1 word  */
  draw_bboxtyp   bbox;       /* 4 words */
  /* Text columns go in here */
} draw_textareahdr;

/* End structure - follows all the column */
typedef struct               /* Structure for getting size */
{
  int            endmark;    /* 1 word, always 0 */
  int            blank1;     /* 1 word, reserved for future expansion */
  int            blank2;     /* 1 word, reserved for future expansion */
  draw_coltyp    textcolour; /* 1 word */
  draw_coltyp    backcolour; /* 1 word */
  /* String goes in here */
} draw_textareastrend;

typedef struct
{
  int            endmark;    /* 1 word, always 0 */
  int            blank1;     /* 1 word, reserved for future expansion */
  int            blank2;     /* 1 word, reserved for future expansion */
  draw_coltyp    textcolour; /* 1 word */
  draw_coltyp    backcolour; /* 1 word */
  char           text[1];    /* String, null terminated */
} draw_textareaend;


/* ------------------------------------------------------------------------- */
/*                                                                           */
/* A type that can point at any object or its sub-components                 */
/*                                                                           */

typedef union
{ draw_objhdr         *objhdrp;

  draw_fileheader     *filehdrp;

  draw_fontliststrhdr *fontlisthdrp;
  draw_textstrhdr     *texthdrp;
  draw_pathstrhdr     *pathhdrp;
  draw_spristrhdr     *spritehdrp;
  draw_taggstrhdr     *tagghdrp;
  draw_textareastrhdr *textareastrp;
  draw_textareastrend *textareastrendp;

  draw_fontliststr    *fontlistp;
  draw_textstr        *textp;
  draw_pathstr        *pathp;
  draw_spristr        *spritep;
  draw_groustr        *groupp;
  draw_taggstr        *taggp;
  draw_textareahdr    *textareap;
  draw_textareaend    *textareaendp;
  draw_textcolhdr     *textcolp;

  draw_objcoord   *coordp;      /* ? is this used ? */

  char *bytep;
  int  *wordp;
} draw_objptr;


typedef struct      /* cached values read by bbc_vduvars, so ordering */ 
                    /* is important, see cache_currentmodevars        */      
{
  int gcharaltered; /* flag set if ArcDraw changes the system font size */

  int gcharsizex;   /* if so, restore from here */  /* first cached value */
  int gcharsizey;
  int gcharspacex;
  int gcharspacey;
 
  int ncolour;
  int xeigfactor;
  int yeigfactor;                                   /* last cached value  */

  int pixsizex;     /* in dBase coords, ie 0x100 << xeigfactor */
  int pixsizey;     /* in dBase coords, ie 0x100 << yeigfactor */
} currentmodestr;

extern currentmodestr currentmode;

path_movestr *address_pathstart(draw_objptr hdrptr);
draw_dashstr *address_dashstart(draw_objptr hdrptr);

#define xscaledown(A) ((int)((double)((A)<<8)/(xscalefactor)))
#define yscaledown(A) ((int)((double)((A)<<8)/(yscalefactor)))


/*============================================================================*/

/* The following part of the file is extracted from h.drawDispl. */

extern double xdr_scalefactor;
extern double ydr_scalefactor;

void note_fontcat(draw_objptr hdrptr);

/*============================================================================*/

/* The following part of the file is extracted from h.drawMenu. */

typedef struct
{ int menu_size;        /* Number found on start up                        */
  int list_size;        /* Same or includes extra found from file fontlist */
  char* name[256];      /* Space for names is malloced, so it won't move   */
} fontcatstr;

extern fontcatstr fontcat;

/*============================================================================*/

/* The following part of the file is extracted from h.drawTextC. */

/* Current version of text columns */
#define draw_text_VERSION 1

os_error *do_objtextcol
         (draw_objptr hdrptr, int orgx, int orgy, draw_bboxtyp *clip);
os_error *do_objtextarea
         (draw_objptr hdrptr, int orgx,int orgy, draw_bboxtyp *clip);

BOOL draw_verifyTextArea(char *text, int *errcode, char **location,
                         int *columns);


/*============================ Private functions ============================*/

/* Functions defined in c.drawLevel0 or c.drawLevel1 */
void dr_spaceCopy(char *to, char *from, int length);
void dr_unifyBoxes(draw_bboxtyp *box1, draw_bboxtyp *box2);

/* Functions defined in c.drawCheck */
BOOL check_Draw_file(char *buffer, int length, int *code, int *location);
BOOL check_Draw_object(draw_objptr object, int *code, int *location);
void shift_Draw_file(char *buffer, int length, int xMove, int yMove);

/* Function defined in c.drawFiles */
os_error *displ_setVDU5charsize(int xsize,int ysize, int xspace,int yspace);
