/* This file defines data structures for interpreting bookreader (DEC$BOOK) * files. * * Every data structure except for text_rec has a common header format: * * struct { unsigned short type; long length; } * * The length includes the header. The primary record types are: * * First: Root record for the document, is always first record in file. * This record contains identifcation information (e.g. author), * size information (e.g. maxfontid), and pointers to the * basic components of the documents (.e.g table of contents). * A crucial item is the record address of the last record, * which maps part numbers (page numbers) to file records * (see below). * * After the fixed portion of the first record, there is * list of ssub-records used to describe and locate the * indices available (contents, index) and optional license * information. * * Bodypart: These records comprise the displayable 'content' of * the document. These records have a fixed header followed * by a variable number of sub-records. The fixed portion * contains sizing info and forward and backward pointers to * the bodyparts logical chain. A sub-record can contain * text, a graphic figure, a hotspot definition, or an * extension definition (e.g. gray area). * * Index: This records contains data to allow a user to select a * section for viewing. It consists of a list of sub-records * describing the items in the index. * * Last: This record contains a table for locating the file records * comprising a part (a.k.a. page). The part number used is an * index into the table and each table entry contains the * RFA of the first record of the part and the size of the part. * Note that a part may be larger than 32767 so it may have to * span multiple RMS records. When a part must continue to the * next record, the last 10 bytes of the record have the RFA and * (remaining??) part size of the continuation record. The * continued record has type of continue_middle or continue_end. * * secmap: Section Map, contains a table maping the section number * values in an index record to the part number containing that * section. * * f_desc: ???? * * font: This part is composed a set of font definition sub-records, * each definition binds a font number (used in the attributes * header of a text sub-record) to the adobe font name. * * continue_middle: * continue_end: These records hold continuation segements for parts * that span multiple RMS records. The data is logically * concatenated to the previous record starting the RFA pointing * to this record (i.e. 10 bytes are trimmed from previous record). */ /* * Define symbolic names for records. */ #define BKREC_FIRST 1 /* Root record for decw$book file */ #define BKREC_BODYPART 3 /* Document body (text) */ #define BKREC_INDEX 4 /* Index to other pages */ #define BKREC_LAST 5 /* Page id to RFA conversion */ #define BKREC_SECMAP 6 #define BKREC_FDX 7 #define BKREC_FONT 9 #define BKREC_CONT_MID 10 /* Page continuation record. */ #define BKREC_CONT_END 11 /* Final record in segmented page */ #define BKSBREC_TABLE 12 #define BKSBREC_ASCZ_32 13 #define BKSBREC_FONT 14 #define BKSBREC_FDESC 15 #define BKSBREC_IXTXT 16 #define BKSBREC_BODYTEXT 18 #define BKSBREC_FIGURE 19 #define BKSBREC_FIGHOT 20 /* Figure hotspot definition */ #define BKSBREC_EXTENSION 22 #define BKSBREC_LICENSE 24 /* Alternate license */ #ifdef __DECC /* Data structures are unaligned */ #pragma nomember_alignment #endif #define BKREC_COMMON_HEADER unsigned short type; long length; /* * Define macros to return char pointer to start of variable region of * record and its size. */ #define BKREC_VAR_P(a,typ) &a->reloff[sizeof(a->typ)] #define BKREC_VAR_S(a,typ) (a->gen.length - sizeof(a->typ)) /* * Some dataFile contains RMS Record File Addresses (RFA), mimic this structure. */ struct file_address { /* RMS Record File Address */ unsigned short wrd[3]; }; struct first_rec { BKREC_COMMON_HEADER unsigned short maj_ver, min_ver; /* ODS version number */ char author[24]; /* ascizz */ char product[36]; long partcount; /* number of parts */ long sectioncount; /* number of subparts */ long dircount; /* maybe */ long fontcount; /* Number of fonts? */ long maxfontid; struct file_address lastptr; /* RFA of last record */ unsigned short lastsize; /* Size of last record */ long docverspage, index_page, index_title, /* page IDs, 0 means absent*/ sym_table, font_page, initial_page, copyright; unsigned char title_len; char title[128]; long credate[2]; char id[33]; }; struct text_rec { /* text record. */ unsigned char type, reclen; unsigned short hor, ver; unsigned char fontno, x, y; char data[246]; /* for type three data is * counted strings separated by * a flags byte (usually escape */ /* unsigned char length; char text[255]; */ }; struct last_rec { BKREC_COMMON_HEADER struct { struct file_address rfa; long size; } dir[1]; }; union bkrdr_rec { struct { /* Generic record format */ BKREC_COMMON_HEADER } gen; /* Generic header */ char raw[1]; char reloff[1]; /* For computing addresses given offset*/ struct first_rec first; /* type = BKREC_FIRST */ struct { BKREC_COMMON_HEADER long partno; /* Part number */ long unk1; long sectcnt; long prevpart; /* page id of previous part */ long nextpart; /* Id of next part */ } body; /* type = BKREC_BODYPART */ struct { BKREC_COMMON_HEADER /* type = BKREC_INDEX, all subrec */ } index; struct last_rec last; /* type = BKREC_LAST */ struct { BKREC_COMMON_HEADER long map[10]; /* Maps section #s to page id */ } secmap; /* type = BKREC_SECMAP */ struct { BKREC_COMMON_HEADER /* type = BKREC_FDX */ char txt[255]; } fdesc; struct { /* Font data */ BKREC_COMMON_HEADER /* type = BKREC_FONT */ } font; struct { BKREC_COMMON_HEADER short flags; long prev, next; } cont; /* type = BKREC_CONT_* */ /* * Sub-record types. */ struct { BKREC_COMMON_HEADER long unknown0; /* total record size */ unsigned char keyid; /* 5=contents, 10=index, 0=other */ long count; /* count of entries */ long part; /* part number */ unsigned char tit_len; /* length of title string */ char title[255]; } table; /* type = BKSBREC_TABLE */ struct { /* Font mapping defintion */ BKREC_COMMON_HEADER unsigned short fontno; /* internal number */ char name[255]; /* Name asciiz */ } fontdef; /* type = BKSBREC_FONT */ struct { BKREC_COMMON_HEADER unsigned short ixhdr[7]; /* struct text_rec ixtxt; */ } ixtxt; /* type = BKSBREC_TABLE */ struct { BKREC_COMMON_HEADER long bodhdr[1]; /* bodhr[0] unknown */ long sect_id; /* section id */ long bodhdr2[7]; /* struct text_rec bodtxt;*/ /* varying number */ } bodytext; /* type = BKSBREC_BODY */ struct { BKREC_COMMON_HEADER long unk1, unk2; long sect, pos, verpos, len, sect_id, target; long unk3; } hotspot; struct { BKREC_COMMON_HEADER long unk1, unk2, sect, x, y, w, h, unk3, unk4; } extension; /* extension grayspot on body */ struct { BKREC_COMMON_HEADER char name[255]; /* no first page */ } license; struct { BKREC_COMMON_HEADER long unk1, unk2; long sect, x, y, w, h; long picbytes; unsigned char primitive, unk5, unk6, unk7; unsigned short col, rows; /* col is fontno for txt */ char var_data[1024]; } figure; }; typedef union bkrdr_rec *bkrdr_recptr; #ifdef __DECC #pragma member_alignment #endif