microsoft word 97 binary file format

microsoft word 97 (aka version 8) for windows and macintosh. from the office book, found in the microsoft office development section in the msdn online library. htmlified june 1998. revised aug 1 1998, added missing definitions section.

contents

note

many of the structures written in word files differ slightly from the corresponding structures word uses internally. the file-specific version of a structure is typically named by adding a preceding or (more often) trailing f. for example, word uses internally a plc (plex of cps), but writes to files a plcf (plex of cps in file). many discussions in this document use the name of the internal structure when the file-specific structure is what is really being referred to. the reader should remember that the name of a seemingly undefined structure type may simply be missing a leading or trailing f.

word and docfiles

word 97 is an ole 2.0 application. a word binary file is a docfile and word binary data is written into streams within the docfile using the ole 2.0 docfile apis. these streams are stored in the file as linked lists of file blocks and this data cannot be reliably accessed by using the operating system open apis. to access data within a word binary file, the file must be opened using the ole 2.0 docfile apis, and it must be read with the appropriate docfile apis.

a word docfile consists of a main stream, a summary information stream, a table stream, a data stream, and 0 or more object streams which contain private data for ole 2.0 objects embedded within the word document. the summary information stream is described in the section immediately following this one. the object storages contain binary data for embedded objects. word has no knowledge of the contents of these storages; this information is accessed and manipulated though the ole 2.0 apis.

the majority of this document describes the contents of the main stream and the table stream.

definitions

ole 2.0:

object linking and embedding 2.0

api (application programming interface):

a set of libraries, functions, definitions, etc. which describe an interface to a programming environment or model.

docfile:

an ole 2.0 compatible multi-stream file. word files are docfiles.

page (or sector):

512 byte segment of the main stream within a word docfile that begins on a 512-byte boundary. (bytes 0-511 are in page 0, bytes 512-1023 are in page 1, etc.). in word data structures, an unsigned two-byte integer page number is given the acronym pn (for page number).

document:

a named, multi-linked list of data structures, representing an ordered stream of text with properties that was produced by a user of microsoft word

stream:

the physical encoding of a word document 's text and sub data structures in a random access stream within a docfile.

main stream:

the stream within a word docfile containing the bulk of word's binary data.

table stream:

the stream within a word docfile containing the various plcf's and tables that describe a documents structures.

data stream:

the stream within a word docfile containing various data that hang off of characters in the main stream. for example, binary data describing in-line pictures and/or formfields.

summary information stream:

the stream within a word docfile containing the document summary information.

object storage:

a storage containing binary data for an embedded ole 2.0 object.

cp (character position):

a four-byte integer which is the position coordinate of a character of text within the logical text stream of a document.

fc( file character position):

a four-byte integer which is the byte offset of a character (or other object) from the beginning of a stream of the docfile. before a file has been edited(i.e. in a full saved word document), cps can be transformed into fcs by adding the fc coordinate of the beginning of a document's text stream to the cp. after a file has been edited (i.e. in a fast-saved word document), the mapping from cp to fc is recorded in the piece table (see below)

xchar( extended character set):

a data type which defines a "character". each xchar corresponds to a character in the document, where "character" is defined as a glyph, regardless of whether it is a single-byte or double-byte character. with word6/fe, word95/fe, word97/all and future versions of word, this is defined as a 16-bit integer corresponding to the unicode character code of the glyph.

plf(plex stored in file):

a data structure consisting of an array of structures preceded by a long count of structures.

plcf(plex of cps(or fcs) stored in file):

a data structure consisting of two parallel arrays that allows a relation to be established between a certain cp position in the document text stream (or fc position in a file) and an arbitrary data structure. it consists of an array of n+1 cps or fcs followed by an array of n instances of a particular arbitrary data structure. in typical usage, the nth cp or fc of the plcf is in one-to-one correspondence with the nth instance of the arbitrary data structure, with the n+1st cp or fc marking the limit of the nth instance's influence. when a plcf is used to record a partitioning of the document's text stream or a partitioning of the bytes stored in a file, the 0th cp/fc stored in the plcf will be 0. when a plcf is used to record the location of certain marks or links within the document text stream, the 0th cp/fc stored in the plcf will record the position of the 0th mark or link. to properly interpret a plcf stored in a word file, the length of the stored plcf and the length of the arbitrary data structure stored in the plcf must be known. the length of the stored plcf is recorded in the fib. the lengths of the data structures stored in plcfs within word files are listed later in this document.

piece table:

the piece table is a data structure that describes the logical sequence of characters in a word document and records recent changes to the formatting of a word document. it is stored in a word file as a plcf named the plcfpcd (plex of cps containing piece descriptors).the piece table relates a logical character number, called a cp (character position), to a physical location within a word file (an fc). the array of cps in the plcfpcd defines a partitioning of the word document into disjoint pieces. the second array is an array of pcds (piece descriptors) which is in 1-to-1 correspondence to the array of cps that records the physical location in the word file where the corresponding piece begins. to find the physical location of a particular logical character in a word document, take the cp coordinate of that character within the document and find the piece that contains that character. this is done by finding the index of the largest cp in the array of cps that is less than the character cp. then reference the pcd with that index in the array of pcds. the fc stored in the pcd gives the position of the beginning of the piece in the file. finally, add the offset of the desired character from the beginning of its piece to the fc of the beginning of the piece. this gives a "virtual" file offset of the character. if the second most significant bit is clear, then this indicates the actual file offset of the unicode character (two bytes). if the second most significant bit is set, then the actual address of the codepage-1252 compressed version of the unicode character (one byte), is actually at the offset indicated by clearing this bit and dividing by two.

sprm (single property modifier):

an instruction to modify one or more properties within one of the property defining data structures (chp, pap, tap, sep, or pic). it consists of an operation code which identifies the field(s) to be changed, and an operand which gives the value that a particular field is changed to or else which is a parameter to a procedure which will change the field or fields. a prl (property modifiers stored in a list) is a sprm plus its operand.

grpprl (group of prls):

a grpprl is a data structure that records a set of sprms. the 0th sprm is recorded at offset 0 of the structure. any succeeding sprms are recorded immediately after the end of the preceding sprm . to traverse a grpprl and locate the sprms recorded within it, it's necessary to fetch the opcode of the first sprm, lookup the length of the sprm with that opcode, use that length to skip past the first sprm, fetch the opcode of the second sprm, lookup the length of that sprm, use the length to skip the second sprm, and so on. see the table in the "sprm definition" topic to determine the length of a sprm.

the phrase "apply the sprms of a grpprl (or papx or sepx)" used later in this document means to fetch the 0th sprm recorded in the grpprl and perform the action for that sprm, fetch the first sprm and perform its action, and continue this procedure until all sprms in the grpprl (or papx or sepx) have been processed.

prm (property modifier):

a field in piece table entries that records how the properties of text within a piece were changed to reflect user formatting operations. the prm usually contains an index to a grpprl which records the user's formatting changes as a group of sprms. if the user has made only a small change to formatting that can be expressed as a single 2 or 1-byte sprm, that sprm is stored within the prm.

sttbf (string table stored in file)

word has many tables of strings that are stored as pascal type strings. sttbfs consist of an optional short containing 0xffff, indicating that the strings are extended character strings, a short indicating how many strings are included in the string table, another short indicating the size in bytes of the extra data stored with each string and each string followed by the extra data. non-extended charater pascal strings begin with a single byte length count which describes how many characters follow the length byte in the string. if pst is a pointer to an array of characters storing a pascal style string then the length of the string is *pst+1. in an sttbf pascal style strings are concatenated one after another until the length of the sttbf recorded in the fib is exhausted. extra data associated with a string may also be stored in an sttbf. when extra data is stored for an sttbf, it is written at the end of each string. for example: the extra data for an sttbf consists of a short. if the string "cat" were stored, the actual entry in the string table would consist of a length byte containing 3 (3 for "cat") followed by the bytes 'c' 'a' 't', followed by the 2 bytes containing the short. extended character strings are stored just the same, except they have a double byte length count and each extended character occupies two bytes.

full-saved (or non-complex) file:

a word file in which the physical order of characters stored in the file is identical to the logical order of characters in the document that the file represents. the text stream of a non-complex file can be described by an fc (an offset from the beginning of the file) to mark where the text begins and a ccp (count of cps) to record how many characters are stored in the text stream. due to unicode compression to code page 1252, all files (simple and complex) now contain a piece table. however, a full-saved piece table will not have property modifiers (prms) and all text in the file will be referenced by the piece table.

fast-saved (or complex) file:

a word file in which the physical order of characters stored in the file does not match the logical order of characters in the document that the file represents. a piece table must be stored in the file to describe the text stream of the document. due to unicode compression to code page 1252, all files (simple and complex) now contain a piece table.

fib (file information block):

the header of a word file. begins at offset 0 in file. gives the beginning offset and lengths of the document's text stream and subsidiary data structures within the file. also stores other file status information.

paragraph

a contiguous sequence of characters within the text stream of a document that is delimited by a paragraph mark, cell mark, row mark, or a section mark (these are special characters described later in this document).

run of text

a contiguous sequence of characters within the text stream of a document that have the same character formatting properties. a single run may cross paragraph boundaries and may encompass the entire document.

section

a contiguous sequence of paragraphs within the text stream of a document that is delimited by a section mark or by the final paragraph mark at the end of a document. users frequently treat sections as the equivalent of a chapter in a book. the boundaries of sections mark locations where the layout rules for a document (number of columns, text of headers and footers to use, whether page numbers should be displayed, etc.) are changed.

paragraph style

a named set of character and paragraph properties that can be associated with any number of paragraphs in a word document's text stream. a paragraph style provides a set of character and paragraph property defaults for the text of any paragraph tagged with that style. when a new paragraph is created and given a particular style, newly typed text is given the character and paragraph properties of that style unless the user makes an exception to the paragraph style definition by performing other editing operations.

chp (character properties)

the data structure describing the character properties of a run of text.

chpx (character property exception)

a data structure which describes how a particular chp differs from a reference chp. in win word 6.0, the chpx simply consists of a grpprl which is applied to the reference chp to produce the originally encoded chp. by applying a chpx to the character properties (chp) inherited by a particular paragraph from its style, it is possible to reconstitute the chp for the portion of the character run that intersects that paragraph

character style

a named character property exception that can be associated with any number of runs of text in a word document's text stream. when a run of text is tagged with a particular character style, a chpx recorded for the character style is applied to the character properties that are defined for the paragraph style of the paragraph that contains the text. this means that the character style can change one or more of the character property field settings specified by the paragraph style of a paragraph to a particular setting without changing the value of any other field.

pap (paragraph properties)

the data structure which describes the properties of a particular paragraph.

papx (paragraph property exception)

a data structure describing how a particular paragraph's properties differ from the paragraph properties of the style assigned to the paragraph. by applying a papx to the paragraph properties (pap) inherited by a particular paragraph from its style, it is possible to reconstitute the pap for that paragraph. the papx contains an istd (a style code to identify the style in control of the paragraph and a grpprl which specifies how the style's paragraph properties must be changed to produce the paragraph properties of the paragraph.

table row:

a contiguous sequence of paragraphs within the text stream of a document that is partitioned into subsequences of paragraphs called cells. the last paragraph of each cell is terminated by a special paragraph mark called a cell mark. following the cell mark that ends the last cell of a table row, the table row is terminated by a special paragraph mark called a row mark. when word displays a table row, it assigns a rectangular shaped display area to each cell in the row. all of the cell display area's top's are aligned at the same vertical position on a page. the leftmost display area in a table row is assigned to the 0th cell of the row; the next display area to the right is assigned to the 1st cell of the row, etc. the text of the cell is wrapped to fit its display area. as more text is added to the cell, the cell display area extends downward. a set of table properties that determine how many cells are in a row, where the horizontal boundaries of cell display areas are, and what borders are drawn around each cell in the table is stored for the row mark that marks the end of the table row.

tap (table properties):

the data structure which describes the properties of a single table row. the information in the tap for a table row is stored in a word file as a list of sprms that modify a tap which has been cleared to zeros. this list of table sprms is appended to the grpprl of paragraph sprms that is recorded in the papx for the row mark that delimits the end of a table row.

stsh (style sheet)

a data structure which represents every style defined within the word document. the stsh records a unique name string for every style and associates each name with a particular chp and/or a pap. the indexes used to refer to individual styles are called istds (indexes to style descriptors). every papx for every paragraph recorded in a document contains an istd which identifies the style from which a paragraph inherited its default character and paragraph properties. chpxs recorded for the text within the paragraph and papxs recorded for the paragraph itself encode changes that the user has made with respect to the style's default properties.

fkp (formatted disk page):

a data structure that fits in one 512-byte page that encodes either the character properties or the paragraph properties of a certain portion of a microsoft word file. an fkp consists of four components:

1) a count of the number of runs or paragraphs described by the page.

2) an array of fcs recorded in ascending order demarcating the boundaries between runs or paragraphs that are recorded adjacent to one another in the word file.

3) in character fkps an array of offsets within the fkp in one to one correspondence with the array of fcs that locate the properties of the run that begins at a particular fc.

in lvc fkps an array of offsets within the fkp in one to one correspondence with the array of fcs that locate the lvcxs that describe the run that begins at a particular fc.

in paragraph fkps an array of bx structures follows the array of fcs in one to one correspondence with the array of fcs. each bx begins with an offset that locates the properties of the paragraph that begins at a particular fc. the remainder of the bx contains a phe structure that encodes information about the height of the paragraph that begins at that fc.

4) a group of chpxs if the fkp stores character properties, a group of papxs if the fkp stores paragraph and table properties, or a group of lvcxs if the fkp stores paragraph level and numbering cache information

to find the chpx/papx corresponding to a particular character in a document, calculate the fc coordinate for that character. then search through the bin table (see next entry) for the type of property you want to produce, to find the fkp in the document stream whose array of fcs encompasses the fc of the document character.

then search within the fkp to find the index of the largest fc entry that is less than or equal to the fc of the document character. use this index to look up an offset in the array of offsets (for character fkps) or look up an offset in the array of bxs (for paragraph fkps) within the fkp. add this offset to the beginning address of the fkp in memory. this will be the first byte of the desired chpx/papx.

bin table

each fkp can be viewed as bucket or bin that contains the properties of a certain range of fcs in the word file. in word files, a plc, the plcfbte (plex of fcs containing bin table entries) is maintained. it records the association between a particular range of fcs and the pn (page number) of the fkp that contains the properties for that fc range in the file. in a complex (fast-saved) word document, fkp pages are intermingled with pages of text in a random pattern which reflects the history of past fast saves. in a complex document, a plcfbtechpx which records the location of every chpx fkp must be stored and a plcfbtepapx which records the location of every papx fkp must be stored. in a non-complex, full-saved document, all of the chpx fkps are recorded in consecutive 512-byte pages with the fkps recorded in ascending fc order, as are all of the papx fkps. a plcfbtelvcx serves the same purpose for lvcx fkps.

in a full save document, the plcfbte's may not have been able to be expanded during the save process due to a lack of ram. in that situation, the plcfbte's will be interspersed with the property pages in a linked list of fbd pages.

sep(section properties)

the data structure describing the properties of a particular section.

sepx(section property exceptions)

a data structure describing how the properties of a particular section differ from a word-defined standard sep. as in the papx, the differences between the sep for a section and the standard sep are encoded as list of sprms that describe how the standard sep can be transformed into the section's sep. by applying a sepx's sprms to the standard sep, it is possible to reconstitute the sep for that section.

the plcfsed, a data structure stored in a word file, records the locations of all sepxs stored in a word file. the array of cps in the plcfsed records the boundaries of sections in the word document . the second array in the plcf, an array of seds (section descriptors), is in 1-to-1 correspondence to the array of cps. each sed stores the beginning fc of the sepx that records the properties for a section. if the fc stored in a sed is -1, the section properties of the section are exactly equal to the standard section properties.

the sep for a particular section may be constructed if a cp of a character in that section is known. first search the array of cps in the plcsed for the index of the largest cp that is less than or equal to the cp of the character. use this index to locate the sed in the plcfsed which describes the section. the fc stored in the sed is the offset from the beginning of the word file at which the sepx is stored. if the stored fc is equal to 0xffffffff, then the sep for the section is exactly equal to the standard sep (see sep structure definition) otherwise, read the sepx into memory and create a copy of the standard sep. finally, apply the sprms stored in the sepx to the standard sep to produce the sep for a section.

dop (document properties)

the data structure describing properties that apply to the document as a whole.

sub-document

a separate logical stream of text with properties for which correspondences with the main document text are maintained. word's headers/footers, footnotes, endnotes, macro procedure text, annotation text, and text within textboxes are kept in separate subdocuments. each subdocument has its own cp coordinate space. in other words, data structures are stored in word files that are components of these subdocuments. these data structures contain cp coordinates whose 0 point is the beginning of the subdocument text stream instead of the beginning of the main document text stream.

in full-saved documents, a simple calculation with values stored in the fib produces the file offset of the beginning of the subdocument text streams (if they exist). the length of these streams is also stored.

in fast-saved documents, the piece tables of subdocuments are concatenated to the end of the main document piece table. in this case, to identify the beginning of subdocument text , you must sum the length of the main document text stream with the lengths of any subdocument text streams stored ahead of the subdocument (information stored in the fib) and treat this sum as a cp coordinate. to retrieve the text of the subdocument, you must do lookups in the piece table, starting with the piece that contains the beginning cp coordinate, to find the physical location of each piece of the subdocument text stream.

field

a field is a two-part structure that may be recorded in the cp stream of a document. the first part of the structure contains field codes which instruct window's word to insert text into the second part of the structure, the field result. fields in window's word are used to insert text from an external file or to quote another part of a document, to mark index and table of contents entries and produce indexes and tables of contents, maintain dde links to other programs, to produce dates, times, page numbers, sequence numbers, etc. there are 91 different field types.

a field begin mark delimits the beginning of a field and precedes any of the field codes stored in the field. the end of the field codes and the beginning of the field result is marked with the field separator and the field result and the field itself are terminated by a field end mark.

the cp locations of the field begin mark, field separator, and field end mark are recorded in plcfld data structures that are maintained for the main document and all of the subdocuments of the main document whenever a field is inserted or edited. a field can be dead, in which case it has no field separator, no field result, and no entry in the plcfld. (see the definition of the fld structure for a list of possible dead field code strings.) an array of two-byte fld structures is stored in the plcfld in one-to-one correspondence with the cp entries recorded. an fld associated with a field begin mark records the type of the field. an fld associated with the field end mark records the current status of the field (i.e. whether the result is dirty or has been edited, whether the result has been locked, etc.)

fields may be nested. 20 levels of nesting are permitted.

bookmark

a bookmark associates a user definable name with a range of text within a document. a bookmark is frequently used as an operand in field code instructions within a field. in window's word a bookmark is represented by three parallel data structures, the sttbbkmk, the plcbkf and the plcbkl. the sttbbkmk is a string table which contains the name of each bookmark that is defined. the plcbkf records the beginning cp position of each bookmark. the plcbkl records the limit cp position that delimits the end of a bookmark. since bookmarks may be nested within one another to any level, the bkf structure stored in the plcbkf consists of a single index which specifies which plcbkl marks the end of the bookmark. the bkl structure is not written to the file, and the plcbkl contains only cps.

picture

a picture is represented in the document text stream as a special character, an ascii 1 whose chp has the fspec bit set to 1. the file location of the picture in the word binary file is stored in the character's chp in chp.fcpic. the fcpic is a byte offset into the data stream. beginning at the position recorded in chp.fcpic, a header data structure, the pic, will be stored. if the picture is a reference to a tiff file, a picture file or an office shape file, the name of the file will be recorded immediately following the pic in a pascal style string. if the picture is an office shape, a window's metafile or a bitmap, the shape, metafile or bitmap will immediately follow the pic. pictures that are a reference to an office shape file will include both the filename and the shape in that order. pictures inserted with word97 are in the new office shape format (documented elsewhere). however, pictures can be copied from older files into newer ones and their old format will persist until the picture is edited or displayed.

some files (including all files created by word for the macintosh) may store macintosh pict pictures as well. in this case, the pic structure is immediately followed by a standard windows metafile depicting a large "x", so that older readers expecting only a metafile after the pic will just display this "x". if a reader detects this standard "x" metafile, it can extract the sizes of the standard "x" metafile and the macintosh pict picture that follows it from an early portion of this "x" metafile. please see appendix b for a discussion of this technique.

embedded object

the native data for embedded objects (objs) is stored similarly to pictures (pics). to locate the native data for embedded objects, scan the plc of field codes for the mother, header, footnote and annotation, textbox and header textbox documents (fib.plcffldmom/hdr/ftn/atn/txbx/hdrtxbx). for each separator field, get the chp.

if chp.fspec=1 and chp.fobj=1, then this separator field has an associated embedded object. the file location of the object data is stored in chp.fcobj. at the specified location an object header is stored followed by the native data for the object. see the _objheader structure.

if chp.fole2=1, then this separator field has an associated ole2 object. the fcpic will be a unique integer that specifies the name of the object's sub-storage instead of an offset into the data stream.

office art object

an office art object is represented in the document stream as a special character, an ascii 8, which has chp.fspec set to 1 for the run of text containing the character . only main documents and header documents contain office art objects. the native data for the office art object may be obtained by taking the cp for the special character and using this to find the corresponding entry in the plcspa. an entry in this plc consists of a fspa structure, which is described elsewhere in this document.

office art objects can have text attached to them. text for the textboxes is stored separately in the textbox subdocument of the main or header document. the textbox subdocument contains a plctxbxs where the text from cp n to cp n+1 in the subdocument is the text which is contained in a textbox as specified in the txbxs structure for this nth entry in the plctxbxs. textboxes can be linked in chains of up to 32 textboxes. ordering of textboxes in the subdocument is completely unrelated to the document structure due to the nature of textbox linking. to find the text for a given office art object, the txid property (a long: high word is itxbxs+1, low word is the sequence number) must be fetched from the office art data for the shape. this contains an index (itxbxs) into plctxbxs and a sequence number in the chain of linked textboxes. the text for the entire chain of linked textboxes is stored from the cp itxbxs to cp itxbxs+1 of plctxbxs. the plctxbxbkd describes the "page table" within textbox stories (where the textboxes in each linked textbox chain are thought of as "pages"). so, for each entry in the plctxbxs there is a corresponding entry in the plctxbxbkd at the same cp, and there may be additional entries in the plctxbxbkd to describe the breaks from one textbox to the next in linked textbox chains.

note

in this document, bit 0 is the low-order bit. structures are described as they would be declared in c for the intel architecture. when numbering bytes in a word from low offset towards high offset, two-byte integers will have their least significant eight bits stored in byte 0 and most significant eight bits in byte 1. if bit 31 is the most significant bit in a four-byte integer, bits 31 through 24 will be stored in byte 3 of a four-byte integer, bits 23 through 16 will be stored in byte 2, bits 15 through 8 will be stored in byte 1, and bits 7 through 0 will be stored in byte 0.

naming conventions

the names in word data structures usually consist of a lower case sequence of characters followed by an optional upper case modifier. the following tags are used in the lower case parts of field names to document the data type of a field:

f used to name a flag (a variable containing a boolean value). usually the object referred to will contain either 1 (ftrue, true) or 0 (ffalse, false). (e.g. fwidowcontrol, fshadow)
l used to name a 4 byte integer value ( a long). (e.g. lcb)
w used to name a 2 byte integer value (a short ).
b used to name a 1 byte integer value
cp used to name a variable that contains a character position within the document. always a 4 byte quantity.
fc used to name a variable that contains an offset from the beginning of a file. always a 4 byte quantity.
xa used to name a variable that contains a width of an object imaged on screen or on hard copy that is measured in units of 1/1440 of an inch. this unit which is one-twentieth of a point size (1/20 * 1/72") is called a twip in this documentation. (e.g. xapage is the width of a page).
ya used to name a variable that contains a height of an object imaged on screen or on hard copy that is measured in twips.
dxa used to name a variable that contains the horizontal distance of an object measured from some reference point expressed in twips. (e.g. pap.dxaleft is the distance of the left boundary of a paragraph measured from the left margin of the page)
dya used to name a variable that contains the vertical distance of an object measured from some reference point expressed in twips. (e.g. pap.dyaabs is the vertical distance of the top of a paragraph from a reference frame declared in the pap).
dxp used to name a variable that contains the horizontal distance of an object measured from some reference point expressed in macintosh pixel units (1/72"). (e.g. dxpspace)
dyp used to name a variable that contains the vertical distance of an object measured from some reference point expressed in macintosh pixel units (1/72").
rg prefix used to signify that the data structure being defined is an array. (e.g. rgb (an array of bytes), rgcp (an array of cps), rgfc (an array of fcs), rgfoo (an array of foos).
i prefix used to signify that an integer value is used as an index into an array. (e.g. itbd is an index into rgtbd, itc is an index into rgtc.)
c prefix used to signify that an integer value is a count of some number of objects. (e.g. a cb is a count of bytes, a cl is a count of lines, ccol is a count of columns, a cpe is a count of picture elements.)
grp prefix used to name an array of bytes that contains one or more copies of a variable length data structure with the instances of the data structure stored one after the other in the array. (e.g. a grpprl is a array of bytes that stores a group of prls.)
grpf prefix used to name an integer or byte value whose bits are used as flags. (e.g. grpfihdt is a group of flags that records the types of headers that are stored for a particular section of a document).

the two following modifiers are used occasionally in this documentation:

first means that variable marks the first of a range of objects. for example, cpfirst would mark the first character position of a range of characters in a document. fcfirst would mark the file offset of the first byte of a range of bytes stored in a file.
lim means the variable marks the limit of a range of objects (i.e. is the index of the last object in a range plus 1). for example, cplim would be the limit cp of a range of characters in a document. fclim would be the limit file offset of a range of bytes stored in a file.

format of the summary info stream in a word file

the summary information for a word document is stored in two structured storage streams, summaryinformation and documentsummaryinformation. information on the layout of the summaryinformation stream can be found in appendix b of the ole 2 programmers reference.

format of the main stream in a word non-complex file

the main stream of a word docfile (non-complex format) consists of the word file header (fib), the text, and the formatting information.

fib
stored at beginning of page 0 of the file. fib.fcomplex will be set to zero.
text of body, footnotes, headers
text begins at the position recorded in fib.fcmin.
fkps for chps, paps and lvcs
the first fkp begins at a 512-byte boundary after the last byte text written.. the remaining fkps are recorded in the 512-byte pages that immediately follow. the fkps for chps paps and lvcs are interleaved. previous versions of word wrote them in contiguous chunks. the hplcfbte's of the three flavors (chp, pap and lvc) are used to find the relevant fkp of the appropriate type.
group of sepxs
sepxs immediately follow the fkps and are concatenated one after the other. sepxs are no longer guaranteed to start on a page boundary if it would span a boundary if placed immediately after the preceding sepx.

format of the main stream in a complex file

the main stream of a word binary file (complex format) consists of the word file header (fib), the text, and the formatting information.

fib
text of body, footnotes, headers stored during last full save
text begins at the position recorded in fib.fcmin.
fkps for chps, paps and lvcs
the first fkp begins at a 512-byte boundary after the last byte text written.. the remaining fkps are recorded in the 512-byte pages that immediately follow. the fkps for chps paps and lvcs are interleaved. previous versions of word wrote them in contiguous chunks. the hplcfbte's of the three flavors (chp, pap and lvc) are used to find the relevant fkp of the appropriate type.
group of sepxs stored during last full save
any text, stored during first fast save
any fkps stored during first fast save
any sepxs stored during first fast save
any text, stored during second fast save
any fkps stored during second fast save
any sepxs stored during second fast save
...
any text, stored during nth fast save
any fkps stored during nth fast save
any sepxs stored during nth fast save

format of the table stream

word stores various plcfs and tables with the stream named either "0table" or "1table". ordinarily a file will contain only one table stream. however, in some unusual circumstances (e.g. crash during file save) a file might have two table streams. in that case the bit field fwhichtblstm in the fib should be used to determine which table stream to read. if fwhichtblstm is 0, then the fib refers to the stream named "0table", and if fwhichtblstm is 1, then the fib refers to the stream name "1table".

sttbfussr
undocumented undo / versioning data
plcupcrgbuse
undocumented undo / versioning data
plcupcusp
undocumented undo / versioning data
uskf
undocumented undo / versioning data
stsh (style sheet)
written immediately after the preivous table. this is recorded in all word documents.
plcffndref (footnote reference position table)
written immediately after the stsh if the document contains footnotes
plcffndtxt (footnote text position table)
written immediately after the plcffndref if the document contains footnotes
pgdftn (footnote text page description table)
written immediately after the plcffndtxt if the document contains footnotes
bkdftn (footnote text break descriptor table)
written immediately after the pgdftn if the document contains footnotes.
plcfendref (endnote reference position table)
written immediately after the previously recorded table if the document contains endnotes
plcfendtxt (endnote text position table)
written immediately after the plcfendref if the document contains endnotes
pgdedn (endnote text page description table)
written immediately after the plcfendtxt if the document contains endnotes
bkdedn (endnote text break descriptor table)
written immediately after the pgdedn if the document contains endnotes
plcftxbxtxt (text box link table)
written immediately after the previously recorded table if the document contains textboxes
plcftxbxbkd (text box break descriptor table)
written immediately after the plcftxbxtxt if the document contains textboxes
plcfhdrtxbxtxt (header text box link table)
written immediately after the previously recorded table if the header subdocument contains textboxes
plcfhdrtxbxbkd (header text box break descriptor table)
written immediately after the plcfhdrtxbxtxt if the header subdocument contains textboxes.
grpxstatnowners (annotation owner table)
written immediately after the previously recorded table if the document contains annotations.
plcfandref (annotation reference position table)
written immediately after the grpxstatnowners if the document contains annotations
plcfandtxt (annotation text position table)
written immediately after the plcfandref if the document contains annotations.
plcfsed (section table)
written immediately after the previously recorded table. recorded in all word documents
pgdmother (page description table)
written immediately after the plcfsed in all word documents
bkdmother (break descriptor table)
written immediately after the pgdmother in all word documents
plcfphe (paragraph height table)
written after the previously recorded table, if paragraph heights have been recorded. only written during a fast save.
plcfsea (private)
plcf reserved for private use by word.
plcflvc (list and outline level table)
written immediately after the previously recorded table during fast save only.
plcasumy (autosummary analysis)
written immediately after the previously recorded table, if the document stored is in autosummary view mode.
sttbglsy (glossary name string table)
written immediately after the previously recorded table, if the document stored is a glossary.
sttbglsystyle (glossary style name string table)
written immediately after sttbglsy, if the document stored is a glossary.
plcfglsy (glossary entry text position table)
written immediately after the previously recorded table, if the document stored is a glossary.
plcfhdd (header text position table)
written immediately after the previously recorded table, if the document contains headers or footers.
plcfbtechpx (bin table for chp fkps)
written immediately after the previously recorded table. this is recorded in all word documents.
plcfbtepapx (bin table for pap fkps)
written immediately after the plcfbtechpx. this is recorded in all word documents.
plcfbtelvc (bin table for lvc fkps)
written immediately after the plcfbtepapx. this is recorded in all word documents.
sttbfrmark (revision mark author string table)
written immediately after plcfbtelvc, if the document contains revision marks.
plcffldmom (table of field positions and statuses for main document)
written immediately after the previously recorded table if the main document contains fields.
plcffldhdr (table of field positions and statuses for header subdocument)
written immediately after the previously recorded table, if the header subdocument contains fields.
plcffldftn (table of field positions and statuses for footnote subdocument)
written immediately after the previously recorded table, if the footnote subdocument contains fields.
plcffldatn (table of field positions and statuses for annotation subdocument)
written immediately after the previously recorded table, if the annotation subdocument contains fields.
plcffldedn (table of field positions and statuses for endnote subdocument)
written immediately after the previously recorded table, if the endnote subdocument contains fields.
plcffldtxbx (table of field positions and statuses for textbox subdocument)
written immediately after the previously recorded table, if the textbox subdocument contains fields.
plcocx (ocx position table)
written immediately after the previously recorded table, if the document contains ole controls. undocumented.
plcffldhdrtxbx (table of field positions and statuses for textbox subdocument of header subdocument)
written immediately after the previously recorded table, if the textbox subdocument of the header subdocument contains fields.
dgginfo (office drawing information)
written immediately after the previously recorded table. format is described in the office drawing group format document.
plcspamom (office drawing table)
written immediately after the previously recorded table, if the document contains office drawings.
plcspahdr (header office drawing table)
written immediately after the previously recorded table, if the header subdocument contains office drawings.
sttbfbkmk (table of bookmark name strings)
written immediately after the previously recorded table, if the document contains bookmarks.
plcfbkmkf (table recording beginning cps of bookmarks)
written immediately after the sttbfbkmk, if the document contains bookmarks.
plcfbkmkl (table recording limit cps of bookmarks)
written immediately after the plcfbkmkf, if the document contains bookmarks.
sttbfatnbkmk (table of annotation bookmark string names)
written immediately after the previously recorded table, if the document contains annotations with bookmarks.
plcfatnbkf (table recording beginning cps of bookmarks in the annotation subdocument)
written immediately after the sttbfatnbkmk previously recorded table, if the document contains annotations with bookmarks.
plcfatnbkl (table recording limit cps of bookmarks in the annotation subdocument)
written immediately after the plcfatnbkf previously recorded table, if the document contains anotations with bookmarks.
plcfspl (spelling state table)
written immediately after the previously recorded table. records state of spell checking in a plcf of spls structures.
plcfgram (grammar state table)
written immediately after the previously recorded table. records state of grammar checking in a plcf of spls structures.
plcfwkb (work book document partition table)
written immediately after the previously recorded table, if the document is a master document.
formfldsttbs (form field dropdown string tables)
written immediately after the previously recorded table, if the document contains form field dropdown controls.
sttbcaption (caption title string table)
written immediately after the previously recorded table, if the document contains captions.
sttbautocaption (auto caption string table)
written immediately after the previously recorded table, if the document contains auto captions.
sttbfnm (filename reference string table)
written immediately after the previously recorded table, if the document references other documents.
sttbsavedby (last saved by string table)
written immediately after the previously recorded table.
plcflst (list formats)
written immediately after the end of the previously recorded, if there are any lists defined in the document. this begins with a short count of lstf structures followed by those lstf structures.
this is immediately followed by the allocated data hanging off the lstfs. this data consists of the array of lvls for each lstf. (each lvl consists of an lvlf followed by two grpprls and an xst.)
plflfo (more list formats)
written immediately after the end of the plcflst and its accompanying data, if there are any lists defined in the document. this consists first of a pl of lfo records, followed by the allocated data (if any) hanging off the lfos. the allocated data consists of the array of lfolvlfs for each lfo (and each lfolvlf is immediately followed by some lvls).
sttbflistnames (more list formats)
written immediately after the end of the plflfo and its accompanying data, if there are any lists defined in the document. this is a string table containg the list names for each list. it is parallel with the plcflst, and may contain null strings if the corresponding lst does not have a list name.
hplgosl (grammar option settings)
written immediately after the previously recorded table. this undocumented structure maps lid and grammar checker type to grammar checking options.
stwuser (macro user storage)
routeslip (mailer routing slip)
written immediately after the previously recorded table, if this document has a mailer routing slip.
cmds (recording of command data structures)
written immediately after the previously recorded table, if special commands are linked to this document.
prdrvr (printer driver information)
written immediately after the previously recorded table, if a print environment is recorded for the document.
prenvport (print environment in portrait mode)
written immediately after the previously recorded table, if a portrait mode print environment is recorded for this document.
prenvland (print environment in landscape mode)
written immediately after the previously recorded table, if a landscape mode print environment is recorded for this document.
wss (window state structure)
written immediately after the end of previously recorded structure, if the document was saved while a window was open.
pms (print merge state)
written immediately after the previously recorded table, if information about the print / mail merge state is recorded for the document
clx (encoding of the sprm lists for a complex file and piece table for a any file)
written immediately after the end of previously recorded structure. this is recorded in all word documents.
sttbfffn (table of font name strings)
written immediately after the clx. this is recorded in all word documents. the sttbfffn is an sttbf where each string is instead an ffn structure (note that just as for a pascal-style string, the first byte in the ffn records the total number of bytes not counting the count byte itself). the names of the fonts correspond to the ftc codes in the chp structure. for example, the first font name listed corresponds is the name for ftc = 0.
sttbttmbd (true type font embedding string table)
written immediately after the end of previously recorded structure if document contains embedded true type fonts.
dop (document properties record)
written immediately after the end of previously recorded structure. this is recorded in all word documents
sttbfassoc (table of associated strings)
autosavesource (name of original)
written immediately after the sttbfassoc table. this field only appears in autosave files. these files are normal word documents in every other way. also, autosaved files are typically in the complex file format except that we don't overwrite the tables (plcf*, etc.). i.e., an autosaved file is typically longer than the equivalent word document.

format of the data stream

pictures
word picture structures are concatenated one after the other if the document contains pictures.
embedded objects-native data
word embedded object structures are concatenated one after the other if the document contains embedded objects.
huge papxs
the grpprls from papxs which are too large to fit in an fkp are concatenated one after the other as necessary.

fib

the fib contains a "magic word" and pointers to the various other parts of the file, as well as information about the length of the file. the fib starts at the beginning of the file. the fib is defined in the structure definition section of this document.

text

the text of the file starts at fib.fcmin. fib.fcmin is usually set to the next 128 byte boundary after the end of the fib. the text in a word document is ascii text with the following restrictions (ascii codes given in decimal):\

the following ascii codes are treated as "special" characters when they have the character property special on (chp.fspec == 1):

ascii code special character
0 current page number
1 picture
2 autonumbered footnote reference.
3 footnote separator character
4 footnote continuation character
5 annotation reference
6 line number
7 hand annotation picture (generated in pen windows)
8 drawn object
10 abbreviated date (e.g. "wed, dec 1, 1993")
11 time in hours:minutes:seconds
12 current section number
14 abbreviated day of week (e.g. "thu" for "thursday")
15 day of week (e.g. "thursday")
16 day short (e.g. "9" for the ninth day of the month)
22 hour of current time with no leading zero
23 hour of current time (two digit with leading zero when necessary)
24 minute of current time with no leading zero
25 minute of current time(two digit with leading zero when necessary)
26 seconds of current time
27 am/pm for current time
28 current time in hours:minutes:seconds in old format
29 date m (e.g. "december 2, 1993")
30 short date (e.g. "12/2/93")
33 short month (e.g. "12" to represent "december")
34 long year (e.g. "1993")
35 short year (e.g. "93")
36 abbreviated month (e.g. "dec" to represent "december")
37 long month (e.g. "december")
38 current time in hours:minutes (e.g. "2:01")
39 long date (e.g. "thursday, december 2, 1993")
41 print merge helper field

note

the end of a section is also the end of a paragraph. the last character of a section is a section mark which stands in place of the paragraph mark normally required to end a paragraph. an exception is made for the last character of a document which is always a paragraph mark although the end of a document is always an implicit end of section.

if !fib.fcomplex, the document text stream is represented by the text beginning at fib.fcmin up to (but not including) fib.fcmac. otherwise, the document is represented by the piece table stored in the file in the data beginning at .fib.fcclx.

the document text stream includes text that is part of the main document, plus any text that exists for the footnote, header, macro, or annotation subdocuments. the sizes of the main document and the header, footnote, macro and annotation subdocuments are stored in the fib, in variables fib.ccptext, fib.ccpftn, fib.ccphdr, fib.ccpmcr, fib.ccpedn, fib.ccptxbx, fib.ccphdrtxbox and fib.ccpatn respectively. in a non-complex file, this means that the text of the main document begins at fib.fcmin in the file and continues through fib.fcmin + fib.ccptext; that the text of the footnote subdocument begins at fib.fcmin + fib.ccptext and extends to fib.fcmin + fib.ccptext + fib.ccpftn; that the text of the header subdocument begins at fib.fcmin + fib.ccptext + fib.ccpftn and extends to fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr; that the text of the annotation subdocument begins at .fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr and extends to fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr + ccpatn; that the text of the endnote subdocument begins at .fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr +ccpatn and extends to fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr + fib.ccpedn; that the text of the textbox subdocument begins at .fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr +fib.ccpatn + fib.ccpedn and extends to fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr + fib.ccpedn + fib.ccptxbx and that the text of the header textbox subdocument begins at .fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr +fib.ccpatn + fib.ccpedn + fib.ccptxbx and extends to fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr + fib.ccpedn + fib.ccptxbx + fib.ccphdrtxbx.

in a complex, fast-saved file, the main document text must be located by examining the piece table entries from the 0th piece table entry through the piece table entry that describes cp = fib.ccptext.

a footnote subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext through the entry that describes cp = fib.ccptext + fib.ccpftn.

a header subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext + ccpftn through the entry that describes cp = fib.ccptext +fib.ccpftn + fib.ccphdr.

an annotation subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext + ccpftn + fib.ccphdr through the entry that describes cp = fib.ccptext +fib.ccpftn + fib.ccphdr +fib.ccpatn.

an endnote subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext + ccpftn + fib.ccphdr + fib.ccpatn through the entry that describes cp = fib.ccptext +fib.ccpftn + fib.ccphdr +fib.ccpatn.+ fib.ccpedn

a textbox subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext + ccpftn + fib.ccphdr + fib.ccpatn + fib.ccpedn through the entry that describes cp = fib.ccptext +fib.ccpftn + fib.ccphdr +fib.ccpatn.+ fib.ccpedn + fib.ccptxbx

a header textbox subdocument's text must be located by examining the piece table entries beginning with the one that describes cp=fib.ccptext + ccpftn + fib.ccphdr + fib.ccpatn + fib.ccpedn + fib.ccptxbx through the entry that describes cp = fib.ccptext +fib.ccpftn + fib.ccphdr +fib.ccpatn.+ fib.ccpedn + fib.ccptxbx+ fib.ccphdrtxbx

character and paragraph formatting properties

character and paragraph properties in word documents are stored in a compressed format. the information that is stored on disk is not the actual properties of a particular sequence of text but the difference of the properties of a sequence from some reference property.

the pap is a data structure that holds uncompressed paragraph property information; the chp (pronounced like "chip") is a structure that holds uncompressed character property information. each paragraph in a word document inherits a default set of paragraph and character properties from one of the paragraph styles recorded in the style sheet data structure (stsh).

a particular pap is converted into its compressed form, the papx, by first comparing the pap for a paragraph with the pap stored in the style sheet for the paragraph's style. any properties in the paragraph's pap that are different from those stored in the style sheet pap are encoded as a list of sprms (grpprl). sprms express how the content of the style sheet pap should be transformed to create the properties for the paragraph. a papx is a variable-length data structure that begins with a count of words that encodes the papx length. it contains a istd (index to style descriptor) which specifies which style entry in the style sheet contains the default paragraph and character properties for the paragraph, paragraph height information, and the list of difference sprms. if the only difference between the paragraph's pap and the style's pap were in the justification code field, which is one byte long, one two-byte sprm, sprmpjc, would be generated to express that difference; thus the total papx size would be 5 bytes. this is better than 54-1 compression since the total size of a pap is 274 bytes.

to convert a chp for a sequence of characters contained within a single paragraph into its compressed form, the chpx, it's first necessary to know the paragraph style that is assigned to the paragraph containing those characters and any character style that may be tagging the character run. the character properties inherited from the paragraph style are moved into a buffer. if the chp.istd of the chp to be compressed is not istdnormalchar, the changes recorded for that character style are applied to buffer. then the character properties of the character sequence are compared with the character properties generated using the paragraph's style and the run's character style. any properties in the paragraph's chp that are different from those stored in the generated chp are encoded as a list of sprms (grpprl). the sprms express how the content of the chp generated from the paragraph and character styles should be transformed to create the character properties for the text run. a chpx is a variable-length data structure that begins with a count of words that encodes the chpx length followed by the list of difference sprms.

if one of the bit fields in the chp to be compressed such as fbold is different from the reference chp, you would build a difference sprm using sprmcfbold in the first byte and the bytes pattern 0x81 in the second byte which signifies that the value of the bit in the chp to be compressed is of opposite value from the value stored in the reference chp. if there was no difference, sprmcfbold would not be recorded in the grrprl to be generated. if there were difference in a field larger than a single bit such as the chp.hps, a sprmchps would be generated to record the value of chp.hps in the chp to be compressed. if the chp.hps were equal in both the chp to be compressed and the reference chp, sprmchps would not be recorded in the grrprl that is generated. if a sequence of characters has the same character properties and the sequence spans more than one paragraph, it's necessary to examine each paragraph's properties and to generate a different chpx every time there is a change of style.

in word documents, the fundamental unit of text for which character exception information is kept is the run of exception text, a contiguous sequence of characters stored on disk that all have the same exception properties with respect to their underlying style character properties. each run would have an entry recorded in a chpx fkp. if a user never changed the character properties inherited from the styles used in his document and did a complete save of his document, although each of those styles may have different properties, the entire document stream would be one large run of exception text and one chpx would suffice to describe the character properties of the entire document.

the fundamental unit of text for which paragraph properties are recorded is the paragraph. every paragraph has an entry recorded in a papx fkp.

the chpx fkp and the papx fkp have similar physical structures. an fkp is a 512-byte data structure that is stored in one page of a word file. at offset 511 is a 1-byte count named crun, which is a count of runs of exception text for chpx fkps and which is a count of paragraphs in papx fkps. beginning at offset 0 of the fkp is an array of crun+1 fcs, named rgfc, which records the beginning and limit fcs of crun runs of exception text or paragraphs.

for chpx fkps, immediately following fkp.rgfc is a byte array of crun word offsets to chpxs from the beginning of the fkp. this byte array, named rgb, is in 1-to-1 correspondence with the rgfc. the ith rgb gives the word offset of the exception property that belongs to the run\paragraph whose beginning

for papx fkpss, immediately following the fkp.rgfc is an array of 13 byte entries called bxs. this array called the rgbx is in 1-to-1 correspondence with the rgfc. the first byte of the ith bx entry contains a single byte field which gives the word offset of the papx that belongs to the paragraph whose beginning in fc space is rgfc[i] and whose limit is rgfc[i+1] in fc space. the last 12 bytes of the ith bx entry contain a phe structure that stores the current paragraph height of the paragraph whose beginning in fc space is rgfc[i] and whose limit is rgfc[i+1] in fc space.

the fact that the offset to property stored in the rgb or rgbx is a word offset implies that chpxs and papxs are stored in fkps beginning on word boundaries. since the values stored in the rgb/rgbx allow random access throughout the fkp, space within an fkp can be conserved by storing the offset of the same physical chpx/papx in rgb/rgbx entries when several runs or paragraphs in the fkp have the same properties. word uses this optimization.

an rgb or rgbx[].b value of 0 is used in another optimization. when a rgb or rgbx[].b value of 0 is stored in an fkp, it means that instead of referring to a particular chpx/papx in the fkp the 0 value is a signal that the reader should construct for itself a commonly encountered predefined set of properties.

for chpx fkps a 0 rgb value means that the properties of the run of text were exactly equal to the character properties inherited from the style of the paragraph it was in. for papx fkps, a 0 rgbx[].b value means that the paragraph's properties were exactly equal to the paragraph properties of the normal style (stc == 0) and the paragraph contained 1 line of 240 pixels, with a column width of 7980 dxas.

when new entries are added to an fkp, there must be unallocated space in the middle of the fkp equal to 5 bytes for chpxs (size of an fc plus size of one-byte word offset) or 11 bytes for papxs (size of an fc plus the size of a seven byte bx entry), plus the size of the new chpx or papx if the property being added is not already recorded in the fkp and is not the property coded with a 0 rgb/rgbx[].b value. to add a new property in a chpx fkp, existing rgb entries are moved four bytes to the right in the fkp. . to add a new property in a papx fkp, existing rgbx entries are moved four bytes to the right in the fkp. the new fc is added at the end of the rgfc. the new chpx or papx is recorded on a 2-byte boundary before the previously recorded properties stored at the end of the block. the word offset of the beginning of the chpx or papx is stored as the last entry of the relocated rgb/rgbx[].b, and finally, the crun stored at offset 511 is incremented. in word '97, papxs can be generated which are too large to fit in an fkp. in such a case, the grpprl of the papx is written to the data stream and a papx is stored in an fkp with that grpprl replaced by a sprmphugepapx.

bin tables

a bin table (plcfbte) partitions the total extent of the word file that contains text characters into a set of contiguous intervals marked by a fcfirst and an fclim. the fcfirst for the nth interval would be plcfbte.rgfc[n] and the fclim for the nth interval would be plcfbte.rgfc[n+1]. associated with each interval is a bte. a bte holds a four-byte pn (page number) which identifies the fkp page in the file which contains the formatting information for that interval. a chpx fkp further partitions an interval into runs of exception text. a papx fkp in a non-complex, full-saved file, partitions the text within intervals into paragraphs. if a file is in complex format (has been fast-saved), the papx fkp only records the fcs within the text that are preceded by a paragraph mark. even though a sequence of text may be physically located between two paragraph end marks, it may reside in a paragraph different from the one defined by the following paragraph end mark, because the text may have been moved by the user into a different paragraph. in the logical text stream represented by the document's piece table, the paragraph mark that follows the moved text is stored in a non-adjacent physical location in the file.

stylesheet

a stylesheet is a collection of styles. in word, each document has its own stylesheet.

a style is a set of formatting information collected together and given a name. word 6.0 supports paragraph and character styles, previous versions supported only paragraph styles. character styles have just character formatting, paragraph styles have both character and paragraph formatting. the style sheet establishes a correspondence between a style code and a style definition.

note that the storage and behavior of styles has changed radically since word 2 for windows, beginning with nfib 63. some of the differences are:

this document describes only the final word 6.0 version of the stylesheet, not the word 2.x version.

the styles for a document (both paragraph and character styles) are stored in an array in each document. when new styles are created, they are added to the end of the array. the array can have unused slots. some slots at the beginning of the array are reserved for specific styles, whether they have been created yet or not. paragraph and character styles are stored in the same array. each document has a separate array, so the same style will usually have a different istd in two different documents. thus style matching between documents must be done by name (or by sti if the styles are built-in.)

styles are usually referred to using an istd. the istd is an index into an array of std's (style descriptions). a (doc, istd) pair uniquely identifies a style because it tells which style in which array.

parts of a style (for more information, see the std structure below):

every paragraph has a paragraph style. every character has a character style. the default paragraph style is normal (stinormal, istdnormal). the default character style is default paragraph font (stinormalchar, istdnormalchar).

the formatting of a paragraph (the pap) and a character (the chp) depend on the paragraph and character styles applied to them, as well as any additional formatting stored in the fkps. the pap and chp are constructed in a layered fashion:

for a pap:

for a chp:

note that the resulting pap and chp have fields that indicate what style was applied: pap.istd, chp.istd.

stylesheet file format

the style sheet (stsh) is stored in the file in two parts, a stshi and then an array of stds. the stshi contains general information about the following stylesheet, including how many styles are in it. after the stshi, each style is written as an std. both the stshi and each std are preceded by a ushort that indicates their length.

field size comment
cbstshi 2 bytes size of the following stshi structure
stshi (cbstshi) stylesheet information
then for each style in the stylesheet (stshi.cstd), the following is stored:
cbstd 2 bytes size of the following std structure
std (cbstd) the style description

stshi:

the stshi structure has the following format:

// stshi: stylesheet information, as stored in a file
//  note that new fields can be added to the stshi without invalidating
//  the file format, because it is stored preceded by it's length.
//  when reading a stshi from an older version, new fields will be zero.
typedef struct _stshi
{
ushort  cstd;                          // count of styles in stylesheet
ushort  cbstdbaseinfile;               // length of std base as stored in a file
bf      fstdstylenameswritten : 1;     // are built-in stylenames stored?
bf   :  15;                            // spare flags
ushort  stimaxwhensaved;               // max sti known when this file was written
ushort  istdmaxfixedwhensaved;         // how many fixed-index istds are there?
ushort  nverbuiltinnameswhensaved;     // current version of built-in stylenames
ftc     rgftcstandardchpstsh[3];       // ftc used by standardchpstsh for this document
} stshi;

the cb preceding the stshi in the file is the length of the stshi as stored in the file. the current definition of the stshi structure might be longer or shorter than that stored in the file, the stylesheet reader routine needs to take this into account.

stshi.cstd: the number of styles in this stylesheet. there will be stshi.cstd (cbstd, std) pairs in the file following the stshi. note that styles can be empty, i.e. cbstd == 0.

stshi.cbstdbaseinfile: the std structure (see below) is divided into a fixed-length "base", and a variable length part. the stshi.cbstdbaseinfile indicates the size in bytes of the fixed-length base of the std as it was written in this file. if the std base is grown in a future version, the file format doesn't change, because the stylesheet reader can discard parts it doesn't know about, or use defaults if the file's std is not as large as it was expecting. (currently, stshi.cbstdbaseinfile is 8.)

stshi.fstdstylenameswritten: previous versions of word did not store the style name if the style was a built-in style; word 6.0 does, for compatibility with future versions. note that the built-in stylenames may need to be "regenerated" if the file is opened in a different language or if stshi.nverbuiltinnameswhensaved doesn't match the expected value.

stshi.stimaxwhensaved: this indicates the last built-in style known to the version of word that saved this file.

stshi.istdmaxfixedwhensaved: each array of styles has some fixed-index styles at the beginning. this indicates the number of fixed-index positions reserved in the stylesheet when it was saved.

stshi.nverbuiltinnameswhensaved: since built-in stylenames are saved with the document, this provides an way to see if the saved names are the same "version" as the names in the version of word that is loading the file. if not, the built-in stylenames need to be "regenerated", i.e. the old names need to be replaced with the new.

stshi.rgftcstandardchpstsh: this is the default fonts for this stylesheet. the first is for asci characters (0-127), the second is for far east characters, and the third is the default font for non-far east, non-asci text. see notes on sprmcrgftcx for details.

std:

the style description is stored in an std structure as follows:

// std: style definition
//   the std contains the entire definition of a style.
//   it has two parts, a fixed-length base (cbstdbase bytes long)
//   and a variable length remainder holding the name, and the upx and upe
//   arrays (a upx and upe for each type stored in the style, std.cupx)
//   note that new fields can be added to the base of the std without
//   invalidating the file format, because the stshi contains the length
//   that is stored in the file.  when reading stds from an older version,
//   new fields will be zero.
typedef struct _std
{
// base part of std:
ushort    sti : 12;          /* invariant style identifier */
ushort    fscratch : 1;      /* spare field for any temporary use,
always reset back to zero! */
ushort    finvalheight : 1;  /* phes of all text with this style are wrong */
ushort    fhasupe : 1;       /* upes have been generated */
ushort    fmasscopy : 1;     /* std has been mass-copied; if unused at
save time, style should be deleted */
ushort    sgc : 4;           /* style type code */
ushort    istdbase : 12;     /* base style */
ushort    cupx : 4;          /* # of upxs (and upes) */
ushort    istdnext : 12;     /* next style */
ushort    bchupe;            /* offset to end of upx's, start of upe's */

ushort    fautoredef : 1;    /* auto redefine style when appropriate */
ushort    fhidden : 1;       /* hidden from ui? */
ushort : 14;                 /* unused bits */

// variable length part of std:
xchar    xstzname[2];        /* sub-names are separated by chdelimstyle */
/* char  grupx[]; */
/* the upes are not stored on the file; they are a cache of the based-on
chain */
/* char  grupe[]; */
} std;

the cb preceding each std is the length of the data, which includes all of the std except the grupe array (which is derived after the file is read in, by building each upe from the base style upe plus the exceptions in the upx.) a cb of zero indicates an empty slot in the style array, i.e. no style has that istd. note that the std structure may be longer or shorter than the one stored in the file, stshi.cbstdbaseinfile indicates the length of the base of the std (up to stzname) as stored in the file. the stylesheet reader routine has to take this into account.

the variable-length part of the std actually has three variable-length subparts, the xstzname, the grupx, and the grupe. since this doesn't fit well into a c structure declaration, some processing is needed to figure out where one part stops and the next part begins. an important note is that all variable-length parts and subparts of the std begin on even-byte offsets within the std, even if the length of the preceding variable-length part was odd.

std.sti: the sti is an identifier which built-in style this is, or stiuser for a user-defined style. an sti is intended to be permanent through versions of word, although new sti's may be added in new versions. the sti definitions are:

// standard sti codes - these are invariant identifiers for built-in styles
// and must remain the same (i.e. don't renumber them, or old files will be
// messed up.)
// note: sti and istd are the same for normal and level styles
// if you want to define a new built-in style:
//   1) decide if you really need one--it will exist in all future versions!
//   2) add a new sti below.  you can take the first available slot.
//   3) change stimax, and stipapmax or stichpmax
//   4) add entry to _dnsti, and the two ids's in strman.pp
//   5) add case in getdefaultupdforsti
//   6) change cstimaxbuiltindependents if necessary
// if you want to change the definition of a built-in style
//   1) in order to make winword 2 documents that use the style look like
//      they did in winword 2, add a case in getdefaultupdforsti to handle
//      folddef.  this definition will be used when converting winword 2
//      stylesheets.
//   2) if you change the name of a built-in style, increment nverbuiltinnames
#define stinormal      0     // 0x0000

#define stilev1        1     // 0x0001
#define stilev2        2     // 0x0002
#define stilev3        3     // 0x0003
#define stilev4        4     // 0x0004
#define stilev5        5     // 0x0005
#define stilev6        6     // 0x0006
#define stilev7        7     // 0x0007
#define stilev8        8     // 0x0008
#define stilev9        9     // 0x0009
#define stilevfirst    stilev1
#define stilevlast     stilev9

#define stiindex1      10    // 0x000a
#define stiindex2      11    // 0x000b
#define stiindex3      12    // 0x000c
#define stiindex4      13    // 0x000d
#define stiindex5      14    // 0x000e
#define stiindex6      15    // 0x000f
#define stiindex7      16    // 0x0010
#define stiindex8      17    // 0x0011
#define stiindex9      18    // 0x0012
#define stiindexfirst  stiindex1
#define stiindexlast   stiindex9

#define stitoc1        19    // 0x0013
#define stitoc2        20    // 0x0014
#define stitoc3        21    // 0x0015
#define stitoc4        22    // 0x0016
#define stitoc5        23    // 0x0017
#define stitoc6        24    // 0x0018
#define stitoc7        25    // 0x0019
#define stitoc8        26    // 0x001a
#define stitoc9        27    // 0x001b
#define stitocfirst    stitoc1
#define stitoclast     stitoc9

#define stinormindent  28    // 0x001c
#define stiftntext     29    // 0x001d
#define stiatntext     30    // 0x001e
#define stiheader      31    // 0x001f
#define stifooter      32    // 0x0020
#define stiindexheading 33   // 0x0021
#define sticaption     34    // 0x0022
#define stitocaption   35    // 0x0023
#define stienvaddr     36    // 0x0024
#define stienvret      37    // 0x0025
#define stiftnref      38    // 0x0026  char style
#define stiatnref      39    // 0x0027  char style
#define stilnn         40    // 0x0028  char style
#define stipgn         41    // 0x0029  char style
#define stiednref      42    // 0x002a  char style
#define stiedntext     43    // 0x002b
#define stitoa         44    // 0x002c
#define stimacro       45    // 0x002d
#define stitoaheading  46    // 0x002e
#define stilist        47    // 0x002f
#define stilistbullet  48    // 0x0030
#define stilistnumber  49    // 0x0031
#define stilist2       50    // 0x0032
#define stilist3       51    // 0x0033
#define stilist4       52    // 0x0034
#define stilist5       53    // 0x0035
#define stilistbullet2 54    // 0x0036
#define stilistbullet3 55    // 0x0037
#define stilistbullet4 56    // 0x0038
#define stilistbullet5 57    // 0x0039
#define stilistnumber2 58    // 0x003a
#define stilistnumber3 59    // 0x003b
#define stilistnumber4 60    // 0x003c
#define stilistnumber5 61    // 0x003d
#define stititle       62    // 0x003e
#define sticlosing     63    // 0x003f
#define stisignature   64    // 0x0040
#define stinormalchar  65    // 0x0041  char style
#define stibodytext    66    // 0x0042
#define stibodytext2   67    // 0x0043
#define stilistcont    68    // 0x0044
#define stilistcont2   69    // 0x0045
#define stilistcont3   70    // 0x0046
#define stilistcont4   71    // 0x0047
#define stilistcont5   72    // 0x0048
#define stimsgheader   73    // 0x0049
#define stisubtitle    74    // 0x004a
#define stisalutation  75    // 0x004b
#define stidate        76    // 0x004c
#define stibodytext1i  77    // 0x004d
#define stibodytext1i2 78    // 0x004e
#define stinoteheading 79    // 0x004f
#define stibodytext2   80    // 0x0050
#define stibodytext3   81    // 0x0051
#define stibodytextind2 82   // 0x0052
#define stibodytextind3 83   // 0x0053
#define stiblockquote  84    // 0x0054
#define stihyperlink   85    // 0x0055  char style
#define stihyperlinkfollowed 86 // 0x0056   char style
#define stistrong      87    // 0x0057  char style
#define stiemphasis    88    // 0x0058  char style
#define stinavpane     89    // 0x0059  char style
#define stiplaintext   90    // 0x005a
#define stimax         91    // number of defined sti's

#define stiuser      0x0ffe  // user styles are distinguished by name
#define stinil       0x0fff  // max for 12 bits

see below for the names of these styles.

std.stc: the type of each style is indicated by std.sgc. the two types currently in use are:

sgcpara 1 // a paragraph style
sgcchp 2 // a character style

more style types may exist in the future, so styles of an unknown type should be discarded.

std.istdbase: the style that this style is based on. a style is always based on another style or the null style (istdnil). following a "chain" of based-on styles will always end at the null style, because a based-on chain cannot have a loop in it. a style can have up to 11 "ancestors" in its based-on chain, including the null style. a style's definition is built up from the style that it is based on. see std.cupx, std.grupx, std.grupe.

std.istdnext: the style that should be applied after this one. for a paragraph style, this is the style that is applied when enter is pressed at the end of a paragraph. for a character style, the next style is essentially ignored, but should be the same as the current style.

std.xstzname: the name of the style, including aliases. the name is stored as an xstz (preceded by a length byte, followed by a null-terminator.) a style name can contain multiple "aliases", separated by commas. aliases are alternate names for the same style (e.g. a style named "a,b,c" has three aliases, and can be referred to by "a", "b", or "c", or any combination.) winword 2.x did not have aliases, but macword 5.x did. if a style is a built-in style, the built-in stylename is always stored first.

all names (and aliases) must be unique within a stylesheet (e.g. styles "a,b" and "b,c" should not exist in the same stylesheet, as "b" matches multiple stylenames.)

a stylename (including all its aliases and comma separators) can be up to 253 characters long. so the xstz format of that name can be up to 255 characters. stylenames are case sensitive.

the built-in stylenames (corresponding to each sti above) are defined for each language version of word. for the usa, the names are:

// these are the names of the built-in styles as we want to present them
// to the user.
normal
heading 1
heading 2
heading 3
heading 4
heading 5
heading 6
heading 7
heading 8
heading 9
index 1
index 2
index 3
index 4
index 5
index 6
index 7
index 8
index 9
toc 1
toc 2
toc 3
toc 4
toc 5
toc 6
toc 7
toc 8
toc 9
normal indent
footnote text
annotation text
header
footer
index heading
caption
table of figures
envelope address
envelope return
footnote reference
annotation reference
line number
page number
endnote reference
endnote text
table of authorities
macro text
toa heading
list
list 2
list 3
list 4
list 5
list bullet
list bullet 2
list bullet 3
list bullet 4
list bullet 5
list number
list number 2
list number 3
list number 4
list number 5
title
closing
signature
default paragraph font
body text
body text indent
list continue
list continue 2
list continue 3
list continue 4
list continue 5
message header
subtitle
salutation
date
body text first indent
body text first indent 2
note heading
body text 2
body text 3
body text indent 2
body text indent 3
block text
hyperlink
followed hyperlink
strong
emphasis
document map
plain text

std.cupx: this is the number of upxs in the std.grupx array. see below.

std.grupx: this is an array of variable-length upxs, with std.cupx upxs in the array. this array begins after the variable-length xstzname field, at the next even-byte offset within the std. a upx (universal property exception) describes the difference in formatting of this style as compared to its based-on style. the upx structure looks like this:

typedef union _upx
{
struct
{
uchar grpprl[cbmaxgrpprlstylechpx];
} chpx;
struct
{
ushort istd;
uchar grpprl[cbmaxgrpprlstylepapx];
} papx;
uchar rgb[1];
} upx;

each upx stored in a file is not a complete upx, rather it is a upx with all trailing zero bytes lopped off, and preceded by a ushort length field. so it is stored like:

field size comment
cbupx 2 bytes size of the following upx structure
upx (cbupx) nonzero prefix of a upx structure

each upx begins on an even-byte offset within the std, even if the length of the previous upx (cbupx) was odd.

the meaning of each upx depends on the style type (std.sgc). for a paragraph style, std.cupx is 2. the first upx is a paragraph upx (upx.papx) and the second upx is a character upx (upx.chpx). for a character style, std.cupx is 1, and that upx is a character upx (upx.chpx). note that new upxs may be added in the future, so std.cupx might be larger than expected. any upxs past those expected should be discarded.

the grpprl within each upx contains the differences of this property type for this style from the upe of that property type for the based on style. for example, if two paragraph styles, a and b, were identical except that b was bold where a was not, and b was based on a, b would have two upxs, where the paragraph upx would have an empty grpprl, and the character upx would have a bold sprm in the grpprl. thus b looks just like a (since b is based on a), with the exception that b is bold.

std.grupe: this is an array (group) of variable-length upes. these are not stored in the file! rather, they are constructed using the std.istdbase and std.grupx fields. a upe (universal property expansion) describes the "end-result" of the property formatting, i.e. what the style looks like. the upe structure is the non-zero prefix of a upd structure. the upd structure looks like this:

typedef union _upd
{
pap pap;
chp chp;
struct
{
ushort istd;
uchar cbgrpprl;
uchar grpprl[cbmaxgrpprlstylechpx];
} chpx;
} upd;

the std.grupe and std.grupx arrays are similar: there is one upe for each upx, and internally they are stored similarly (a length ushort followed by a non-zero prefix), though remember that the upes are not stored in the file. the meaning of each upe depends on the style type (std.sgc). for a paragraph style, the first upe is a pap (upe.pap). the second upe is a chp (upe.chp). for a character style, the first upe is a chpx (upe.chpx).

the upes for a style are constructed by taking the upes from the based-on style, and applying the upxs to them. obviously, if the upes for the based-on style haven't yet been constructed, that style's upe needs to be constructed first. eventually by following the based-on chain, a style will be based on the null style (istdnil). the upes for the null style are predefined:

so, for a paragraph style, the first upe is a upe.pap. it can be constructed by starting the with first upe from the based-on style (std.istdbase), and then applying the first upx (upx.papx) in std.grupx to that upe. to apply a upx.papx to a upe.pap, set upe.pap.istd equal to upx.papx.istd, and then apply the upx.papx.grpprl to upe.pap. similarly, the second upe is a upe.chp. it can be constructed by starting with the second upe from the based-on style, and then applying the second upx (upx.chpx) in std.grupx to that upe. to apply a upx.chpx to a upe.chp, apply the upx.chpx.grpprl to upe.chp. note that a upe.chp for a paragraph style should always have upe.chp.istd == istdnormalchar.

for a character style, the first (and only) upe (a upe.chpx) can be constructed by starting with the first upe from the based-on style (std.istdbase), and then applying the first upx (upx.chpx) in std.grupx to that upe. to apply a upx.chpx to a upe.chpx, take the grpprl in upe.chpx.grpprl (which has a length of upe.chpx.cbgrpprl) and merge the grpprl in upx.chpx.grpprl into it. merging grpprls is a tricky business, but for character styles it is easy because no prls in character style grpprls should interact with each other. each prl from the source (the upx.chpx.grpprl) should be inserted into the destination (the upe.chpx.grpprl) so that the sprm of each prl is in increasing order, and any prls that have the same sprm are replaced by the prl in the source. upe.chpx.cbgrpprl is then set to the length of resulting grpprl, and upe.chpx.istd is set to the style's istd.

list tables

word 97 stores its paragraph numbering information very differently from word 6.0. in word 6.0, all information for a paragraph was stored in that paragraph's pap.anld. in word 97, the pap only contains two values: a short ilfo and a byte ilvl, which indicate which list the paragraph belongs to and which level of that list it should be, respectively. the ilfo is actually an index into one of the the document's list tables: the pllfo, and the paragraph gets most of its information about appearance from the list tables.

there are three list tables in a word document: the rglst, the hpllfo, and the hsttblistnames. they will be described below in greater detail, and the precise formats of several of these structures (the lstf, lvlf, lfo, and lfolvl) are listed in the appendix.

lst records and the rglst

the lst structure is where most of the list appearance data is stored. an lst consists of two main parts: (1) an lstf, which is stored on disk and contains formatting properties which apply to the entire list, such as whether the list is simple or multilevel, the list's unique list index and template code, the istd's (see stylesheet above) of the styles (if any) that each level in the list is linked to, and a number of word 6 compatilibity option; (2) an array of lvl structures, which describe the appearance of each individual level in the lst.

a lvl structure contains two parts to it: (1) an lvlf, which stores all static data such as the start-at value for the list level, the numbering type (arabic or roman), the alignment (left, right or centered) of the number, and several word 6.0 compatibility options; and (2) a set of pointers to variable length data: (a) a grpprlchpx, which gives character formatting to the paragraph number text itself, (b) a grpprlpapx, which gives paragraph formatting to the paragraph containing the number, such as indenting and tab information, and (c) the number text itself.

word writes out the rglst as the plcflst by writing out, first, a short integer containing the number of lst structures to be written. it then enumerates through the rglst, writing out each lstf structure. it then enumerates through the rglst again, deciding, for each lst, whether it has one level (lstf.fsimplelist) or nine levels (!lstf.fsimplelist). it then writes the appropriate number of lvl structures as described below.

when word writes out an lvl structure, it first writes out the lvlf, followed by the grpprlpapx (of lvlf.cbgrpprlpapx bytes in length), followed by the grpprlchpx (of length lvlf.cbgrpprlchpx), and an xchar string with the number text, preceded by an xchar containing the string's length.

list names and the sttblistnames

the string table containing the list names is by far the least significant of the three list tables. most lists do not have names, and the names are only useful to users of the macro language. if this list has a name, however, it will be in this table: the table is a parallel array with the rglst above, and will contain an empty string for any list which does not have a list name.

lfo records and the pllfo

the lfo structure serves primarily as a level of indirection between the paragraph and the lst, but also can be used to override certain features of the list formats (lfo stands for list format override). an lfo consists of two main parts: (1) the list id of the list (lst record) to which this lfo belongs, and an array of overrides to the formatting in that lst. for the vast majority of lfos, there are no overrides, but if there are any, they reside in an array of lfolvl structures -- one lfolvl per level of the lst to be overridden. an lfolvl contains a set of flags to indicate whether just the start-at value of the lst is overridden, or whether just the formatting is overrridden, or both, as well as either a start-at value or a pointer to a lvl record, depending upon the values of the flags. note that if the lfolvl says the start-at value should be overridden, what that means is that the first paragraph in the document with this lfo should have a number equal exactly to that start-at value, but any subsequent paragraphs should just follow the previous paragraph in the sequence. also, if lfolvl.fformatting and lfolvl.fstartat are both true (rare) then lfolvl.istartat should be ignored in favor of the istartat value from the corresponding lvl.

word writes out the pllfo first by writing out a pl of lfo structures. it then enumerates through each lfo to figure out how many lfolvls each one has (lfo.clfolvl), and writes out, in order, each lfolvl structure followed by its corresponding lvl structure (if lfolvl.fformatting is set).

paragraph list formatting

given a paragraph and its corresponding pap, the following process must be followed to find out the paragraph's list information:

sprm definitions

a sprm is an instruction to modify one or more properties within one of the property defining data structures (chp, pap, tap, sep, or pic). a sprm is a two-byte opcode at offset 0 which identifies the operation to be performed. if necessary information for the operation can always be expressed with a fixed length parameter, the fixed length parameter is recorded immediately after the opcode beginning at offset 2. the length of a fixed length sprm is always 2 plus the size of the sprm's parameter. if the parameter for the sprm is variable length, the count of bytes of the following parameter is stored in the byte at offset 2, followed by the parameter at offset 3.

three sprms -- sprmpchgtabs , sprmtdeftable, and sprmtdeftable10 -- can be longer than 256 bytes. the method for calculating the length of sprmpchgtabs is recorded below with the description of the sprm. for sprmtdeftable and sprmtdeftable10, the length of the parameter plus 1 is recorded in the two bytes beginning at offset 2.

for all other variable length sprms, the total length of the sprm is the count recorded at offset 2 plus three (2 for the sprm + 1 for the count byte). the parameter immediately follows the count.

the sprm value encodes information on the size of the operand, the type of sprm (pap, chp, etc), and whether the sprm requires special handling (in cases where a property value isn't simply replaced).

sprm bits (0 = low) value details
0-8 ispmd unique identifier within sgc group
9 fspec sprm requires special handling
10-12 sgc sprm group; type of sprm (pap, chp, etc)
13-15 spra size of sprm argument (see following table for values)
sgc value type of sprm
1 pap
2 chp
3 pic
4 sep
5 tap
spra value operand size
0 1 byte (operand affects 1 bit)
1 1 byte
2 2 bytes
3 4 bytes
4 2 bytes
5 2 bytes
6 variable length -- following byte is size of operand
7 3 bytes

when parsing a grpprl, you can use the sprm's spra value to determine how many bytes are used by that sprm; it also enables you to skip over sprms you don't handle.

unless otherwise noted, when a sprm is applied to a property the sprm's parameter changes the old value of the property in question to the value stored in the sprm parameter.

name sprm property modified parameter parameter size
sprmpistd 0x4600 pap.istd istd (style code) short
sprmpistdpermute 0xc601 pap.istd permutation vector (see below) variable length
sprmpinclvl 0x2602 pap.istd, pap.lvl difference between istd of base pap and istd of pap to be produced (see below) byte
sprmpjc 0x2403 pap.jc jc (justification) byte
sprmpfsidebyside 0x2404 pap.fsidebyside 0 or 1 byte
sprmpfkeep 0x2405 pap.fkeep 0 or 1 byte
sprmpfkeepfollow 0x2406 pap.fkeepfollow 0 or 1 byte
sprmpfpagebreakbefore 0x2407 pap.fpagebreakbefore 0 or 1 byte
sprmpbrcl 0x2408 pap.brcl brcl byte
sprmpbrcp 0x2409 pap.brcp brcp byte
sprmpilvl 0x260a pap.ilvl ilvl byte
sprmpilfo 0x460b pap.ilfo ilfo (list index) short
sprmpfnolinenumb 0x240c pap.fnolnn 0 or 1 byte
sprmpchgtabspapx 0xc60d pap.itbdmac, pap.rgdxatab, pap.rgtbd complex - see below variable length
sprmpdxaright 0x840e pap.dxaright dxa word
sprmpdxaleft 0x840f pap.dxaleft dxa word
sprmpnest 0x4610 pap.dxaleft dxa-see below word
sprmpdxaleft1 0x8411 pap.dxaleft1 dxa word
sprmpdyaline 0x6412 pap.lspd an lspd, a long word structure consisting of a short of dyaline followed by a short of fmultlinespace - see below long
sprmpdyabefore 0xa413 pap.dyabefore dya word
sprmpdyaafter 0xa414 pap.dyaafter dya word
sprmpchgtabs 0xc615 pap.itbdmac, pap.rgdxatab, pap.rgtbd complex - see below variable length
sprmpfintable 0x2416 pap.fintable 0 or 1 byte
sprmpfttp 0x2417 pap.fttp 0 or 1 byte
sprmpdxaabs 0x8418 pap.dxaabs dxa word
sprmpdyaabs 0x8419 pap.dyaabs dya word
sprmpdxawidth 0x841a pap.dxawidth dxa word
sprmppc 0x261b pap.pchorz, pap.pcvert complex - see below byte
sprmpbrctop10 0x461c pap.brctop brc10 word
sprmpbrcleft10 0x461d pap.brcleft brc10 word
sprmpbrcbottom10 0x461e pap.brcbottom brc10 word
sprmpbrcright10 0x461f pap.brcright brc10 word
sprmpbrcbetween10 0x4620 pap.brcbetween brc10 word
sprmpbrcbar10 0x4621 pap.brcbar brc10 word
sprmpdxafromtext10 0x4622 pap.dxafromtext dxa word
sprmpwr 0x2423 pap.wr wr (see description of pap for definition byte
sprmpbrctop 0x6424 pap.brctop brc long
sprmpbrcleft 0x6425 pap.brcleft brc long
sprmpbrcbottom 0x6426 pap.brcbottom brc long
sprmpbrcright 0x6427 pap.brcright brc long
sprmpbrcbetween 0x6428 pap.brcbetween brc long
sprmpbrcbar 0x6629 pap.brcbar brc long
sprmpfnoautohyph 0x242a pap.fnoautohyph 0 or 1 byte
sprmpwheightabs 0x442b pap.wheightabs w word
sprmpdcs 0x442c pap.dcs dcs short
sprmpshd 0x442d pap.shd shd word
sprmpdyafromtext 0x842e pap.dyafromtext dya word
sprmpdxafromtext 0x842f pap.dxafromtext dxa word
sprmpflocked 0x2430 pap.flocked 0 or 1 byte
sprmpfwidowcontrol 0x2431 pap.fwidowcontrol 0 or 1 byte
sprmpruler 0xc632     variable length
sprmpfkinsoku 0x2433 pap.fkinsoku 0 or 1 byte
sprmpfwordwrap 0x2434 pap.fwordwrap 0 or 1 byte
sprmpfoverflowpunct 0x2435 pap.foverflowpunct 0 or 1 byte
sprmpftoplinepunct 0x2436 pap.ftoplinepunct 0 or 1 byte
sprmpfautospacede 0x2437 pap.fautospacede 0 or 1 byte
sprmpfautospacedn 0x2438 pap.fautospacedn 0 or 1 byte
sprmpwalignfont 0x4439 pap.walignfont ifa (see description of pap for definition) word
sprmpframetextflow 0x443a pap.fvertical pap.fbackward pap.frotatefont complex (see description of pap for definition) word
sprmpisnapbaseline 0x243b obsolete: not applicable in word97 and later versions   byte
sprmpanld 0xc63e pap.anld   variable length
sprmpproprmark 0xc63f pap.fproprmark complex (see below) variable length
sprmpoutlvl 0x2640 pap.lvl has no effect if pap.istd is < 1 or is > 9 byte
sprmpfbidi 0x2441     byte
sprmpfnumrmins 0x2443 pap.fnumrmins 1 or 0 bit
sprmpcrlf 0x2444     byte
sprmpnumrm 0xc645 pap.numrm   variable length
sprmphugepapx 0x6645 see below fc in the data stream to locate the huge grpprl (see below) long
sprmpfusepgsusettings 0x2447 pap.fusepgsusettings 1 or 0 byte
sprmpfadjustright 0x2448 pap.fadjustright 1 or 0 byte
sprmcfrmarkdel 0x0800 chp.frmarkdel 1 or 0 bit
sprmcfrmark 0x0801 chp.frmark 1 or 0 bit
sprmcffldvanish 0x0802 chp.ffldvanish 1 or 0 bit
sprmcpiclocation 0x6a03 chp.fcpic and chp.fspec see below variable length, length recorded is always 4
sprmcibstrmark 0x4804 chp.ibstrmark index into sttbrmark short
sprmcdttmrmark 0x6805 chp.dttmrmark dttm long
sprmcfdata 0x0806 chp.fdata 1 or 0 bit
sprmcidslrmark 0x4807 chp.idslrmreason an index to a table of strings defined in word 6.0 executables short
sprmcchs 0xea08 chp.fchsdiff and chp.chse see below 3 bytes
sprmcsymbol 0x6a09 chp.fspec, chp.xchsym and chp.ftcsym see below variable length, length recorded is always 4
sprmcfole2 0x080a chp.fole2 1 or 0 bit
sprmcidchartype 0x480b obsolete: not applicable in word97 and later versions    
sprmchighlight 0x2a0c chp.fhighlight, chp.icohighlight ico (fhighlight is set to 1 iff ico is not 0) byte
sprmcobjlocation 0x680e chp.fcobj fc long
sprmcfftcascisymb 0x2a10      
sprmcistd 0x4a30 chp.istd istd, see stylesheet definition short
sprmcistdpermute 0xca31 chp.istd permutation vector (see below) variable length
sprmcdefault 0x2a32 whole chp (see below) none variable length
sprmcplain 0x2a33 whole chp (see below) none 0
sprmckcd 0x2a34      
sprmcfbold 0x0835 chp.fbold 0,1, 128, or 129 (see below) byte
sprmcfitalic 0x0836 chp.fitalic 0,1, 128, or 129 (see below) byte
sprmcfstrike 0x0837 chp.fstrike 0,1, 128, or 129 (see below) byte
sprmcfoutline 0x0838 chp.foutline 0,1, 128, or 129 (see below) byte
sprmcfshadow 0x0839 chp.fshadow 0,1, 128, or 129 (see below) byte
sprmcfsmallcaps 0x083a chp.fsmallcaps 0,1, 128, or 129 (see below) byte
sprmcfcaps 0x083b chp.fcaps 0,1, 128, or 129 (see below) byte
sprmcfvanish 0x083c chp.fvanish 0,1, 128, or 129 (see below) byte
sprmcftcdefault 0x4a3d   ftc, only used internally, never stored in file word
sprmckul 0x2a3e chp.kul kul byte
sprmcsizepos 0xea3f chp.hps, chp.hpspos (see below) 3 bytes
sprmcdxaspace 0x8840 chp.dxaspace dxa word
sprmclid 0x4a41   only used internally never stored word
sprmcico 0x2a42 chp.ico ico byte
sprmchps 0x4a43 chp.hps hps byte
sprmchpsinc 0x2a44 chp.hps (see below) byte
sprmchpspos 0x4845 chp.hpspos hps byte
sprmchpsposadj 0x2a46 chp.hpspos hps (see below) byte
sprmcmajority 0xca47 chp.fbold, chp.fitalic, chp.fsmallcaps, chp.fvanish, chp.fstrike, chp.fcaps, chp.rgftc, chp.hps, chp.hpspos, chp.kul, chp.dxaspace, chp.ico, chp.rglid complex (see below) variable length, length byte plus size of following grpprl
sprmciss 0x2a48 chp.iss iss byte
sprmchpsnew50 0xca49 chp.hps hps variable width, length always recorded as 2
sprmchpsinc1 0xca4a chp.hps complex (see below) variable width, length always recorded as 2
sprmchpskern 0x484b chp.hpskern hps short
sprmcmajority50 0xca4c chp.fbold, chp.fitalic, chp.fsmallcaps, chp.fvanish, chp.fstrike, chp.fcaps, chp.ftc, chp.hps, chp.hpspos, chp.kul, chp.dxaspace, chp.ico, complex (see below) variable length
sprmchpsmul 0x4a4d chp.hps percentage to grow hps short
sprmcysri 0x484e chp.ysri ysri short
sprmcrgftc0 0x4a4f chp.rgftc[0] ftc for ascii text (see below) short
sprmcrgftc1 0x4a50 chp.rgftc[1] ftc for far east text (see below) short
sprmcrgftc2 0x4a51 chp.rgftc[2] ftc for non-far east text (see below) short
sprmccharscale 0x4852      
sprmcfdstrike 0x2a53 chp.fdstrike   byte
sprmcfimprint 0x0854 chp.fimprint 1 or 0 bit
sprmcfspec 0x0855 chp.fspec 1 or 0 bit
sprmcfobj 0x0856 chp.fobj 1 or 0 bit
sprmcproprmark 0xca57 chp.fproprmark, chp.ibstproprmark, chp.dttmproprmark complex (see below) variable length always recorded as 7 bytes
sprmcfemboss 0x0858 chp.femboss 1 or 0 bit
sprmcsfxtext 0x2859 chp.sfxttext text animation byte
sprmcfbidi 0x085a      
sprmcfdiaccolor 0x085b      
sprmcfboldbi 0x085c      
sprmcfitalicbi 0x085d      
sprmcftcbi 0x4a5e      
sprmclidbi 0x485f      
sprmcicobi 0x4a60      
sprmchpsbi 0x4a61      
sprmcdispfldrmark 0xca62 chp.fdispfldrmark, chp.ibstdispfldrmark, chp.dttmdispfldrmark complex (see below) variable length always recorded as 39 bytes
sprmcibstrmarkdel 0x4863 chp.ibstrmarkdel index into sttbrmark short
sprmcdttmrmarkdel 0x6864 chp.dttmrmarkdel dttm long
sprmcbrc 0x6865 chp.brc brc long
sprmcshd 0x4866 chp.shd shd short
sprmcidslrmarkdel 0x4867 chp.idslrmreasondel an index to a table of strings defined in word 6.0 executables short
sprmcfusepgsusettings 0x0868 chp.fusepgsusettings 1 or 0 bit
sprmccpg 0x486b     word
sprmcrglid0 0x486d chp.rglid[0] lid: for non-far east text word
sprmcrglid1 0x486e chp.rglid[1] lid: for far east text word
sprmcidcthint 0x286f chp.idcthint idct: (see below) byte
sprmpicbrcl 0x2e00 pic.brcl brcl (see pic structure definition) byte
sprmpicscale 0xce01 pic.mx, pic.my, pic.dxacropleft, pic.dyacroptop pic.dxacropright, pic.dyacropbottom complex (see below) length byte plus 12 bytes
sprmpicbrctop 0x6c02 pic.brctop brc long
sprmpicbrcleft 0x6c03 pic.brcleft brc long
sprmpicbrcbottom 0x6c04 pic.brcbottom brc long
sprmpicbrcright 0x6c05 pic.brcright brc long
sprmscnspgn 0x3000 sep.cnspgn cns byte
sprmsiheadingpgn 0x3001 sep.iheadingpgn heading number level byte
sprmsolstanm 0xd202 sep.olstanm olst variable length
sprmsdxacolwidth 0xf203 sep.rgdxacolwidthspacing complex (see below) 3 bytes
sprmsdxacolspacing 0xf204 sep.rgdxacolwidthspacing complex (see below) 3 bytes
sprmsfevenlyspaced 0x3005 sep.fevenlyspaced 1 or 0 byte
sprmsfprotected 0x3006 sep.funlocked 1 or 0 byte
sprmsdmbinfirst 0x5007 sep.dmbinfirst   word
sprmsdmbinother 0x5008 sep.dmbinother   word
sprmsbkc 0x3009 sep.bkc bkc byte
sprmsftitlepage 0x300a sep.ftitlepage 0 or 1 byte
sprmsccolumns 0x500b sep.ccolm1 # of cols - 1 word
sprmsdxacolumns 0x900c sep.dxacolumns dxa word
sprmsfautopgn 0x300d sep.fautopgn obsolete byte
sprmsnfcpgn 0x300e sep.nfcpgn nfc byte
sprmsdyapgn 0xb00f sep.dyapgn dya short
sprmsdxapgn 0xb010 sep.dxapgn dya short
sprmsfpgnrestart 0x3011 sep.fpgnrestart 0 or 1 byte
sprmsfendnote 0x3012 sep.fendnote 0 or 1 byte
sprmslnc 0x3013 sep.lnc lnc byte
sprmsgprfihdt 0x3014 sep.grpfihdt grpfihdt (see headers and footers topic) byte
sprmsnlnnmod 0x5015 sep.nlnnmod non-neg int. word
sprmsdxalnn 0x9016 sep.dxalnn dxa word
sprmsdyahdrtop 0xb017 sep.dyahdrtop dya word
sprmsdyahdrbottom 0xb018 sep.dyahdrbottom dya word
sprmslbetween 0x3019 sep.flbetween 0 or 1 byte
sprmsvjc 0x301a sep.vjc vjc byte
sprmslnnmin 0x501b sep.lnnmin lnn word
sprmspgnstart 0x501c sep.pgnstart pgn word
sprmsborientation 0x301d sep.dmorientpage dm byte
sprmsbcustomize 0x301e      
sprmsxapage 0xb01f sep.xapage xa word
sprmsyapage 0xb020 sep.yapage ya word
sprmsdxaleft 0xb021 sep.dxaleft dxa word
sprmsdxaright 0xb022 sep.dxaright dxa word
sprmsdyatop 0x9023 sep.dyatop dya word
sprmsdyabottom 0x9024 sep.dyabottom dya word
sprmsdzagutter 0xb025 sep.dzagutter dza word
sprmsdmpaperreq 0x5026 sep.dmpaperreq dm word
sprmsproprmark 0xd227 sep.fproprmark, sep.ibstproprmark, sep.dttmproprmark complex (see below) variable length always recorded as 7 bytes
sprmsfbidi 0x3228      
sprmsffacingcol 0x3229      
sprmsfrtlgutter 0x322a      
sprmsbrctop 0x702b sep.brctop brc long
sprmsbrcleft 0x702c sep.brcleft brc long
sprmsbrcbottom 0x702d sep.brcbottom brc long
sprmsbrcright 0x702e sep.brcright brc long
sprmspgbprop 0x522f sep.pgbprop   word
sprmsdxtcharspace 0x7030 sep.dxtcharspace dxt long
sprmsdyalinepitch 0x9031 sep.dyalinepitch dya long
sprmsclm 0x5032      
sprmstextflow 0x5033 sep.wtextflow complex (see below) short
sprmtjc 0x5400 tap.jc jc word (low order byte is significant)
sprmtdxaleft 0x9601 tap.rgdxacenter (see below) dxa word
sprmtdxagaphalf 0x9602 tap.dxagaphalf, tap.rgdxacenter (see below) dxa word
sprmtfcantsplit 0x3403 tap.fcantsplit 1 or 0 byte
sprmttableheader 0x3404 tap.ftableheader 1 or 0 byte
sprmttableborders 0xd605 tap.rgbrctable complex(see below) 24 bytes
sprmtdeftable10 0xd606 tap.rgdxacenter, tap.rgtc complex (see below) variable length
sprmtdyarowheight 0x9407 tap.dyarowheight dya word
sprmtdeftable 0xd608 tap.rgtc complex (see below)  
sprmtdeftableshd 0xd609 tap.rgshd complex (see below)  
sprmttlp 0x740a tap.tlp tlp 4 bytes
sprmtfbidi 0x560b      
sprmthtmlprops 0x740c      
sprmtsetbrc 0xd620 tap.rgtc[].rgbrc complex (see below) 5 bytes
sprmtinsert 0x7621 tap.rgdxacenter, tap.rgtc complex (see below) 4 bytes
sprmtdelete 0x5622 tap.rgdxacenter, tap.rgtc complex (see below) word
sprmtdxacol 0x7623 tap.rgdxacenter complex (see below) 4 bytes
sprmtmerge 0x5624 tap.ffirstmerged, tap.fmerged complex (see below) word
sprmtsplit 0x5625 tap.ffirstmerged, tap.fmerged complex (see below) word
sprmtsetbrc10 0xd626 tap.rgtc[].rgbrc complex (see below) 5 bytes
sprmtsetshd 0x7627 tap.rgshd complex (see below) 4 bytes
sprmtsetshdodd 0x7628 tap.rgshd complex (see below) 4 bytes
sprmttextflow 0x7629 tap.rgtc[].fvertical
tap.rgtc[].fbackward
tap.rgtc[].frotatefont
0 or 1
0 or 1
0 or 1
word
sprmtdiagline 0xd62a      
sprmtvertmerge 0xd62b tap.rgtc[].vertmerge complex (see below) variable length always recorded as 2 bytes
sprmtvertalign 0xd62c tap.rgtc[].vertalign complex (see below) variable length always recorded as 3 byte

sprmpistdpermute (opcode 0xc601) is a complex sprm which is applied to a piece when the style codes of paragraphs within a piece must be mapped to other style codes. it has the following format:

field size comment
sprm short opcode( ==0xc601)
cch byte count of bytes (not including sprm and cch)
flongg byte always 0
fspare byte always 0
istdfirst unsigned short index of first style in range to which permutation stored in rgistd applies
istdlast unsigned short index of last style in range to which permutation stored in rgistd applies
rgistd[] unsigned short array of istd entries that records the mapping of istds for text copied from a source document to istds that exists in the destination document after the text has been pasted

to interpret sprmpistdpermute, first check if pap.istd is greater than the istdfirst recorded in the sprm and less than or equal to the istdlast recorded in the sprm if not, the sprm has no effect. if it is, pap.istd is set to rgistd[pap.istd - istdfirst]. sprmpistdpermute is only stored in grpprls linked to a piece table. it should never be recorded in a papx.

sprmpinclvl (opcode 0x2602) is applied to pieces in the piece table that contain paragraphs with style codes (istds) greater than or equal to 1 and less than or equal to 9. these style codes identify heading levels in a word outline structure. the sprm causes a set of paragraphs to be changed to a new heading level. the sprm is three bytes long and consists of the sprm code and a one byte two's complement value.

if pap.stc is < 1 or > 9, sprmpinclvl has no effect. otherwise, if the value stored in the byte has its highest order bit off, the value is a positive difference which should be added to pap.istd and pap.lvl and then pap.stc should be set to min(pap.istd, 9). if the byte value has its highest order bit on, the value is a negative difference which should be sign extended to a word and then subtracted from pap.istd and pap.lvl. then pap.stc should be set to max(1, pap.istd). sprmpinclvl is only stored in grpprls linked to a piece table.

sprmpilfo (opcode 0x460b) sets the pap.ilfo. its argument, an ilfo, is an index into the document's hpllfo, which contains the list data for that paragraph, describing the appearance of the automatic number at the beginning of the paragraph. a value of zero means that the paragraph is not numbered, and a value of 2047 indicates that this paragraph came from a pre-word 97 file so the formatting information is still stored in the pap.anld and the paragraph should be converted to word 97 format.

sprmpilvl (opcode (0x260a) sets the pap.ilvl. it takes an index (0 through 8) which indicates which level of a multilevel list this paragraph belongs to. for simple (one-level lists) or unnumbered paragraphs, this value should always be zero.

sprmpanld (opcode ...) is currently only used for compatibility with pre-word 97 docs. it sets the pap.anld, which before word 97 described the automatic number at the beginning of any numbered paragraph. now we use it only long enough to put the data into the document's list table (rglst) and set the pap.ilfo to point to the proper entry in the list table. the pap.anld is only relavent if pap.ilfo is equal to 2047 (see sprmpilfo above).

the sprmpchgtabspapx (opcode 0xc60d) is a complex sprm that describes changes in tab settings from the underlying style. it is only stored as part of papxs stored in fkps and in the stsh. it has the following format:

field size comment
sprm short opcode
cch byte count of bytes (not including sprm and cch)
itbddelmax byte number of tabs to delete
rgdxadel int[itbddelmax] array of tab positions for which tabs should be deleted
itbdaddmax byte number of tabs to add
rgdxaadd int[itbdaddmax] array of tab positions for which tabs should be added
rgtbdadd byte[itbdaddmax] array of tab descriptors corresponding to rgdxaadd

when sprmpchgtabspapx is interpreted, the rgdxadel of the sprm is applied first to the pap that is being transformed. this is done by deleting from the pap the rgdxatab entry and rgtbd entry of any tab whose rgdxatab value is equal to one of the rgdxadel values in the sprm. it is guaranteed that the entries in pap.rgdxatab and the sprm's rgdxadel and rgdxaadd are recorded in ascending dxa order.

then the rgdxaadd and rgtbdadd entries are merged into the pap's rgdxatab and rgtbd arrays so that the resulting pap rgdxatab is sorted in ascending order with no duplicates.

sprmpnest (opcode 0x4610) causes its operand, a two-byte dxa value to be added to pap.dxaleft. if the result of the addition is less than 0, 0 is stored into pap.dxaleft. it is used to shift the left indent of a paragraph to the right or left. sprmpnest is only stored in grpprls linked to a piece table.

sprmpdyaline (opcode 0x6412) moves a 4 byte lspd structure into pap.lspd. two short fields are stored in this data structure. the first short in the structure is named lspd.dyaline and the second is named lspd.fmultlinespace. when lspd.fmultlinespace is 0, the magnitude of lspd.dyaline specifies the amount of space that will be provided for lines in the paragraph in twips. when lspd.dyaline is positive, word will ensure that at least the magnitude of lspd.dyaline will be reserved on the page for each line displayed in the paragraph. if the height of a line becomes greater than lspd.dyaline, the size calculated for that line will be reserved on the page. when lspd.dyaline is negative, word will ensure that exactly the magnitude of lspd.dyaline (-lspd.dyaline) will be reserved on the page for each line displayed in the paragraph. when lspd.fmultlinespace is 1, word will reserve for each line the (maximal height of the line*lspd.dyaline)/240.

the sprmpchgtabs (opcode 0xc615) is a complex sprm which describes changes tab settings for any paragraph within a piece. it is only stored as part of a grpprl linked to a piece table. it has the following format:

field size comment
sprm short opcode
cch byte count of bytes (not including sprm and cch)
itbddelmax byte number of tabs to delete
rgdxadel int[itbddelmax] array of tab positions for which tabs should be deleted
rgdxaclose int[itbddelmax] array of tolerances corresponding to rgdxadel where each tolerance defines an interval around corresponding rgdxadel entry within which all tabs should be removed
itbdaddmax byte number of tabs to add
rgdxaadd int[itbdaddmax] array of tab positions for which tabs should be added
rgtbdadd byte[itbdaddmax] array of tab descriptors corresponding to rgdxaadd

itbddelmax and itbdaddmax are defined to be equal to 50. this means that the largest possible instance of sprmpchgtabs is 354. when the length of the sprm is greater than or equal to 255, the cch field will be set equal to 255. when cch == 255, the actual length of the sprm can be calculated as follows: length = 2 + itbddelmax * 4 + itbdaddmax * 3.

when sprmpchgtabs is interpreted, the rgdxadel of the sprm is applied first to the pap that is being transformed. this is done by deleting from the pap the rgdxatab entry and rgtbd entry of any tab whose rgdxatab value is within the interval [rgdxadel[i] - rgdxaclose[i], rgdxadel[i] + rgdxaclose[i]] it is guaranteed that the entries in pap.rgdxatab and the sprm's rgdxadel and rgdxaadd are recorded in ascending dxa order.

then the rgdxaadd and rgtbdadd entries are merged into the pap's rgdxatab and rgtbd arrays so that the resulting pap rgdxatab is sorted in ascending order with no duplicates.

the sprmppc (opcode 0x261b) is a complex sprm which describes changes in the pap.pchorz and pap.pcvert. it is able to change both fields' contents in parallel. it has the following format:

b10 b16 field type size bitfield comments
0 0 sprm short     opcode
2 2   short :4 f0 reserved
    pcvert short :2 0c if pcvert ==3, pap.pcvert should not be changed. otherwise, contains new value of pap.pcvert.
    pchorz short :2 03 if pchorz==3, pap.pchorz should not be changed. otherwise, contains new value of pap.pchorz.

length of sprmppc is three bytes.

sprmppc is interpreted by moving pcvert to pap.pcvert if pcvert != 3 and by moving pchorz to pap.pchorz if pchorz != 3. sprmppc is stored in papx fkps and also in grpprls linked to piece table entries.

sprmpproprmark (opcode 0xc63f) is interpreted by moving the first parameter byte to pap.fproprmark, the next two bytes to pap.ibstproprmark, and the remaining four bytes to pap.dttmproprmark.

sprmphugepapx is stored in papx fkps in place of the grpprl of a papx which would otherwise be too big to fit in an fkp (as of this writing, 488 bytes is the size of the largest papx which can fit in an fkp). the parameter fc gives the location of the grpprl in the data stream. the first word at that fc counts the number of bytes in the grpprl (not including the byte count itself). a sprmphugepapx should therefore only be found in a papx fkp and should be the only sprm in that papx's grpprl.

sprmcpiclocation (opcode 0x6a03) is used only in chpx fkps. this sprm moves the 4-byte operand of the sprm into the chp.fcpic field. it simultaneously sets chp.fspec to 1. this sprm is also when the chp.ltagobj field that is unioned with chp.fcpic is to be set for ole objects.

sprmcchs (opcode 0xea08) is used to record a character set id for text that was pasted into the word document that used a character set different than word's default character set. when chp.fchsdiff is 0, the character set used for a run of text is the default character set for the version of word that last saved the document. when chp.fchsdiff is 1, chp.chse specifies the character set used for this run of text. this sprm's operand is 3 bytes. when this sprm is interpreted, the first byte of the operand is moved to chp.fchsdiff and the remaining word is moved to chp.chse.

sprmcsymbol (opcode 0x6a09) is used to specify the font and the character that will be used within that font to display a symbol character in word. this sprm's operand is 4 bytes. the first 2 hold the font code; the last 2 hold a character specifier. when this sprm is interpreted, the font code is moved to chp.ftcsym and the character specifier is moved to chp.xchsym and chp.fspec is set to 1.

sprmcistdpermute (opcode 0xca31) (which has the same format as sprmpistdpermute (opcode 0xc601)) is a complex sprm which is applied to a piece when the style codes for character styles tagging character runs within a piece must be mapped to other style codes. it has the following format:

field size comment
sprm short opcode( ==0xca31)
cch byte count of bytes (not including sprm and cch)
flongg byte always 0
fspare byte always 0
istdfirst unsigned short index of first style in range to which permutation stored in rgistd applies
istdlast unsigned short index of last style in range to which permutation stored in rgistd applies
rgistd[] unsigned short array of istd entries that records the mapping of istds for text copied from a source document to istds that exists in the destination document after the text has been pasted

to interpret sprmcistdpermute, first check if chp.istd is greater than the istdfirst recorded in the sprm and less than or equal to the istdlast recorded in the sprm if not, the sprm has no effect. if it is, chp.istd is set to rgstd[chp.istd - istdfirst] and any chpx stored in that rgstd entry is applied to the chp. sprmcistdpermute is only stored in grpprls linked to a piece table. it should never be recorded in a chpx.

note that it is possible that an istd may be recorded in the rgistd that refers to a paragraph style. this will no harmful consequences since the istd for a paragraph style should never be recorded in chp.istd.

sprmcdefault (opcode 0x2a32) clears the fbold, fitalic, foutline, fstrike, fshadow, fsmallcaps, fcaps, fvanish, kul and ico fields of the chp to 0. it was first defined for word 3.01 and had to be backward compatible with word 3.00 so it is a variable length sprm whose count of bytes is 0. it consists of the sprmcdefault opcode followed by a byte of 0. sprmcdefault is stored only in grpprls linked to piece table entries.

sprmcplain (opcode 0x2a33) is used to make the character properties of runs of text equal to the style character properties of the paragraph that contains the text. when word interprets this sprm, the style sheet chp is copied over the original chp preserving the fspec setting from the original chp. sprmcplain is stored only in grpprls linked to piece table entries.

sprms 0x0835 through 0x083c (sprmcfbold through sprmcfvanish) set single bit properties in the chp. when the parameter of the sprm is set to 0 or 1, then the chp property is set to the parameter value.

when the parameter of the sprm is 128, then the chp property is set to the value that is stored for the property in the style sheet. chp when the parameter of the sprm is 129, the chp property is set to the negation of the value that is stored for the property in the style sheet chp. sprmcfbold through sprmcfvanish are stored only in grpprls linked to piece table entries.

sprmcsizepos (opcode 0xea3f) is a five-byte sprm consisting of the sprm opcode and a three byte parameter. the sprm has the following format:

b10 b16 field type size bitfield comments
0 0 sprm short     opcode
2 2 hpssize short :8 ff when != 0, contains new size of chp.hps
3 3 cinc short :7 fe contains the number of font levels to increase or decrease size of chp.hps as a twos complement value.
    fadjust short :1 01 when == 1, means that chp.hps should be adjusted up/down by one font level for super/subscripting change
4 4 hpspos short :8 ff when != 128, contains super/subscript position as a twos complement number

when word interprets this sprm, if hpssize != 0 then chp.hps is set to hpssize. if cinc is != 0, the cinc is interpreted as a 7 bit twos complement number and the procedure described below for interpreting sprmchpsinc is followed to increase or decrease the chp.hps by the specified number of levels. if hpspos is != 128, then chp.hpspos is set equal to hpspos. if fadjust is on , hpspos != 128 and hpspos != 0 and the previous value of chp.hpspos == 0, then chp.hps is reduced by one level following the method described for sprmchpsinc. if fadjust is on, hpspos == 0 and the previous value of chp.hpspos != 0, then the chp.hps value is increased by one level using the method described below for sprmchpsinc.

sprmchpsinc(opcode 0x2a44) is a three-byte sprm consisting of the sprm opcode and a one-byte parameter. word keeps an ordered array of the font sizes that are defined for the fonts recorded in the system file with each font size transformed into an hps. the parameter is a one-byte twos complement number. word uses this number to calculate an index in the font size array to determine the new hps for a run. when word interprets this sprm and the parameter is positive, it searches the array of font sizes to find the index of the smallest entry in the font size table that is greater than the current chp.hps.it then adds the parameter minus 1 to the index and maxes this with the index of the last array entry. it uses the result as an index into the font size array and assigns that entry of the array to chp.hps.

when the parameter is negative, word searches the array of font sizes to find the index of the entry that is less than or equal to the current chp.hps. it then adds the negative parameter to the index and does a min of the result with 0. the result of the min function is used as an index into the font size array and that entry of the array is assigned to chp.hps. sprmchpsinc is stored only in grpprls linked to piece table entries.

sprmchpsposadj (opcode 0x2a46) causes the hps of a run to be reduced the first time text is superscripted or subscripted and causes the hps of a run to be increased when superscripting/subscripting is removed from a run. the one byte parameter of this sprm is the new hpspos value that is to be stored in chp.hpspos. if the new hpspos is not equal 0 (meaning that the text is to be super/subscripted), word first examines the current value of chp.hpspos to see if it is equal to 0. if so, word uses the algorithm described for sprmchpsinc to decrease chp.hps by one level. if the new hpspos == 0 (meaning the text is not super/subscripted), word examines the current chp.hpspos to see if it is not equal to 0. if it is not (which means text is being restored to normal position), word uses the sprmchpsinc algorithm to increase chp.hps by one level. after chp.hps is adjusted, the parameter value is stored in chp.hpspos. sprmchpsposadj is stored only in grpprls linked to piece table entries.

the parameter of sprmcmajority (opcode 0xca47) is itself a list of character sprms which encodes a criterion under which certain fields of the chp are to be set equal to the values stored in a style's chp. bytes 0 and 1 of sprmcmajority contains the opcode, byte 2 contains the length of the following list of character sprms. . word begins interpretation of this sprm by applying the stored character sprm list to a standard chp. that chp has chp.istd = istdnormalchar. chp.hps=20, chp.lid=0x0400 and chp.ftc = 4. word then compares fbold, fitalic, fstrike, foutline, fshadow, fsmallcaps, fcaps, ftc, hps, hpspos, kul, qpsspace and ico in the original chp with the values recorded for these fields in the generated chp.. if a field in the original chp has the same value as the field stored in the generated chp, then that field is reset to the value stored in the style's chp. if the two copies differ, then the original chp value is left unchanged. sprmcmajority is stored only in grpprls linked to piece table entries.

sprmchpsinc1 (opcode 0xca4a) is used to increase or decrease chp.hps by increments of 1. this sprm is interpreted by adding the two byte increment stored as the opcode of the sprm to chp.hps. if this result is less than 8, the chp.hps is set to 8. if the result is greater than 32766, the chp.hps is set to 32766.

sprmcmajority50 (opcode 0xca4c) has the same format as sprmcmajority and is interpreted in the same way.

sprmcproprmark (opcode 0xca57) is interpreted by moving the first parameter byte to chp.fproprmark, the next two bytes to chp.ibstproprmark, and the remaining four bytes to chp.dttmproprmark.

sprmcdispfldrmark (opcode 0xca62) is interpreted by moving the first parameter byte to chp.fdispfldrmark, the next two bytes to chp.ibstdispfldrmark, the next four bytes to chp.dttmdispfldrmark, and the remaining 32 bytes to chp.xstdispfldrmark.

sprmcrgftc0 (opcode 0x4a4f), sprmccrgftc1(opcode 0x4a50), and sprmcrgftc2 (opcode 0x4a4f) are used to specify the fonts that are available for use with text. rgftc0 specifies the font used for characters from u+0000 -> u+007f. rgftc1 specifies the font to be used for far east characters, and rgftc2 specifies the font to be used for all other text. see appendix c for details on how the font is calculated.

sprmcrglid0 (opcode 0x486d) and sprmcrglid1 (opcode 0x486e) are used to specify the languages that are available for use with the text in this run. sprmcrglid1 specifies the language for far east text, sprmcrglid0 specifies the language for all other text. see appendix c for details on the language is calculated.

sprmcidcthint (opcode 0x286f) specifies a script bias for the text in the run. for unicode characters that are shared between far east and non-far east scripts, this property determines what font and language the character will use. when this value is 0, text properties bias towards non-far east properties. when this value is 1, text properties bias towards far east properties. see appendix c for details on the calculation of font and language properties.

sprmpicscale (opcode 0xce01) is used to scale the x and y dimensions of a word picture and to set the cropping for each side of the picture. the sprm begins with the two-byte opcode, followed by the length of the parameter (always 12) stored in a byte. the 12-byte long operand consists of an array of 6 two-byte integer fields. the 0th integer contains the new setting for pic.mx. the 1st integer contains the new setting for pic.my. the 2nd integer contains the new setting for pic.dxacropleft. the 3rd integer contains the new setting for pic.dyacroptop. the 4th integer contains the new setting for pic.dxacropright. the 5th integer contains the new setting of pic.dxacropbottom. sprmpicscale is stored only in grpprls linked to piece table entries.

sprmsproprmark (opcode 0xd227) is interpreted by moving the first parameter byte to sep.fproprmark, the next two bytes to sep.ibstproprmark, and the remaining four bytes to sep.dttmproprmark.

sprmstextflow (opcode 0x5033) represents the textflow to be applied to this section. possible values are:

0 horizontal, non-@font
1 top to bottom, @font
2 bottom to top, non-@font
3 top to botton, non-@font
4 horizontal, @-font

sprmtdxaleft (opcode 0x9601) is called to adjust the x position within a column which marks the left boundary of text within the first cell of a table row. this sprm causes a whole table row to be shifted left or right within its column leaving the horizontal width and vertical height of cells in the row unchanged. bytes 0-1 of the sprm contains the opcode, and the new dxa position, call it dxanew, is stored as an integer in bytes 2 and 3. word interprets this sprm by addingdxanew - (rgdxacenter[0] + tap.dxagaphalf) to every entry of tap.rgdxacenter whose index is less than tap.itcmac. sprmtdxaleft is stored only in grpprls linked to piece table entries.

sprmtdxagaphalf (opcode 0x9602) adjusts the white space that is maintained between columns by changing tap.dxagaphalf. because we want the left boundary of text within the leftmost cell to be at the same location after the sprm is applied, word also adjusts tap.rgdxcenter[0] by the amount that tap.dxagaphalf changes. bytes 0-1 of the sprm contains the opcode, and the new dxagaphalf, call it dxagaphalfnew, is stored in bytes 2 and 3. when the sprm is interpreted, the change between the old and new dxagaphalf values, tap.dxagaphalf - dxagaphalfnew, is added to tap.rgdxacenter[0] and then dxagaphalfnew is moved to tap.dxagaphalf. sprmtdxagaphalf is stored in papxs and also in grpprls linked to piece table entries.

sprmttableborders (opcode 0xd605) sets the tap.rgbrctable. the sprm is interpreted by moving the 24 bytes of the sprm's operand to tap.rgbrctable.

sprmtdeftable10 (opcode0xd606) is an obsolete version of sprmtdeftable (opcode 0xd608) that was used in winword 1.x. its contents are identical to those in sprmtdeftable, except that the tc structures contain the obsolete structures brc10s.

sprmtdeftable (opcode 0xd608) defines the boundaries of table cells (tap.rgdxacenter) and the properties of each cell in a table (tap.rgtc). bytes 0 and 1 of the sprm contain its opcode. bytes 2 and 3 store a two-byte length of the following parameter. byte 4 contains the number of cells that are to be defined by the sprm, call it itcmac. when the sprm is interpreted, itcmac is moved to tap.itcmac. itcmac cannot be larger than 32. in bytes 5 through 5+2*(itcmac + 1) -1 , is stored an array of integer dxa values sorted in ascending order which will be moved to tap.rgdxacenter. in bytes 5+ 2*(itcmac + 1) through byte 5+2*(itcmac + 1) + 10*itcmac - 1 is stored an array of tc entries corresponding to the stored tap.rgdxacenter. this array is moved to tap.rgtc. sprmtdeftable is only stored in papxs.

sprmtdeftableshd (opcode 0xd609) is similar to sprmtdeftable, and compliments it by defining the shading of each cell in a table (tap.rgshd). bytes 0 and 1 of the sprm contain its opcode. bytes 2 and 3 store a two-byte length of the following parameter. byte 4 contains the number of cells that are to be defined by the sprm, call it itcmac. itcmac cannot be larger than 32. in bytes 5 through 5+2*(itcmac + 1) -1 , is stored an array of shds. this array is moved to tap.rgshd. sprmtdeftable is only stored in papxs.

sprmtsetbrc (opcode 0xd620) allows the border definitions(brcs) within tcs to be set to new values. it has the following format:

b10 b16 field type size bitfield comments
0 0 sprm short     opcode 0xd620
2 2 count byte     number of bytes for operand
3 3 itcfirst byte     the index of the first cell that is to have its borders changed.
4 4 itclim byte     index of the cell that follows the last cell to have its borders changed
5 5   short :4 f0 reserved
    fchangeright short :1 08 =1 when tap.rgtc[].brcright is to be changed
    fchangebottom short :1 04 =1 when tap.rgtc[].brcbottom is to be changed
    fchangeleft short :1 02 =1 when tap.rgtc[].brcleft is to be changed
    fchangetop short :1 01 =1 when tap.rgtc[].brctop is to be changed
6 6 brc brc     new brc value to be stored in tcs.

this sprm changes the brc fields selected by the fchange* flags in the sprm to the brc value stored in the sprm, for every tap.rgtc entry whose index is greater than or equal to itcfirst and less than itclim.sprmtsetbrc is stored only in grpprls linked to piece table entries.

sprmtinsert (opcode 0x7621) inserts new cell definitions in an existing table's cell structure. bytes 0 and 1 of the sprm contain the opcode. byte 2 is the index within tap.rgdxacenter and tap.rgtc at which the new dxacenter and tc values will be inserted. call this index itcinsert. byte 3 contains a count of the cell definitions to be added to the tap, call it ctc. bytes 4 and 5 contain the width of the cells that will be added, call it dxacol. if there are already cells defined at the index where cells are to be inserted, tap.rgdxacenter entries at or above this index must be moved to the entry ctc higher and must be adjusted by adding ctc*dxacol to the value stored. the contents of tap.rgtc at or above the index must be moved 10*ctc bytes higher in tap.rgtc. if itcinsert is greater than the original tap.itcmac, itcinsert - tap.ctc columns beginning with index tap.itcmac must be added of width dxacol (loop from itcmac to itcmac+itcinsert-tap.ctc adding dxacol to the rgdxacenter value of the previous entry and storing sum as dxacenter of new entry), whose tc entries are cleared to zeros. beginning with index itcinsert, ctc columns of width dxacol must be added by constructing new tap.rgdxacenter and tap.rgtc entries with the newly defined rgtc entries cleared to zeros. finally, the number of cells that were added to the tap is added to tap.itcmac. sprmtinsert is stored only in grpprls linked to piece table entries.

sprmtdelete (opcode 0x5622) deletes cell definitions from an existing table's cell structure. bytes 0 and 1of the sprm contain the opcode. byte 2 contains the index of the first cell to delete, call it itcfirst. byte 3 contains the index of the cell that follows the last cell to be deleted, call it itclim. sprmtdelete causes any rgdxacenter and rgtc entries whose index is greater than or equal to itclim to be moved to the entry that is itclim - itcfirst lower, and causes tap.itcmac to be decreased by the number of cells deleted. sprmtdelete is stored only in grpprls linked to piece table entries.

sprmtdxacol (opcode 0x7623) changes the width of cells whose index is within a certain range to be a certain value. bytes 0 and 1of the sprm contain the opcode. byte 2 contains the index of the first cell whose width is to be changed, call it itcfirst. byte 3 contains the index of the cell that follows the last cell whose width is to be changed, call it itclim. bytes 4 and 5 contain the new width of the cell, call it dxacol. this sprm causes the itclim - itcfirst entries of tap.rgdxacenter to be adjusted so that tap.rgdxacenter[i+1] = tap.rgdxacenter[i] + dxacol. any tap.rgdxacenter entries that exist beyond itclim are adjusted to take into account the amount added to or removed from the previous columns.sprmtdxacol is stored only in grpprls linked to piece table entries.

sprmtmerge (opcode 0x5624) merges the display areas of cells within a specified range. bytes 0 and 1 of the sprm contain the opcode. byte 2 contains the index of the first cell that is to be merged, call it itcfirst. byte 3 contains the index of the cell that follows the last cell to be merged, call it itclim. this sprm causes tap.rgtc[itcfirst].ffirstmerged to be set to 1. cells in the range whose index is greater than itcfirst and less than itclim have tap.rgtc[].fmerged set to 1. sprmtmerge is stored only in grpprls linked to piece table entries.

sprmtsplit (opcode 0x5625) splits the display areas of merged cells into their originally assigned display areas. bytes 0 and 1 of the sprm contain the opcode. byte 2 contains the index of the first cell that is to be split, call it itcfirst. byte 3 contains the index of the cell that follows the last cell to be split, call it itclim. this sprm clears tap.rgtc[].ffirstmerged and tap.rgtc[].fmerged for all rgtc entries >= itcfirst and < itclim. sprmtsplit is stored only in grpprls linked to piece table entries.

sprmtsetbrc10 (opcode 0xd626) has the same format as sprmtsetbrc but uses the old brc10 structure.

sprmtsetshd (opcode 0x7627) allows the shading definitions(shds) within a tap to be set to new values. bytes 0 and 1 of the sprm contain the opcode. byte 2 contains the index of the first cell whose shading is to be changed, call it itcfirst. byte 3 contains the index of the cell that follows the last cell whose shading is to be changed, call it itclim. bytes 4 and 5 contain the shd structure, call it shd. this sprm causes the itclim - itcfirst entries of tap.rgshd to be set to shd. sprmtsetshd is stored only in grpprls linked to piece table entries.

sprmtsetshdodd (opcode 0x7628) is identical to sprmtsetshd, but it only changes the rgshd for odd indices between itcfirst and. sprmtsetshdodd is stored only in grpprls linked to piece table entries.

sprmtvertmerge (opcode 0xd62b) changes the vertical cell merge properties for a cell in the tap.rgtc[]. bytes 0 and 1 of the sprm contain the opcode. byte 2 contains the index of the cell whose vertical cell merge properties are to be changed. byte 3 codes the new vertical cell merge properties for the cell, a 0 clears both fvertmerge and fvertrestart, a 1 sets fvertmerge and clears fvertrestart, and a 3 sets both flags. sprmtvertmerge is stored only in grpprls linked to piece table entries.

sprmtvertalign (opcode 0xd62c) changes the vertical alignment property in the tap.rgtc[]. bytes 0 and 1 of the sprm contain the opcode. byte 2 contains the index of the first cell whose shading is to be changed, call it itcfirst. byte 3 contains the index of the cell that follows the last cell whose shading is to be changed, call it itclim. this sprm causes the vertalign properties of the itclim - itcfirst entries of tap.rgtc[] to be set to the new vertical alignment property contained in byte 4. sprmtvertalign is stored only in grpprls linked to piece table entries.

complex file format

there are some differences between the file format of a full saved document and that of a fast saved document. in previous versions of word, one of the differences was the necessity of the "complex" table information. in word '97 and later, the fcclx always indicates the location of the "complex" table information and it is always necessary to determine the location and contents of text and properties. this arises due to unicode and unicode compression.

fcclx is the fc where the complex part of the file begins, and cbclx is the size (in bytes) of the complex part. the complex part of the file contains a group of grpprls that encode formatting changes made by the user and a piece table (plcfpcd). the piece table is needed because the text of the document is not stored contiguously in the file after a fast save.

the complex part of a file (clx) is composed of a number of variable-sized blocks of data. recorded first are any grpprls that may be referenced by the plcfpcd (if the plcfpcd has no grpprl references, no grpprls will be recorded) followed by the plcfpcd. each block in the complex part is prefaced by a clxt (clx type), which is a 1-byte code, either 1 (meaning the block contains a grpprl) or 2 (meaning this is the plcfpcd). a clxtgrpprl (1) is followed by a 2-byte cb which is the count of bytes of the grpprl. a clxtplcfpcd (2) is followed by a 4-byte lcb which is the count of bytes of the piece table. a full saved file will have no clxtgrpprl's. so the formats of the two types of blocks are:

clxt = 1 clxtgrpprl
cb count of bytes in grpprl
grpprl see "definitions" for description of grpprl; a grpprl can contain sprms modifying character, paragraph, table, section or picture properties

or

clxt = 2 clxtplcfpcd
lcb count of bytes in piece table
plcfpcd piece table

the entire clx would look like this, depending on the number of grpprl's:

clxtgrpprl
cb
grpprl (0th grpprl)
clxtgrpprl
cb
grpprl (1st grpprl)
...
clxtplcfpcd
cb
plcfpcd

when the prm in pcds stored in the plcfpcd, contains an igrpprl (index to a grpprl), the index stored is the order in which that grpprl was stored in the clx.

algorithm to determine the bounds of a paragraph containing a certain character in a complex file

when a document is recorded in non-complex format, the bounds of the paragraph that contains a particular character can be found by calculating the fc coordinate of the character, searching the bin table to find an fkp page that describes that fc, fetching that fkp, and then searching the fkp to find the interval in the rgfc that encloses the character. the bounds of the interval are the fcfirst and fclim of the containing paragraph. every character greater than or equal to fcfirst and less than fclim is part of the containing paragraph.

when a document is recorded in complex format, a piece that was originally part of one paragraph can be copied or moved within a different paragraph. to find the beginning of the paragraph containing a character in a complex document, it's first necessary to search for the piece containing the character in the piece table. then calculate the fc in the file that stores the character from the piece table information. using the fc, search the fcs fkp for the largest fc less than the character's fc, call it fctest. if the character at fctest-1 is contained in the current piece, then the character corresponding to that fc in the piece is the first character of the paragraph. if that fc is before or marks the beginning of the piece, scan a piece at a time towards the beginning of the piece table until a piece is found that contains a paragraph mark. this can be done by using the end of the piece fc, finding the largest fc in its fkp that is less than or equal to the end of piece fc, and checking to see if the character in front of the fkp fc (which must mark a paragraph end) is within the piece. when such an fkp fc is found, the fc marks the first byte of paragraph text.

to find the end of a paragraph for a character in a complex format file, again it is necessary to know the piece that contains the character and the fc assigned to the character. using the fc of the character, first search the fkp that describes the character to find the smallest fc in the rgfc that is larger than the character fc. if the fc found in the fkp is less than or equal to the limit fc of the piece, the end of the paragraph that contains the character is at the fkp fc minus 1. if the fkp fc that was found was greater than the fc of the end of the piece, scan piece by piece toward the end of the document until a piece is found that contains a paragraph end mark. it's possible to check if a piece contains a paragraph mark by using the fc of the beginning of the piece to search in the fkps for the smallest fc in the fkp rgfc that is greater than the fc of the beginning of the piece. if the fc found is less than or equal to the limit fc of the piece, then the character that ends the paragraph is the character immediately before the fkp fc.

a special procedure must be followed to locate the last paragraph of the main document text when footnote or header/footer text is saved in a word file (i.e. when fib.ccpftn != 0 or fib.ccphdr != 0).

in this case the cp of that paragraph mark is fib.ccptext + fib.ccpftn + fib.ccphdr + fib.ccpmcr + fib.ccpatn and the limit cp of the entire plcfpcd is fib.ccptext + fib.ccpftn + fib.ccphdr + fib.ccpmcr + fib.ccpatn + 1.

algorithm to determine paragraph properties for a paragraph in a complex file

having found the index i of the fc in an fkp that marks the character stored in the file immediately after the paragraph's paragraph mark, it is necessary to use the word offset stored in the first byte of the fkp.rgbx[i - 1] to find the papx for the paragraph. using papx.istd to index into the properties stored for the style sheet , the paragraph properties of the style are copied to a local pap. then the grpprl stored in the papx is applied to the local pap, and papx.istd along with fkp.rgbx.phe are moved into the local pap. the process thus far has created a pap that describes what the paragraph properties of the paragraph were at the last full save. now it's necessary to apply any paragraph sprms that were linked to the piece that contains the paragraph's paragraph mark. if pcd.prm.fcomplex is 0, pcd.prm contains 1 sprm which should only be applied to the local pap if it is a paragraph sprm. if pcd.prm.fcomplex is 1, pcd.prm.igrpprl is the index of a grpprl in the clx. if that grpprl contains any paragraph sprms, they should be applied to the local pap. after applying all of the sprms for the piece, the local pap contains the correct paragraph property values.

algorithm to determine table properties for a table row in a complex file

to determine the table properties for a table row in a complex file, scan paragraph-by-paragraph toward the end of the table row, until a paragraph is found that has pap.fttp set to 1. this paragraph consists of a single row end character. this row end character is linked to the table properties of the row. to create the tap for the table row, clear a local tap to zeros. then the papx for the row end character must be fetched from an fkp, and the table sprms that are stored in this papx must be applied to the local tap. the process thus far has created a tap that describes what the table properties of the table row were at the last full save. now apply any table sprms that were linked to the piece that contains the table row's row end character. if pcd.prm.fcomplex is 0, pcd.prm contains 1 sprm which should be applied to the local tap if it is a table sprm. if pcd.prm.fcomplex is 1, pcd.prm.igrpprl is the index of a grpprl in the clx. if that grpprl contains any table sprms, apply them to the local tap. after all of the sprms for the piece are applied, the local tap contains the correct table property values for the table row.

algorithm to determine the character properties of a character in a complex file

it is first necessary to fetch the paragraph properties of the paragraph that contains the character. the pap.istd of the fetched properties specifies which style sheet entry provides the default character properties for the character. the character properties recorded in the style sheet for that style are copied into a local chp. then, the piece containing the character is located in the piece table (plcfpcd) and the fc of the character is calculated. using the character's fc, the page number of the chpx fkp that describes the character is found by searching the bin table (hplcfbtechpx). the chpx fkp stored in that page is fetched and then the rgfc in the fkp is searched to locate the bounds of the run of exception text that encompasses the character. the chpx for that run is then located within the fkp, and the chpx is applied to the contents of the local chp. the process thus far has created a chp that describes what the character properties of the character were at the last full save. now apply any character sprms that were linked to the piece that contains the character. if pcd.prm.fcomplex is 0, pcd.prm contains 1 sprm which should be applied to the local chp if it is a character sprm. if pcd.prm.fcomplex is 1, pcd.prm.igrpprl is the index of a grpprl in the clx. if that grpprl contains any character sprms, apply them to the local chp. after applying all of the sprms for the piece, the local chp contains the correct properties for the character.

characters that are within the same piece, same paragraph, and same run of exception text are guaranteed to have the same properties. this fact can be used to construct a scanner that can return the limit cps and properties of a sequence of characters that all have the same properties.

algorithm to determine the section properties of a section in a complex file

to determine which section a character belongs to and what its section properties are, it is necessary to use the cp of the character to search the plcfsed for the index i of the largest cp that is less than or equal to the character's cp. plcfsed.rgcp[i] is the cp of the first character of the section and plcfsed.rgcp[i+1] is the cp of the character following the section mark that terminates the section (call it cplim). then retrieve plcfsed.rgsed[i]. the fc in this sed gives the location where the sepx for the section is stored. then create a local sep with default section properties. if the sed.fc != 0xffffffff, then the sprms within the sepx that is stored at offset sed.fc must be applied to the local sep. the process thus far has created a sep that describes what the section properties of the section at the last full save. now apply any section sprms that were linked to the piece that contains the section's section mark. if pcd.prm.fcomplex is 0, pcd.prm contains 1 sprm which should be applied to the local sep if it is a section sprm. if pcd.prm.fcomplex is 1, pcd.prm.igrpprl is the index of a grpprl in the clx. if that grpprl contains any section sprms, they should be applied to the local sep. after applying all of the section sprms for the piece , the local sep contains the correct section properties.

algorithm to determine the pic of a picture in a complex file.

the picture sprms contained in the prm's grpprl apply to any picture characters within the piece that have their chp.fspec character == ftrue. the picture properties for a picture (the pic described in the structure definitions) are derived by fetching the pic stored with the picture and applying to that pic any picture sprms linked to the piece containing the picture special character.

footnotes & endnotes

in word the text of footnotes and endnotes is anchored to a particular position within the document's main text , the location of its footnote/endnote reference. the following discussion only describes footnotes, with endnotes being handled identically except that the endnote data structures contain the "edn" abbreviation where footnote data structures contain the "fnd" abbreviation. there is a structure referenced by the fib, the plcffndref, which records the locations of the footnote references within the main text address space and another structure referenced by the fib, the plcffndtxt, which records the beginning locations of corresponding footnote text within the footnote text address space . the footnote text characters in a full saved file begin at offset fib.fcmin + fib.ccptext and extends till fib.fcmin + fib.ccptext + fib.ccpftn. in a complex fast-saved document , the footnote text begins at cp fib.ccptext and extends till fib.ccptext + fib.ccpftn. to find the location of the ith footnote reference in the main text address space, look up the ith entry in the plcffndref and find the location of the text corresponding to the reference within the footnote text address space by looking up the ith entry in the plcffndtxt.

when there are n footnotes, the plcffndtxt structure consists of n+2 cp entries. the cp entries mark the beginning character position within the footnote text address space of the footnote text for the footnotes defined for the file. the beginning cp of the text of the ith footnote is the ith cp within the plcffndtxt. the limit cp of the text of the ith footnote is the i+1st cp within the plcffndtxt.

the last character of footnote text for a footnote (i.e. the character at limit cp - 1) is always a paragraph end(ascii 13). if there are n footnotes, the n+2nd cp entry value is always 1 greater than the n+1st cp entry value. a paragraph end (ascii 13) is always stored at the file position marked by the n+1st cp value.

when there are n footnotes, the plcffndref structure consists of n+1 cp entries followed by n integer flags, named fauto. the ith cp in the plcffndref corresponds to the ith fauto flag. the cp entries give the locations of footnote references within the main text address space. the n+1th cp entry contains the value fib.ccptext + fib.ccpftn + fib.ccphdr + 1. the fauto flag contains 1 whenever the footnote reference name is auto-generated by word.

when a footnote reference name is automatically generated by word, word generates the name by adding 1 to the index number of the reference in the plcffndref and translating that number to ascii text. when the footnote reference is auto generated, the character at the main text cp position for the footnote reference should be a footnote reference character (ascii 5) which has a chp recorded with chp.fspec = 1.

the number of footnotes stored in a word binary file can be found by dividing fib.cbplcffndtxt by 4 and subtracting 1.

headers and footers

the header and footer text characters in a full saved file begin at offset fib.fcmin + fib.ccptext + fib.ccpftn and extend till fib.fcmin + fib.ccptext + fib.ccpftn + fib.ccphdr. in a complex fast-saved document , the footnote text begins at cp fib.ccptext + fib.ccpftn and extends till fib.ccptext + fib.ccpftn + fib.ccphdr. the plcfhdd, a table whose location and length within the file is stored in fib.fcplcfhdd and fib.cbplcfhdd, describes where the text of each header/footer begins. if there are n headers/footers stored in the word file, the plcfhdd consists of n + 2 cp entries. the beginning cp of the ith header/footer is the ith cp in the plcfhdd. the limit cp (the cp of character 1 position past the end of a header/footer) of the ith header/footer is the i + 1 st cp in the plcfhdd. note that at the limit cp - 1, word always places a cheop as a placeholder which is never displayed as part of the header/footer. this allows word to change an existing header/footer to be empty.

if there are n header/footers, the n+2nd cp entry value is always 1 greater than the n+1st cp entry value. a paragraph end (ascii 13) is always stored at the file position marked by the n+1st cp value.

the transformation in a full saved file from a header/footer cp to an offset from the beginning of a file (fc) is fc = fib.fcmin + ccptext + ccpftn + cp.

in word, headers/footers can be defined for a document that:

also for each section defined for the document, distinct headers can be defined for printing on odd-numbered/right facing pages, even-numbered /left facing pages and the first page of a section. similarly for each document section, distinct footers can be defined for printing on odd-numbered/right facing pages, even-numbered/left facing pages and the first page of a section.

the plcfhdd contains an entry for each kind of header or footer. (the grpfihdt is no longer used to find entries in the plcfhdd.) indices in the plcfhdd are as follows:

0 header for even pages
1 header for odd pages
2 footer for even pages
3 footer for odd pages
4 header for first page of section
5 footer for first page of section
6 footnote separator
7 footnote continuation separator
8 footnote continuation notice
9 endnote separator
10 endnote continuation separator
11 endnote continuation notice

page table

page table information is optional data which is not always stored in a word binary file. it may be stored for the main text, footnote text and endnote text. the fib contains three fcpgd structures (fcpgdmother, fcpgdftn, fcpgdedn) which point to where the data is stored. each fcpgd points to a plf of pgd structures and a plcf of bkd structures. the plf of pgd descriptors contains n entries where n is the number of pages in the associated text stream. the plc of bkds contains >= n entries where each entry describes a single break (page break or otherwise) within the text stream. each bkd is associated with a pgd and contains an ipgd which is an index into the plf of pgds. to find the cp range of a given page, traverse the bkds searching for the first and last bkd which refer to the given page. the cp range of these bkds is the cp range of the page.

third-party creators of word files should not attempt to create fcpgd structures. they can only be created properly using word's page layout routines. if a word document is edited in any way, the fcpgds in the fib should be filled with 0s.

glossary files

a word glossary file is a normal word binary file with two supplemental files, the sttbfglsy, the sttbglsystyle and the plcfglsy, also stored in the file. the sttbfglsy contains a list of the names of glossary entries, the sttbglsystyle contains a list of the stylenames for every autotext entry, and the plcfglsy contains a table of beginning positions within the text address space of the file of the text of glossary entries.

the sttbfglsy begins with an integer count of bytes of the size of the sttbfglsy (includes the size of the integer count of bytes). if there are n glossary entries defined, there will follow n pascal-type strings (string preceded by length byte) concatenated one after the other which store glossary entry names. the glossary entry names must be sorted in case-insensitive ascending order. (i.e. a and a are treated as equal). also the names date and time must be included in the list of names. the name of the ith glossary entry is the ith name defined in the sttbfglsy. the extra field in each entry contains an index on the sttbglsystyle that indicates the stylename of the first paragraph in plcfglsy.

the sttbglsystyle is not sorted and has no duplicates. each entry has an extra field indicating how many autotext entries have that style.

if there are n glossary entries, the plcfglsy, will consist of n+2 cp entries. the ith cp entry will contain the location of the beginning of the text for the ith glossary entry. the i+1st cp entry will contain the limit cp of the ith glossary entry. the character at a cp position of limit cp - 1 is always a paragraph mark. the n+2nd cp entry always contains fib.ccptext + fib.ccpftn + fib.ccphdr + 1 if there are headers, footers or footnotes stored in the glossary and contains fib.ccptext + fib.ccpftn + fib.ccphdr otherwise. the n+1st cp entry is always 1 less than the value of the n+2nd entry.

the text for the time and date entries will always be a single paragraph mark (ascii 13).

routing slip

a routing slip is stored in the main document stream as an rs (routing slip) structure followed by a set of variable length data. after the rs are 4 null terminated strings. each string is preceded by a short containing the string length (including the null terminator). the strings are: the subject, the message text, status and title. following these strings are a variable number (rs.crecip) of routing recipient (rr) records. each rr is immediately followed by a variable number (rr.cb) of bytescontaining private data, which is in turn followed by a null terminated string containing the recipient name.

autosummary

for a document for which autosummary view is active (specified in the asumyi), the plcfasumy records the result of the last autosummary analysis. each asumy in the plcf gives the autosummary level for the text starting at the corresponding cp. the level must be non-negative and no greater than the upper bound specified in the asumyi. the asumyi specifies the current summary view level. in emphasize view mode, all text at and below the current summary view level is highlighted. in reduce view mode, all text above the current summary view level is hidden.

sttbfassoc (table of associated strings)

the following are indices into a table of associated strings:

ibst index description
ibstassocfilenext 0 unused
ibstassocdot 1 filename of associated template
ibstassoctitle 2 title of document
ibstassocsubject 3 subject of document
ibstassockeywords 4 keywords of document
ibstassoccomments 5 comments of document
ibstassocauthor 6 author of document
ibstassoclastrevby 7 name of person who last revised the document
ibstassocdatadoc 8 filename of data document
ibstassocheaderdoc 9 filename of header document
ibstassoccriteria1 10 packed string used by print merge record selection
ibstassoccriteria2 11 packed string used by print merge record selection
ibstassoccriteria3 12 packed string used by print merge record selection
ibstassoccriteria4 13 packed string used by print merge record selection
ibstassoccriteria5 14 packed string used by print merge record selection
ibstassoccriteria6 15 packed string used by print merge record selection
ibstassoccriteria7 16 packed string used by print merge record selection
ibstassocmax 17 maximum number of strings in string table

the format of the ibstassoccriteriax strings are as follows:

int   cbibstassoc:8;         // byte 0  size of ibstassoccriteriax string
int   fcompor:1;             // byte 1  set if cond is an or cond
int   icompop:7;             // byte 1  index of comparison operator
char  stmergefield[];        // name of mergefield
char  stcompinfo[];          // user supplied comparison information

both stmergefield and stcompinfo are variable length character arrays preceded by a length byte.

structure definitions

annotation reference descriptor (atrd)

b10 b16 field type size bitfield comments
0 0 xstusrinitl xchar[10]     pascal-style string holding initials of annotation author
20 14 ibst short     index into grpxstatnowners
22 16 ak short :2 0003 unused
      short :14 fffc unused
24 18 grfbmc uns short     unused
26 1a ltagbkmk long     when not -1, this tag identifies the annotation bookmark that locates the range of cps in the main document which this annotation references.

cbatrd (count of bytes of atrd) is 30 (decimal), 1e(hex).

autonumbered list data descriptor (anld)

b10 b16 field type size bitfield comments
0 0 nfc unsigned char     number format code
0 arabic numbering
1 upper case roman
2 lower case roman
3 upper case letter
4 lower case letter
5 ordinal
1 1 cxchtextbefore unsigned char     offset into anld.rgxch that is the limit of the text that will be displayed as the prefix of the autonumber text
2 2 cxchtextafter unsigned char     anld.cxchtextbefore will be the beginning offset of the text in the anld.rgxch that will be displayed as the suffix of an autonumber. the sum of anld.cxchtextbefore + anld.cxchtextafter will be the limit of the autonumber suffix in anld.rgch
3 3 jc uns char :2 03 justification code
0 left justify
1 center
2 right justify
3 left and right justify
    fprev uns char :1 04 when ==1, number generated will include previous levels (used for legal numbering)
    fhang uns char :1 08 when ==1, number will be displayed using a hanging indent
    fsetbold uns char :1 10 when ==1, boldness of number will be determined by anld.fbold.
    fsetitalic uns char :1 20 when ==1, italicness of number will be determined by anld.fitalic
    fsetsmallcaps uns char :1 40 when ==1, anld.fsmallcaps will determine whether number will be displayed in small caps or not.
    fsetcaps uns char :1 80 when ==1, anld.fcaps will determine whether number will be displayed capitalized or not
4 4 fsetstrike uns char :1 01 when ==1, anld.fstrike will determine whether the number will be displayed using strikethrough or not.
    fsetkul uns char :1 02 when ==1, anld.kul will determine the underlining state of the autonumber.
    fprevspace uns char :1 04 when ==1, autonumber will be displayed with a single prefixing space character
    fbold uns char :1 08 determines boldness of autonumber when anld.fsetbold == 1.
    fitalic uns char :1 10 determines italicness of autonumber when anld.fsetitalic == 1.
    fsmallcaps uns char :1 20 determines whether autonumber will be displayed using small caps when anld.fsetsmallcaps == 1.
    fcaps uns char :1 40 determines whether autonumber will be displayed using caps when anld.fsetcaps == 1.
    fstrike uns char :1 80 determines whether autonumber will be displayed using caps when anld.fsetstrike == 1.
5 5 kul uns char :3 07 determines whether autonumber will be displayed with underlining when anld.fsetkul == 1.
    ico uns char :5 f1 color of autonumber
6 6 ftc short     font code of autonumber
8 8 hps uns short     font half point size (or 0=auto)
10 a istartat uns short     starting value (0 to 65535)
12 c dxaindent       width of prefix text (same as indent)
14 e dxaspace uns short     minimum space between number and paragraph
16 10 fnumber1 uns char     number only 1 item per table cell
17 11 fnumberacross uns char     number across cells in table rows(instead of down)
18 12 frestarthdn uns char     restart heading number on section boundary
19 13 fsparex uns char     unused( should be 0)
20 14 rgxch array of 32 xchars     characters displayed before/after autonumber

cbanld (count of bytes of anld) is 84 (decimal), 54(hex).

autonumber level descriptor (anlv)

b10 b16 field type size bitfield comments
0 0 nfc unsigned char     number format code
0 arabic numbering
1 upper case roman
2 lower case roman
3 upper case letter
4 lower case letter
5 ordinal
1 1 cxchtextbefore unsigned char     offset into anld.rgxch that is the limit of the text that will be displayed as the prefix of the autonumber text
2 2 cxchtextafter unsigned char     anld.cxchtextbefore will be the beginning offset of the text in the anld.rgxch that will be displayed as the suffix of an autonumber. the sum of anld.cxchtextbefore + anld.cxchtextafter will be the limit of the autonumber suffix in anld.rgxch
3 3 jc uns char :2 03 justification code
0 left justify
1 center
2 right justify
3 left and right justify
    fprev uns char :1 04 when ==1, number generated will include previous levels (used for legal numbering)
    fhang uns char :1 08 when ==1, number will be displayed using a hanging indent
    fsetbold uns char :1 10 when ==1, boldness of number will be determined by anld.fbold.
    fsetitalic uns char :1 20 when ==1, italicness of number will be determined by anld.fitalic
    fsetsmallcaps uns char :1 40 when ==1, anld.fsmallcaps will determine whether number will be displayed in small caps or not.
    fsetcaps uns char :1 80 when ==1, anld.fcaps will determine whether number will be displayed capitalized or not
4 4 fsetstrike uns char :1 01 when ==1, anld.fstrike will determine whether the number will be displayed using strikethrough or not.
    fsetkul uns char :1 02 when ==1, anld.kul will determine the underlining state of the autonumber.
    fprevspace uns char :1 04 when ==1, autonumber will be displayed with a single prefixing space character
    fbold uns char :1 08 determines boldness of autonumber when anld.fsetbold == 1.
    fitalic uns char :1 10 determines italicness of autonumber when anld.fsetitalic == 1.
    fsmallcaps uns char :1 20 determines whether autonumber will be displayed using small caps when anld.fsetsmallcaps == 1.
    fcaps uns char :1 40 determines whether autonumber will be displayed using caps when anld.fsetcaps == 1.
    fstrike uns char :1 80 determines whether autonumber will be displayed using caps when anld.fsetstrike == 1.
5 5 kul uns char :3 07 determines whether autonumber will be displayed with underlining when anld.fsetkul == 1.
    ico uns char :5 f1 color of autonumber
6 6 ftc short     font code of autonumber
8 8 hps uns short     font half point size (or 0=auto)
10 a istartat uns short     starting value (0 to 65535)
12 c dxaindent       width of prefix text (same as indent)
14 e dxaspace uns short     minimum space between number and paragraph

cbanlv (count of bytes of anlv) is 16 bytes (decimal), 10 bytes (hex).

autosummary analysis (asumy)

b10 b16 field type size bitfield comments
0 0 llevel long     autosummary level

cbasumy (count of bytes of asumy) is 4 bytes.

autosummary info (asumyi)

b10 b16 field type size bitfield comments
0 0 fvalid short :1 0001 true iff the asumyi is valid
    fview short :1 0002 true iff autosummary view is active
    iviewby short :2 000c display method for autosummary view:
0 = emphasize in current doc
1 = reduce doc to summary
2 = insert into doc
3 = show in new document
    fupdateprops short :1 0010 true if we should update file properties summary information after the next summarization
    reserved short :11 ffe0 reserved
2 2 wdlglevel short     dialog summary level
4 4 lhighestlevel long     upper bound for llevel for sentences in this document
8 8 lcurrentlevel long     show document sentences at or below this level

cbasumyi (count of bytes of asumyi) is 12 bytes (decimal), c bytes (hex).

bin table entry (bte)

b10 b16 field type size bitfield comments
0 0 pn long :22   autosummary level
    unused long :10   unused

cbbte (count of bytes of bte) is 4 bytes.

break descriptor (bkd)

b10 b16 field type size bitfield comments
0 0 ipgd short     except in textbox bkd, index to pgd in plfpgd that describes the page this break is on.
0 0 itxbxs short     in textbox bkd,
2 2 dcpdepend short     number of cp's considered for this break; note that the cp's described by cpdepend in this break reside in the next bkd
    icol uns short :8 00ff  
    ftablebreak uns short :1 0100 when 1, this indicates that this is a table break.
    fcolumnbreak uns short :1 0200 when 1, this indicates that this is a column break.
    fmarked uns short :1 0400 used temporarily while word is running.
    funk uns short :1 0800 in textbox bkd, when == 1 indicates cplim of this textbox is not valid
    ftextoverflow uns short :1 1000 in textbox bkd, when == 1 indicates that text overflows the end of this textbox

cbbkd (count of bytes of bkd) is 6.

bookmark first descriptor (bkf)

b10 b16 field type size bitfield comments
0 0 ibkl short     index to bkl entry in plcfbkl that describes the ending position of this bookmark in the cp stream.
2 2 itcfirst uns short :7 007f when bkf.fcol is 1, this is the index to the first column of a table column bookmark.
    fpub uns short :1 0080 when 1, this indicates that this bookmark is marking the range of a macintosh publisher section.
    itclim uns short :7 7f00 when bkf.fcol is 1, this is the index to limit column of a table column bookmark.
    fcol uns short :1 8000 when 1, this bookmark marks a range of columns in a table specified by [bkf.itcfirst, bkf.itclim).

cbbkf (count of bytes of bkf) is 4.

bookmark lim descriptor (bkl)

the bkl is no longer stored in the plcfbkl or plcfatnbkl, and is instead reconstructed from the plcfbkf or plcfatnbkf when the file is opened.

b10 b16 field type size bitfield comments
0 0 ibkf short     index to bkf entry in plcfbkf that describes the beginning position of this bookmark in the cp stream. if the bkl.ibkf is negative, add on the number of bookmarks recorded in the hplcbkf to the bkl.ibkf to calculate the index to the bkf that corresponds to this entry.

cbbkl (count of bytes of bkl) is 2.

border code (brc)

the brc is a substructure of the chp, pap, pic, sep, tap and tc. see also the obsolete brc10 structure.

b10 b16 field type size bitfield comments
0 0 dptlinewidth short :8 00ff width of a single line in 1/8 pt, max of 32 pt.
    brctype short :8 ff00 border type code:
0 none
1 single
2 thick
3 double
5 hairline
6 dot
7 dash large gap
8 dot dash
9 dot dot dash
10 triple
11 thin-thick small gap
12 thick-thin small gap
13 thin-thick-thin small gap
14 thin-thick medium gap
15 thick-thin medium gap
16 thin-thick-thin medium gap
17 thin-thick large gap
18 thick-thin large gap
19 thin-thick-thin large gap
20 wave
21 double wave
22 dash small gap
23 dash dot stroked
24 emboss 3d
25 engrave 3d
codes 64 - 230 represent border art types and are used only for page borders.
2 2 ico short :8 00ff color code (see chp.ico)
    dptspace short :5 1f00 width of space to maintain between border and text within border. must be 0 when brc is a substructure of tc. stored in points.
    fshadow short :1 2000 when 1, border is drawn with shadow. must be 0 when brc is a substructure of the tc
    fframe short :1 4000  
      short :1 8000 reserved

cbbrc (count of bytes of brc) is 4.

border code for windows word 1.0 (brc10)

b10 b16 field type size bitfield comments
0 0 dxpline2width short :3 0007 width of second line of border in pixels
    dxpspacebetween short :3 0038 distance to maintain between both lines of border in pixels
    dxpline1width short :3 01c0 width of first border line in pixels
    dxpspace short :5 3e00 width of space to maintain between border and text within border. must be 0 when brc is a substructure of the tc.
    fshadow short :1 4000 when 1, border is drawn with shadow. must be 0 when brc10 is a substructure of the tc.
    fspare short :1 8000 reserved

the seven types of border lines that windows word 1.0 supports are coded with different sets of values for dxpline1width, dxpspacebetween, and dxpline2 width.

the border lines and their brc10 settings follow:

line type dxpline1width dxpspacebetween dxpline2width
no border 0 0 0
single line border 1 0 0
two single line border 1 1 1
fat solid border 4 0 0
thick solid border 2 0 0
dotted border 6 (special value meaning dotted line) 0 0
hairline border 7(special value meaning hairline) 0 0

when the no border settings are stored in the brc, brc.fshadow and brc.dxpspace should be set to 0.

cbbrc10 (count of bytes of brc10) is 2.

character properties (chp)

the chp is never stored in word files. it is the result of decompression operations applied to chpxs

the chpx is stored in chpx fkps and within the stsh

note

when a chpx is stored in an fkp it is prefixed by a one-byte count of bytes that records the size of the non-zero prefix of the chpx. since the count of bytes must begin on an even boundary within the fkp followed by the non-zero prefix, it's guaranteed that the int and fc fields of the chpx are aligned on an odd-byte boundary. using normal integer or long load instructions will cause address errors on a 68000. the best technique for reconstituting the chpx is to move the non-zero prefix to the beginning of a local instance of a chpx that has been cleared to zeros.

b10 b16 field type size bitfield comment
0 0 fbold short :1 0001 text is bold when 1 , and not bold when 0.
    fitalic short :1 0002 italic when 1, not italic when 0
    frmarkdel short :1 0004 when 1, text has been deleted and will be displayed with strikethrough when revision marked text is to be displayed
    foutline short :1 0008 outlined when 1, not outlined when 0
    ffldvanish short :1 0010 used internally by word
    fsmallcaps short :1 0020 displayed with small caps when 1, no small caps when 0
    fcaps short :1 0040 displayed with caps when 1, no caps when 0
    fvanish short :1 0080 when 1, text has "hidden" format, and is not displayed unless fpaghidden is set in the dop
1 1 frmark short :1 0100 when 1, text is newly typed since the last time revision marks have been accepted and will be displayed with an underline when revision marked text is to be displayed
    fspec short :1 0200 character is a word special character when 1, not a special character when 0
    fstrike short :1 0400 displayed with strikethrough when 1, no strikethrough when 0
    fobj short :1 0800 embedded object when 1, not an embedded object when 0
    fshadow short :1 1000 character is drawn with a shadow when 1; drawn without shadow when 0
    flowercase short :1 2000 character is displayed in lower case when 1. no case transformation is performed when 0. this field may be set to 1 only when chp.fsmallcaps is 1.
    fdata short :1 4000 when 1, chp.fcpic points to an ffdata, the data structure binary data used by word to describe a form field. the bit chp.fdata may only be 1 when chp.fspec is also 1 and the special character in the document stream that has this property is a chpicture (0x01).
    fole2 short :1 8000 when 1, chp.ltagobj specifies a particular object in the object stream that specifies the particular ole object in the stream that should be displayed when the chpicture fspec character that is tagged with the fole2 is encountered. the bit chp.fole2 may only be 1 when chp.fspec is also 1 and the special character in the document stream that has this property is a chpicture (0x01).
2 2 femboss short :1 0001 text is embossed when 1 and not embossed when 0
    fimprint short :1 0002 text is engraved when 1 and not engraved when 0
    fdstrike short :1 0004 displayed with double strikethrough when 1, no double strikethrough when 0
    fusepgsusettings short :1 0008  
      short :12 fff0 reserved
4 4   long     reserved
8 8 ftc short     no longer stored
10 a ftcascii(rgftc[0]) short     font for ascii text
12 c ftcfe(rgftc[1]) short     font for far east text
14 e ftcother(rgftc[2]) short     font for non-far east text
16 10 hps unsigned short     font size in half points
18 12 dxaspace long     space following each character in the run expressed in twip units.
22 16 iss short :3 0007 superscript/subscript indices
0 means no super/subscripting
1 means text in run is superscripted
2 means text in run is subscripted
    kul short :4 0078 underline code:
0 none
1 single
2 by word
3 double
4 dotted
5 hidden
6 thick
7 dash
8 dot (not used)
9 dot dash
10 dot dot dash
11 wave
    fspecsymbol short :1 0080 used by word internally, not stored in file
23 17 ico short :5 1f00 color of text:
0 auto
1 black
2 blue
3 cyan
4 green
5 magenta
6 red
7 yellow
8 white
9 dkblue
10 dkcyan
11 dkgreen
12 dkmagenta
13 dkred
14 dkyellow
15 dkgray
16 ltgray
      short :1 2000 reserved
    fsysvanish short :1 4000 used by word internally, not stored in file
    hpspos short :1 8000 reserved
24 18   short     super/subscript position in half points; positive means text is raised; negative means text is lowered.
26 1a lid lid     language identification code
(no longer stored here, see rglid below)
      language id
0x0400
0x0401
0x0402
0x0403
0x0404
0x0804
0x0405
0x0406
0x0407
0x0807
0x0408
0x0409
0x0809
0x0c09
0x040a
0x080a
0x040b
0x040c
0x080c
0x0c0c
0x100c
0x040d
0x040e
0x040f
0x0410
0x0810
0x0411
0x0412
0x0413
0x0813
0x0414
0x0814
0x0415
0x0416
0x0816
0x0417
0x0418
0x0419
0x041a
0x081a
0x041b
0x041c
0x041d
0x041e
0x041f
0x0420
0x0421
0x0422
0x0423
0x0424
0x0425
0x0426
0x0427
0x0429
0x042d
0x042f
0x0436
0x043e
language name
no proofing
arabic
bulgarian
catalan
traditional chinese
simplified chinese
czech
danish
german
swiss german
greek
u.s. english
u.k. english
australian english
castilian spanish
mexican spanish
finnish
french
belgian french
canadian french
swiss french
hebrew
hungarian
icelandic
italian
swiss italian
japanese
korean
dutch
belgian dutch
norwegian - bokmal
norwegian - nynorsk
polish
brazilian portuguese
portuguese
rhaeto-romanic
romanian
russian
croato-serbian (latin)
serbo-croatian (cyrillic)
slovak
albanian
swedish
thai
turkish
urdu
bahasa
ukrainian
byelorussian
slovenian
estonian
latvian
lithuanian
farsi
basque
macedonian
afrikaans
malaysian
28 1c liddefault(rglid[0]) lid     language for non-far east text
30 1e lidfe(rglid[1]) lid     language for far east text
32 20 idct unsigned char     not stored in file
33 21 idcthint unsigned char     identifier of characte type
            0 -> shared chars get non-fe props
            1 -> shared chars get fe props
            (see appendix c)
34 22 wcharscale unsigned short      
36 24 fcpic fc     offset in data stream pointing to beginning of a picture when character is a picture character (character is 0x01 and chp.fspec is 1)
36 24 fcobj fc     offset in data stream pointing to beginning of a picture when character is an ole1 object character (character is 0x20 and chp.fspec is 1, chp.fole2 is 0)
36 24 ltagobj unsigned long     long word tag that identifies an ole2 object in the object stream when the character is an ole2 object character. (character is 0x01 and chp.fspec is 1, chp.fole2 is 1)
40 28 ibstrmark short     index to author ids stored in hsttbfrmark. used when text in run was newly typed when revision marking was enabled
42 2a ibstrmarkdel short     index to author ids stored in hsttbfrmark. used when text in run was deleted when revision marking was enabled
44 2c dttmrmark dttm     date/time at which this run of text was entered/modified by the author. (only recorded when revision marking is on.)
48 30 dttmrmarkdel dttm     date/time at which this run of text was deleted by the author. (only recorded when revision marking is on.)
52 34   short     reserved
54 36 istd unsigned short     index to character style descriptor in the stylesheet that tags this run of text when istd is istdnormalchar (10 decimal), characters in run are not affected by a character style. if chp.istd contains any other value, chpx of the specified character style are applied to chp for this run before any other exceptional properties are applied.
56 38 ftcsym short     when chp.fspec is 1 and the character recorded for the run in the document stream is chsymbol (0x28), chp.ftcsym identifies the font code of the symbol font that will be used to display the symbol character recorded in chp.xchsym. chp.ftcsym is an index into the rgffn structure.
58 3a xchsym xchar     when chp.fspec is 1 and the character recorded for the run in the document stream is chsymbol (0x28), the character stored chp.xchsym will be displayed using the font specified in chp.ftcsym.
60 3c idslrmreason short     an index to strings displayed as reasons for actions taken by word's autoformat code
62 3e idslreasondel short     an index to strings displayed as reasons for actions taken by word's autoformat code
64 40 ysr unsigned character     hyphenation rule
0 no hyphenation
1 normal hyphenation
2 add letter before hyphen
3 change letter before hyphen
4 delete letter before hyphen
5 change letter after hyphen
6 delete letter before the hyphen and change the letter preceding the deleted character
65 41 chysr unsigned character     the character that will be used to add or change a letter when chp.ysr is 2,3, 5 or 6
66 42 cpg unsigned short      
68 44 hpskern unsigned short     kerning distance for characters in run recorded in half points
70 46 icohighlight short :5 001f highlight color (see chp.ico)
    fhighlight short :1 0020 when 1, characters are highlighted with color specified by chp.icohighlight.
    kcd short :3 01c0  
    fnavhighlight short :1 0200 used internally by word
    fchsdiff short :1 0400  
    fmacchs short :1 0800  
    fftcascisym short :1 1000  
      short :3 e000 reserved
72 48 fpropmark unsigned short     when 1, properties have been changed with revision marking on
74 4a ibstproprmark short     index to author ids stored in hsttbfrmark. used when properties have been changed when revision marking was enabled
76 4c dttmproprmark dttm     date/time at which properties of this were changed for this run of text by the author. (only recorded when revision marking is on.)
80 50 sfxttext unsigned char     text animation:
0 no animation
1 las vegas lights
2 background../jpg/di1.JPGd blink
3 sparkle text
4 marching ants
5 marchine red ants
6 shimmer
81 51   unsigned char     reserved
82 52   unsigned char     reserved
83 53   unsigned short     reserved
85 55   short     reserved
87 57   dttm     reserved
91 5b fdispfldrmark byte     (only valid for listnum fields). when 1, the number for a listnum field is being tracked in xstdispfldrmark -- if that number is different from the current value, the number has changed.
92 5c ibstdispfldrmark short     index to author ids stored in hsttbfrmark. used when listnum field numbering has been changed when revision marking was enabled
94 5e dttmdispfldrmark dttm     the date for the listnum field number change
98 62 xstdispfldrmark xchar[16]     the string value of the listnum field when revision mark tracking began
130 82 shd shd     shading
132 84 brc brc     border

cbchp (count of bytes of chp) is 136 (decimal), 88(hex).

the standard chp is all zeros except:

hps 20 half-points
fcpic -1
istd 10 (the standard character style)
liddefault, lidfe 0x0400 (no proofing)
wcharscale 100
fusepgsusettings -1

character property exceptions (chpx)

the chpx is stored within character fkps and within the stsh in stds for paragraph style and character style entries.

b10 b16 field type size bitfield comments
0 0 cb byte     count of bytes of following data in chpx.
1 1 grpprl character array     a list of the sprms that encode the differences between chp for a run of text and the chp generated by the paragraph and character styles that tag the run.

date and time (internal date format) (dttm)

b10 b16 field type size bitfield comment
0 0 mint short :6 003f minutes (0-59)
    hr short :5 07c0 hours (0-23)
    dom short :5 f800 days of month (1-31)
2 2 mon short :4 000f months (1-12)
    yr short :9 1ff0 years (1900-2411)-1900
    wdy short :3 e000 weekday
sunday=0
monday=1
tuesday=2
wednesday=3
thursday=4
friday=5
saturday=6

cbdttm (count of bytes of dttm) is 4.

drop cap specifier(dcs)

b10 b16 field type size bitfield default value comment
0 0 fdct short :3 0007 0 drop cap type
0 no drop cap
1 normal drop cap
2 drop cap in margin
      short :5 00f8 0 count of lines to drop
1 1   short :8     reserved

cbdcs (count of bytes of dcs) is 2.

drawing object grid (dogrid)

the drawing object grid is far east only, and it sets up a grid in which far eastern characters are displayed (one character per grid square).

b10 b16 field type size bitfield comment
0 0 xagrid short     x-coordinate of the upper left-hand corner of the grid
2 2 yagrid short     y-coordinate of the upper left-hand corner of the grid
4 4 dxagrid short     width of each grid square
6 6 dyagrid short     height of each grid square
8 8 dygriddisplay short :7 007f the number of grid squares (in the y direction) between each gridline drawn on the screen. 0 means don't display any gridlines in the y direction.
    fturnitoff short :1 0080 suppress display of gridlines
    dxgriddisplay short :7 7f00 the number of grid squares (in the x direction) between each gridline drawn on the screen. 0 means don't display any gridlines in the y direction.
    ffollowmargins short :1 8000 if true, the grid will start at the left and top margins and ignore xagrid and yagrid.

cbdogrid (count of bytes of dogrid) is 10 bytes (decimal), a bytes (hex).

document typography info (doptypography)

these options are far east only, and are accessible through the typography tab of the tools/options dialog.

b10 b16 field type size bitfield comment
0 0 fkerningpunct short :1 00000001 true if we're kerning punctuation
    ijustification short :2 00000006 kinsoku method of justification:
0 = always expand
1 = compress punctuation
2 = compress punctuation and kana.
    ilevelofkinsoku short :2 00000018 level of kinsoku:
0 = level 1
1 = level 2
2 = custom
    f2on1 short :1 00000020 2-page-on-1 feature is turned on.
    reserved short :10 0000ffc0 reserved
2 2 cchfollowingpunct short     length of rgxchfpunct
4 4 cchleadingpunct short     length of rgxchlpunct
6 6 rgxchfpunct xchar[101]     array of characters that should never appear at the start of a line
208 d0 rgxchlpunct xchar[51]     array of characters that should never appear at the end of a line

cbdoptypography (count of bytes of doptypography) is 310 bytes (decimal), 136 (hex)..

field descriptor (fld)

b10 b16 field type size bitfield comment
0 0 ch char :5 1f type of field boundary the fld describes:
19 field begin mark
20 field separator mark
21 field end mark
      char :3 e0 reserved
            variant used when fld.ch == 19 (field begin mark)
1 1 flt char     field type (see flt table below)
            variant used when fld.ch == 21 (field end mark)
1 1 fdiffer char :1 01 ignored for saved file
    fzombieembed char :1 02 ==1 when result still believes this field is an embed or link field
    fresultdirty char :1 04 ==1 when user has edited or formatted the result. == 0 otherwise.
    fresultedited char :1 08 ==1 when user has inserted text into or deleted text from the result.
    flocked char :1 10 ==1 when field is locked from recalc
    fprivateresult char :1 20 ==1 whenever the result of the field is never to be shown.
    fnested char :1 40 ==1 when field is nested within another field
    fhassep char :1 80 ==1 when field has a field separator
flt value live/dead field type
1   unknown keyword
2 live possible bookmark (syntax matches bookmark name)
3 live bookmark reference
4 dead index entry
5 live footnote reference
6 live set command (for print merge)
7 live if command (for print merge)
8 live create index
9 dead table of contents entry
10 live style reference
11 dead document reference
12 live sequence mark
13 live create table-of-contents
14 live quote info variable
15 live quote title variable
16 live quote subject variable
17 live quote author variable
18 live quote keywords variable
19 live quote comments variable
20 live quote last revised by variable
21 live quote creation date variable
22 live quote revision date variable
23 live quote print date variable
24 live quote revision number variable
25 live quote edit time variable
26 live quote number of pages variable
27 live quote number of words variable
28 live quote number of characters variable
29 live quote file name variable
30 live quote document template name variable
31 live quote current date variable
32 live quote current time variable
33 live quote current page variable
34 live evaluate expression
35 live insert literal text
36 live include command (print merge)
37 live page reference
38 live ask command (print merge)
39 live fill-in command to display prompt (print merge)
40 live data command (print merge)
41 live next command (print merge)
42 live nextif command (print merge)
43 live skipif (print merge)
44 live inserts number of current print merge record
45 live dde reference
46 live dde automatic reference
47 live inserts glossary entry
48 live sends characters to printer without translation
49 live formula definition
50 live goto button
51 live macro button
52 live insert auto numbering field in outline format
53 live insert auto numbering field in legal format
54 live insert auto numbering field in arabic number format
55 live reads a tiff file
56 live link
57 live symbol
58 live embedded object
59 live merge fields
60 live user name
61 live user initial
62 live user address
63 live bar code
64 live document variable
65 live section
66 live section pages
67 live include picture
68 live include text
69 live file size
70 live form text box
71 live form check box
72 live note reference
73 live create table of authorities
74 dead mark table of authorities entry
75 live merge record sequence number
76 either macro
77 dead private
78 live insert database
79 live autotext
80 live compare two values
81 live plug-in module private
82 live subscriber
83 live form list box
84 live advance
85 live document property
86 live  
87 live ocx
88 live hyperlink
89 live autotextlist
90 live list element
91 live html control

since dead fields have no entry in the plcffld, the string in the field code must be used to determine the field type. all versions of word '97 use english field code strings, except french, german, and spanish versions of word. the strings for all languages for all possible dead fields are listed below.

flt value english string french string german string spanish string field type
4 xe ex xe e index entry
9 tc te inhalt tc table of contents entry
11 rd rd rd rd document reference
74 ta ta ta ta mark table of authorities entry
76         macro
77 private prive private privatespa private

file shape address (fspa)

b10 b16 field type size bitfield comment
0 0 spid long     shape identifier. used in conjunction with the office art data (found via fcdgginfo in the fib) to find the actual data for this shape.
4 4 xaleft xa     left of rectangle enclosing shape relative to the origin of the shape
8 8 yatop ya     top of rectangle enclosing shape relative to the origin of the shape
12 c xaright xa     right of rectangle enclosing shape relative to the origin of the shape
16 10 yabottom ya     bottom of the rectangle enclosing shape relative to the origin of the shape
20 14 fhdr uns short :1 0001 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc)
    bx uns short :2 0006 x position of shape relative to anchor cp
0 relative to page margin
1 relative to top of page
2 relative to text (column for horizontal text; paragraph for vertical text)
3 reserved for future use
    by uns short :2 0018 y position of shape relative to anchor cp
0 relative to page margin
1 relative to top of page
2 relative to text (paragraph for horizontal text; column for vertical text)
    wr uns short :4 01e0 text wrapping mode
0 like 2, but doesn't require absolute object
1 no text next to shape
2 wrap around absolute object
3 wrap as if no object present
4 wrap tightly around object
5 wrap tightly, but allow holes
6-15 reserved for future use
    wrk uns short :4 1e00 text wrapping mode type (valid only for wrapping modes 2 and 4
0 wrap both sides
1 wrap only on left
2 wrap only on right
3 wrap only on largest side
    frcasimple uns short :1 2000 when set, temporarily overrides bx, by, forcing the xaleft, xaright, yatop, and yabottom fields to all be page relative.
    fbelowtext uns short :1 4000 1 shape is below text
0 shape is above text
    fanchorlock uns short :1 8000 1 anchor is locked
0 anchor is not locked
22 16 ctxbx long     count of textboxes in shape (undo doc only)

cbfspa (count of bytes of fspa) is 26 (decimal), 1a (hex).

font family name (ffn)

b10 b16 field type size bitfield comment
0 0 cbffnm1 uns char     total length of ffn - 1.
1 1 prq uns char :2 03 pitch request
    ftruetype uns char :1 04 when 1, font is a truetype font
      uns char :1 08 reserved
    ff uns char :3 70 font family id
      uns char :1 80 reserved
2 2 wweight short     base weight of font
4 4 chs uns char     character set identifier
5 5 ixchszalt uns char     index into ffn.szffn to the name of the alternate font
6 6 panose panose      
16 10 fs fontsignature      
40 28 xszffn xchar[]     zero terminated string that records name of font. possibly followed by a second xsz which records the name of an alternate font to use if the first named font does not exist on this system. maximal size of xszffn is 65 characters.

file information block (fib)

b10 b16 field type size bitfield comment

definition of type: "fibfclcb"

decimal hex field type bitfield comments
0 0x0000 fc long    
4 0x0004 lcb ulong    

definition of type: "fib"

in word version 8, the fib is reorganized to make future extention easier, and to make it easier to make backward compatible file format changes. the fib now consists of four substructures: the header and three arrays. the fib header, is unchanged from past versions. the second part is an array of 16-bit "shorts", most of which were present in earlier versions in different locations. the third part is an array of 32-bit longs, many of which were scattered through the previous version fib. finally, there is an array of fc/lcb pairs, which were divided into several disjoint arrays in the previous fib. future versions of word will add entries to the three arrays, so readers of the fib must be careful to skip over any entries in each array that were not present in the version for which the reader was designed. writers of the fib must write exactly as many entries as was defined for the nfib value they put in the fib.

the fibfclcb structure, used in the last array in the fib:

decimal hex name type bitfield size bitfield mask comments
0 0x0000 fc long     file position where data begins.
4 0x0004 lcb ulong     size of data. ignore fc if lcb is zero.

the fib structure itself:

dec hex name type size bitfield mask comments
0 0x0000 fibh fibh     beginning of the fib header
0 0x0000 wident ushort     magic number
2 0x0002 nfib ushort     fib version written. this will be >= 101 for all word 6.0 for windows and after documents.
4 0x0004 nproduct ushort     product version written by
6 0x0006 lid ushort     language stamp -- localized version
in pre-winword 2.0 files this value was the nlocale. if value is < 999, then it is the nlocale, otherwise it is the lid.
8 0x0008 pnnext short      
10 0x000a fdot ushort :1 0x0001 set if this document is a template
    fglsy ushort :1 0x0002 set if this document is a glossary
    fcomplex ushort :1 0x0004 when 1, file is in complex, fast-saved format.
    fhaspic ushort :1 0x0008 set if file contains 1 or more pictures
    cquicksaves ushort :4 0x00f0 count of times file was quicksaved
    fencrypted ushort :1 0x0100 set if file is encrypted
    fwhichtblstm ushort :1 0x0200 when 0, this fib refers to the table stream named "0table", when 1, this fib refers to the table stream named "1table". normally, a file will have only one table stream, but under unusual circumstances a file may have table streams with both names. in that case, this flag must be used to decide which table stream is valid.
    freadonlyrecommended ushort :1 0x0400 set when user has recommended that file be read read-only
    fwritereservation ushort :1 0x0800 set when file owner has made the file write reserved
    fextchar ushort :1 0x1000 set when using extended character set in file
    floadoverride ushort :1 0x2000 review
    ffareast ushort :1 0x4000 review
    fcrypto ushort :1 0x8000 review
12 0x000c nfibback ushort     this file format it compatible with readers that understand nfib at or above this value.
14 0x000e lkey       file encrypted key, only valid if fencrypted.
18 0x0012 envr uchar     environment in which file was created
0 created by win word
1 created by mac word
19 0x0013 fmac uchar :1 0x01 when 1, this file was last saved in the mac environment
    femptyspecial uchar :1 0x02  
    floadoverridepage uchar :1 0x04  
    ffuturesavedundo uchar :1 0x08  
    fword97saved uchar :1 0x10  
    fspare0 uchar :3 0xfe  
20 0x0014 chs ushort     default extended character set id for text in document stream. (overridden by chp.chse)
0 by default characters in doc stream should be interpreted using the ansi character set used by windows
256 characters in doc stream should be interpreted using the macintosh character set.
22 0x0016 chstables ushort     default extended character set id for text in internal data structures
0 by default characters stored in internal data structures should be interpreted using the ansi character set used by windows
256 characters stored in internal data structures should be interpreted using the macintosh character set.
24 0x0018 fcmin long     file offset of first character of text. in non-complex files a cp can be transformed into an fc by the following transformation:
fc = cp + fib.fcmin.
28 0x001c fcmac long     file offset of last character of text in document text stream + 1
32 0x0020 csw ushort     count of fields in the array of "shorts"
34 0x0022 rgsw       beginning of the array of shorts
34 0x0022 wmagiccreated       unique number identifying the file's creator 0x6a62 is the creator id for word and is reserved. other creators should choose a different value.
36 0x0024 wmagicrevised       identifies the file's last modifier
38 0x0026 wmagiccreatedprivate       private data
40 0x0028 wmagicrevisedprivate       private data
42 0x002a pnfbpchpfirst_w6 short     not used
44 0x002c pnchpfirst_w6 short     not used
46 0x002e cpnbtechp_w6 short     not used
48 0x0030 pnfbppapfirst_w6 short     not used
50 0x0032 pnpapfirst_w6 short     not used
52 0x0034 cpnbtepap_w6 short     not used
54 0x0036 pnfbplvcfirst_w6 short     not used
56 0x0038 pnlvcfirst_w6 short     not used
58 0x003a cpnbtelvc_w6 short     not used
60 0x003c lidfe short     language id if document was written by far east version of word (i.e. fib.ffareast is on)
62 0x003e clw ushort     number of fields in the array of longs
64 0x0040 rglw       beginning of the array of longs
64 0x0040 cbmac long     file offset of last byte written to file + 1.
68 0x0044 lproductcreated       contains the build date of the creator. 10695 indicates the creator program was compiled on jan 6, 1995
72 0x0048 lproductrevised       contains the build date of the file's last modifier
76 0x004c ccptext long     length of main document text stream
80 0x0050 ccpftn long     length of footnote subdocument text stream
84 0x0054 ccphdd long     length of header subdocument text stream
88 0x0058 ccpmcr long     length of macro subdocument text stream, which should now always be 0.
92 0x005c ccpatn long     length of annotation subdocument text stream
96 0x0060 ccpedn long     length of endnote subdocument text stream
100 0x0064 ccptxbx long     length of textbox subdocument text stream
104 0x0068 ccphdrtxbx long     length of header textbox subdocument text stream.
108 0x006c pnfbpchpfirst long     when there was insufficient memory for word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn
112 0x0070 pnchpfirst long     the page number of the lowest numbered page in the document that records chpx fkp information
116 0x0074 cpnbtechp long     count of chpx fkps recorded in file. in non-complex files if the number of entries in the plcfbtechpx is less than this, the plcfbtechpx is incomplete.
120 0x0078 pnfbppapfirst long     when there was insufficient memory for word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn
124 0x007c pnpapfirst long     the page number of the lowest numbered page in the document that records papx fkp information
128 0x0080 cpnbtepap long     count of papx fkps recorded in file. in non-complex files if the number of entries in the plcfbtepapx is less than this, the plcfbtepapx is incomplete.
132 0x0084 pnfbplvcfirst long     when there was insufficient memory for word to expand the plcfbte at save time, the plcfbte is written to the file in a linked list of 512-byte pieces starting with this pn
136 0x0088 pnlvcfirst long     the page number of the lowest numbered page in the document that records lvc fkp information
140 0x008c cpnbtelvc long     count of lvc fkps recorded in file. in non-complex files if the number of entries in the plcfbtepapx is less than this, the plcfbtepapx is incomplete.
144 0x0090 fcislandfirst long      
148 0x0094 fcislandlim long      
152 0x0098 cfclcb ushort     number of fields in the array of fc/lcb pairs.
154 0x009a rgfclcb       beginning of array of fc/lcb pairs.
154 0x009a fcstshforig long     file offset of original allocation for stsh in table stream. during fast save word will attempt to reuse this allocation if stsh is small enough to fit.
158 0x009e lcbstshforig ulong     count of bytes of original stsh allocation
162 0x00a2 fcstshf long     offset of stsh in table stream.
166 0x00a6 lcbstshf ulong     count of bytes of current stsh allocation
170 0x00aa fcplcffndref long     offset in table stream of footnote reference plcf of frd structures. cps in plc are relative to main document text stream and give location of footnote references.
174 0x00ae lcbplcffndref ulong     count of bytes of footnote reference plc== 0 if no footnotes defined in document.
178 0x00b2 fcplcffndtxt long     offset in table stream of footnote text plc. cps in plc are relative to footnote subdocument text stream and give location of beginnings of footnote text for corresponding references recorded in plcffndref. no structure is stored in this plc. there will just be n+1 fc entries in this plc when there are n footnotes
182 0x00b6 lcbplcffndtxt ulong     count of bytes of footnote text plc. == 0 if no footnotes defined in document
186 0x00ba fcplcfandref long     offset in table stream of annotation reference atrd plc. the cps recorded in this plc give the offset of annotation references in the main document.
190 0x00be lcbplcfandref ulong     count of bytes of annotation reference plc.
194 0x00c2 fcplcfandtxt long     offset in table stream of annotation text plc. the cps recorded in this plc give the offset of the annotation text in the annotation sub document corresponding to the references stored in the plcfandref. there is a 1 to 1 correspondence between entries recorded in the plcfandtxt and the plcfandref. no structure is stored in this plc.
198 0x00c6 lcbplcfandtxt ulong     count of bytes of the annotation text plc
202 0x00ca fcplcfsed long     offset in table stream of section descriptor sed plc. cps in plc are relative to main document.
206 0x00ce lcbplcfsed ulong     count of bytes of section descriptor plc.
210 0x00d2 fcplcpad long     no longer used
214 0x00d6 lcbplcpad ulong     no longer used
218 0x00da fcplcfphe long     offset in table stream of phe plc of paragraph heights. cps in plc are relative to main document text stream. only written for files in complex format. should not be written by third party creators of word files.
222 0x00de lcbplcfphe ulong     count of bytes of paragraph height plc. ==0 when file is non-complex.
226 0x00e2 fcsttbfglsy long     offset in table stream of glossary string table. this table consists of pascal style strings (strings stored prefixed with a length byte) concatenated one after another.
230 0x00e6 lcbsttbfglsy ulong     count of bytes of glossary string table. == 0 for non-glossary documents.!=0 for glossary documents.
234 0x00ea fcplcfglsy long     offset in table stream of glossary plc. cps in plc are relative to main document and mark the beginnings of glossary entries and are in 1-1 correspondence with entries of sttbfglsy. no structure is stored in this plc. there will be n+1 fc entries in this plc when there are n glossary entries.
238 0x00ee lcbplcfglsy ulong     count of bytes of glossary plc.== 0 for non-glossary documents.!=0 for glossary documents.
242 0x00f2 fcplcfhdd long     byte offset in table stream of header hdd plc. cps are relative to header subdocument and mark the beginnings of individual headers in the header subdocument. no structure is stored in this plc. there will be n+1 fc entries in this plc when there are n headers stored for the document.
246 0x00f6 lcbplcfhdd ulong     count of bytes of header plc.
== 0 if document contains no headers
250 0x00fa fcplcfbtechpx long     offset in table stream of character property bin table.plc. fcs in plc are file offsets in the main stream. describes text of main document and all subdocuments.
254 0x00fe lcbplcfbtechpx ulong     count of bytes of character property bin table plc.
258 0x0102 fcplcfbtepapx long     offset in table stream of paragraph property bin table.plc. fcs in plc are file offsets in the main stream. describes text of main document and all subdocuments.
262 0x0106 lcbplcfbtepapx ulong     count of bytes of paragraph property bin table plc
266 0x010a fcplcfsea long     offset in table stream of plc reserved for private use. the sea is 6 bytes long.
270 0x010e lcbplcfsea ulong     count of bytes of private use plc.
274 0x0112 fcsttbfffn long     offset in table stream of font information sttbf. the sttbfffn is a sttbf where is string is actually an ffn structure. the nth entry in the sttbf describes the font that will be displayed when the chp.ftc for text is equal to n. see the ffn file structure definition.
278 0x0116 lcbsttbfffn ulong     count of bytes in sttbfffn.
282 0x011a fcplcffldmom long     offset in table stream to the fld plc of field positions in the main document. the cps point to the beginning cp of a field, the cp of field separator character inside a field and the ending cp of the field. a field may be nested within another field. 20 levels of field nesting are allowed.
286 0x011e lcbplcffldmom ulong     count of bytes in plcffldmom
290 0x0122 fcplcffldhdr long     offset in table stream to the fld plc of field positions in the header subdocument.
294 0x0126 lcbplcffldhdr ulong     count of bytes in plcffldhdr
298 0x012a fcplcffldftn long     offset in table stream to the fld plc of field positions in the footnote subdocument.
302 0x012e lcbplcffldftn ulong     count of bytes in plcffldftn
306 0x0132 fcplcffldatn long     offset in table stream to the fld plc of field positions in the annotation subdocument.
310 0x0136 lcbplcffldatn ulong     count of bytes in plcffldatn
314 0x013a fcplcffldmcr long     no longer used
318 0x013e lcbplcffldmcr ulong     no longer used
322 0x0142 fcsttbfbkmk long     offset in table stream of the sttbf that records bookmark names in the main document
326 0x0146 lcbsttbfbkmk ulong      
330 0x014a fcplcfbkf long     offset in table stream of the plcf that records the beginning cp offsets of bookmarks in the main document. see bkf structure definition
334 0x014e lcbplcfbkf ulong      
338 0x0152 fcplcfbkl long     offset in table stream of the plcf that records the ending cp offsets of bookmarks recorded in the main document. no structure is stored in this plcf.
342 0x0156 lcbplcfbkl ulong      
346 0x015a fccmds long     offset in table stream of the macro commands. these commands are private and undocumented.
350 0x015e lcbcmds ulong     undocument size of undocument structure not documented above
354 0x0162 fcplcmcr long     no longer used
358 0x0166 lcbplcmcr ulong      
362 0x016a fcsttbfmcr long     no longer used
366 0x016e lcbsttbfmcr ulong      
370 0x0172 fcprdrvr long     offset in table stream of the printer driver information (names of drivers, port, etc.)
374 0x0176 lcbprdrvr ulong     count of bytes of the printer driver information (names of drivers, port, etc.)
378 0x017a fcprenvport long     offset in table stream of the print environment in portrait mode.
382 0x017e lcbprenvport ulong     count of bytes of the print environment in portrait mode.
386 0x0182 fcprenvland long     offset in table stream of the print environment in landscape mode.
390 0x0186 lcbprenvland ulong     count of bytes of the print environment in landscape mode.
394 0x018a fcwss long     offset in table stream of window save state data structure. wss contains dimensions of document's main text window and the last selection made by word user.
398 0x018e lcbwss ulong     count of bytes of wss. ==0 if unable to store the window state. should not be written by third party creators of word files.
402 0x0192 fcdop long     offset in table stream of document property data structure.
406 0x0196 lcbdop ulong     count of bytes of document properties.
410 0x019a fcsttbfassoc long     offset in table stream of sttbf of associated strings. the strings in this table specify document summary info and the paths to special documents related to this document. see documentation of the sttbfassoc.
414 0x019e lcbsttbfassoc ulong      
418 0x01a2 fcclx long     offset in table stream of beginning of information for complex files. consists of an encoding of all of the prms quoted by the document followed by the plcpcd (piece table) for the document.
422 0x01a6 lcbclx ulong     count of bytes of complex file information == 0 if file is non-complex.
426 0x01aa fcplcfpgdftn long     not used
430 0x01ae lcbplcfpgdftn ulong      
434 0x01b2 fcautosavesource long     offset in table stream of the name of the original file. fcautosavesource and cbautosavesource should both be 0 if autosave is off.
438 0x01b6 lcbautosavesource ulong     count of bytes of the name of the original file.
442 0x01ba fcgrpxstatnowners long     offset in table stream of group of strings recording the names of the owners of annotations stored in the document
446 0x01be lcbgrpxstatnowners ulong     count of bytes of the group of strings
450 0x01c2 fcsttbfatnbkmk long     offset in table stream of the sttbf that records names of bookmarks for the annotation subdocument
454 0x01c6 lcbsttbfatnbkmk ulong     length in bytes of the sttbf that records names of bookmarks for the annotation subdocument
458 0x01ca fcplcdoamom long     no longer used
462 0x01ce lcbplcdoamom ulong      
466 0x01d2 fcplcdoahdr long     no longer used
470 0x01d6 lcbplcdoahdr ulong      
474 0x01da fcplcspamom long     offset in table stream of the fspa plc for main document. == 0 if document has no office art objects.
478 0x01de lcbplcspamom ulong     length in bytes of the fspa plc of the main document.
482 0x01e2 fcplcspahdr long     offset in table stream of the fspa plc for header document. == 0 if document has no office art objects.
486 0x01e6 lcbplcspahdr ulong     length in bytes of the fspa plc of the header document.
490 0x01ea fcplcfatnbkf long     offset in table stream of bkf (bookmark first) plc of the annotation subdocument
494 0x01ee lcbplcfatnbkf ulong     length in bytes of bkf (bookmark first) plc of the annotation subdocument
498 0x01f2 fcplcfatnbkl long     offset in table stream of bkl (bookmark last) plc of the annotation subdocument
502 0x01f6 lcbplcfatnbkl ulong     length in bytes of plc marking the cp limits of the annotation bookmarks. no structure is stored in this plc.
506 0x01fa fcpms long     offset in table stream of pms (print merge state) information block. this contains the current state of a print merge operation
510 0x01fe lcbpms ulong     length in bytes of pms. ==0 if no current print merge state. should not be written by third party creators of word files.
514 0x0202 fcformfldsttbs long     offset in table stream of form field sttbf which contains strings used in form field dropdown controls
518 0x0206 lcbformfldsttbs ulong     length in bytes of form field sttbf
522 0x020a fcplcfendref long     offset in table stream of endnote reference plcf of frd structures. cps in plcf are relative to main document text stream and give location of endnote references.
526 0x020e lcbplcfendref ulong      
530 0x0212 fcplcfendtxt long     offset in table stream of plcfendref which points to endnote text in the endnote document stream which corresponds with the plcfendref. no structure is stored in this plc.
534 0x0216 lcbplcfendtxt ulong      
538 0x021a fcplcffldedn long     offset in table stream to fld plcf of field positions in the endnote subdoc
542 0x021e lcbplcffldedn ulong      
546 0x0222 fcplcfpgdedn long     not used
550 0x0226 lcbplcfpgdedn ulong      
554 0x022a fcdgginfo long     offset in table stream of the office art object table data. the format of office art object table data is found in a separate document.
558 0x022e lcbdgginfo ulong     length in bytes of the office art object table data
562 0x0232 fcsttbfrmark long     offset in table stream to sttbf that records the author abbreviations for authors who have made revisions in the document.
566 0x0236 lcbsttbfrmark ulong      
570 0x023a fcsttbcaption long     offset in table stream to sttbf that records caption titles used in the document.
574 0x023e lcbsttbcaption ulong      
578 0x0242 fcsttbautocaption long     offset in table stream to the sttbf that records the object names and indices into the caption sttbf for objects which get auto captions.
582 0x0246 lcbsttbautocaption ulong      
586 0x024a fcplcfwkb long     offset in table stream to wkb plcf that describes the boundaries of contributing documents in a master document
590 0x024e lcbplcfwkb ulong      
594 0x0252 fcplcfspl long     offset in table stream of plcf (of spls structures) that records spell check state
598 0x0256 lcbplcfspl ulong      
602 0x025a fcplcftxbxtxt long     offset in table stream of plcf that records the beginning cp in the text box subdoc of the text of individual text box entries. no structure is stored in this plcf
606 0x025e lcbplcftxbxtxt ulong      
610 0x0262 fcplcffldtxbx long     offset in table stream of the fld plcf that records field boundaries recorded in the textbox subdoc.
614 0x0266 lcbplcffldtxbx ulong      
618 0x026a fcplcfhdrtxbxtxt long     offset in table stream of plcf that records the beginning cp in the header text box subdoc of the text of individual header text box entries. no structure is stored in this plc.
622 0x026e lcbplcfhdrtxbxtxt ulong      
626 0x0272 fcplcffldhdrtxbx long     offset in table stream of the fld plcf that records field boundaries recorded in the header textbox subdoc.
630 0x0276 lcbplcffldhdrtxbx ulong      
634 0x027a fcstwuser long     macro user storage
638 0x027e lcbstwuser ulong      
642 0x0282 fcsttbttmbd long     offset in table stream of embedded true type font data.
646 0x0286 cbsttbttmbd ulong      
650 0x028a fcunused long      
654 0x028e lcbunused ulong      
658 0x0292 rgpgdbkd fcpgd     beginning of array of fcpgd / fcbkd pairs
658 0x0292 fcpgdmother long     offset in table stream of the plf that records the page descriptors for the main text of the doc.
662 0x0296 lcbpgdmother ulong      
666 0x029a fcbkdmother long     offset in table stream of the plcf that records the break descriptors for the main text of the doc.
670 0x029e lcbbkdmother ulong      
674 0x02a2 fcpgdftn long     offset in table stream of the plf that records the page descriptors for the footnote text of the doc.
678 0x02a6 lcbpgdftn ulong      
682 0x02aa fcbkdftn long     offset in table stream of the plcf that records the break descriptors for the footnote text of the doc.
686 0x02ae lcbbkdftn ulong      
690 0x02b2 fcpgdedn long     offset in table stream of the plf that records the page descriptors for the endnote text of the doc.
694 0x02b6 lcbpgdedn ulong      
698 0x02ba fcbkdedn long     offset in table stream of the plcf that records the break descriptors for the endnote text of the doc.
702 0x02be lcbbkdedn ulong      
706 0x02c2 fcsttbfintlfld long     offset in table stream of the sttbf containing field keywords. this is only used in a small number of the international versions of word. this field is no longer written to the file for nfib >= 167.
710 0x02c6 lcbsttbfintlfld ulong     always 0 for nfib >= 167.
714 0x02ca fcrouteslip long     offset in table stream of a mailer routing slip.
718 0x02ce lcbrouteslip ulong      
722 0x02d2 fcsttbsavedby long     offset in table stream of sttbf recording the names of the users who have saved this document alternating with the save locations.
726 0x02d6 lcbsttbsavedby ulong      
730 0x02da fcsttbfnm long     offset in table stream of sttbf recording filenames of documents which are referenced by this document.
734 0x02de lcbsttbfnm ulong      
738 0x02e2 fcplcflst long     offset in the table stream of list format information.
742 0x02e6 lcbplcflst ulong      
746 0x02ea fcplflfo long     offset in the table stream of list format override information.
750 0x02ee lcbplflfo ulong      
754 0x02f2 fcplcftxbxbkd long     offset in the table stream of the textbox break table (a plcf of bkds) for the main document
758 0x02f6 lcbplcftxbxbkd ulong      
762 0x02fa fcplcftxbxhdrbkd long     offset in the table stream of the textbox break table (a plcf of bkds) for the header subdocument
766 0x02fe lcbplcftxbxhdrbkd ulong      
770 0x0302 fcdocundo long     offset in main stream of undocumented undo / versioning data
774 0x0306 lcbdocundo ulong      
778 0x030a fcrgbuse long     offset in main stream of undocumented undo / versioning data
782 0x030e lcbrgbuse ulong      
786 0x0312 fcusp long     offset in main stream of undocumented undo / versioning data
790 0x0316 lcbusp ulong      
794 0x031a fcuskf long     offset in table stream of undocumented undo / versioning data
798 0x031e lcbuskf ulong      
802 0x0322 fcplcupcrgbuse long     offset in table stream of undocumented undo / versioning data
806 0x0326 lcbplcupcrgbuse ulong      
810 0x032a fcplcupcusp long     offset in table stream of undocumented undo / versioning data
814 0x032e lcbplcupcusp ulong      
818 0x0332 fcsttbglsystyle long     offset in table stream of string table of style names for glossary entries
822 0x0336 lcbsttbglsystyle ulong      
826 0x033a fcplgosl long     offset in table stream of undocumented grammar options pl
830 0x033e lcbplgosl ulong      
834 0x0342 fcplcocx long     offset in table stream of undocumented ocx data
838 0x0346 lcbplcocx ulong      
842 0x034a fcplcfbtelvc long     offset in table stream of character property bin table.plc. fcs in plc are file offsets. describes text of main document and all subdocuments.
846 0x034e lcbplcfbtelvc ulong      
850 0x0352 ftmodified filetime      
850 0x0352 dwlowdatetime ulong      
854 0x0356 dwhighdatetime ulong      
858 0x035a fcplcflvc long     offset in table stream of lvc plcf
862 0x035e lcbplcflvc ulong     size of lvc plcf, ==0 for non-complex files
866 0x0362 fcplcasumy long     offset in table stream of autosummary asumy plcf.
870 0x0366 lcbplcasumy ulong      
874 0x036a fcplcfgram long     offset in table stream of plcf (of spls structures) which records grammar check state
878 0x036e lcbplcfgram ulong      
882 0x0372 fcsttblistnames long     offset in table stream of list names string table
886 0x0376 lcbsttblistnames ulong      
890 0x037a fcsttbfussr long     offset in table stream of undocumented undo / versioning data
894 0x037e lcbsttbfussr ulong      

cbfib (count of bytes of fib) is 898 (decimal), 382 (hex).

note

if a table does not exist in the file, its cb in the fib is zero and its fc is equal to that of the following table (the latter equality is irrelevant, as the cb should be used to determine existence of the table).

footnote reference descriptor (frd)

the frd is stored in both the plcffndref and the plcfendref

offset (base 10) field type size bitfield comments
0   nauto short   if > 0, the note is an automatically numbered note, otherwise it has a custom mark

formatted disk page for chpxs (chpx fkp)

offset (base 10) field type size bitfield comments
0   rgfc array of fcs   each fc is the limit fc of a run of exception text.
4*(fkp.crun+1) rgb array of bytes     an array of bytes where each byte is the word offset of a chpx. if the byte stored is 0, there is no difference between run's character properties and the style's character properties.
5*fkp.crun+4   unused space     as new runs/paragraphs are recorded in the fkp, unused space is reduced by 5 if chpx is already recorded and is reduced by 5+sizeof(chpx) if property is not already recorded.
511-sizeof(grpchpx) grpchpx array of bytes     grpchpx consists of all of the chpxs stored in fkp concatenated end to end. each chpx is prefixed with a count of bytes which records its length.
511   crun byte   count of runs for chpx fkp,

the chp is never stored in a word file. it is derived by expanding stored chpxs.

formatted disk page for papxs (papx fkp)

offset (base 10) field type size bitfield comments
0 rgfc fc[fkp.crun+1]     each fc is the limit fc of a paragraph (i.e. points to the next character past an end of paragraph mark). there will be fkp.crun+1 recorded in the fkp.
4*(fkp.crun+1) rgbx bx[fkp.crun]     an array of the bx data structure. the ith bx entry in the array describes the paragraph beginning at fkp.rgfc[i]. the bx is a 13 byte data structure. the first byte of each bx is the word offset of the papx recorded for the paragraph corresponding to this bx. .. if the byte stored is 0, this represents a 1 line paragraph 15 pixels high with normal style (stc == 0) whose column width is 7980 dxas. the last 12 bytes of the bx is a phe structure which stores the current paragraph height for the paragraph corresponding to the bx. if a plcfphe has an entry that maps to the fc for this paragraph, that entry's phe overrides the phe stored in the fkp.11*fkp.crun+4 unused space. as new runs/paragraphs are recorded in the fkp, unused space is reduced by 17 if chpx/papx is already recorded and is reduced by 17+sizeof(papx) if property is not already recorded.
511-sizeof(grppapx) grppapx array of bytes     grppapx consists of all of the papxs stored in fkp concatenated end to end. each papx begins with a count of words which records its length padded to a word boundary.
511 crun byte     count of paragraphs for papx fkp.

the pap is never stored in a word file. it is derived by expanding stored papxs.

list level (on file) (lvlf)

b10 b16 field type size bitfield comments
0 0x00 istartat long 4   start at value for this list level
4 0x04 nfc byte 1   number format code (see anld.nfc for a list of options)
5 0x05 jc uns char :2 0x03 alignment (left, right, or centered) of the paragraph number.
    flegal uns char :1 0x04 true (==1) if the level turns all inherited numbers to arabic, false if it preserves their number format code (nfc)
    fnorestart uns char :1 0x08 true if the level's number sequence is not restarted by higher (more significant) levels in the list
    fprev uns char :1 0x10 word 6 compatibility option: equivalent to anld.fprev (see anld)
    fprevspace uns char :1 0x20 word 6 compatibility option: equivalent to anld.fprevspace (see anld)
    fword6 uns char :1 0x40 true if this level was from a converted word 6 document. if it is true, all of the word 6 compability options become valid; otherwise they are ignored.
6 0x06 rgbxchnums[9] array 9   contains the character offsets into the lvl's xst of the inherited numbers of previous levels. this array should be zero terminated unless it is full (all 9 levels full). the xst contains place holders for any paragraph numbers contained in the text of the number, and the place holder contains the ilvl of the inherited number, so lvl.xst[lvl.rgbxchnums[0]] == the level of the first inherited number in this level.
15 0x0f ixchfollow uns char 1   the type of character following the number text for the paragraph: 0 == tab, 1 == space, 2 == nothing.
16 0x10 dxaspace long 4   word 6 compatibility option: equivalent to anld.dxaspace (see anld)
20 0x14 dxaindent long 4   word 6 compatibility optino: equivalent to anld.dxaindent (see anld)
24 0x18 cbgrpprlchpx byte 1   length, in bytes, of the lvl's grpprlchpx
25 0x19 cbgrpprlpapx byte 1   length, in bytes, of the lvl's grpprlpapx
26 0x1a reserved short 2   reserved

line spacing descriptor (lspd)

b10 b16 field type size bitfield comments
0 0 dyaline short     see description of sprmpdyaline for description of the meaning of dyaline
2 2 fmultlinespace short     see description of sprmpdyaline in the sprm definitions section for description of the meaning of dyaline and fmultlinespace fields.

cblspd (count of bytes of lspd) is 4.

list data (on file) (lstf)

b10 b16 field type size bitfield comments
0 0x00 lsid long 4   unique list id
4 0x04 tplc long 4   unique template code
8 0x08 rgistd[9] array 18   array of shorts containing the istd's linked to each level of the list, or istdnil (4095) if no style is linked.
26 0x1a fsimplelist uns char :1 0x01 true if this is a simple (one-level) list; false if this is a multilevel (nine-level) list.
    frestarthdn uns char :1 0x02 word 6 compatibility option: true if the list should start numbering over at the beginning of each section
    reserved uns char :6 0xfc reserved
27 0x1b reserved uns char byte   reserved

list format override (lfo)

b10 b16 field type size bitfield comments
0 0x0 lsid long 4   list id of corresponding lstf (see lstf)
4 0x4 reserved long 4   reserved
8 0x8 reserved long 4   reserved
12 0xc clfolvl uns char 1   count of levels whose format is overridden (see lfolvl)
13 0xd reserved array 3   reserved

list format override for a single level (lfolvl)

b10 b16 field type size bitfield comments
0 0 istartat long 4   start-at value if fformatting == false and fstartat == true. (if fformatting == true, the start-at is stored in the lvl)
4 4 ilvl uns char :4 0x0f the level to be overridden
    fstartat uns char :1 0x10 true if the start-at value is overridden
    fformatting uns char :1 0x20 true if the formatting is overriden (in which case the lfolvl should contain a pointer to a lvl)
    reserved uns char :2 0xc0 reserved
5 5 reserved array 3   reserved

outline list data (olst)

b10 b16 field type size bitfield comments
0 0 rganlv[9] anlv     an array of 9 anlv structures describing how heading numbers should be displayed for each of word's 9 outline heading levels
144 90 frestarthdr uns char     when ==1, restart heading on section break
145 91 fspareolst2 uns char     reserved
146 92 fspareolst3 uns char     reserved
147 93 fspareolst4 uns char     reserved
148 94 rgxch[32] array of 32 xchars     text before/after number

cbolst (count of bytes of olst) is 212(decimal), d4(hex).

number revision mark data (numrm)

the numrm structure is used to track revision marking data for paragraph numbers, and is stored in the pap for each numbered paragraph. when revision marking tracking is turned on, we fill out the numrm for each number with the data required to recreate the number's text. then at display time, that string is compared with the current paragraph number string, and displayed as changed (old deleted, current inserted) if the strings differ. the string construction algorithm is the same as for an lvl structure.

b10 b16 field type size bitfield comment
0 0 fnumrm uns char 1   true if this paragraph was numbered when revision mark tracking was turned on
1 1 spare uns char 1    
2 2 ibstnumrm short 2   index to author ids stored in hsttbfrmark for the paragraph number change
4 4 dttmnumrm dttm 4   date of the paragraph number change
8 8 rgbxchnums[9] uns char[9] 9   index into numrm.xst of the locations of paragraph number place holders for each level (see lvl.rgxchnums)
17 11 rgnfc[9] uns char[9] 9   number format code for the paragraph number place holders for each level (see lvl.nfc)
26 1a spare short 2    
28 1c pnbr int [9] 36   numerical value for each level place holder in numrm.xst.
64 40 xst xchar[32] 64   the text string for the paragraph number, containing level place holders

cbnumrm (count of bytes of numrm) is 128 (decimal), 80 (hex).

page descriptor (pgd)

b10 b16 field type size bitfield comments
0 0 * short :4 000f  
    fghost short :2 0030 redefine femptypage and fallftn. true when blank page or footnote only page
    * short :10 ffc0  
0 0 fcontinue short :1 0001 1 only when footnote is continued from previous page
    funk short :1 0002 1 when page is dirty (i.e. pagination cannot be trusted)
    fright short :1 0004 1 when right hand side page
    fpgnrestart short :1 0008 1 when page number must be reset to 1.
    femptypage short :1 0010 1 when section break forced page to be empty.
    fallftn short :1 0020 1 when page contains nothing but footnotes
      short :1 0040 unused
    ftablebreaks short :1 0080 table breaks have been calculated for this page.
    fmarked short :1 0100 used temporarily while word is running.
    fcolumnbreaks short :1 0200 column breaks have been calculated for this page.
    ftableheader short :1 0400 page had a table header at the end
    fnewpage short :1 0800 page has never been valid since created, must recalculate the bounds of this page. if this is the last page, this pgd may really represent many pages.
    bkc short :4 f000 section break code
2 2 lnn uns short     line number of first line, -1 if no line numbering
4 4 pgn uns short     page number as printed
6 6 dym long      

cbpgd (count of bytes of pgd) is 10.

paragraph height (phe)

the phe is a substructure of the pap and the papx fkp and is also stored in the plcfphe.

b10 b16 field type size bitfield comments
0 0 fspare short :1 0001 reserved
    funk short :1 0002 phe entry is invalid when == 1
    fdifflines short :1 0004 when 1, total height of paragraph is known but lines in paragraph have different heights.
    * short :5 00f8 reserved
    clmac short :8 ff00 when fdifflines is 0 is number of lines in paragraph
2 2   short     reserved
4 4 dxacol long     width of lines in paragraph
8 8 dymline long     when fdifflines is 0, is height of every line in paragraph in pixels
8 8 dymheight long     when fdifflines is 1, is the total height in pixels of the paragraph

if the phe is stored in a pap whose fttp field is set (non-zero), the following structure is used:

b10 b16 field type size bitfield comments
0 0 fspare short :1 0001 reserved
    funk short :1 0002 phe entry is invalid when == 1
    dcpttpnext short :30   if not == 0, used as a hint when finding the next row
4 4 dxacol long      
8 8 dymtableheight long     height of table row

cbphe (the count of bytes of phe) is 12.

if there is no paragraph height information stored for a paragraph, all of the fields in the phe are set to 0. if a paragraph contains more than 127 lines, the clmac, dylline variant cannot be used, so fdifflines must be set to 1 and the total size of the paragraph stored in dylheight. if a paragraph height is greater than 32767 twips, the height cannot be represented by a phe so all fields of the phe must be set to 0.

if a new word file is created, the phe of every papx fkp entry created to describe the paragraphs of the file should be set to 0. if a word file is altered in place (a character of the file changed to a new character or a property changed), the paragraph containing the change must have its papx.phe field set to 0. if this paragraph is in a table row, the phe in the papx at the end of the row (indicated by fintable) must also be set to 0.

paragraph properties (pap)

b10 b16 field type size bitfield comments
0 0 istd uns short     index to style descriptor . this is an index to an std in the stsh structure
2 2 jc uns char     justification code
0 left justify
1 center
2 right justify
3 left and right justify
3 3 fkeep uns char     keep entire paragraph on one page if possible
4 4 fkeepfollow uns char     keep paragraph on same page with next paragraph if possible
5 5 fpagebreakbefore uns char     start this paragraph on new page
6 6 fbrlnabove short :1 0001  
    fbrlnbelow short :1 0002  
    funused short :2 0006 reserved
    pcvert short :2 0030 vertical position code. specifies coordinate frame to use when paragraphs are absolutely positioned.
0 vertical position coordinates are relative to margin
1 coordinates are relative to page
2 coordinates are relative to text. this means: relative to where the next non-apo text would have been placed if this apo did not exist.
    pchorz short :2 00c0 horizontal position code. specifies coordinate frame to use when paragraphs are absolutely positioned.
0 horiz. position coordinates are relative to column.
1 coordinates are relative to margin
2 coordinates are relative to page

/* the brcp and brcl fields have been superseded by the newly defined brcleft, brctop, etc. fields. they remain in the pap for compatibility with macword 3.0 */

b10 b16 field type size bitfield comments
7 7 brcp uns char     rectangle border codes
0 none
1 border above
2 border below
15 box around
16 bar to left of paragraph
8 8 brcl uns char     border line style
0 single
1 thick
2 double
3 shadow
9 9         reserved
10 a ilvl uns char     when non-zero, list level for this paragraph
11 b fnolnn uns char     no line numbering for this paragraph. (makes this an exception to the section property of line numbering)
12 c ilfo short     when non-zero, (1-based) index into the pllfo identifying the list to which the paragraph belongs
14 e nlvlanm uns char     no longer used
15 f         reserved
16 10 fsidebyside uns char     when 1, paragraph is a side by side paragraph
17 11         reserved
18 12 fnoautohyph uns char     when 0, text in paragraph may be auto hyphenated.
19 13 fwidowcontrol uns char     when 1, word will prevent widowed lines in this paragraph from being placed at the beginning of a page
20 14 dxaright long     indent from right margin (signed).
24 18 dxaleft long     indent from left margin (signed)
28 1c dxaleft1 long     first line indent; signed number relative to dxaleft
32 20 lspd lspd     line spacing descriptor
36 24 dyabefore uns long     vertical spacing before paragraph (unsigned)
40 28 dyaafter uns long     vertical spacing after paragraph (unsigned)
44 2c phe phe     height of current paragraph.
56 38 fcrlf uns char      
57 39 fusepgsusettings uns char      
58 3a fadjustright uns char      
59 3b         reserved
60 3c fkinsoku uns char     when 1, apply kinsoku rules when performing line wrapping
61 3d fwordwrap uns char     when 1, perform word wrap
62 3e foverflowpunct uns char     when 1, apply overflow punctuation rules when performing line wrapping
63 3f ftoplinepunct uns char     when 1, perform top line punctuation processing
64 40 fautospacede uns char     when 1, auto space fe and alphabetic characters
65 41 fatuospacedn uns char     when 1, auto space fe and numeric characters
66 42 walignfont uns short     font alignment
0 hanging
1 centered
2 roman
3 variable
4 auto
68 44 fvertical short :1 0001  
    fbackward short :1 0002  
    frotatefont short :1 0004  
      short :13 fff8 reserved
70 46         reserved
72 48 fintable char     when 1, paragraph is contained in a table row
73 49 fttp char     when 1, paragraph consists only of the row mark special character and marks the end of a table row.
74 4a wr byte     wrap code for absolute objects
75 4b flocked byte     when 1, paragraph may not be edited
76 4c ptap *tap*     used internally by word
80 50 dxaabs long     when positive, is the horizontal distance from the reference frame specified by pap.pchorz. 0 means paragraph is positioned at the left with respect to the reference frame specified by pchorz. certain negative values have special meaning:
-4 paragraph centered horizontally within reference frame
-8 paragraph adjusted right within reference frame
-12 paragraph placed immediately inside of reference frame
-16 paragraph placed immediately outside of reference frame
84 54 dyaabs long     when positive, is the vertical distance from the reference frame specified by pap.pcvert. 0 means paragraph's y-position is unconstrained. certain negative values have special meaning:
-4 paragraph is placed at top of reference frame
-8 paragraph is centered vertically within reference frame
-12 paragraph is placed at bottom of reference frame.
88 58 dxawidth long     when not == 0, paragraph is constrained to be dxawidth wide, independent of current margin or column settings.
92 5c brctop brc     specification for border above paragraph
96 60 brcleft brc     specification for border to the left of paragraph
100 64 brcbottom brc     specification for border below paragraph
104 68 brcright brc     specification for border to the right of paragraph
108 6c brcbetween brc     specification of border to place between conforming paragraphs. two paragraphs conform when both have borders, their brcleft and brcright matches, their widths are the same, they both belong to tables or both do not, and have the same absolute positioning props.
112 70 brcbar brc     specification of border to place on outside of text when facing pages are to be displayed.
116 74 dxafromtext long     horizontal distance to be maintained between an absolutely positioned paragraph and any non-absolute positioned text
120 78 dyafromtext long     vertical distance to be maintained between an absolutely positioned paragraph and any non-absolute positioned text
124 7c dyaheight short :15 7fff height of abs obj; 0 == auto
    fminheight short :1 8000 0 = exact, 1 = at least
126 7e shd shd     shading
128 80 dcs dcs     drop cap specifier (see dcs definition)
130 82 lvl char      
131 83 fnumrmins char      
132 84 anld anld     autonumber list descriptor (see anld definition)
216 d8 fproprmark short     when 1, properties have been changed with revision marking on
218 da ibstproprmark short     index to author ids stored in hsttbfrmark. used when properties have been changed when revision marking was enabled
220 dc dttmproprmark dttm     date/time at which properties of this were changed for this run of text by the author. (only recorded when revision marking is on.)
224 e0 numrm numrm     paragraph numbering revision mark data (see numrm)
352 160 itbdmac short     number of tabs stops defined for paragraph. must be >= 0 and <= 64.
354 162 rgdxatab short[itbdmax]     array of positions of itbdmac tab stops. itbdmax == 64
482 1e2 rgtbd char[itbdmax]     array of itbdmac tab descriptors

cbpap (count of bytes of pap) is 610 (decimal), 262(hex)

the standard pap is all zeros except:

fwidowcontrol 1
fmultlinespace 1
dyaline 240 twips
lvl 9

paragraph property exceptions (papx)

the papx is stored within fkps and within the stsh.

b10 b16 field type size bitfield comments
0 0 cb byte     count of bytes of following data in papx. the first byte of a papx is a count of bytes when a papx is stored in a stsh. count of bytes is used because only paragraph sprms are stored in a stsh papx.
0 0 cw byte     count of words for this byte and the following data in papx. the first byte of a papx is a count of words when papx is stored in an fkp. if this value is 0, it is a 'pad' byte and the count is stored in the following byte, count of words is used because papx in an fkp can contain paragraph and table sprms.
1 1 (cw) byte     if previous byte is 0, this is the count of words of following data in papx (not including this and previous 'pad' byte)
1/2 1/2 istd uns short     index to style descriptor of the style from which the paragraph inherits its paragraph and character properties
3/4 3/4 grpprl character array     a list of the sprms that encode the differences between pap for a paragraph and the pap for the style used. when a paragraph bound is also the end of a table row, the papx also contains a list of table sprms which express the difference of table row's tap from an empty tap that has been cleared to zeros. the table sprms are recorded in the list after all of the paragraph sprms. see sprms definitions for list of sprms that are used in papxs.

for calculating papx.cw when storing in a fkp: for even-sized grpprl's, the grpprl plus the istd and cw bytes will be an even number of bytes, so we store the count of words for all three elements in papx.cw. for odd-sized grpprl's, the three elements will be an odd number of bytes, which can't be represented with a count of words; so, we store a 'pad' byte of 0 at the beginning (in the normal cw location), followed by a count that is the size of the grpprl and istd byte only (since that's an even number of bytes). in either case, papx.cw is immediately followed by the istd and grpprl.

picture descriptor (on file) (picf)

b10 b16 field type size bitfield comments
0 0 lcb long     number of bytes in the pic structure plus size of following picture data which may be a window's metafile, a bitmap, or the filename of a tiff file. in the case of a macintosh pict picture, this includes the size of the pic, the standard "x" metafile, and the macintosh pict data. see appendix b for more information.
4 4 cbheader unsigned     number of bytes in the pic (to allow for future expansion).
6 6 mfp.mm short      
8 8 mfp.xext short      
10 a mfp.yext short      
12 c mfp.hmf short      

if a windows metafile is stored immediately following the pic structure, the mfp is a window's metafilepict structure. when the data immediately following the pic is a tiff filename, mfp.mm == 98 if a bitmap is stored after the pic, mfp.mm == 99

when the pic describes a bitmap, mfp.xext is the width of the bitmap in pixels and mfp.yext is the height of the bitmap in pixels..

b10 b16 field type size bitfield comments
14 e bm bitmap
(14 bytes)
    window's bitmap structure when pic describes a bitmap.
14 e rcwinmf rc
(rectangle
- 8 bytes)
    rect for window origin and extents when metafile is stored -- ignored if 0
28 1c dxagoal short     horizontal measurement in twips of the rectangle the picture should be imaged within.
30 1e dyagoal short     vertical measurement in twips of the rectangle the picture should be imaged within.

when scaling bitmaps, dxagoal and dyagoal may be ignored if the operation would cause the bitmap to shrink or grow by a non -power-of-two factor

b10 b16 field type size bitfield comments
32 20 mx uns short     horizontal scaling factor supplied by user expressed in .001% units.
34 22 my uns short     vertical scaling factor supplied by user expressed in .001% units.

for all of the crop values, a positive measurement means the specified border has been moved inward from its original setting and a negative measurement means the border has been moved outward from its original setting.

b10 b16 field type size bitfield comments
36 24 dxacropleft short     the amount the picture has been cropped on the left in twips.
38 26 dyacroptop short     the amount the picture has been cropped on the top in twips.
40 28 dxacropright short     the amount the picture has been cropped on the right in twips.
42 2a dyacropbottom short     the amount the picture has been cropped on the bottom in twips.
44 2c brcl short :4 000f obsolete, superseded by brctop, etc. in winword 1.x, it was the type of border to place around picture
0 single
1 thick
2 double
3 shadow
    fframeempty short :1 0010 picture consists of a single frame
    fbitmap short :1 0020 ==1, when picture is just a bitmap
    fdrawhatch short :1 0040 ==1, when picture is an active ole object
    ferror short :1 0080 ==1, when picture is just an error message
    bpp short :8   bits per pixel
0 unknown
1 monochrome
4 vga
46 2e brctop brc     specification for border above picture
50 32 brcleft brc     specification for border to the left of
            picture
54 36 brcbottom brc     specification for border below picture
58 3a brcright brc     specification for border to the right of
            picture
62 3e dxaorigin short     horizontal offset of hand annotation origin
64 40 dyaorigin short     vertical offset of hand annotation origin
66 42 cprops short     unused
68 44 rgb       variable array of bytes containing window's metafile, bitmap or tiff file filename.

piece descriptor (pcd)

b10 b16 field type size bitfield comment
0 0 fnoparalast short :1 0001 when 1, means that piece contains no end of paragraph marks.
    fpaphnil short :1 0002 used internally by word
    fcopied short :1 0004 used internally by word
    * short :5    
1 1 fn short :8 ff00 used internally by word
2 2 fc fc     file offset of beginning of piece. the size of the ith piece can be determined by subtracting rgcp[i] of the containing plcfpcd from its rgcp[i+1].
6 6 prm prm     contains either a single sprm or else an index number of the grpprl which contains the sprms that modify the properties of the piece.

cbpcd (count of bytes of pcd) is 8.

plex of cps stored in file (plcf)

offset (in decimal) field type comment
0 rgfc fc[] given that the size of plcf is cb and the size of the structure stored in plc is cbstruct, then the number of structure instances stored in plcf, imac is given by (cb -4)/(4 + cbstruct) the number of fcs stored in the plcf will be imac + 1.
4*(imac+1) rgstruct struct[] array of some arbitrary structure.

cbplc (count of bytes of a plc) is imac(4 + cbstruct) + 4.

property modifier(variant 1) (prm)

the prm has two variants. in the first variant, the prm records a single sprm with a bit- or byte-sized operand.

b10 b16 field type size bitfield comment
0 0 fcomplex short :1 0001 set to 0 for variant 1
    isprm short :7 00fe index to entry into rgsprmprm
    val short :8 ff00 sprm's operand

cbprm (count of bytes of prm) is 2.

since isprm is 7 bits, rgsprmprm can hold 0x80 entries.

{sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmpinclvl, sprmpjc, sprmpfsidebyside, sprmpfkeep, sprmpfkeepfollow, sprmpfpagebreakbefore, sprmpbrcl, sprmpbrcp, sprmpilvl, sprmnoop, sprmpfnolinenumb, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmpfintable, sprmpfttp, sprmnoop, sprmnoop, sprmnoop, sprmppc, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmpwr, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmpfnoautohyph, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmpflocked, sprmpfwidowcontrol, sprmnoop, sprmpfkinsoku, sprmpfwordwrap, sprmpfoverflowpunct, sprmpftoplinepunct, sprmpfautospacede, sprmpfautospacedn, sprmnoop, sprmnoop, sprmpisnapbaseline, sprmnoop, sprmnoop, sprmnoop, sprmcfstrikerm, sprmcfrmark, sprmcffldvanish, sprmnoop, sprmnoop, sprmnoop, sprmcfdata, sprmnoop, sprmnoop, sprmnoop, sprmcfole2, sprmnoop, sprmchighlight, sprmcfemboss, sprmcsfxtext, sprmnoop, sprmnoop, sprmnoop, sprmcplain, sprmnoop, sprmcfbold, sprmcfitalic, sprmcfstrike, sprmcfoutline, sprmcfshadow, sprmcfsmallcaps, sprmcfcaps, sprmcfvanish, sprmnoop, sprmckul, sprmnoop, sprmnoop, sprmnoop, sprmcico, sprmnoop, sprmchpsinc, sprmnoop, sprmchpsposadj, sprmnoop, sprmciss, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmcfdstrike, sprmcfimprint, sprmcfspec, sprmcfobj, sprmpicbrcl, sprmpoutlvl, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmnoop, sprmppnbrrmarknot}

property modifier(variant 2) (prm)

in the second variant, prm.fcomplex is 1, and the rest of the structure records an index to a grpprl stored in the clx (described in complex file format topic).

b10 b16 field type size bitfield comment
0 0 fcomplex short :1 0001 set to 1 for variant 2
    igrpprl short :15 fffe index to a grpprl stored in clx portion of file.

cbprm (count of bytes of prm) is 2.

routing slip (rs)

b10 b16 field type size bitfield comments
0 0 frouted short     when 1, document has been routed to at least one recipient.
2 2 freturnorig short     when 1, document should be routed to the originator after it has been routed to all recipients.
4 4 ftrackstatus short     when 1, a status message is sent to the originator each time the document is forwarded to a recipient on the routing list.
6 6 fdirty short     unused( should be 0)
8 8 nprotect short     document protection while routing
0 recipients can make changes to the document and all changes are untracked.
1 recipients can add annotations and make changes to the document. any changes are tracked by revision marks, and revision marking cannot be turned off.
2 recipients can only add annotations to the document.
3 recipients can enter information only in form fields.
10 a istage short     index of the current recipient.
12 c deloption short     when 0, document is routed to each recipient in turn. when 1, document is routed to all recipients simultaneously.
14 e crecip short     count of recipients.

cbrs (count of bytes of rs) is 16 (decimal), 10 (hex).

routing recipient (rr)

b10 b16 field type size bitfield comments
0 0 cb short     count of bytes of private system data
2 2 cbszrecip short     count of bytes in recipient string (including null terminator).

cbrr (count of bytes of rr) is 4.

section descriptor (sed)

b10 b16 field type size bitfield comments
0 0 fn short     used internally by word
2 2 fcsepx fc     file offset in main stream to beginning of sepx stored for section. if sed.fcsepx == 0xffffffff, the section properties for the section are equal to the standard sep (see sep definition).
6 6 fnmpr short     used internally by word
8 8 fcmpr fc     points to offset in fc space of main stream where the macintosh print record for a document created on a mac will be stored

cbsed (count of bytes of sed) is 12 (decimal), c (hex).

section properties (sep)

b10 b16 field type size bitfield comments
0 0 bkc uns char     break code:
0 no break
1 new column
2 new page
3 even page
4 odd page
1 1 ftitlepage uns char     set to 1 when a title page is to be displayed
2 2 fautopgn char     only for mac compatibility, used only during open, when 1, sep.dxapgn and sep.dyapgn are valid page number locations
3 3 nfcpgn uns char     page number format code:
0 arabic
1 roman (upper case)
2 roman (lower case)
3 letter (upper case)
4 letter (lower case)
4 4 funlocked uns char     set to 1, when a section in a locked document is unlocked
5 5 cnspgn uns char     chapter number separator for page numbers
6 6 fpgnrestart uns char     set to 1 when page numbering should be restarted at the beginning of this section
7 7 fendnote uns char     when 1, footnotes placed at end of section. when 0, footnotes are placed at bottom of page.
8 8 lnc char     line numbering code:
0 per page
1 restart
2 continue
9 9 grpfihdt char     specification of which headers and footers are included in this section. see explanation in headers and footers topic. no longer used.
10 a nlnnmod uns short     if 0, no line numbering, otherwise this is the line number modulus (e.g. if nlnnmod is 5, line numbers appear on line 5, 10, etc.)
12 c dxalnn long     distance of
16 10 dxapgn short     when fautopgn ==1, gives the x position of auto page number on page in twips (for mac compatibility only)
18 12 dyapgn short     when fautopgn ==1, gives the y position of auto page number on page in twips (for mac compatibility only)
20 14 flbetween char     when ==1, draw vertical lines between columns
21 15 vjc char     vertical justification code
0 top justified
1 centered
2 fully justified vertically
  3 bottom justified        
22 16 dmbinfirst uns short     bin number supplied from windows printer driver indicating which bin the first page of section will be printed.
24 18 dmbinother uns short     bin number supplied from windows printer driver indicating which bin the pages other than the first page of section will be printed.
26 1a dmpaperreq uns short     dmpaper code for form selected by user
28 1c brctop brc     top page border
32 20 brcleft brc     left page border
36 24 brcbottom brc     bottom page border
40 28 brcright brc     right page border
44 2c fproprmark short     when 1, properties have been changed with revision marking on
46 2e ibstproprmark short     index to author ids stored in hsttbfrmark. used when properties have been changed when revision marking was enabled
48 30 dttmproprmark dttm     date/time at which properties of this were changed for this run of text by the author. (only recorded when revision marking is on.)
52 34 dxtcharspace long      
56 38 dyalinepitch long      
60 3c clm uns short      
  62 3e short     reserved
64 40 dmorientpage uns char     orientation of pages in that section. set to 0 when portrait, 1 when landscape
65 41 iheadingpgn uns char     heading number level for page number
66 42 pgnstart uns short     user specified starting page number.
68 44 lnnmin short     beginning line number for section
70 46 wtextflow uns short      
72 48   short     reserved
74 4a pgbprop short     page border properties
74 4a pgbapplyto short :3 0007 page border applies to:
0 all pages in this section
1 first page in this section
2 all pages in this section but first
3 whole document (all sections)
    pgbpagedepth short :2 0018 page border depth:
0 in front
1 in back
    pgboffsetfrom short :3 00e0 page border offset from:
0 offset from text
1 offset from edge of page
      short :8 ff00 reserved
76 4c xapage uns long     default value is 12240 twipswidth of page
80 50 yapage uns long     default value is 15840 twipsheight of page
84 54 xapagenup uns long     used internally by word
88 58 yapagenup uns long     used internally by word
92 5c dxaleft uns long     default value is 1800 twipsleft margin
96 60 dxaright uns long     default value is 1800 twipsright margin
100 64 dyatop long     default value is 1440 twipstop margin
104 68 dyabottom long     default value is 1440 twipsbottom margin
108 6c dzagutter uns long     default value is 0 twips gutter width
112 70 dyahdrtop uns long     y position of top header measured from top edge of page.
116 74 dyahdrbottom uns long     y position of bottom header measured from top edge of page.
120 78 ccolm1 short     number of columns in section - 1.
122 7a fevenlyspaced char     when == 1, columns are evenly spaced. default value is 1.
123 7b   char     reserved
124 7c dxacolumns long     distance that will be maintained between columns
128 80 rgdxacolumnwidthspacing array of xa       array of 89 longs that determine bounds of irregular width columns
484 1e4 dxacolumnwidth long     used internally by word
488 1e8 dmorientfirst uns char      
489 1e9 flayout uns char     used internally by word
490 1ea   short     reserved
492 1ec olstanm olst     multilevel autonumbering list data (see olst definition)

the standard sep is all zeros except as follows:

bkc 2 (new page)
dyapgn 720 twips (equivalent to .5 in)
dxapgn 720 twips
fendnote 1 (true)
fevenlyspaced 1 (true)
xapage 12240 twips
yapage 15840 twips
xapagenup 12240 twips
yapagenup 15840 twips
dyahdrtop 720 twips
dyahdrbottom 720 twips
dmorientpage 1 (portrait orientation)
dxacolumns 720 twips
dyatop 1440 twips
dxaleft 1800 twips
dyabottom 1440 twips
dxaright 1800 twips
pgnstart 1

cbsep (count of bytes of sep) is 704(decimal), 2c0(hex).

section property exceptions (sepx)

b10 b16 field type size bitfield comment
0 0 cb uns short     count of bytes in remainder of sepx.
  2 2 grpprl char[]   list of sprms that encodes the differences between the properties of a section and word's default section properties.

shading descriptor (shd)

the shd is a substructure of the chp and pap.

b10 b16 field type size bitfield comments
0 0 icofore short :5 001f foreground color (see chp.ico)
    icoback short :5 03e0 background../jpg/di1.JPGr (see chp.ico)
    ipat short :6 fc00 shading pattern (see ipat table below)
ipat pattern
0 automatic
1 solid
2 5 percent
3 10 percent
4 20 percent
5 25 percent
6 30 percent
7 40 percent
8 50 percent
9 60 percent
10 70 percent
11 75 percent
12 80 percent
13 90 percent
14 dark horizontal
15 dark vertical
16 dark forward diagonal
17 dark backward diagonal
18 dark cross
19 dark diagonal cross
20 horizontal
21 vertical
22 forward diagonal
23 backward diagonal
24 cross
25 diagonal cross
35 2.5 percent
36 7.5 percent
37 12.5 percent
38 15 percent
39 17.5 percent
40 22.5 percent
41 27.5 percent
42 32.5 percent
43 35 percent
44 37.5 percent
45 42.5 percent
46 45 percent
47 47.5 percent
48 52.5 percent
49 55 percent
50 57.5 percent
51 62.5 percent
52 65 percent
53 67.5 percent
54 72.5 percent
55 77.5 percent
56 82.5 percent
57 85 percent
58 87.5 percent
59 92.5 percent
60 95 percent
61 97.5 percent
62 97 percent

cbshd (count of bytes of shd) is 2.

tab descriptor (tbd)

the tbd is a substructure of the pap.

b10 b16 field type size bitfield comments
0 0 jc byte :3 07 justification code
0 left tab
1 centered tab
2 right tab
3 decimal tab
4 bar
    tlc byte :3 38 tab leader code
0 no leader
1 dotted leader
2 hyphenated leader
3 single line leader
4 heavy line leader
    * byte :2 c0 reserved

cbtbd (count of bytes of tbd) is 1.

table cell descriptors (tc)

the tc is a substructure of the tap.

b10 b16 field type size bitfield comments
0 0 rgf short 0 0  
    ffirstmerged short :1 0001 set to 1 when cell is first cell of a range of cells that have been merged. when a cell is merged, the display areas of the merged cells are consolidated and the text within the cells is interpreted as belonging to one text stream for purposes of calculating line breaks.
    fmerged short :1 0002 set to 1 when cell has been merged with preceding cell.
    fvertical short :1 0004 set to 1 when cell has vertical text flow
    fbackward short :1 0008 for a vertical table cell, text flow is bottom to top when 1 and is bottom to top when 0.
    frotatefont short :1 0010 set to 1 when cell has rotated characters (i.e. uses @font)
    fvertmerge short :1 0020 set to 1 when cell is vertically merged with the cell(s) above and/or below. when cells are vertically merged, the display area of the merged cells are consolidated. the consolidated area is used to display the contents of the first vertically merged cell (the cell with fvertrestart set to 1), and all other vertically merged cells (those with fvertrestart set to 0) must be empty. cells can only be merged vertically if their left and right boundaries are (nearly) identical (i.e. if corresponding entries in rgdxacenter of the table rows differ by at most 3).
    fvertrestart short :1 0040 set to 1 when the cell is the first of a set of vertically merged cells. the contents of a cell with fvertstart set to 1 are displayed in the consolidated area belonging to the entire set of vertically merged cells. vertically merged cells with fvertrestart set to 0 must be empty.
    vertalign short :2 0180 specifies the alignment of the cell contents relative to text flow (e.g. in a cell with bottom to top text flow and bottom vertical alignment, the text is shifted horizontally to match the cell's right boundary):
0 top
1 center
2 bottom
    funused short :7 fe00 reserved
2 2 wunused uns short     reserved
4 4 rgbrc brc[cbrctc]     notational convenience for referring to brctop, brcleft, etc. fields.
4 4 brctop brc     specification of the top border of a table cell
8 8 brcleft brc     specification of left border of table row
12 12 brcbottom brc     specification of bottom border of table row
16 16 brcright brc     specification of right border of table row.

cbtc (count of bytes of tc) is 20(decimal), 14(hex).

table autoformat look specifier (tlp)

b10 b16 field type size bitfield comments
0 0 itl short     index to word's table of table looks (see itl table below)
2 2 fborders short :1 0001 when ==1, use the border properties from the selected table look
    fshading short :1 0002 when ==1, use the shading properties from the selected table look
    ffont short :1 0004 when ==1, use the font from the selected table look
    fcolor short :1 0008 when ==1, use the color from the selected table look
    fbestfit short :1 0010 when ==1, do best fit from the selected table look
    fhdrrows short :1 0020 when ==1, apply properties from the selected table look to the header rows in the table
    flastrow short :1 0040 when ==1, apply properties from the selected table look to the last row in the table
    fhdrcols short :1 0080 when ==1, apply properties from the selected table look to the header columns of the table
    flastcol short :1 0100 when ==1, apply properties from the selected table look to the last column of the table
itl table look
0 (none)
1 simple 1
2 simple 2
3 simple 3
4 classic 1
5 classic 2
6 classic 3
7 classic 4
8 colorful 1
9 colorful 2
10 colorful 3
11 columns 1
12 columns 2
13 columns 3
14 columns 4
15 columns 5
16 grid 1
17 grid 2
18 grid 3
19 grid 4
20 grid 5
21 grid 6
22 grid 7
23 grid 8
24 list 1
25 list 2
26 list 3
27 list 4
28 list 5
29 list 6
30 list 7
31 list 8
32 3d effects 1
33 3d effects 2
34 3d effects 3
35 contemporary
36 elegant
37 professional
38 subtle1
39 subtle2

cbtlp (count of bytes of tlp) is 4.

table properties (tap)

b10 b16 field type size bitfield comments
0 0 jc short     justification code. specifies how table row should be justified within its column.
0 left justify
1 center
2 right justify
2 2 dxagaphalf long     measures half of the white space that will be maintained between text in adjacent columns of a table row. a dxagaphalf width of white space will be maintained on both sides of a column boundary.
6 6 dyarowheight long     when greater than 0. guarantees that the height of the table will be at least dyarowheight high. when less than 0, guarantees that the height of the table will be exactly absolute value of dyarowheight high. when 0, table will be given a height large enough to represent all of the text in all of the cells of the table. cells with vertical text flow make no contribution to the computation of the height of rows with auto or at least height. neither do vertically merged cells, except in the last row of the vertical merge. if an auto height row consists entirely of cells which have vertical text direction or are vertically merged, and the row does not contain the last cell in any vertical cell merge, then the row is given height equal to that of the end of cell mark in the first cell.
10 a6 fcantsplit uns char     when 1, table row may not be split across page bounds
11 b ftableheader uns char     when 1, table row is to be used as the header of the table
12 c tlp tlp     table look specifier (see tlp definition)
16 10 lwhtmlprops long     reserved for future use
20 14 fcafull short :1 0001 used internally by word
    ffirstrow short :1 0002 used internally by word
    flastrow short :1 0004 used internally by word
    foutline short :1 0008 used internally by word
    * short :12 ffe0 reserved
22 16 itcmac short     count of cells defined for this row. itcmac must be >= 0 and less than or equal to 64.
24 18 dxaadjust long     used internally by word
28 1c dxascale long     used internally by word
32 20 dxsinch int     used internally by word
36 24 rgdxacenter short[itcmax + 1]     rgdxacenter[0] is the left boundary of cell 0 measured relative to margin.. rgdxacenter[tap.itcmac - 1] is left boundary of last cell. rgdxacenter[tap.itcmac] is right boundary of last cell.
166 a6 rgdxacenterprint short[itcmax + 1]     used internally by word
296 128 rgtc tc[itcmax]     array of table cell descriptors
1576 628 rgshd shd[itcmax]     array of cell shades
1704 6a81d4 rgbrctable brc[6]     array of border defaults for cells

cbtap (count of bytes of tap) is 1728 (decimal), 6c0(hex).

textbox story (ftxbxs)

b10 b16 field type size bitfield comments
0 0 ctxbx long     when not freusable, counts the number of textboxes in this story chain
0 0 inextreuse long     when freusable, the index of the next in the linked list of reusable ftxbxss
4 4 creusable long     if freusable, counts the number of reusable ftxbxss follow this one in the linked list
8 8 freusable short     this ftxbxs is not currently in use
10 a   long     reserved
14 e lid long     shape identifier (see fspa) for first office shape in textbox chain.
18 12 txidundo long      

cbftxbxs (cout of bytes of ftxbxs) is 22 (decimal), 16 (hex).

work book (wkb)

b10 b16 field type size bitfield comments
0 0 fn short      
2 2 grfwkb uns short      
4 4 lvl short      
6 6 fnpt short :4 000f  
    fnpd short :12 fff0  
8 8 doc long     unused

cbwkb (count of bytes of wkb) is 12 (decimal), c (hex).

appendix a - reading a macintosh pict graphic

as described under "picture" in the definition section of this document, some pictures in word documents are stored as macintosh pict graphics, particularly in files created by word for the macintosh. all pictures, including these, are stored as a block of binary data attached to a special chpic character in the text stream. this block always begins with a pic structure. (please see the "picture" definition mentioned above for more information on general picture-reading.)

normal graphics follow the pic structure with a single office shape, windows metafile, bitmap, or tiff representation, as described in the "picture" definition section. macintosh pict graphics have a standard, unchanging windows metafile after the pic which always depicts an "x", followed by the actual macintosh pict picture. this is for backward-compatibility with older readers, which expect to find a windows metafile after the pic structure. these readers will simply display the fixed "x" image. in the macintosh pict case, the pic structure's lcb field represents the size of the entire picture data block, including the pic itself, the "x" metafile and the macintosh pict data. (see the description of the pic structure in the structure definitions section of this document.)

to distinguish between normal and macintosh pict graphics, a reader needs to detect the presence of the special "x" metafile. the bytes below are in an early portion of the "x" metafile.

unsigned char rgbwmfxbegin[] =
{
'\x14', '\x00', '\x00', '\x00', '\x26', '\x06', '\x0f', '\x00', '\x1e', '\x00',
'\xff', '\xff', '\xff', '\xff', '\x04', '\x00', '\x14', '\x00', '\x00', '\x00',
'\x57', '\x6f', '\x72', '\x64', '\x0e', '\x00', '\x4d', '\x69', '\x63', '\x72',
'\x6f', '\x73', '\x6f', '\x66', '\x74', '\x20', '\x57', '\x6f', '\x72', '\x64',
'\x0e', '\x00', '\x00', '\x00', '\x26', '\x06', '\x0f', '\x00', '\x12', '\x00',
'\x57', '\x6f', '\x72', '\x64', '\xff', '\xff', '\x08', '\x00', '\x00', '\x00'

/* "x" wmf and pict data sizes immediately follow as 2 four-byte longs */
};

#define cbmetahdr 18 // size of a standard windows metafile header
#define cbwmfxbegin 60  // length of this beginning section of the x metafile

after reading the pic structure from the picture data block, the reader should skip cbmetahdr bytes (the size of a standard windows metafile header). it should then compare the next cbwmfxbegin bytes in the picture data block against the bytes in the rgbwmfxbegin array above. if they do not match, the picture is a normal picture -- windows metafile, bitmap or tiff.

if they do match, then the reader should read the next 8 bytes in the picture data block as two 4-byte "long"s (intel 80x86 byte order). these numbers are the sizes (in bytes) of the "x" metafile and the macintosh pict data, respectively. the size of the "x" metafile is measured from its start immediately after the pic structure. it is possible for the pict's size to be zero. in this case, there is no pict data, and the reader may use the "x" windows metafile as the picture's representation.

appendix b - calculation of font (ftc) and language (lid)

certain unicode characters are shared between far east and non-far east scripts requiring the calculation of font and language based on the unicode character code and the chp.idcthint property.

characters are classified into one of four groups, ascii, far east, floating, and non-far east. properties are calculated as follows:

character type font (ftc) language (lid)
ascii sprmcrgftc0 sprmcrglid0
non-far east sprmcrgftc2 sprmcrglid0
far east sprmcrgftc1 sprmcrglid1
shared character sprmcrgftc2 if chp.idcthint is 0
sprmcrgftc1 if chp.idcthint is 1
sprmcrglid0 if chp.idcthint is 0
sprmcrglid1 if chp.idcthint is 1

the table below defines the classification of various ranges of unicode characters:

unicode subrange character range classification
usrbasiclatin 0x20 -> 0x7f ascii
usrlatin1 0xa0 -> 0xff some shared (see notes below)
usrlatinxa 0x100 -> 0x17f some shared (see notes below)
usrlatinxb 0x180 -> 0x24f some shared (see notes below)
usripaextensions 0x250 -> 0x2af some shared (see notes below)
usrspacingmodletters 0x2b0 -> 0x2ff shared
usrcombdiacritical 0x300 -> 0x36f shared
usrbasicgreek 0x370 -> 0x3cf shared
usrgreeksymbolscop 0x3d0 -> 0x3ff non-far east
usrcyrillic 0x400 -> 0x4ff shared
usrarmenian 0x500 -> 0x58f non-far east
usrbasichebrew 0x5d0 -> 0x5ff non-far east
usrhebrewxa 0x590 -> 0x5cf non-far east
usrbasicarabic 0x600 -> 0x652 non-far east
usrarabicx 0x653 -> 0x6ff non-far east
usrdevangari 0x900 -> 0x97f non-far east
usrbengali 0x980 -> 0x9ff non-far east
usrgurmukhi 0xa00 -> 0xa7f non-far east
usrgujarati 0xa80 -> 0xaff non-far east
usroriya 0xb00 -> 0xb7f non-far east
usrtamil 0x0b80 -> 0x0bff non-far east
usrtelugu 0x0c00 -> 0x0c7f non-far east
usrkannada 0x0c80 -> 0x0cff non-far east
usrmalayalam 0x0d00 -> 0x0d7f non-far east
usrthai 0x0e00 -> 0x0e7f non-far east
usrlao 0x0e80 -> 0x0eff non-far east
usrbasicgeorgian 0x10d0 -> 0x10ff non-far east
usrgeorgianextended 0x10a0 -> 0x10cf non-far east
usrhanguljamo 0x1100 -> 0x11ff non-far east
usrlatinextendedadd 0x1e00 -> 0x1eff shared
usrgreekextended 0x1f00 -> 0x1fff non-far east
usrgeneralpunct 0x2000 -> 0x206f shared
usrsuperandsubscript 0x2070 -> 0x209f shared
usrcurrencysymbols 0x20a0 -> 0x20cf shared
usrcombdiacriticss 0x20d0 -> 0x20ff shared
usrletterlikesymbols 0x2100 -> 0x214f shared
usrnumberforms 0x2150 -> 0x218f shared
usrarrows 0x2190 -> 0x21ff shared
usrmathematicalops 0x2200 -> 0x22ff shared
usrmisctechnical 0x2300 -> 0x23ff shared
usrcontrolpictures 0x2400 -> 0x243f shared
usropticalcharrecog 0x2440 -> 0x245f shared
usrenclosedalphanum 0x2460 -> 0x24ff shared
usrboxdrawing 0x2500 -> 0x257f shared
usrblockelements 0x2580 -> 0x259f shared
usrgeometricshapes 0x25a0 -> 0x25ff shared
usrmiscdingbats 0x2600 -> 0x26ff shared
usrdingbats 0x2700 -> 0x27bf shared
usrcjksymandpunct 0x3000 -> 0x303f far east
usrhiragana 0x3040 -> 0x309f far east
usrkatakana 0x30a0 -> 0x30ff far east
usrbopomofo 0x3100 -> 0x312f far east
usrhangulcompatjamo 0x3130 -> 0x318f far east
usrcjkmisc 0x3190 -> 0x319f far east
usrenclosedcjkltmnth 0x3200 -> 0x32ff far east
usrcjkcompatibility 0x3300 -> 0x33ff far east
usrhangul 0xac00 -> 0xd7a3 far east
usrreserved1    
usrreserved2    
usrcjkunifiedideo 0x4e00 -> 0x9fff far east
usrprivateusearea 0xe000 -> 0xf8ff shared
usrcjkcompatibilityideographs 0xf900 -> 0xfaff far east
usralphapresentationforms 0xfb00 -> 0xfb4f shared
usrarabicpresentationformsa 0xfb50 -> 0xfdff shared
usrcombininghalfmarks 0xfe20 -> 0xfe2f far east
usrcjkcompatforms 0xfe30 -> 0xfe4f far east
usrsmallformvariants 0xfe50 -> 0xfe6f far east
usrarabicpresentationformsb 0xfe70 -> 0xfefe shared
usrhfwidthforms 0xff00 -> 0xffef far east
usrspecials 0xfff0 -> 0xfffd non-far east

the table below describes the behavior of the unicode subrange usrlatin1. shared characters are marked in this table with a 1, while characters marked with a 0 are considered "non-far east". all other characters in this unicode subrange are considered "non-far east".

   // 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, // 0x00a0-0x00af
1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, // 0x00b0-0x00bf
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00c0-0x00cf
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00d0-0x00df
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00e0-0x00ef
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00f0-0x00ff
};

the table below describes the behavior of the unicode range usrlatinxa. shared characters are marked in this table with a 1, while characters marked with a 0 are considered "non-far east". all other characters in this unicode subrange are considered "non-far east".

   // 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0100-0x010f
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // 0x0110-0x011f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // 0x0120-0x012f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0130-0x013f
0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, // 0x0140-0x014f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0150-0x015f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // 0x0160-0x016f

in usrlatinxb shared characters are 0x192, 0x1fa, 0x1fb, 0x1fc, 0x1fd, 0x1fe and 0x1ff. all other characters in this unicode subrange are considered "non-far east".

in usripaextensions shared characters are 0x251, and 0x261.

an optimization is available. if the far east font chp.ftcfe is 0 and chp.idcthint is 0 and chp.ftcascii is equal to chp.ftcother, the font is chp.ftcascii and the language is chp.liddefault.

卦指