(*
 * Title:    drawmod.h
 * Purpose:  C interface to the Draw module
 *
 *)


(*
 * This file provides an interface to the Draw module (not to be confused
 * with the !Draw application). It defines a number of types used for
 * PostScript-like operations (with enhancements). The enhancements consist
 * mainly of choice of fill style (fill including/excluding boundary etc),
 * extra winding numbers, differing "leading"/"trailing" line caps and
 * triangular line caps. It calls the Draw SWIs.
 *
 *)

#ifndef __drawmod_h
#define __drawmod_h

#ifndef __os_h
#include "os.h"
#endif

#ifndef __drawftypes_h
#include "drawftypes.h"
#endif

(************************** Definition of a path **************************)

const     path_term      = 0;   (* end of path                  *)
          path_ptr       = 1;   (* pointer to path continuation *)
          path_move_2    = 2;   (* move to (x,y) -- new subpath *)
                                (* affects winding numbers      *)
          path_move_3    = 3;   (* move to (x,y) -- new subpath *)
                                (* winding numbers unaffected   *)
                                (* (used internally)            *)
          path_closegap  = 4;   (* close current subpath with   *)
                                (* a gap                        *)
          path_closeline = 5;   (* close current subpath with   *)
                                (* a line                       *)
          path_bezier    = 6;   (* Bezier curve to (x3,y3) with *)
                                (* control points at (x1,y1)    *)
                                (* and (x2,y2)                  *)
          path_gapto     = 7;   (* gap to (x,y), not starting   *)
                                (* new subpath (used internally)*)
          path_lineto    = 8;   (* line to (x,y)                *)

type drawmod_path_tagtype = integer;

type drawmod_path_endstr_ptr = ^drawmod_path_endstr;
     drawmod_path_endstr =            (* end of path element *)
       record
         tag : drawmod_path_tagtype;
         bytes_free : integer
       end;

type drawmod_path_ptrstr_ptr = ^drawmod_path_ptrstr;
     drawmod_path_ptrstr =            (* continuation ptr element *)
       record
         tag : drawmod_path_tagtype;
         ptr : pointer
       end;

type drawmod_path_movestr_ptr = ^drawmod_path_movestr;
     drawmod_path_movestr =           (* move2/move3 element *)
       record
         tag : drawmod_path_tagtype;
         x, y : integer
       end;

type drawmod_path_closegapstr_ptr = ^drawmod_path_closegapstr;
     drawmod_path_closegapstr =       (* close with gap element *)
       record
         tag : drawmod_path_tagtype
       end;

type drawmod_path_closelinestr_ptr = ^drawmod_path_closelinestr;
     drawmod_path_closelinestr =      (* close with line element *)
       record
         tag : drawmod_path_tagtype
       end;

type drawmod_path_bezierstr_ptr = ^drawmod_path_bezierstr;
     drawmod_path_bezierstr =         (* Bezier curve element *)
       record
         tag : drawmod_path_tagtype;
         x1, y1 : integer;            (* control point (x1,y1) *)
         x2, y2 : integer;            (* control point (x2,y2) *)
         x3, y3 : integer             (* end point (x3,y3)     *)
       end;

type drawmod_path_gaptostr_ptr = ^drawmod_path_gaptostr;
     drawmod_path_gaptostr =          (* gap to (x,y) element *)
       record
         tag : drawmod_path_tagtype;
         x, y : integer
       end;

type drawmod_path_linetostr_ptr = ^drawmod_path_linetostr;
     drawmod_path_linetostr =         (* line to (x,y) element *)
       record
         tag : drawmod_path_tagtype;
         x, y : integer
       end;

type drawmod_pathelemptr_tag = 0..10;
     drawmod_pathelemptr_ptr = ^drawmod_pathelemptr;
     drawmod_pathelemptr =            (* pointer to a path element *)
       record
         case drawmod_pathelemptr_tag of
           0 : (_end : drawmod_path_endstr_ptr);
           1 : (ptr : drawmod_path_ptrstr_ptr);
           2 : (move2 : drawmod_path_movestr_ptr);
           3 : (move3 : drawmod_path_movestr_ptr);
           4 : (closegap : drawmod_path_closegapstr_ptr);
           5 : (closeline : drawmod_path_closelinestr_ptr);
           6 : (bezier : drawmod_path_bezierstr_ptr);
           7 : (gapto : drawmod_path_gaptostr_ptr);
           8 : (lineto : drawmod_path_linetostr_ptr);
           9 : (bytep : ^byte);
          10 : (wordp : ^integer)
       end;

(****************************** fill type **********************************)

const     fill_Default        = $00000000;   (* default fill style - "fill to
                                              * halfway through boundary,
                                              * non-zero winding rule"
                                              * NOTE: if used this should not
                                              * be ORed with any other types
                                              *)
          fill_WNonzero       = $00000000;   (* non-zero winding rule *)
          fill_WNegative      = $00000001;   (* negative   "       "  *)
          fill_WEvenodd       = $00000002;   (* even-odd   "       "  *)
          fill_WPositive      = $00000003;   (* positve    "       "  *)

          fill_FNonbext       = $00000004;   (* plot non-boundary exterior
                                              * pixels
                                              *)
          fill_FBext          = $00000008;   (* plot boundary exterior
                                              * pixels
                                              *)
          fill_FNonbint       = $00000010;   (* plot boundary interior
                                              * pixels
                                              *)
          fill_FBint          = $00000020;   (* plot non-boundary interior
                                              * pixels
                                              *)
                (**************************************
                 **************** NOTE ****************
                 * The following should only be used in 
                 * drawmod_processpath.
                 **************************************
                 **************************************
                 *)

          fill_PClose         = $08000000;   (* close open subpaths *)
          fill_PFlatten       = $10000000;   (* flatten the path *)
          fill_PThicken       = $20000000;   (* thicken the path *)
          fill_PReflatten     = $40000000;   (* re-flatten the path *)
 
                                             (* NOTE: floating point not
                                              * supported so no $80000000.
                                              *)

type drawmod_filltype_ptr = ^drawmod_filltype;
     drawmod_filltype = integer;

(************************** line cap and join specs ************************)

type drawmod_capjoinspec_ptr = ^drawmod_capjoinspec;
     drawmod_capjoinspec =
       record
         join : byte;                (* join style *)
         leadcap : byte;             (* leading cap style *)
         trailcap : byte;            (* trailing cap style *)
         reserved8 : byte;           (* must be zero *)
         mitrelimit : integer;       (* limit for mitred joins *)
         lead_tricap_w : short;      (* "width" of leading triangular
                                      * caps
                                      *)
         lead_tricap_h : short;      (* "height of leading triangular
                                      * caps
                                      *)
         trail_tricap_w : short;     (* "width" of trailing triangular
                                      * caps
                                      *)
         trail_tricap_h : short      (* "height" of trailing 
                                      * triangular caps
                                      *)
       end;

(***************************** dash patterns *******************************)
(*
 * NOTE: This is the "header" for a dash pattern. It should be followed
 * immediately in memory by the dash pattern itself. Each element of the
 * dash pattern is a distance.
 *)
type drawmod_dashhdr_ptr = ^drawmod_dashhdr;
     drawmod_dashhdr =
       record
         dashstart : integer;   (* distance into dash pattern to start *)
         dashcount : integer    (* number of elements in the dash pattern *)
       end;

(***************************** Line attributes *****************************)
(*
 * A line can have the following attributes:
 *            Flatness:  given in user coords (0 means default == 2 OS units)
 *            Thickness: 0 means one pixel wide, with line caps/joins
 *                       ignored
 *            Cap and Join specification: deals with joins and leading/
 *                                        trailing caps.
 *                                        see #defines in the line and cap
 *                                        spec section above for their 
 *                                        permissible values.
 *            Dash pattern:  A contiguous block of memory, consisting of
 *                           a header followed by a number of dash pattern
 *                           elements.
 *
 *)
type drawmod_line_ptr = ^drawmod_line;
     drawmod_line =
       record
         flatness : integer;
         thickness : integer;
         spec : drawmod_capjoinspec;
         dash_pattern : drawmod_dashhdr_ptr
       end;
          

(*************************** transformation matrix *************************)
(*
 * The transformation matrix has six elements (say a,b,c,d,e,f), where 
 * elements appear in the standard matrix thus:
 *                ( a b 0 )
 *                ( c d 0 )
 *                ( e f 1 )
 * a,b,c,d should be considered as having 16 binary places (ie. 0x10000 is
 * given to represent 1.0); e and f represent a translation in output units
 *
 *) 
type drawmod_transmat_ptr = ^drawmod_transmat;
     drawmod_transmat = array[0..5] of integer;


(******************************* path buffer *******************************)
(*
 * This data type is used both as an input path buffer and an output path
 * buffer header. Typically, you should allocate enough space for your path
 * and then set a variable of type drawmod_buffer* to point at it.
 * NOTE that on passing to functions in this module which take a
 * drawmod_buffer* parameter, field zeroword should contain 0,and
 * sizeword should indicate how many bytes follow in memory.
 *
 *)
type drawmod_buffer_ptr = ^drawmod_buffer;
     drawmod_buffer =
       record
         zeroword : integer;
         sizeword : integer
       end;
          

(**************************** options for process path *********************)

const       tag_fill = 1;
            tag_box  = 2;
            tag_buf  = 3;

type drawmod_tagtype = 1..3;


const       option_insitu      = 0;  (* output path to input path *)
            option_normalfill  = 1;  (* fill normally *)
            option_subpathfill = 2;  (* fill subpath by subpath *)
            option_countsize   = 3;  (* count size of required buffer *)

type drawmod_filling_options = integer;

type drawmod_box_ptr = ^drawmod_box;
     drawmod_box =
       record
         lowX, lowY : integer;
         highX, highY : integer
       end;

type drawmod_options_ptr = ^drawmod_options;
     drawmod_options =
       record
         case tag : drawmod_tagtype of
           1 : (opts : drawmod_filling_options);
           2 : (box : drawmod_box_ptr); (* pointer to word-aligned, four-word
                                         * area to hold bounding box of
                                         * processed path.
                                         *)
           3 : (buffer : drawmod_buffer_ptr)
       end;
           

(* ----------------------------- drawmod_fill ------------------------------
 * Description:   Emulate Postscript "fill" operator - ie. close open 
 *                subpaths, flatten the path, transform it to standard coords
 *                and fill the result.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_filltype fill_style - style of fill
 *                drawmod_transmat *matrix - transformation matrix
 *                                           (0 for the identity matrix)
 *                int flatness - flatness in user coords (0 means default)
 *
 * Returns:       possible error condition
 * Other Info:    none.
 *
 *)
procedure drawmod_fill(path_seq : drawmod_pathelemptr;
                fill_style : drawmod_filltype;
                matrix : drawmod_transmat_ptr;
                flatness : integer) : os_error; extern;


(* -------------------------- drawmod_stroke -------------------------------
 * Description:   Emulate PostScript "stroke" operator.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_filltype fill_style - style of fill
 *                drawmod_transmat *matrix - transformation matrix
 *                                           (0 means identity matrix)
 *                drawmod_line *line_style - (see typedef above for details)
 *
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_stroke(path_seq : drawmod_pathelemptr;
                fill_style : drawmod_filltype;
                matrix : drawmod_transmat_ptr;
                line_style : drawmod_line_ptr) : os_error; extern;


(* -------------------------- drawmod_do_strokepath ------------------------
 * Description:   Puts path through all stages of drawmod_stroke except the
 *                final fill. Resulting path is placed in the buffer.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_transmat *matrix - transformation matrix
 *                drawmod_line *line_style - (see typedef above for details)
 *                drawmod_buffer *buffer - buffer to hold stroked path. 
 * Returns:       possible error condition
 * Other Info:    none.
 *
 *)
procedure drawmod_do_strokepath(path_seq : drawmod_pathelemptr;
                matrix : drawmod_transmat_ptr;
                line_style : drawmod_line_ptr;
                buffer : drawmod_buffer_ptr) : os_error; extern;


(* ------------------------ drawmod_ask_strokepath -------------------------
 * Description:   Puts path through all stages of drawmod_stroke, except the
 *                fill, and returns the size of buffer needed to hold such
 *                a path.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_transmat *matrix - transformation matrix
 *                drawmod_line *line_style - (see typedef above for details)
 *                int *buflen - returned length of required buffer.
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_ask_strokepath(path_seq : drawmod_pathelemptr;
                matrix : drawmod_transmat_ptr;
                line_style : drawmod_line_ptr;
                var buflen : integer) : os_error; extern;


(* -------------------------- drawmod_do_flattenpath -----------------------
 * Description:   Flatten the given path, and put into the supplied buffer.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drwamod_buffer *buffer - buffer to hold flattened path
 *                int flatness - required flatness.
 *
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_do_flattenpath(path_seq : drawmod_pathelemptr;
                buffer : drawmod_buffer_ptr;
                flatness : integer) : os_error; extern;


(* -------------------------- drawmod_ask_flattenpath ----------------------
 * Description:   Put the given path through the stages of 
 *                drawmod_flattenpath and return the size of buffer needed
 *                to hold the resulting path.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                int flatness - required flatness.
 *                int *buflen - returned length of required buffer.
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_ask_flattenpath(path_seq : drawmod_pathelemptr;
                flatness : integer;
                var buflen : integer) : os_error; extern;


(* -------------------------- drawmod_buf_transformpath --------------------
 * Description:   Put a path through a transformation matrix, and put the
 *                result in the supplied buffer.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequenec of path elements
 *                drawmod_buffer *buffer - buffer to hold transformed path
 *                drawmod_transmat *matrix - the transformation matrix.
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_buf_transformpath(path_seq : drawmod_pathelemptr;
                buffer : drawmod_buffer_ptr;
                matrix : drawmod_transmat_ptr) : os_error; extern;
                                                       

(* ----------------------- drawmod_insitu_transformpath --------------------
 * Description:   Put a path through a transformation matrix, by modifying
 *                the supplied path itself.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_transmat *matrix - the transformation matrix.
 * Returns:       possible error condition.
 * Other Info:    none.
 *
 *)
procedure drawmod_insitu_transformpath(path_seq : drawmod_pathelemptr;
                matrix : drawmod_transmat_ptr) : os_error; extern;


(* -------------------------- drawmod_processpath --------------------------
 * Description:   Put the path through a set of processes used when doing
 *                Stroke and Fill.
 *
 * Parameters:    drawmod_pathelemptr path_seq - sequence of path elements
 *                drawmod_filltype fill_style - style of fill
 *                drawmod_transmat *matrix - the transformation matrix
 *                drawmod_line *line_style - (see typedef above for details)
 *                drawmod_options *options - this can have the values
 *                                           detailed below. Note: pass in 
 *                                           address of a draw_options struct
 *                int *buflen - returned length of required buffer
 *                              (only used when options->tagtype==tag_fill
 *                               && options->data.opts == option_countsize).  * Returns:       possible error condition.
 * Other Info:    Possible values for options:
 *                     drawmod_insitu: output to the input path
 *                                     (only if path size wouldn't change)
 *                     drawmod_fillnormal : fill path normally
 *                     drawmod_fillsubpath : fill path, subpath by subpath
 *                  OR an address : output bounding box of path to the
 *                                  word-aligned address, and three next
 *                                  words, with word-order lowX, lowY, 
 *                                  highX, highY
 *                  OR a buffer to hold processed path.
 *
 *)
procedure drawmod_processpath(path_seq : drawmod_pathelemptr;
                fill_style : drawmod_filltype;
                matrix : drawmod_transmat_ptr;
                line_style : drawmod_line_ptr;
                options : drawmod_options_ptr;
                var buflen : integer) : os_error; extern;

#endif

(* end drawmod.h *)
