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.