🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #9450

IFF form for 2D drawings (again)

#9450
From: Ross Cunniff
Date: Fri, 05 Aug 1988 17:07
376 lines
13680 bytes
OK, here it comes again...
This is a revised proposal for a standard IFF two-dimensional drawing
format (named DR2D).  The things that have changed include:

	1. Objects now have their points relative to an
	   X,Y position; they also have bounding information.
	   stored with them (for efficient clipping/rendering).

	2. Each object now has a 16-bit layer ID in it.

	3. The original 16 cross-hatch patterns have been replaced
	   with a more generalized object-oriented fill.
	
	4. Probably some other details I've forgotten.

Things I have NOT changed include:

	1. I still use single-precision IEEE floating point
	   numbers for coordinates instead of scaled integers.
	
	2. It is not a full-blown programming language like
	   PostScript.
	
	3. Rectangles may still be rotated.

	4. I haven't added a dimension object; my program doesn't
	   yet support such beasties.  If you have a definition
	   that fits in the general structure of DR2D, feel free
	   to post a description of it and I'll consider including
	   it.

Comments and critiques specifically about the format are welcome
but I would prefer that discussion about the relative merits of
PostScript, NALPS, GKS, etc. happen under a different title/notes-string.
This format is SPECIFICALLY intended to be the save-file format of
a 2-D drawing program that I intend to have on the market by December;
in addition, I think that it is powerful enough to become a standard
for the emerging CAD and desktop publishing markets.

				Ross Cunniff
				Hewlett-Packard Colorado Language Lab
				...{ucbvax,hplabs}!hpda!cunniff
				cunniff%hpda@hplabs.ARPA

---cut here------------------cut here----------------------cut here---
/* SCCS ID @(#)dr2d	1.5 88/08/05 */
The following is a proposed format of the DR2D IFF FORM file designed for
use with 2-dimensional CAD programs.  Each chunk is described by
first giving the chunk ID (both in ASCII and in hex) and then giving
the structure associated with the chunk, as well as any extra
definitions that make sense.  Coordinates are specified in IEEE
format (see note 1 for a description of the IEEE format).  Note
that most chunks have both a chunk Size and an object Count.  I
know this is redundant; however, this allows the data structures
to be extended in a compatible manner if it should become necessary
in the far future.  Please address questions and comments to:

			Ross Cunniff
			...{ucbvax,hplabs}!hpda!cunniff
			cunniff%hpda@hplabs.ARPA
			(303)-229-4644 -or- (303)-223-7569



FORM (0x464F524D)	/* All drawings are a FORM */

	struct FORMstruct {
	    LONG	ID;
	    LONG	Size;		/* Total size of the file	*/
	};


DR2D (0x44523244)	/* ID of 2D drawing */

DRHD (0x44524844)	/* Drawing header */

	struct DRHDstruct {
	    LONG	ID;
	    LONG	Size;		/* Always 16 */
	    IEEE	p_xmin, p_ymin,	/* Minimum and maximum */
			p_xmax, p_ymax;	/*   coordinates of the drawing area */
	};

CMAP (0x434D4150)	/* Color map */

	struct CMAPstruct {
	    LONG	ID;
	    LONG	Size;		/* 2 + 3*NumColor + NumColor%2 */
	    SHORT	NumColor;	/* Typically 256 */
	    UBYTE	ColorMap[NumColor][3];
	    UBYTE	PAD[NumColor%1];/* Padding to make Size even */
	};

PATT (0x50415454)	/* Fill Patterns */

	struct PATTstruct {
	    LONG	ID;
	    LONG	Size;		/* 2 + 64*NumPatts */
	    SHORT	NumPatts;	/* Typically 16 */
	    UBYTE	Patterns[NumPatts][8][8];
	};

	/* Each pixel in the 8x8 pattern may be a different color
	   from the palette.  Note that these colors may be
	   approximated by any given output device. */

FONT (0x464F4E54)	/* Font table */

	struct FONTstruct {
	    LONG	ID;
	    LONG	Size;		/* 2 + 128*NumFonts */
	    SHORT	NumFonts;
	    CHAR	FontNames[NumFonts][128];
	};
	/* FontNames is an array containing the names of all the fonts
	   used in this drawing. */

FILL (0x46494C4C)	/* Line fill pattern table */

	typedef struct {
	    SHORT	NumLines;
	    IEEE	Width, Height;
	    IEEE	XMag, YMag;
	    IEEE	EndPoints[4*NumLines];
	} LineFillPat;

	struct FILLstruct {
	    LONG	ID;
	    LONG	Size;		/* 2 + sum(sizeof(Patterns)) */
	    SHORT	NumPatts;	/* Typically 16 */
	    LineFillPat	Patterns[NumPatts];
	};

	/* A line fill pattern consists of an arbitrary number
	   of line segments.  The segments have coordinates
	   ranging from (0.0,0.0) to (Width,Height), and the
	   pattern is tiled by first multiplying the coordinates
	   by (XMag, YMag) and then repeating the pattern across
	   the filled object every (XMag*Width,YMag*Height) interval. */


DSYM (0x4453594D)	/* Define a symbol */

	struct DSYMstruct {
	    LONG	ID;
	    LONG	Size;
	    SHORT	SymbID;			/* Unique ID for this symbol */
	    SHORT	NumObjs;
	    UBYTE	SymbChunk[Size-4];	/* See note 5 */
	};

SYMB (0x53594D42)	/* Use a symbol */
	struct SYMBstruct {
	    LONG	ID;
	    LONG	Size;			/* Always 22	*/
	    SHORT	SymbID;			/* Which symbol	*/
	    USHORT	WhichLayer;		/* Which layer it's in */
	    IEEE	XPos, YPos,		/* Where to put it */
			XMag, YMag,		/* How big should it be? */
			Rotation;		/* Angle of rotation */
	};

CPLY (0x43504C59)	/* Closed polygon */
OPLY (0x4F504C59)	/* Open polygon, i.e. line segments */
CSPL (0x4353504C)	/* Closed interpolating B-Spline */
OSPL (0x4353504C)	/* Open interpolating B-Spline */
RECT (0x52454354)	/* Rectangle (should have 4 vertices, so that they */
			/* can be rotated) */
ELLP (0x454C4C50)	/* Ellipse (should have 3 vertices [see note 2]) */
CBEZ (0x4340455A)	/* Closed bezier splines (see note 3) */
OBEZ (0x4F40455A)	/* Open bezier splines (see note 3) */

	/* Various fill types */
	#define F_NONE		0	/* No fill			*/
	#define F_COLOR		1	/* Fill with color from palette */
	#define F_BITMAP	2	/* Fill with bitmap pattern	*/
	#define F_LINES		3	/* Fill with lines [see note 4]) */

	/* Various edge types */
	#define E_NONE		0	/* No edges		*/
	#define E_SOLID		1	/* Solid (thin) lines	*/
	#define E_DASH		2	/* Dashed lines		*/
	#define E_DOT		3	/* Dotted lines		*/
	#define E_DOT_DASH	4	/* dot-dash-dot-dash	*/
	#define E_THICK		5	/* Thick line		*/

	typedef struct {
	    UBYTE	FillType;	/* One of F_*, above	*/
	    UBYTE	FillValue;	/* See note 4		*/
	    UBYTE	EdgeType;	/* One of E_*, above	*/
	    UBYTE	EdgeValue;	/* Edge color index	*/
	    USHORT	WhichLayer;	/* Which layer it's in	*/
	    IEEE	EdgeThick;	/* Line width, if E_THICK */
	    IEEE	XPos, YPos,	/* Where to place the obj. */
			Width, Height;	/* Bounding box of obj.	*/
	} ObjHdr;	/* Size == 26 */

	struct POLYstruct {
	    LONG	ID;
	    LONG	Size;		/* 28 + 4*NumCoords */
	    ObjHdr	Styles;
	    SHORT	NumCoords;
	    IEEE	PolyPoints[NumCoords]; /* XY coords of vertices */
	};



SGRP (0x53475250)	/* Strong group; all objects in group have same color */
WGRP (0x57475250)	/* Weak group; objects retain individual color */

	struct GROUPstruct {
	    LONG	ID;
	    LONG	Size;
	    ObjHdr	Styles;		/* Styles for strong group */
	    SHORT	NumObjs;
	    UBYTE	GroupChunk[Size-14];	/* See note 5 */
	};


TEXT (0x54455854)	/* A text string */

	struct TEXTstruct {
	    LONG	ID;
	    LONG	Size;		/* 34 + NumChars + NumChars%2 */
	    ObjHdr	Styles;
	    SHORT	WhichFont;	/* Index into font table */
	    IEEE	CharW, CharH,	/* W/H of an individual char	*/
			Rotation;	/* Angle of text (in radians) */
	    SHORT	NumChars;
	    char	TextChars[NumChars];
	    UBYTE	PAD[NumChars%2];/* Padding to make Size even */
	};

The following is a hexdump of a sample DR2D file, giving you some idea of
how this is all put together:

00000000:  46 4f 52 4d 00 00 01 bc 44 52 32 44 44 52 48 44    FORM....DR2DDRHD
00000010:  00 00 00 10 00 00 00 00 00 00 00 00 41 20 00 00    ............A ..
00000020:  41 00 00 00 43 4d 41 50 00 00 00 1a 00 08 00 00    A...CMAP........
00000030:  00 00 00 ff 00 ff 00 00 ff ff ff 00 00 ff 00 ff    ................
00000040:  ff ff 00 ff ff ff 50 41 54 54 00 00 00 42 00 01    ......PATT...B..
00000050:  00 01 00 01 00 01 00 01 01 00 01 00 01 00 01 00    ................
00000060:  00 01 00 01 00 01 00 01 01 00 01 00 01 00 01 00    ................
00000070:  00 01 00 01 00 01 00 01 01 00 01 00 01 00 01 00    ................
00000080:  00 01 00 01 00 01 00 01 01 00 01 00 01 00 01 00    ................
00000090:  46 4f 4e 54 00 00 00 82 00 01 73 69 6d 70 6c 65    FONT......simple
000000a0:  78 20 72 6f 6d 61 6e 00 00 00 00 00 00 00 00 00    x roman.........
000000b0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000c0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000d0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000e0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000f0:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
00000100:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
00000110:  00 00 00 00 00 00 00 00 00 00 46 49 4c 4c 00 00    ..........FILL..
00000120:  00 24 00 01 00 01 3f 80 00 00 3f 80 00 00 3f 80    .$....?...?...?.
00000130:  00 00 3f 80 00 00 00 00 00 00 3f 00 00 00 3f 80    ..?.......?...?.
00000140:  00 00 3f 00 00 00 54 45 58 54 00 00 00 32 00 00    ..?...TEXT...2..
00000150:  01 01 00 00 00 00 00 00 40 40 00 00 40 00 00 00    ........@@..@...
00000160:  40 c0 00 00 40 00 00 00 00 00 3f 80 00 00 40 00    @...@.....?...@.
00000170:  00 00 00 00 00 00 00 07 66 6f 6f 62 61 72 00 00    ........foobar..
00000180:  52 45 43 54 00 00 00 3c 00 00 03 01 00 00 00 00    RECT...<........
00000190:  00 00 40 00 00 00 3f 80 00 00 41 00 00 00 40 80    ..@...?...A...@.
000001a0:  00 00 00 04 40 00 00 00 3f 80 00 00 40 00 00 00    ....@...?...@...
000001b0:  41 10 00 00 40 c0 00 00 41 10 00 00 40 c0 00 00    A...@...A...@...
000001c0:  3f 80 00 00                                        ?...

The picture should look something like this:


			.................
			.		.
			.    foobar	.
			.		.
			.................

NOTE 1:	IEEE represents a single-precision IEEE floating point number.
	These numbers consist of 32 bits, arranged as follows:

	+---------------+---------------+---------------+---------------+
	|s e e e e e e e|e m m m m m m m|m m m m m m m m|m m m m m m m m|
	+---------------+---------------+---------------+---------------+
	 31	      24 23           16 15            8 7             0
	
	where
		s	is the sign bit of the entire number.  If this
			bit is '1', the number is negative.  If '0',
			the number is positive.
		e	is the 8-bit exponent, in excess-127 form.
			This is the power of two to which the mantissa
			should be raised before using the number
			in calculations.  Excess-127 means that
			127 is added to the exponent before packing
			it into the number. An exponent of 0 here means
			the real exponent is actually -127.  A value
			of 127 means the exponent is actually 0.
			A value of 255 means the exponenent is actually
			128.
		m	is the 23-bit mantissa.  A leading binary
			1 is assumed.  This means that the mantissa
			may vary from 1.0000000 to 1.999999...
	
	The value 0.0000000 is represented by all bits being cleared
	to zero.  Note that on many computers, the natural format
	of single-precision floating point numbers *IS* IEEE.  This
	is true of the Amiga.  There are system calls to transform
	IEEE numbers to and from Motorola FFP numbers, should your
	application require them.

NOTE 2: For an Ellipse, the 3 vertices are as follows:

	XPos+CX, YPos+CY	The center of the ellipse
	XPos+AX, YPos+AY	A point at the intersection
				of the major axis and the ellipse
	XPos+BX, YPos+BY	A point at the intersection of
				the minor axis and the ellipse

NOTE 3: For a Bezier spline, the vertices are defined as follows:

	typedef union {
	    IEEE num;
	    LONG bits;
	} Marker;

	#define LINETO		0xFFFFFFFF
	#define SPLINETO	0xFFFFFFFE

	Marker Temp;

	MoveTo( XPos + PolyPoints[0], YPos + PolyPoints[1] );
	for( i = 2; i < NumCoords; ) {
	    Temp.num = PolyPoints[i];
	    switch( Temp.bits ) {
		case LINETO :
		    DrawTo( XPos + PolyPoints[i+1], YPos + PolyPoints[i+2] );
		    i += 3;
		    break;
		case SPLINETO :
		    SplineTo(	XPos+PolyPoints[i+1], YPos+PolyPoints[i+2],
				XPos+PolyPoints[i+3], YPos+PolyPoints[i+4],
				XPos+PolyPoints[i+5], YPos+PolyPoints[i+6] );
		    i += 7;
		    break;
	    }
	}
	if( ID == CBEZ ) {
	    LineTo( XPos+PolyPoints[0], YPos+PolyPoints[1] );
	    FillPath();
	}
	else {
	    TracePath();
	}


NOTE 4: The actual fill of one of these objects is done as follows:

	switch( FillType ) {
	    case F_NONE :
		SetNoFill();
		break;
	    case F_COLOR :
		SetSolidFill( Palette[FillValue] );
		break;
	    case F_BITMAP :
		SetSolidFill( Bitmaps[FillValue] );
		break;
	    case F_LINES :
		SetLineFill( FillPats[FillValue] );
		break;
	   }

	Note also that on most pen plotters, F_LINES and F_NONE
	are the only meaningful fills.

NOTE 5: The data in a DSYM, SGRP or WGRP chunk is a series of nested object
	chunks.  All object chunks except DSYM, CMAP, PATT, FILL, and FONT are
	allowed in a DSYM, SGRP or WGRP.
Technical Details
Message-ID: <11640003@hpfcdc.HP.COM>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!husc6!uwvax!rutgers!ucsd!ucsdhub!hp-sdd!hplabs!hpl-opus!hpccc!hp-sde!hpfcdc!cunniff

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!husc6!uwvax!rutgers!ucsd!ucsdhub!hp-sdd!hplabs!hpl-opus!hpccc!hp-sde!hpfcdc!cunniff
From: cunniff@hpfcdc.HP.COM (Ross Cunniff)
Newsgroups: comp.sys.amiga.tech
Subject: IFF form for 2D drawings (again)
Message-ID: <11640003@hpfcdc.HP.COM>
Date: 5 Aug 88 17:07:13 GMT
Organization: HP Ft. Collins, Co.
Lines: 376