/*->h.Drawlevel1 */
/****************************************************************************
 * 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.DrawLevel1
 *
 * DrawFile module, level 1 (object level interface)
 * History:
 * Version 0.0 : 21 Nov 88, DAHE: created
 *         0.0a: 23 Nov 88, DAHE: first working version
 *         0.1 : 30 Nov 88, DAHE: released
 *
 * Needs: h.os, h.sprite, h.drawLevel0
 *
 * This file supplements the level 0 interface with routines for dealing with
 * individual objects.
 */

#ifdef DRAWFILE_INTERNAL
#include "h.DrawCvtTyp"
#else
/* Data types for specifying object details */
#include "h.DrawTypes"
#endif

/* A type for specifying the full details of any object type */
/* It is used in operations on complete objects, such as creation
   and querying, and so does not include the types needed for
   contained structures and types, such as path elements or text
   columns : those are defined in h.DrawTypes
*/
typedef union
{
  Draw_objhdr      *object;
  Draw_fileheader  *fileHeader;
  Draw_fontliststr *fontList;
  Draw_textstr     *text;
  Draw_pathstr     *path;
  Draw_spristr     *sprite;
  Draw_groustr     *group;
  Draw_textareahdr *textarea;
  char             *bytep;
  int              *wordp;
} Draw_objectType;

/* Symbolic code for no object */
#define Draw_NoObject (Draw_object)-1

/* For functions that operate on a range of objects (and ONLY those functions),
   the following special codes may be used to mean 'from the start' and 'to the
   end'.
*/
#define Draw_FirstObject (Draw_object)-1
#define Draw_LastObject  (Draw_object)-2

/*-------------------------------- Global data ---------------------------------*/

extern int Draw_transTable[];
/* An array of 256 integers, used for font translation. Immediately after a
   call to Draw_createObject where the object was a font table, this contains
   the mapping between old and new font reference numbers, such that
   transTable[old fontref] = new fontref
   Draw_translateText makes use of this table; it is exported for callers who
   may want to do something fancy.
*/

/*------------------------------ Interface functions ---------------------------*/

void Draw_create_diag(Draw_diag *diag, char *creator, Draw_box bbox);
/* Create an empty diagram (ie just the file header), with the given bounding
   box, measured in Draw units. The memory for the diagram must have already
   been allocated. The length field in the diagram structure is set up. The
   first 12 characters of the creator name are also logged in the file header;
   the remaining fields are given standard values.
*/


BOOL Draw_doObjects(Draw_diag diag, Draw_object start, Draw_object end,
       Draw_redrawstr *r, double xscale, double yscale, Draw_error *error);
/* Render the specified range of objects. The remaining parameters are used in
   the same way as Draw_render_diag() in level 0.
   As with Draw_render_diag the diagram should have been verified first.
   If the range of objects includes text with anti-aliased fonts, but no font
   table, you MUST call Draw_setFontTable first.

   Note: very large, very small and negative scale factors will give a run-time
   error. This is not trapped by the routine. The lowest scale factor that is
   usually ok is about 0.00009. It is up to the caller to do range checks on
   the scale factor.
*/

void Draw_setFontTable(Draw_diag);
/* Scan the diagram for a font table object and record it for a following call
   of Draw_doObjects. This is needed if Draw_doObjects is to work on a
   sequence of objects that includes text objects using anti-aliased fonts,
   but no font table object. The result of Draw_doObjects in this case is
   unpredictable if it is not called first (may cause an exception). The font
   table remains valid until either a different one is encounted during
   Draw_doObjects, or until Draw_render_diag is called, or until a different
   diagram is rendered.
*/

BOOL Draw_verifyObject(Draw_diag diag, Draw_object object, int *size,
                       Draw_error *error);
/* Check the data for an existing object. 'size', if non-NULL returns the
   amount of memory occupied by the object. Verifying an object also ensures
   that its bounding box is consistent with the data in it; if not, no error
   is reported; the box is made consistent instead. On an error, the location
   is relative to the start of the diagram.
*/

BOOL Draw_createObject(Draw_diag *diag, Draw_objectType newObject,
                       Draw_object after, BOOL rebind, Draw_object *object,
                       Draw_error *error);
/* Create an object with the given data. The object is inserted in the diagram
   after the specified one, and the remaining data moved down.
   'after' may be Draw_FirstObject/Draw_LastObject for inserting at the
   start/end of the diagram. The diagram must be large enough for the new data;
   its length field is updated.
   The diagram bounding box (in the file header) is updated to the union of its
   existing value and that of the new object if the flag 'rebind' is TRUE.
   On an error, the location is not meaningful.
   The handle for the new object (or the merged font table) is returned in
   'object'.
   If the routine is used to create a font table, 'after' is ignored, and the
   object merged with the existing one (if there is one) or inserted at the
   start of the diagram (if not). This can cause the font reference numbers to
   change; immediately following this routine by a call to Draw_translate text
   will apply the change (only needed if there are text objects in anti-aliased
   fonts.
*/

BOOL Draw_deleteObjects(Draw_diag *diag, Draw_object start, Draw_object end,
                        BOOL rebind, Draw_error *error);
/* Delete the specified range of objects. If 'rebind' is TRUE, the diagram
   bounding box is set to the union of those of the remaining objects. The
   length field of the diagram is updated.
*/

BOOL Draw_extractObject(Draw_diag diag, Draw_object object,
                        Draw_objectType result, Draw_error *error);
/* Extract the definition of the given object into the buffer at 'result',
   which must be large enough to contain it (use Draw_verifyObject() to find
   the size).
*/

void Draw_translateText(Draw_diag);
/* Updates all font reference numbers for text objects following creation of
   a font table. See Draw_createObject. If the last call did not change the
   font table, the routine does nothing.
*/
