drawfdiag 14.4 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the RISCOS 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 3 or later.            *
 *                                                                          *
 ***************************************************************************/

/*
 * Title:  drawfdiag.h
 * Purpose: Processing of Draw format files (diagram level interface)
 *
 */

/*
 *
 * This file defines the interface to the simplest version of the
 * DrawFile module. It can read in files to diagrams and render them.
 * There is no checking of whether we have overrun the end of the
 * diagram.
 *
 * To read in Draw files, it is expected that the caller will do the
 * work of the I/O themselves.
 *
 * To dispose of a diagram, the caller can just throw it away, ie,
 * the module does not keep any hidden information about what
 * diagrams it has seen.
 *
 * Note on returning errors: some calls return an offset to the bad data on
 * an error. This is not necessarily the start of an object: it may be bad
 * data part way through it. The offset is relative to the start of the
 * diagram.
 *
 * The module cannot handle rectangle or ellipse objects. Use a path instead.
 */

#ifndef __drawfdiag_h
#define __drawfdiag_h

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

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif

/********************************* Data types ******************************/

/*
 * Type for a diagram: it consists of a pointer to the data and a
 * length field. The length must be an exact number of words, and is
 * the amount of space used in the diagram, not the size of the
 * memory allocated to it.
 */

typedef struct
{ char * data;
  int  length;
} draw_diag;


/* --- Abstract handle for an object --- */
/* The object handle is an offset from the start of the diagram to the
 * object data.  You may use it to set a pointer directly to an object,
 * when using the object level interface
 */

typedef int draw_object;

/* --- Rectangular box: bounding boxes, etc. --- */

typedef struct {int x0, y0, x1, y1;} draw_box;

/* --- Redraw structure: similar to a wimp_redrawstr --- */

typedef struct
{
  int      reserved;
  draw_box box;         /* Work area box (x0, y1 used) */
  int      scx, scy;    /* Scroll positions */
  draw_box g;           /* Graphics window box */
} draw_redrawstr;


/* Error type.
 * Where a routine can produce an error, the actual value returned is a BOOL,
 * which is TRUE if the routine succeeded. The error itself is returned in a
 * block passed by the user; if NULL, then the details of the error are not
 * passed back.
 * The error block may contain either an operating system error, or an
 * internal error. In the latter case, it consists of a code and possibly a
 * pointer to the location in the file where the error occurred (if NULL,
 * the location is not known or not specified). By convention, this should
 * be reported by the caller in the form '<message> (location &xx in file)'.
 * For a list of codes and standard errors, see h.DrawErrors. The location is
 * relative to the start of the data block in the diagram.
 *
 */

typedef struct
{
  enum { DrawOSError, DrawOwnError, None } type;
  union
  {
    os_error os;
    struct { int  code; int location; } draw;
  } err;
} draw_error;


/*----------------------------- Macros ---------------------------*/

/* Macros for unit conversion between Draw units and screen units */

#define draw_drawToScreen(i) ((i) >> 8)
#define draw_screenToDraw(i) ((i) << 8)

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


/* ------------------------- draw_verify_diag ------------------------------
 * Description:   Verifies a diagram which has been read in from file
 *
 * Parameters:    draw_diag *diag -- the diagram to be verified
 *                draw_error *error -- the first error encountered (if any)
 * Returns:       True if diagram is correct.
 * Other Info:    Each object in the file is checked and the first error
 *                encountered causes return (with error set appropriately)
 *
 */

BOOL draw_verify_diag(draw_diag *diag, draw_error *error);


/* ------------------------- draw_append_diag ------------------------------
 * Description:   Merges two diagrams into one.
 *
 * Parameters:    draw_diag *diag1 -- diagram to which to append diag2
 *                draw_diag *diag2 -- diagram to be appended to diag1
 *                draw_error *error -- possible error condition.
 * Returns:       True if merge was successful.
 * Other Info:    Both diagrams should have been processed by
 *                draw_verify_diag(). Diag1's data block must be at least
 *                diag1.length+diag2.length. Diag1.length will be updated
 *                to its new appropriate value. Diag1's bounding box will
 *                be set to the union of the bounding boxes of the two
 *                diagrams. NOTE: offsets of objects in diag1 may change
 *                due to a change in font table size (if diag2 has fonts).
 *                Errors referring to specific locations, refer to diag2.
 *
 */

BOOL draw_append_diag(draw_diag *diag1, draw_diag *diag2, draw_error *error);


/* -------------------------- draw_render_diag -----------------------------
 * Description:   Render a diagram with a given scale factor, in a given
 *                WIMP redraw rectangle
 *
 * Parameters:    draw_diag *diag -- the diagram to be rendered
 *                draw_redrawstr *r -- the WIMP redraw rectangle
 *                double scale -- scale factor
 *                draw_error *error -- possible error condition
 *
 * Returns:       True if render was successful
 * Other Info:    The diagram must have been processed by
 *                draw_verify_diag(). Note that draw_redrawstr is the same
 *                as wimp_redrawstr, which may be cast to it.
 *                Very small and negative scale factors will result in a
 *                run-time error (safe > 0.00009). The caller should do
 *                range checking on the scale factor.
 *                Note: following the normal convention for coordinate
 *                mapping, the part of the diagram rendered is found by
 *                mapping the top left of the diagram, in draw coord space
 *                onto a point:
 *                   (r->box.x0 - r->scx, r->box.y1 - r->scy)
 *                in screen coordinates.
 *
 */

BOOL draw_render_diag(draw_diag *diag, draw_redrawstr *r, double scale,
                      draw_error *error);


/************************** Memory allocation functions ********************/

typedef int  (*draw_allocate)(void **anchor, int n);
typedef int  (*draw_extend)(void **anchor, int n);
typedef void (*draw_free)(void **anchor);


/* ---------------------- draw_registerMemoryFunctions ---------------------
 * Description:   Register three functions to be used to allocate, extend
 *                and free memory, when rendering text objects
 *
 * Parameters:    draw_allocate alloc -- pointer to function to be used for
 *                                       memory allocation
 *                draw_extend extend  -- pointer to function to be used for
 *                                       memory extension
 *                draw_free   free    -- pointer to function to be used for
 *                                       memory freeing.
 * Returns:       void.
 * Other Info:    These three functions will be used only when rendering text
 *                area objects. Any memory allocated during rendering will
 *                be freed (using the supplied function) after rendering.
 *                If draw_registerMemoryFunctions() is never called,
 *                or if memory allocation fails, then an attempt to render
 *                a text area will produce no effect.
 *                The three functions should operate as follows:
 *                  int alloc(void **anchor, int n) :
 *                          allocate n bytes of store and set *anchor
 *                          to point to them.
 *                          Return 0 if store can't be allocated, otherwise
 *                          non-zero.
 *                  int extend (void **anchor, int n):
 *                          extend the block of memory which starts at
 *                          *anchor to a total size of n bytes. Note that
 *                          n will always be positive, and the new memory
 *                          should be appended to the existing block (which
 *                          may be moved by the operation).
 *                          Return 0 if the memory can't be allocated, else
 *                          non-zero.
 *                  void free(void **anchor):
 *                          free the block of memory which starts at
 *                          *anchor, and set *anchor to 0.
 *
 *                **NOTE** : The specification for these three functions is
 *                           the same as that for flex_alloc, flex_extend
 *                           and flex_free (in the flex module), so these
 *                           can be used as the three required functions!!
 *
 */

void draw_registerMemoryFunctions(draw_allocate alloc,
                                  draw_extend   extend,
                                  draw_free     free);


/* -------------------------- draw_shift_diag ------------------------------
 * Description:   Shift a diagram by a given distance.
 *
 * Parameters:    draw_diag *diag -- the diagram to be shifted
 *                int xMove -- distance to shift in x direction
 *                int yMove -- distance to shift in y direction.
 * Returns:       void.
 * Other Info:    All coordinates in the diagram are moved by the given
 *                distance.
 *
 */

void draw_shift_diag(draw_diag *diag, int xMove, int yMove);


/* ---------------------------- draw_querybox ------------------------------
 * Description:   Find the bounding box of a diagram.
 *
 * Parameters:    draw_diag *diag -- the diagram
 *                draw_box *box  -- the returned bounding box
 *                BOOL screenUnits -- indication whether the box is to be
 *                                    specified in draw or screen units.
 * Returns:       void.
 * Other Info:    The bounding box of diag is returned in box. If
 *                screenUnits is true, box is in screen units, else in draw
 *                units.
 *
 */

void draw_queryBox(draw_diag *diag, draw_box *box, BOOL screenUnits);


/* ----------------------------- draw_convertBox ---------------------------
 * Description:   Convert a box to/from screen coordinates.
 *
 * Parameters:    draw_box *from -- box to be converted
 *                draw_box *to   -- converted box.
 *                BOOL toScreen  -- should set to TRUE if conversion is to
 *                                  be from draw coords to screen coords
 *                                  FALSE means from screen coords to draw
 *                                  coords.
 * Returns:       void.
 * Other Info:    from and to may point to the same box.
 *
 */

void draw_convertBox(draw_box *from, draw_box *to, BOOL toScreen);


/* --------------------------- draw_rebind_diag ----------------------------
 * Description:   Force the header of a diagram's bounding box to be exactly
 *                the union of the objects in it.
 *
 * Parameters:    draw_diag *diag -- the diagram.
 * Returns:       void.
 * Other Info:    The diagram should have been processed by
 *                draw_verify_diag() first.
 *
 */

void draw_rebind_diag(draw_diag *diag);



/************************ Unknown object handling **************************/

/*
 * New types of object can be added by registering an unknown object handler.
 * The handler is called whenever an attempt is made to render an object
 * whose tag is not one of the standard ones known to DrawFile. It is passed
 * a pointer to the object to be rendered (cast to a void *), and a pointer
 * to a block into which to write any error status. The object pointer may
 * be cast to one of the standard Draw types (defined in the object level
 * interface), or to a client-defined type. If an error occurs, the handler
 * must return FALSE and set up the error block; otherwise it must return
 * TRUE. Unknown objects must conform to the standard convention for object
 * headers, i.e. 1-word object tag; 1-word object size; 4-word bounding box.
 * The unknown object handler is only called if the object is visible, i.e.
 * if there is an overlap between its bounding box and the region of the
 * diagram being rendered. The object size field must be correct, otherwise
 * catastrophes will probably result.
 *
 */

/* Type for unknown object handler */

typedef BOOL (*draw_unknown_object_handler)(void *object, void *handle,
                                            draw_error *error);


/* ------------------------ draw_set_unknown_object_handler ----------------
 * Description:   Registers a function to be called when an attempt is made
 *                to render an object with an object tag which is not known
 *
 * Parameters:    draw_unknown_object_handler handler -- the handler function
 *                void *handle -- arbitrary handle to pass to function
 * Returns:       The previous handler.
 * Other Info:    The handler can be removed by calling with 0 as a
 *                parameter.
 *
 */

draw_unknown_object_handler draw_set_unknown_object_handler
                           (draw_unknown_object_handler handler, void *handle);



/* ------------------------- drawfdiag_init --------------------------------
 * Description:   Initialise the diagram level interface
 *
 * Parameters:    void
 * Returns:       TRUE if all went OK.
 * Other Info:    none
 *
 */

BOOL drawfdiag_init(void);

#endif

/* end drawfdiag.h */