#ifndef draw_H
#define draw_H

/* C header file for Draw
 * Written by DefMod (Dec  9 2012) on Sun Dec  9 15:46:01 2012
 * Jonathan Coxhead, jonathan@doves.demon.co.uk, 21 Aug 1995
 */

/* OSLib---efficient, type-safe, transparent, extensible,
 * register-safe API coverage of RISC OS
 * 
 * Copyright (c) 1994-2012 Jonathan Coxhead and OSLib maintainers
 * 
 * Licence:
 * 
 *    OSLib is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 1, or (at your option)
 * any later version - and this with the following clarification and
 * special exception:
 * 
 *    Linking this library statically or dynamically with other modules
 * is making a combined work based on this library. Thus, the terms
 * and conditions of the GNU General Public License cover the whole
 * combination.
 * 
 *    As a special exception, the copyright holders of this library
 * give you permission to link this library with independent modules
 * to produce an executable, regardless of the license terms of these
 * independent modules, and to copy and distribute the resulting
 * executable under terms of your choice, provided that you also meet,
 * for each linked independent module, the terms and conditions of the
 * license of that module. An independent module is a module which is
 * not derived from or based on this library. If you modify this
 * library, you may extend this exception to your version of the library,
 * but you are not obliged to do so. If you do not wish to do so, delete
 * this exception statement from your version.
 * 
 *    OSLib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 *    You should have received a copy of the GNU General Public License
 * along with this programme; if not, write to the Free Software
 * Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef types_H
#include "oslib/types.h"
#endif

#ifndef os_H
#include "oslib/os.h"
#endif

#if defined NAMESPACE_OSLIB
  namespace OSLib {
#endif

/**********************************
 * SWI names and SWI reason codes *
 **********************************/
#undef  Draw_ProcessPath
#define Draw_ProcessPath                        0x40700
#undef  XDraw_ProcessPath
#define XDraw_ProcessPath                       0x60700
#undef  Draw_Fill
#define Draw_Fill                               0x40702
#undef  XDraw_Fill
#define XDraw_Fill                              0x60702
#undef  Draw_Stroke
#define Draw_Stroke                             0x40704
#undef  XDraw_Stroke
#define XDraw_Stroke                            0x60704
#undef  Draw_StrokePath
#define Draw_StrokePath                         0x40706
#undef  XDraw_StrokePath
#define XDraw_StrokePath                        0x60706
#undef  Draw_FlattenPath
#define Draw_FlattenPath                        0x40708
#undef  XDraw_FlattenPath
#define XDraw_FlattenPath                       0x60708
#undef  Draw_TransformPath
#define Draw_TransformPath                      0x4070A
#undef  XDraw_TransformPath
#define XDraw_TransformPath                     0x6070A
#undef  Draw_FillClipped
#define Draw_FillClipped                        0x4070C
#undef  XDraw_FillClipped
#define XDraw_FillClipped                       0x6070C
#undef  Draw_StrokeClipped
#define Draw_StrokeClipped                      0x4070E
#undef  XDraw_StrokeClipped
#define XDraw_StrokeClipped                     0x6070E
#undef  DrawV
#define DrawV                                   0x20

/************************************
 * Structure and union declarations *
 ************************************/
typedef struct draw_path_element                draw_path_element;
typedef struct draw_line_style                  draw_line_style;
typedef struct draw_dash_pattern                draw_dash_pattern;
typedef struct draw_dash_pattern_base           draw_dash_pattern_base;
typedef struct draw_path                        draw_path;
typedef struct draw_clip_descriptor             draw_clip_descriptor;

/********************
 * Type definitions *
 ********************/
typedef byte draw_tag;

typedef bits draw_fill_style;

typedef byte draw_join_style;

typedef byte draw_cap_style;

typedef draw_path *draw_output_path;

struct draw_path_element
   {  draw_tag tag;
      byte reserved [3];
      union
      {  int end_path;
         draw_path_element *continuation;
         os_coord move_to;
         os_coord special_move_to;
         os_coord bezier_to [3];
         os_coord gap_to;
         os_coord line_to;
         byte reserved [24];
      }
      data;
   };

struct draw_line_style
   {  draw_join_style join_style;
      draw_cap_style end_cap_style;
      draw_cap_style start_cap_style;
      byte reserved;
      int mitre_limit;
      short start_cap_width;
      short start_cap_length;
      short end_cap_width;
      short end_cap_length;
   };

#define draw_DASH_PATTERN_MEMBERS \
   int start; \
   int element_count;

/* Base draw_dash_pattern structure without variable part */
struct draw_dash_pattern_base
   {  draw_DASH_PATTERN_MEMBERS
   };

/* legacy structure */
struct draw_dash_pattern
   {  draw_DASH_PATTERN_MEMBERS
      int elements [UNKNOWN];
   };

#define draw_DASH_PATTERN(N) \
   struct \
      {  draw_DASH_PATTERN_MEMBERS \
         int elements [N]; \
      }

#define draw_SIZEOF_DASH_PATTERN(N) \
   (offsetof (draw_dash_pattern, elements) + \
         (N)*sizeof ((draw_dash_pattern *) NULL)->elements)

struct draw_path
   {  draw_path_element elements [UNKNOWN];
   };

struct draw_clip_descriptor
   {  draw_path *path;
      draw_fill_style fill_style;
      os_trfm trfm;
   };

typedef int drawv_reason;

/************************
 * Constant definitions *
 ************************/
#define draw_OS_UNIT                            (256)
      /*1 OS unit in draw units*/
#define draw_INCH                               (46080)
      /*1in in draw units*/
#define draw_POINT                              (640)
      /*1pt in draw units*/
#define draw_END_PATH                           ((draw_tag) 0x0u)
#define draw_CONTINUATION                       ((draw_tag) 0x1u)
#define draw_MOVE_TO                            ((draw_tag) 0x2u)
#define draw_SPECIAL_MOVE_TO                    ((draw_tag) 0x3u)
#define draw_CLOSE_GAP                          ((draw_tag) 0x4u)
#define draw_CLOSE_LINE                         ((draw_tag) 0x5u)
#define draw_BEZIER_TO                          ((draw_tag) 0x6u)
#define draw_GAP_TO                             ((draw_tag) 0x7u)
#define draw_LINE_TO                            ((draw_tag) 0x8u)
#define draw_FILL_NONZERO                       ((draw_fill_style) 0x0u)
#define draw_FILL_NEGATIVE                      ((draw_fill_style) 0x1u)
#define draw_FILL_EVEN_ODD                      ((draw_fill_style) 0x2u)
#define draw_FILL_POSITIVE                      ((draw_fill_style) 0x3u)
#define draw_FILL_WINDING_RULE_SHIFT            (0)
#define draw_FILL_WINDING_RULE                  ((draw_fill_style) 0x3u)
#define draw_FILL_FULL_EXTERIOR                 ((draw_fill_style) 0x4u)
#define draw_FILL_EXTERIOR_BOUNDARY             ((draw_fill_style) 0x8u)
#define draw_FILL_INTERIOR_BOUNDARY             ((draw_fill_style) 0x10u)
#define draw_FILL_FULL_INTERIOR                 ((draw_fill_style) 0x20u)
#define draw_FILL_OUTPUT_BBOX                   ((draw_fill_style) 0x2000000u)
      /*RISC OS 5+*/
#define draw_FILL32_BIT_CLEAN                   ((draw_fill_style) 0x4000000u)
      /*RISC OS 5+*/
#define draw_FILL_CLOSE_OPEN_SUBPATHS           ((draw_fill_style) 0x8000000u)
#define draw_FILL_FLATTEN                       ((draw_fill_style) 0x10000000u)
#define draw_FILL_THICKEN                       ((draw_fill_style) 0x20000000u)
#define draw_FILL_REFLATTEN                     ((draw_fill_style) 0x40000000u)
#define draw_FILL_FLOAT                         ((draw_fill_style) 0x80000000u)
#define draw_JOIN_MITRED                        ((draw_join_style) 0x0u)
#define draw_JOIN_ROUND                         ((draw_join_style) 0x1u)
#define draw_JOIN_BEVELLED                      ((draw_join_style) 0x2u)
#define draw_CAP_BUTT                           ((draw_cap_style) 0x0u)
#define draw_CAP_ROUND                          ((draw_cap_style) 0x1u)
#define draw_CAP_SQUARE                         ((draw_cap_style) 0x2u)
#define draw_CAP_TRIANGULAR                     ((draw_cap_style) 0x3u)
#define draw_SPECIAL_IN_SITU                    ((draw_output_path) 0x0u)
#define draw_SPECIAL_FILL                       ((draw_output_path) 0x1u)
#define draw_SPECIAL_FILL_BY_SUBPATHS           ((draw_output_path) 0x2u)
#define draw_SPECIAL_COUNT                      ((draw_output_path) 0x3u)
#define draw_SPECIAL_BBOX                       ((draw_output_path) 0x80000000u)
#define error_DRAW_NO_DRAW_IN_IRQ_MODE          0x980u
#define error_DRAW_BAD_DRAW_REASON_CODE         0x981u
#define error_DRAW_RESERVED_DRAW_BITS           0x982u
#define error_DRAW_INVALID_DRAW_ADDRESS         0x983u
#define error_DRAW_BAD_PATH_ELEMENT             0x984u
#define error_DRAW_BAD_PATH_SEQUENCE            0x985u
#define error_DRAW_MAY_EXPAND_PATH              0x986u
#define error_DRAW_PATH_FULL                    0x987u
#define error_DRAW_PATH_NOT_FLAT                0x988u
#define error_DRAW_BAD_CAPS_OR_JOINS            0x989u
#define error_DRAW_TRANSFORM_OVERFLOW           0x98Au
#define error_DRAW_DRAW_NEEDS_GRAPHICS_MODE     0x98Bu
#define error_DRAW_UNIMPLEMENTED_DRAW           0x9FFu
#define drawv_PROCESS_PATH                      ((drawv_reason) 0x0u)
#define drawv_FILL                              ((drawv_reason) 0x2u)
#define drawv_STROKE                            ((drawv_reason) 0x4u)
#define drawv_STROKE_PATH                       ((drawv_reason) 0x6u)
#define drawv_FLATTEN_PATH                      ((drawv_reason) 0x8u)
#define drawv_TRANSFORM_PATH                    ((drawv_reason) 0xAu)
#define drawv_FILL_CLIPPED                      ((drawv_reason) 0xCu)
#define drawv_STROKE_CLIPPED                    ((drawv_reason) 0xEu)

/*************************
 * Function declarations *
 *************************/

#ifdef __cplusplus
   extern "C" {
#endif

/* ------------------------------------------------------------------------
 * Function:      draw_process_path()
 *
 * Description:   Main Draw SWI
 *
 * Input:         path - value of R0 on entry
 *                fill_style - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *                thickness - value of R4 on entry
 *                line_style - value of R5 on entry
 *                dash_pattern - value of R6 on entry
 *                processed_path - value of R7 on entry
 *
 * Output:        end_or_used - value of R0 on exit (X version only)
 *
 * Returns:       R0 (non-X version only)
 *
 * Other notes:   Calls SWI 0x40700.
 */

extern os_error *xdraw_process_path (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern,
      draw_output_path processed_path,
      byte **end_or_used);
extern byte *draw_process_path (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern,
      draw_output_path processed_path);

/* ------------------------------------------------------------------------
 * Function:      draw_fill()
 *
 * Description:   Processes a path and sends it to the VDU, filling the
 *                interior portion
 *
 * Input:         path - value of R0 on entry
 *                fill_style - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *
 * Other notes:   Calls SWI 0x40702.
 */

extern os_error *xdraw_fill (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness);
__swi (0x40702) void draw_fill (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness);

/* ------------------------------------------------------------------------
 * Function:      draw_stroke()
 *
 * Description:   Processes a path and sends it to the VDU
 *
 * Input:         path - value of R0 on entry
 *                fill_style - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *                thickness - value of R4 on entry
 *                line_style - value of R5 on entry
 *                dash_pattern - value of R6 on entry
 *
 * Other notes:   Calls SWI 0x40704.
 */

extern os_error *xdraw_stroke (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern);
extern void draw_stroke (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern);

/* ------------------------------------------------------------------------
 * Function:      draw_stroke_path()
 *
 * Description:   Processes a path and writes its output to another path
 *
 * Input:         path - value of R0 on entry
 *                stroked_path - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *                thickness - value of R4 on entry
 *                line_style - value of R5 on entry
 *                dash_pattern - value of R6 on entry
 *
 * Output:        end_or_used - value of R0 on exit (X version only)
 *
 * Returns:       R0 (non-X version only)
 *
 * Other notes:   Calls SWI 0x40706.
 */

extern os_error *xdraw_stroke_path (draw_path const *path,
      draw_path *stroked_path,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern,
      byte **end_or_used);
extern byte *draw_stroke_path (draw_path const *path,
      draw_path *stroked_path,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern);

/* ------------------------------------------------------------------------
 * Function:      draw_flatten_path()
 *
 * Description:   Flattens a path and writes its output to another path
 *
 * Input:         path - value of R0 on entry
 *                flattened_path - value of R1 on entry
 *                flatness - value of R2 on entry
 *
 * Output:        end_or_used - value of R0 on exit (X version only)
 *
 * Returns:       R0 (non-X version only)
 *
 * Other notes:   Calls SWI 0x40708.
 */

extern os_error *xdraw_flatten_path (draw_path const *path,
      draw_path *flattened_path,
      int flatness,
      byte **end_or_used);
__swi (0x40708) byte *draw_flatten_path (draw_path const *path,
      draw_path *flattened_path,
      int flatness);

/* ------------------------------------------------------------------------
 * Function:      draw_transform_path()
 *
 * Description:   Transforms a path and writes its output to another path
 *
 * Input:         path - value of R0 on entry
 *                transformed_path - value of R1 on entry
 *                trfm - value of R2 on entry
 *
 * Output:        end_or_used - value of R0 on exit (X version only)
 *
 * Returns:       R0 (non-X version only)
 *
 * Other notes:   Calls SWI 0x4070A with R3 = 0x0.
 */

extern os_error *xdraw_transform_path (draw_path const *path,
      draw_path *transformed_path,
      os_trfm const *trfm,
      byte **end_or_used);
extern byte *draw_transform_path (draw_path const *path,
      draw_path *transformed_path,
      os_trfm const *trfm);

/* ------------------------------------------------------------------------
 * Function:      draw_fill_clipped()
 *
 * Description:   Processes a path and sends it to the VDU, filling the
 *                interior portion and clipping against the clip descriptor
 *                - RISC OS 5+
 *
 * Input:         path - value of R0 on entry
 *                fill_style - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *                clip_descriptor - value of R4 on entry
 *
 * Other notes:   Calls SWI 0x4070C.
 */

extern os_error *xdraw_fill_clipped (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      draw_clip_descriptor const *clip_descriptor);
extern void draw_fill_clipped (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      draw_clip_descriptor const *clip_descriptor);

/* ------------------------------------------------------------------------
 * Function:      draw_stroke_clipped()
 *
 * Description:   Processes a path and sends it to the VDU after clipping
 *                against the clip descriptor - RISC OS 5+
 *
 * Input:         path - value of R0 on entry
 *                fill_style - value of R1 on entry
 *                trfm - value of R2 on entry
 *                flatness - value of R3 on entry
 *                thickness - value of R4 on entry
 *                line_style - value of R5 on entry
 *                dash_pattern - value of R6 on entry
 *                clip_descriptor - value of R7 on entry
 *
 * Other notes:   Calls SWI 0x4070E.
 */

extern os_error *xdraw_stroke_clipped (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern,
      draw_clip_descriptor const *clip_descriptor);
extern void draw_stroke_clipped (draw_path const *path,
      draw_fill_style fill_style,
      os_trfm const *trfm,
      int flatness,
      int thickness,
      draw_line_style const *line_style,
      draw_dash_pattern const *dash_pattern,
      draw_clip_descriptor const *clip_descriptor);

#ifdef __cplusplus
   }
#endif

#if defined NAMESPACE_OSLIB
  } 
#endif

#endif
