Path: utzoo!utgpu!attcan!uunet!husc6!psuvax1!rutgers!ucsd!ames!lll-lcc!well!shf From: shf@well.UUCP (Stuart H. Ferguson) Newsgroups: comp.sys.amiga.tech Subject: Re: IFF form for 2D drawings (again) Summary: Zen and the Art of IFF Design Keywords: IFF, standard, drawing, 2D Message-ID: <6793@well.UUCP> Date: 10 Aug 88 21:55:45 GMT References: <11640003@hpfcdc.HP.COM> Reply-To: shf@well.UUCP (Stuart H. Ferguson) Organization: The Blue Planet Lines: 255 +--- Ross Cunniff writes about a possible IFF standard for drawings | OK, here it comes again... I guess I missed the first one... | This is a revised proposal for a standard IFF two-dimensional drawing | format (named DR2D). The things that have changed include: How about R2D2 ? :-) | Comments and critiques specifically about the format are welcome [...] | 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. These are two very different problems. A format for your own purposes is one matter, a standard format is another entirely. I can't say what's appropriate to your application, so I'll just address the concept of this being an IFF standard. IFF has a kind of underlying philosophy that many would-be standards ignore. The basic thing is that the format is to be used for data "Interchange," which means that lots of different programs with lots of different purposes may read or write this data. An IFF format must be carefully designed so that the data is stored in a way that is as independent of the application and as close to its pure abstract form as possible. The goals of programmer for a specific application program may conflict with this philosophy since the programmer wants the file format to closely match the internal design of his program. Whereas this makes things easy for him, it often makes for a poor standard. If you just want this as just format for your own files, fine, but don't make any pretenses about this being a "standard." If you want this to be a good standard, expect to do some extra work. Specific comments: | 1. Objects now have their points relative to an | X,Y position; they also have bounding information. | stored with them (for efficient clipping/rendering). ^^^^^^^^^^^^^^^^ Lousy idea. One of the main reasons the Draw Plus format is so klunky and bulky is that the definition for each object explicitly states its bounding rectangle. If you need this info, you can derive it -- don't include it in the file. | 2. Each object now has a 16-bit layer ID in it. This sounds wrong for IFF. How about providing a LYID property chunk with the layer ID in it and storing the different layers in your program as a CAT of FORM DR2D's each with a different LYID chunk? This would make it so that those people who want a drawing and don't want to fuss with layers don't have to deal with a layer ID word in every chunk. This is really what you want in some sense, since each separate FORM DR2D is a different layer, rather than having all the different layers interspersed throughout one FORM. | Things I have NOT changed include: | 1. I still use single-precision IEEE floating point | numbers for coordinates instead of scaled integers. Like I said, I missed the first part of the discussion, but let me lodge a strong vote AGAINST using floating point in IFF files. For some applications, floating point is essential, but not for drawings. Since your format already specifies maximum and minimum X and Y for the drawing area, why not just leave these out and use numbers scaled from -2^31 to 2^31? Makes things more IFF-like (you know, _Interchange_ File Format), and also gives you more (albeit fixed) precision with the same number of bits. | [...] 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. IFF already provides for upward compatibility. All you need to do is add new chunk types with the new information and they will be ignored by programs that only understand the old chunks. Once defined, a given chunk should be considered SET IN STONE and NOT subject to change. The format should be enhanced by adding chunks, not by changing the already defined chunks. Redundant information of this type is therefore unnecessary. | CMAP (0x434D4150) /* Color map */ Like Leo, I strongly recommend you use the ILBM CMAP chunk definition for several reasons: people already know how to read it, you're using the same chunk ID, and your definition really adds no new information (NumColors is just Size/3 (like Leo said, you don't have to add the pad byte to the Size field)). | 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. */ Why not use nested ILBM FORM's here? Something like: LIST { PATT FORM { ILBM ... BODY } ... as many ILBM FORM's as you have patterns } This gives you more flexibility in the size and shape of the fill pattern, as well as making it simple to import IFF brushes to use as patterns. Question: What's a pixel-based fill pattern doing in a floating-point, scaled lines drawing format? How do you do the conversion from pixels to your floating-point coordinates? Perhaps this conversion factor (i.e. the pixel size in world coordinates) should be included in the PATT chunk or LIST in some way. | FONT (0x464F4E54) /* Font table */ Isn't there a standard FONT chunk defined for FORM FTXT? You should probably use it, like using ILBM CMAP chunks. | TEXT (0x54455854) /* A text string */ Same with TEXT. Use the FTXT CHRS chunk instead. | FILL (0x46494C4C) /* Line fill pattern table */ Could a line fill pattern be stored as a nested FORM DR2D, or a symbol? The next comments relate to the concept of "symbols" and "groups" as described for this proposed format. | 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. The supported way of doing this with IFF files is to use nested generic chunks, such as CATs, FORMs and LISTs. So instead of a DSYM chunk looking like this: | struct DSYMstruct { | LONG ID; | LONG Size; | SHORT SymbID; /* Unique ID for this symbol */ | SHORT NumObjs; | UBYTE SymbChunk[Size-4]; /* See note 5 */ | }; the file would contain a LIST DSYM, for example, like this: LIST { DSYM PROP { DR2D SYID - symbol ID chunk } FORM { DR2D ... - definition of the symbol } } Or, as another example (which I don't like as much but which might also work), something like this: FORM { DSYM SYID - symbol ID chunk .... - more stuff for this symbol FORM { DR2D .... - symbol data chunks } } There are several reasons to do it this way, not the least of which is that this approach or some variation is the correct way to do recursion under IFF. Also, readers which understand how to parse the generic chunks can already parse this format, whereas with the proposed mechanism, the parser would have to know how to parse the special DYSM chunk as a series of nested chunks. This means that someone trying to read this type of file will need to write their own custom reader instead of using generic tools for reading IFF files. One of the best reasons to use this approach is that it's more general; a symbol could be stored in a file by itself. The concept of "weak groups" and "strong groups" are *EXACTLY* what generic CAT and LIST chunks are for, so there's no excuse for not using these to define groups. Do not re-invent the wheel. There are a number of properties that occur in group and symbol definitions, to wit: | 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 put it */ | XMag, YMag, /* How big should it be? */ | Rotation; /* Angle of rotation */ These are more or less general properties that could apply to any object, so why not make each one a property chunk? A given property would apply to any objects within its scope, and nested properties would apply in a nested way. It would actually be required to define properties this way to allow for using LIST chunks as strong groups. In fact, I've already mentioned putting the WhichLayer property into its own chunk for another reason. In addition, the nesting of properties would be much more general. For example, you could have the following DR2D file: FORM DR2D (header) RECT - rectangle #1 ROTA - rotation property, 45 degrees FORM DR2D - nested drawing ROTA - rotation, 45 degrees RECT - rectangle #2 RECT - rectangle #3 Rectangle #1 would be unaffected by any rotations. Rectangle #3 is in the scope of the first ROTAtion property and would therefore be rotated 45 degrees. Rectangle #2 is in the scope of two 45 degree rotations and would be rotated 90 degrees. I understand, Ross, that all this is very different than you originally had in mind; however, if you honestly expect this to become a de-facto standard, I would hope that you would be willing to make it more powerful and general than simply a dump of your program's internal variables. Also, since you're designing an IFF format, you should adopt an IFF philosophy as well. It would not be a bad thing to design a format more complex than your program can handle. In that case, just do the best you can with whatever file you're handed. Files produced by your program might not use the full capability of the format, and files with a very complex structure might need to be simplified by your program while being read. This is how IFF files are intended, and is a pretty common practice. Just think about all the information in ILBMs that most programs ignore. Thanx for being willing to share your design concept with the Net. I hope you find my comments useful. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC (shf@Solar.Stanford.EDU)