Microsoft Office 97 Drawing File Format

Introduction

This document describes the file format of the Office Drawing Layer (Escher). With this document and knowledge of the host application's file format, the reader should be able to construct and interpret an Escher file stream.

Object Container Hierarchy

Escher has an object containership hierarchy similar to other drawing programs. At the root of the hierarchy is a drawing group object. There is one drawing group per client document. Drawing groups contain drawings. Drawings in turn contain shapes that are the objects that actually mark a page. Next to the drawings in a drawing group is a collection that contains the images and pictures used by the drawings. Escher keeps pictures in a separate collection to be able to incrementally load and save them.

Figure 1 -- Containership Hierarchy

A few other points are worth noting

Use by the Host Application

Escher is part of the Office 97 DLL. It replaces the existing drawing layers of PowerPoint, Word, and Excel. Clients access the Escher services through custom APIs and COM interfaces defined in msodr.h.

When serializing Escher data into a file, the client application provides an OLE IStream interface to Escher. This document describes the records Escher writes to this interface. However, it doesn't describe how the actual bytes are saved to disk. The client controls this format, since Escher writes to a client provided interface. Excel, for example, places the bytes of the Escher stream into BIFF records.

Credits

Tagged chunks of data are a common file-format element. Escher's particular record structure follows the record structure used in PowerPoint 97, designed by Tony Lin. Parts of this document were copied from the PowerPoint file format SDK. Matthew Morgan did most of the work on the Escher file format. Rick Hawes did the shape work. John Bowler did the blip work.

Records

The Escher file stream is a series of records that share a common header structure. Records can be categorized in to two groups.

Atoms Records that contain information about an Escher object and are kept inside containers.
ContainersRecords that keep atoms and other containers in a logical and organized way.
Each record, whether it's an atom or a container, has a common header. Container records are just the common header, while the atom records are the common header followed by some record specific data. Escher uses the structure of container records containing atom records and other container records throughout its stream.

Common Header

The common record header is an 8-byte structure defined in msodr.h as follows:

	typedef struct MSOFBH
   {
   struct
       {
       ULONG ver : 4;
       ULONG inst: 12;
       ULONG fbt : 16;
       };
   ULONG 
   cbLength;
   } MSOFBH;
The fields are:
Record TypeIndicates the signature or type of the record. Each record has a symbolic and a numberic signature in msodr.h. Escher uses values from 0xF000 to 0xFFFF. Clients may define their own records in other ranges. A description of each of the different types can be found in the following sections.
Record Instance(inst) Differentiates atoms. Depending on the instance a record's contents it can have different meanings. For example a list container can store a list of slides or a list of fonts, and its instance would vary accordingly. The instance of a record is useful for differentiating atoms when there is more than one atom of the same type in a particular container
Record Version (ver) Indicates the version if the record is an atom. If the record is a container, this field has a value of 0xFFFF.
Record Length(cbLength) Stores the length of the record in bytes. If the record is an atom, it refers to the length of the atom excluding the header. If the record is a container, it refers to the sum of the length of the atoms inside it, plus the length of the record headers.

Notes for Implementers

The common header specifies the length of each record. Consequently, it is possible to parse the Escher record stream without knowledge of the actual contents of each record. The Escher team intends to take advantage of this fact in future versions. As new features are added, Escher will define new record types. Readers of the Escher file format should skip over record types unknown to the reader. In addition, readers should not expect a record to come in a certain order in a container. They can, however, expect that the containership hierarchy will not change. For example, readers do not need to handle the case of a shape record containing a drawing record.

When Escher writes to a client file, it stores client-specific records in it stream to preserve the client features and behaviors. On the other hand, when Escher writes to a clipboard stream, it uses a client-independent form of the file format to allow interchange between applications.

Escher saves records in Intel byte-order even on the Macintosh. The Macintosh version of Escher byte-swaps the records as they are loaded and as they are saved. Records are tightly packed, without alignment. The LONG type is 32 bits in length.

Pointers

The general problem of saving pointers to objects in the file format is solved in ordinary fashion by giving objects unique identifiers, which are saved in the file format in place of the pointer values. At load time, these IDs are converted back into pointers.

The most common instances of this are pointers to shapes, which are saved as shape IDs, or SPIDs. SPIDs are unique per drawing group, and are parceled out by the drawing group to individual drawings in blocks of 1024. The drawing group keeps a table recording which drawing owns which block of SPIDs, so that, given a SPID, it is easy to determine which drawing the shape is in. That table makes up the bulk of the msofbtDgg record, and is the only place where pointers to drawings are saved (as DGIDs).

Record Name

Word

Excel

PowerPoint

FBT value

Version

Instance

Contents

msofbtDggContainer

X

X

X

F000

per-document data

msofbtDgg

X

X

X

F006

0

an FDGG and several FIDCLs

msofbtCLSID

C

C

C

F016

0

the CLSID of the application that put the data on the clipboard

msofbtOPT

X

X

X

F00B

3

count of properties

the document-wide default shape properties

msofbtColorMRU

X

X

X

F11A

0

count of colors

the colors in the MRU swatch

msofbtSplitMenuColors

X

X

X

F11E

0

count of colors

the colors in the top-level split menus

msofbtBstoreContainer

X

X

X

F001

count of BLIPs

all images in the document (JPEGs, metafiles, etc.)

msofbtBSE

X

X

X

F007

2

BLIP type

an FBSE (one per BLIP)

msofbtBlip***

X

X

X

F018 - F117

range of fbts reserved for various kinds of BLIPs

msofbtDgContainer

X

X

X

F002

per-sheet/page/slide data

msofbtDg

X

X

X

F008

0

drawing ID

an FDG

msofbtRegroupItems

X

X

X

F118

0

count of regroup entries

several FRITs

msofbtColorScheme

C

C

F120

0

count of colors

the colors of the source host's color scheme

msofbtSpgrContainer

X

X

X

F003

several SpContainers, the first of which is the group shape itself

msofbtSpContainer

X

X

X

F004

a shape

msofbtSpgr

X

X

X

F009

1

an FSPGR; only present if the shape is a group shape

msofbtSp

X

X

X

F00A

2

shape type

an FSP

msofbtOPT

X

X

X

F00B

3

count of properties

a shape property table

msofbtTextbox

C

C

C

F00C

0

RTF text

msofbtClientTextbox

X

X

X

F00D

host-defined

the text in the textbox, in a host-defined format

msofbtAnchor

C

C

C

F00E

0

a RECT, in 100000ths of an inch

msofbtChildAnchor

X

X

X

F00F

0

a RECT, in units relative to the parent group

msofbtClientAnchor

X

X

X

F010

host-defined

the location of the shape, in a host-defined format

msofbtClientData

X

X

X

F011

host-defined

host-specific data

msofbtOleObject

C

C

C

F11F

0

a serialized IStorage for an OLE object

msofbtDeletedPspl

X

F11D

0

an FPSPL; only present in top-level deleted shapes

msofbtSolverContainer

X

X

X

F005

count of rules

the rules governing shapes

msofbtConnectorRule

X

X

F012

1

an FConnectorRule

msofbtAlignRule

X

X

X

F013

0

an FAlignRule

msofbtArcRule

X

X

X

F014

0

an FARCRU

msofbtClientRule

F015

host-defined

host-defined

msofbtCalloutRule

X

X

X

F017

0

an FCORU

msofbtSelection

X

F119

0

an FDGSL followed by the SPIDs of the shapes in the selection


Drawing Group Container msofbtDggContainer

Drawing Group Record msofbtDgg

The drawing group record is a variable length record consisting of a fixed part followed by an array. The fixed part is defined as follows.

// FDGG - File DGG
typedef struct _FDGG
   {
   MSOSPID spidMax; // The current maximum shape ID
   ULONG cidcl;     // The number of ID clusters (FIDCLs) 
   ULONG cspSaved;  // The total number of shapes saved
                    // (including deleted shapes, if undo
                    // information was saved)
   ULONG cdgSaved;  // The total number of drawings saved
   } FDGG;
The fixed part is followed by an array of ID clusters. The ID clusters are used internally for the translation of shape ids (SPIDs) to shape handles (MSOHSPs).

// File ID Cluster - used to save IDCLs
typedef struct _FIDCL
   {
   MSODGID dgid;    // DG owning the SPIDs in this cluster
   ULONG cspidCur;  // number of SPIDs used so far
   } FIDCL;

Class ID Record msofbtCLSID

The class ID record is only present in the clipboard format. It just contains an OLE CLSID record from the source application, and is used by the destination application to check where the clipboard data originated.

Default Property Table Record msofbtOPT

This describes the default properties of newly created shapes. Only the properties that differ from the per-property defaults are saved. The format of the record is the same as that of the property table in a shape; a discussion of that format is in the Shape Properties section

Color MRU Record msofbtColorMRU

The Color MRU record contains the colors in the most-recently-used-colors swatch that appears at the bottom of color dropdowns. The instance field contains the number of colors; the data of the record contains the colors in order from left to right.

< > < >

Split Menu Colors Record msofbtSplitMenuColors

The single MRU colors of the top-level Fill Color, Line Color, Shadow Color, and 3D Color split menus are saved to a SplitMenuColors record in that order, with the number of colors (currently always four) in the instance field.

BStore Container msofbtBstoreContainer

The images and pictures in a drawing can be dominate the size of a drawing. Consequently, Escher handles these objects in a special way. As an abstraction, Escher names these objects BLIPs for Big Large Image or Picture. Currently, there are five types of blips supported in Escher: Windows Metafiles, Enhanced Metafiles, JPEG Interchange Format, Portable Network Graphics (PNG) and Macintosh PICT. Other types may be defined in future versions.

Escher stores all the BLIPs in a document in a separate container called the BStore. It reference counts the BLIPs, so that if a picture is inserted multiple times in a document it is only stored once in the BStore but is multiply referenced by different shapes.

The host may choose to store the blip data in a separate delay stream. If a delay stream is used, Escher can incrementally load the blips as they are displayed, not when the document is loaded. (As of Office 97, Word and PowerPoint use a delay stream, and Excel does not.)

The BStore container is just an array of Blip Store Entry (BSE) records. Each shape stores indices into the array for the BLIPs they use. BLIPs are used not only for inserted pictures, but also for the textured and pictures fills of the shape.

BLIP Store Entry Record msofbtBSE

Each BLIP in the BStore is serialized to a File BLIP Store Entry (FBSE) record. The instance field encodes the type of the blip. A fixed size header contains the rest of the common information about the BLIP. If the cbName field in the FBSE is nonzero, a null-terminated Unicode string is written immediately after the FBSE in the file.

// FBSE - File Blip Store Entry
typedef struct _FBSE
   {
   BYTE      btWin32;    // Required type on Win32
   BYTE      btMacOS;    // Required type on Mac
   BYTE      rgbUid[16]; // Identifier of blip
   WORD      tag;        // currently unused
   ULONG     size;       // Blip size in stream
   ULONG     cRef;       // Reference count on the blip
   MSOFO     foDelay;    // File offset in the delay stream
   BYTE      usage;      // How this blip is used (MSOBLIPUSAGE)
   BYTE      cbName;     // length of the blip name
   BYTE      unused2;    // for the future
   BYTE      unused3;    // for the future
   } FBSE;

typedef enum
   {
   msoblipUsageDefault,  // All non-texture fill blips get this.
   msoblipUsageTexture,
   msoblipUsageMax = 255 // Since this is stored in a byte
   } MSOBLIPUSAGE;

typedef enum
   {                          // GEL provided types...
   msoblipERROR = 0,          // An error occured during loading
   msoblipUNKNOWN,            // An unknown blip type
   msoblipEMF,                // Windows Enhanced Metafile
   msoblipWMF,                // Windows Metafile
   msoblipPICT,               // Macintosh PICT
   msoblipJPEG,               // JFIF
   msoblipPNG,                // PNG
   msoblipDIB,                // Windows DIB
   msoblipFirstClient = 32,   // First client defined blip type
   msoblipLastClient  = 255   // Last client defined blip type
   } MSOBLIPTYPE;

typedef enum
   {
   msobiUNKNOWN = 0,
   msobiWMF  = 0x216,      // Metafile header then compressed WMF
   msobiEMF  = 0x3D4,      // Metafile header then compressed EMF
   msobiPICT = 0x542,      // Metafile header then compressed PICT
   msobiPNG  = 0x6E0,      // One byte tag then PNG data
   msobiJFIF = 0x46A,      // One byte tag then JFIF data
   msobiJPEG = msobiJFIF,
   msobiDIB  = 0x7A8,      // One byte tag then DIB data
   msobiClient=0x800,      // Clients should set this bit
   }
MSOBI;                     // Blip signature as encoded in the MSOFBH.inst
The btWin32 and btMacOS fields store the MSOBLIPTYPE for the respective operating systems. When the OS blip type doesn't match the blip type of stored, Escher will attempt to convert the blip. For example, a PICT will be stored as a msoblipPICT with a btWin32 field of msoblipWMF and a btMacOS field of msoblipPICT. When the PICT blip is loaded on Windows, the stored field will not match the OS field, so PICTtoWMF filter will be called to create a msoblipWMF BLIP.

A few additional facts are worth noting. Clients can define their own BLIP types. When loading client defined blip types Escher calls the clients to load the blips. Each BSE contains a 16-byte checksum that is used to quickly compare a BLIP with other BLIPs in the store. Any algorithm could be used for this checksum. Escher uses the RSA Data Security, Inc. MD4 Message-Digest Algorithm for the checksums of its BLIP types. Finally, the cRef field can be 0, indicating an empty slot in the BStore.

If a delay stream is not used, then the BLIP data follows the BSE header in a separate record. The FBT of the BLIP record is the MSOBLIPTYPE plus msofbtBlipFirst (0xF018). (If a delay stream is being used, the BLIP's record header and data are both written there instead.)

Metafile/PICT Blips
Those blips have one of the following signatures: msobiEMF, msobiWMF, or msobiPICT. They are normally stored in a compressed format using the LZ compression algorithm in the format used by GNU Zip deflate/inflate with a 32k window. The format is zlib format . The only metafile compression version number currently defined identifies this format and is analogous to the PNG compression type value in the PNG file format. The filter values (MSOBLIPFILTER) define pre-filtering of metafile data to give better compression. Currently no pre-filtering is done (it is likely that filtering on a per-record basis will give substantially better compression in the future).

However, if there is an exception due to out-of-memory or out-of-disk space when saving those blips, the compression operation is skipped and the blips are then saved in a non-compressed format- in this case the compressed bits are simply the original metafile data.. When the blips are loaded back in memory, a check is performed based on a "compression status" flag (MSOBLIPCOMPRESSION) that follows the blip header encoded as follows:

typedef enum
   {
   msocompressionDeflate = 0,
   msocompressionNone = 254,    // Used only if compression fails
   msocompressionTest = 255,    // For testing only
   }
MSOBLIPCOMPRESSION;

typedef enum
   {
   msofilterAdaptive = 0,       // PNG type - not used/supported for metafile
   msofilterNone = 254,
   msofilterTest = 255,         // For testing only
   }
MSOBLIPFILTER;

/* The secondary, or data, UID - should always be set. */
BYTE  m_rgbUid[16];
/* The primary UID - this defaults to 0, in which case the primary ID is
   that of the internal data. NOTE!: The primary UID is only saved to disk
   if (blip_instance ^ blip_signature == 1). Blip_instance is MSOFBH.inst and 
   blip_signature is one of the values defined in MSOBI */
BYTE  m_rgbUidPrimary[16]; /   / optional based on the above check

/* Metafile Blip overhead = 34 bytes. m_cb gives the number of
   bytes required to store an uncompressed version of the file, m_cbSave
   is the compressed size.  m_mfBounds gives the boundary of all the
   drawing calls within the metafile (this may just be the bounding box
   or it may allow some whitespace, for a WMF this comes from the
   SetWindowOrg and SetWindowExt records of the metafile). */
int           m_cb;           // Cache of the metafile size
RECT          m_rcBounds;     // Boundary of metafile drawing commands
POINT         m_ptSize;       // Size of metafile in EMUs
int           m_cbSave;       // Cache of saved size (size of m_pvBits)
BYTE          m_fCompression; // MSOBLIPCOMPRESSION
BYTE          m_fFilter;      // always msofilterNone
void         *m_pvBits;       // Compressed bits of metafile.
Bitmap Blips
Those blips have one of the following signatures: msobiJPEG, msobiPNG, or msobiDIB. They have the same UID header as described in the Metafile Blip case. The data after the header is just a single BYTE "tag" value and is followed by the compressed data of the bitmap in the relevant format (JFIF or PNG, bytes as would be stored in a file). For the msobiDIB format, the data is in the standard DIB format as a BITMAPINFO ER, BITMAPCORE ER or BITMAPV4 ER followed by the color map (DIB_RGB_COLORS) and the bits. This data is not compressed (the format is used for very small DIB bitmaps only).

To determine where the bits are located, refer to the following header:

/* The secondary, or data, UID - should always be set. */
BYTE  m_rgbUid[16];
/* The primary UID - this defaults to 0, in which case the primary ID is
   that of the internal data. NOTE!: The primary UID is only saved to disk
   if (blip_instance ^ blip_signature == 1). Blip_instance is MSOFBH.finst and 
   blip_signature is one of the values defined in MSOBI*/
BYTE  m_rgbUidPrimary[16];    // optional based on the above check
BYTE  m_bTag;            
void  *m_pvBits;              // raster bits of the blip.
< > < >

Drawing Container msofbtDgContainer

The drawing container contains all per-slide/sheet types of information, including the shapes themselves. With a few exceptions, shapes are stored hierarchically according to how they've been grouped (through use of the Draw/Group command). For normal shapes, there is a special parent group shape called the patriarch that contains all of the top-level shapes (which in turn may contain other shapes). The patriarch is always the first msofbtSpgrContainer in the drawing container.

A few kinds of shapes are stored separately from the patriarch. The background shape, if there is one, is saved in its own msofbtSpContainer after the patriarch and its children. Additionally, if undo information is being saved and there are deleted shapes that could be brought back via Undo, the deleted shapes are saved. Note that there is no patriarch for the deleted shapes, so the top-level deleted shapes are saved separately into the drawing container. (Deleted groups still contain their children, though.)

Record Type

Condition

Comments

msofbtDg

Always.

Basic drawing information.

msofbtRegroupItems

Shapes have been ungrouped.

Mappings to reconstitute groups.

msofbtSpgrContainer

Always.

Patriarch shape, with all non-background non-deleted shapes inside it.

msofbtSpContainer with fBackground bit set in the FSP (see below).

Application uses a background shape (currently Word and PowerPoint only).

Special shape used as background of the document, e.g. the background texture of a Web page.

Other msofbtSpContainers and msofbtSpgrContainers

Undo is being saved, and there are deleted shapes in the drawing.

Shapes that have been deleted but that could be brought back via Undo.

msofbtSolverContainer

There are rules in the drawing.

Rules governing shapes in the drawing.

msofbtColorScheme

The application uses a color scheme.

Only present in the clipboard format.


< > < >

Drawing Record msofbtDg

The drawing record is very simple, with just a count and MSOSPID seed. The attentive reader may expect to find the size of the drawing recorded here, but that information is stored elsewhere by the host application.

// FDG - File DG
typedef struct _FDG
   {
   ULONG     csp;          // The number of shapes in this drawing
   MSOSPID   spidCur;      // The last MSOSPID given to an SP in this DG
   } FDG;
< > < >

Regroup msofbtRegroupItems

Each shape in a drawing has a regroup ID (separate from the shape ID), so that the regroup command can find shapes that were once grouped. In order to handle nested cases (e.g. ungroup, ungroup, ungroup, regroup, regroup, regroup), there is a table logging changes to regroup IDs. Each entry has an old ID and a new ID and records the change of all instances of the old ID to the new ID.

The instance of an msofbtRegroupItems record contains the number of entries, and the record itself is just that many FRITs (File Regroup Items).

typedef struct _FRIT // File Regroup item

   {
   FRID fridNew;
   FRID fridOld;
   } FRIT;
< > < >

Group Container msofbtSpgrContainer

A group is a collection of other shapes. The contained shapes are placed in the coordinate system of the group. The group container contains a variable number of shapes (msofbtSpContainer) and other groups (msofbtSpgrContainer, for nested groups). The group itself is a shape, and always appears as the first msofbtSpContainer in the group container.

< > < >

Shape Container msofbtSpContainer

A shape is the elemental object that composes a drawing. All graphical figures on a drawing are shapes. Each shape has a list of properties, which is stored in an array. A shape container contains the following records:

Record Type

Condition

Comments

msofbtSpgr

Shape is a group shape.

Group-shape-specific information.

msofbtSp

Always.

A shape atom record.

msofbtOPT

Always.

The properties of a shape.

msofbtAnchor or msofbtChildAnchor or msofbtClientAnchor

Always, except for the background shape.

The anchor or location of the shape. If the shape is saved to a clipboard, a msofbtAnchor record is used. If the shape is a child of a group shape, a msofbtChildAnchor is used. Otherwise, for top-level shapes, a host anchor record is present.

msofbtClientData

Always.

A client data record, the content of which is up to the host.

msofbtClientTextbox or msofbtTextbox

Shape has attached text.

If the shape has text, a text record is written. For clipboard streams, a msofbtTextbox record is used. Otherwise, a msofbtClientTextbox record is used, the content of which is up to the host.

msofbtOleObject

Shape is an OLE object.

Used only in the clipboard format.

msofbtDeletedPspl

Shape is deleted.

Link to previous spot of object.


Group Shape Record msofbtSpgr

This record is present only in group shapes (not shapes in groups, shapes that are groups). The group shape record defines the coordinate system of the shape, which the anchors of the child shape are expressed in. All other information is stored in the shape records that follow.

typedef struct _FSPGR
   {
   RECT   rcgBounds;
   } FSPGR;

Shape Record msofbtSp

The instance field of the record header contains the shape type; the record itself contains the shape ID and a group of persistent flags:

typedef struct _FSP
   {
   MSOSPID  spid;           // The shape id 
   ULONG    grfPersistent;
   } FSP;
The flags for the shape are:

typedef struct 
{
   ULONG fGroup : 1;        // This shape is a group shape
   ULONG fChild : 1;        // Not a top-level shape
   ULONG fPatriarch : 1;    // This is the topmost group shape.
                            // Exactly one of these per drawing. 
   ULONG fDeleted : 1;      // The shape has been deleted
   ULONG fOleShape : 1;     // The shape is an OLE object
   ULONG fHaveMaster : 1;   // Shape has a hspMaster property
   ULONG fFlipH : 1;        // Shape is flipped horizontally
   ULONG fFlipV : 1;        // Shape is flipped vertically
   ULONG fConnector : 1;    // Connector type of shape
   ULONG fHaveAnchor : 1;   // Shape has an anchor of some kind
   ULONG fBackground : 1;   // Background shape
   ULONG fHaveSpt : 1;      // Shape has a shape type property
   ULONG reserved : 20;     // Not yet used
}

Property Table Record msofbtOPT

A shape's properties are stored in a sorted array of property id-value pairs. Only the properties that differ from the per-shape-type defaults or the per-property defaults are saved. (Note that the per-property defaults are unrelated to the default property table stored in the drawing group container).

The format of a property table record is in another section of this document.

Anchor Record msofbtAnchor

An anchor record is used for top-level shapes when the shape streamed to the clipboard. The content of the record is simply a RECT with a coordinate system of 100,000 units per inch and origin in the top-left of the drawing.

Child Anchor Record msofbtChildAnchor

A child anchor record is used for all shapes that belong to a group. The content of the record is simply a RECT in the coordinate system of the parent group shape.

Textbox Record msofbtTextbox

A textbox record is used when a shape with attached text is written to a clipboard stream. It just contains an RTF string.

OLE Object Record msofbtOleObject

An OLE object record is present when a shape that is an OLE object is saved to the clipboard. It contains the OLE object's storage, serialized using OleConvertIStorageToOLESTREAM.

Deleted PSPL Record msofbtDeletedPspl

Top-level deleted shapes save a pointer back into their former position in the shape tree, so that if they are undeleted via undo they can be easily put back into the main shape tree.

The record consists of a single FPSPL:

// FPSPL - File PSPL
typedef struct _FPSPL 
   {
   union
      {
      ULONG lAll;
      struct
         {
         ULONG spid : 30;   // The SPID of the shape PSPL points at.
         ULONG fFirst : 1;  // Is this a pointer to the m_splFirst?
         ULONG fLast  : 1;  // Is this a pointer to the m_splLast?
         };
      };
   } FPSPL;
< > < >

Solver Container msofbtSolverContainer

Rules give special behaviors to shapes. Rules can govern a single shape, like in the case of a callout shape, or multiple shapes, as in the case of connectors. Each drawing can have a list of rules associated with it.

Connector Rule Record msofbtConnectorRule

Governs a connector shape.

typedef struct _FConnectorRule
   {
   ULONG ruid;       // rule ID
   MSOSPID spidA;    // SPID of shape A
   MSOSPID spidB;    // SPID of shape B
   MSOSPID spidC;    // SPID of connector shape
   ULONG cptiA;      // Connection site Index of shape A
   ULONG cptiB;      // Connection site Index of shape B
   } FConnectorRule;

Align Rule Record msofbtAlignRule

Aligns shapes. The FAlignRule record is followed by the SPIDs of the proxy shapes.

// FAlignRule 
typedef struct _FAlignRule
   {
   ULONG ruid;       // rule ID
   ULONG align;      // alignment  see below
   ULONG cProxies;   // number of shapes governed by rule
   } FAlignRule;

// ALIGN == Shape alignment (Horz and vert can be or'ed together)
#define alignHorz      0x000F   // mask for horizontal component
#define alignLeft      0x0001   // left edges
#define alignCenter    0x0002   // horizontal center
#define alignRight     0x0003   // right edges
#define alignVert      0x00F0   // mask for vertical component
#define alignTop       0x0010   // top edges
#define alignMiddle    0x0020   // vertical center
#define alignBottom    0x0030   // bottom edges
#define alignRelative  0x0100   // Relative to the page

Arc Rule Record msofbtArcRule

One Arc rule per elliptical arc shape.

// FARCRU -- Arc Rule
typedef struct _FARCRU
   {
   ULONG      ruid; // rule ID
   MSOSPID    spid; // spid of arc shape
   } FARCRU;

Callout Rule Record msofbtCalloutRule

One callout rule per callout shape.

// FCORU   -- Callout Rule
typedef struct _FCORU
   {
   ULONG      ruid; // rule ID
   MSOSPID    spid; // spid of callout shape
   } FCORU;
< > < >

Color Scheme msofbtColorScheme

Hosts may define their own color scheme and store colors in shape properties that are an index to that scheme plus an indicating flag (see Appendix B). Since hosts' color schemes are independent of each other, the color scheme is saved when rendering to the clipboard. If the clipboard data is pasted back into the same application, the color scheme block is ignored; otherwise, it is used to translate scheme colors in properties into RGB values.

The data in the block is an array of RGB values, saved as LONGs in order of color scheme index.

< > < >

Selections msofbtSelection

Selections of shapes are saved as top-level file blocks; they are never placed in a container. (Note: As of Office 97, only Excel saves shape selections; Word and PowerPoint do not.) The selection record consists of an FDGSL followed by the SPIDs of the shapes in the selection.

// FDGSL - File Drawing Selection
typedef struct _FDGSL
   {
   ULONG         cpsp;       // number of shapes in the selection
   ULONG         dgslk;      // kind of selection (an MSODGSLK)
   MSOSPID       spidFocus;  // SPID of the focus shape
   } FDGSL;

// DGSLK = DrawinG SeLection Kind.
typedef enum
   {
   msodgslkNormal,          // Normal Selection Mode.
   msodgslkRotate,          // Rotate selection mode
   msodgslkReshape,         // Reshape Selection Mode.
   msodgslkUnused,
   msodgslkWrapPolygon,     // Display and edit of wrap polygons.
   msodgslkTextEdit         // Text Edit Mode.
   } MSODGSLK;
< > < >

Shape Properties msofbtOPT

The first part of an OPT record is an array of FOPTEs, consisting of ID-value pairs tightly packed:

typedef struct _FOPTE
   {
   struct
      {
      USHORT pid : 14;     // Property ID
      USHORT fBid : 1;     // value is a blip ID  only valid if fComplex is FALSE
      USHORT fComplex : 1; // complex property, value is length
      };
   ULONG   op;  // Value
   } FOPTE;
The FOPTE array is sorted by property ID.

Some property values, such as Unicode strings, don't fit in 32 bits. For these properties, the fComplex bit is set in the FOPTE, and the length of the data is saved in the value slot. The data of the complex properties follows the FOPTE array in the file record (sorted by property ID).

BLIPs are usually saved in the BLIP Store, so, in most cases, BLIP properties just store a BLIP ID (basically an index into an array in the BLIP Store). This is signaled by the fBid flag; note however that this flag is only valid if fComplex is FALSE.

Boolean properties are grouped in bitfields by property set; note that the Boolean properties in each property set below are contiguous. They are saved under the property ID of the last Boolean property in the set, and are placed in the value field in reverse order starting with the last property in the low bit.

Notes on types and units:

  • MSOHSP properties are basically just pointers to shapes, and they are therefore saved as SPIDs.
  • WCHAR* properties are Unicode strings; char* properties are ASCII strings.
  • IMsoArray properties are arrays. They are always complex when non-NULL. The complex-data part is saved as three shorts (16 bits each) followed by the array data. The first short is the number of elements in the array; the second short is the number of elements allocated for the array in memory (always greater than or equal to the first short); and the third short is the size of each array element.
  • Absolute distances are specified in English Metric Units (EMUs), occasionally referred to as A units; there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
  • A coordinate space relative to the size of the shape is specified with the geoLeft, geoTop, geoRight, and geoBottom properties; coordinates in this space are said to be in G units.
  • Many quantities are specified as fixed-point 16.16 numbers; that is, the quantity fits in a LONG, where the high word specifies the integer part and the low word specifies the fractional part. In this system, 1<<16 signifies 1, 1<<17 signifies 2, and 1<<15 signifies .
The property listings below contain only those properties which are saved in OPT records in the file. Properties which are never saved, or which appear elsewhere in the file format, have been omitted.

< > < >

Transform

Property

PID

Type

Default

Description

rotation

4

LONG

0

fixed point: 16.16 degrees


< > < >

Protection

Changes the behavior of a shape by restricting direct manipulation.

Property

PID

Type

Default

Description

fLockRotation

119

BOOL

FALSE

No rotation

fLockAspectRatio

120

BOOL

FALSE

Don't allow changes in aspect ratio

fLockPosition

121

BOOL

FALSE

Don't allow the shape to be moved

fLockAgainstSelect

122

BOOL

FALSE

Shape may not be selected

fLockCropping

123

BOOL

FALSE

No cropping this shape

fLockVertices

124

BOOL

FALSE

Edit Points not allowed

fLockText

125

BOOL

FALSE

Do not edit text

fLockAdjustHandles

126

BOOL

FALSE

Do not adjust

fLockAgainstGrouping

127

BOOL

FALSE

Do not group this shape


< > < >

Text

How text fits in a shape. Text is host-dependent, so some hosts may ignore some of these properties.

Property

PID

Type

Default

Description

lTxid

128

LONG

0

id for the text, value determined by the host

dxTextLeft

129

LONG

1/10 inch

margins relative to shape's inscribed text rectangle (in EMUs)

dyTextTop

130

LONG

1/20 inch

dxTextRight

131

LONG

1/10 inch

dyTextBottom

132

LONG

1/20 inch

WrapText

133

MSOWRAPMODE

FALSE

Wrap text at shape margins

scaleText

134

LONG

0

Text zoom/scale (used if fFitTextToShape)

anchorText

135

MSOANCHOR

Top

How to anchor the text

txflTextFlow

136

MSOTXFL

HorzN

Text flow

cdirFont

137

MSOCDIR

msocdir0

Font rotation

hspNext

138

MSOHSP

NULL

ID of the next shape (used by Word for linked textboxes)

txdir

139

MSOTXDIR

LTR

Bi-Di Text direction

fSelectText

187

BOOL

TRUE

TRUE if single click selects text, FALSE if two clicks

fAutoTextMargin

188

BOOL

FALSE

use host's margin calculations

fRotateText

189

BOOL

FALSE

Rotate text with shape

fFitShapeToText

190

BOOL

FALSE

Size shape to fit text size

fFitTextToShape

191

BOOL

FALSE

Size text to fit shape size


< > < >

GeoText

Effect text of the shape - this is what the WordArt tools use, and is separate from the attached text present in ordinary textboxes. Theoretically, a shape could have both (a WordArt with attached text), but this is not currently allowed by the UI. Note that font information is provided here. The default text size is in points, the text effect geometry interfaces require the device size of a point to interpret this. The default point size is a 16.16 fixed-point number. A text effect is present if the fGText boolean is set and either the gtextUNICODE (UNICODE) or gtextRTF (RTF) is present, the UNICODE string takes precedence, however it cannot include any additional font information (unlike the RTF).

Property

PID

Type

Default

Description

gtextUNICODE

192

WCHAR*

NULL

UNICODE text string

gtextRTF

193

char*

NULL

RTF text string

gtextAlign

194

MSOGEOTEXTALIGN

Center

alignment on curve

gtextSize

195

LONG

36<<16

default point size

gtextSpacing

196

LONG

1<<16

fixed point 16.16

gtextFont

197

WCHAR*

NULL

font family name

gtextFReverseRows

240

BOOL

FALSE

Reverse row order

fGtext

241

BOOL

FALSE

Has text effect

gtextFVertical

242

BOOL

FALSE

Rotate characters

gtextFKern

243

BOOL

FALSE

Kern characters

gtextFTight

244

BOOL

FALSE

Tightening or tracking

gtextFStretch

245

BOOL

FALSE

Stretch to fit shape

gtextFShrinkFit

246

BOOL

FALSE

Char bounding box

gtextFBestFit

247

BOOL

FALSE

Scale text-on-path

gtextFNormalize

248

BOOL

FALSE

Stretch char height

gtextFDxMeasure

249

BOOL

FALSE

Do not measure along path

gtextFBold

250

BOOL

FALSE

Bold font

gtextFItalic

251

BOOL

FALSE

Italic font

gtextFUnderline

252

BOOL

FALSE

Underline font

gtextFShadow

253

BOOL

FALSE

Shadow font

gtextFSmallcaps

254

BOOL

FALSE

Small caps font

gtextFStrikethrough

255

BOOL

FALSE

Strike through font


< > < >

Blip

How a BLIP fits into a shape. This includes cropping information as well as picture display modifications such as brightness and contrast.

Property

PID

Type

Default

Description

cropFromTop

256

LONG

0

16.16 fraction times total image width or height, as appropriate.

cropFromBottom

257

LONG

0

cropFromLeft

258

LONG

0

cropFromRight

259

LONG

0

pib

260

IMsoBlip*

NULL

Blip to display

pibName

261

WCHAR*

NULL

Blip file name

pibFlags

262

MSOBLIPFLAGS

Comment

Blip flags

pictureTransparent

263

LONG

~0

transparent color (none if ~0UL)

pictureContrast

264

LONG

1<<16

contrast setting

pictureBrightness

265

LONG

0

brightness setting

pictureGamma

266

LONG

0

16.16 gamma

pictureId

267

LONG

0

Host-defined ID for OLE objects (usually a pointer)

pictureDblCrMod

268

MSOCLR

This

Modification used if shape has double shadow

pictureFillCrMod

269

MSOCLR

undefined

pictureLineCrMod

270

MSOCLR

undefined

pibPrint

271

IMsoBlip*

NULL

Blip to display when printing

pibPrintName

272

WCHAR*

NULL

Blip file name

pibPrintFlags

273

MSOBLIPFLAGS

Comment

Blip flags

fNoHitTestPicture

316

BOOL

FALSE

Do not hit test the picture

pictureGray

317

BOOL

FALSE

grayscale display

pictureBiLevel

318

BOOL

FALSE

bi-level display

pictureActive

319

BOOL

FALSE

Server is active (OLE objects only)


< >< > Geometry < bgcolor="#FFFFFF">

Geometry

The geometry of the shape. Typically, these properties reside in a shape type definition, and so are not written to the file. However, freeform shapes drawing using the polygon tools set the pVertices and pSegmentInfo properties to define their geometries.

Property PID Type Default Description
geoLeft 320 LONG 0 Defines the G (geometry) coordinate space.
geoTop 321 LONG 0  
geoRight 322 LONG 21600  
geoBottom 323 LONG 21600  
shapePath 324 MSOSHAPEPATH msoshapeLinesClosed  
pVertices 325 IMsoArray NULL An array of points, in G units.
pSegmentInfo 326 IMsoArray NULL  
adjustValue 327 LONG 0 Adjustment values corresponding to the positions of the adjust handles of the shape. The number of values used and their allowable ranges vary from shape type to shape type.
adjust2Value 328 LONG 0  
adjust3Value 329 LONG 0  
adjust4Value 330 LONG 0  
adjust5Value 331 LONG 0  
adjust6Value 332 LONG 0  
adjust7Value 333 LONG 0  
adjust8Value 334 LONG 0  
adjust9Value 335 LONG 0  
adjust10Value 336 LONG 0  
fShadowOK 378 BOOL TRUE Shadow may be set
f3DOK 379 BOOL TRUE 3D may be set
fLineOK 380 BOOL TRUE Line style may be set
fGtextOK 381 BOOL FALSE Text effect (WordArt) supported
fFillShadeShapeOK 382 BOOL FALSE  
fFillOK 383 BOOL TRUE OK to fill the shape through the UI or VBA?

< > < >

Fill Style

Two main colors are defined - a foreground color and a background color. Different fillTypes use these values differently. In addition to the foreground and background any number of shade colors can be defined. Each shade color is associated with a "position" which says how far into the shade the color appears colors must be given in position order.

For a solid fill the foreground color is used and the background (and everything else except transparency) is ignored. For pattern and texture fills the fillBlip identifies a BLIP, which will be used for the fill.

fillWidth and fillHeight define the desired pattern/texture size in EMUs. The pattern/tile will be expanded to this size. If the pattern is a bitmap the actual size will be rounded to a close integer multiple of the original (pixel) size of the bitmap. If the size is 0 then the pattern/tile will not be expanded or contracted at all in pixel terms, so the fill will be device dependent - this may result in non-proportional scaling between devices (on devices with non-square pixels).

For a pattern the foreground and background colors define the colors to use when filling with a pattern, for a texture the colors are in the bitmap (this is the only difference).

For both pattern and texture fills the fill is registered with (0,0) on the view in which the effect appears unless fillShape is set to TRUE, in which case the pattern/texture is registered relative to the shape (so it moves with the shape).

For a picture fill the fillBlip is centered in the shape - not tiled.

For a shaded fill the colors define shade bands to use across the shade, shading between each pair of colors. The positions are the positions of the shade at which the given color appears - the shade ends with the first index that is >= 1 (in 16.16 notation), the indices must be in ascending order or the result is undefined. The interpretation of the shade start and shade end points varies according to the exact shade type.

The fillBackground fill indicates a fill inherited from a background object.

Property

PID

Type

Default

Description

fillType

384

MSOFILLTYPE

Solid

Type of fill

fillColor

385

MSOCLR

white

Foreground color

fillOpacity

386

LONG

1<<16

Fixed 16.16

fillBackColor

387

MSOCLR

white

Background color

fillBackOpacity

388

LONG

1<<16

Shades only

fillCrMod

389

MSOCLR

undefined

Modification for BW views

fillBlip

390

IMsoBlip*

NULL

Pattern/texture

fillBlipName

391

WCHAR*

NULL

Blip file name

fillBlipFlags

392

MSOBLIPFLAGS

Comment

Blip flags

fillWidth

393

LONG

0

How big (A units) to make a metafile texture.

fillHeight

394

LONG

0

fillAngle

395

LONG

0

Fade angle - degrees in 16.16

fillFocus

396

LONG

0

Linear shaded fill focus percent

fillToLeft

397

LONG

0

Fraction 16.16

fillToTop

398

LONG

0

Fraction 16.16

fillToRight

399

LONG

0

Fraction 16.16

fillToBottom

400

LONG

0

Fraction 16.16

fillRectLeft

401

LONG

0

For shaded fills, use the specified rectangle instead of the shape's bounding rect to define how large the fade is going to be.

fillRectTop

402

LONG

0

fillRectRight

403

LONG

0

fillRectBottom

404

LONG

0

fillDztype

405

MSODZTYPE

Default

fillShadePreset

406

LONG

0

Special shades

fillShadeColors

407

IMsoArray

NULL

a preset array of colors

fillOriginX

408

LONG

0

fillOriginY

409

LONG

0

fillShapeOriginX

410

LONG

0

fillShapeOriginY

411

LONG

0

fillShadeType

412

MSOSHADETYPE

Default

Type of shading, if a shaded (gradient) fill.

fFilled

443

BOOL

TRUE

Is shape filled?

fHitTestFill

444

BOOL

TRUE

Should we hit test fill?

fillShape

445

BOOL

TRUE

Register pattern on shape

fillUseRect

446

BOOL

FALSE

Use the large rect?

fNoFillHitTest

447

BOOL

FALSE

Hit test a shape as though filled


< > < >

Line Style

Lines are centered about the infinitely thin proto-line along which they are drawn. Complex dash effects are supported only for simple lines (e.g. changing the end cap) - defaults should be used for other line styles. The line width is in EMUs; a line width of zero should not be used - there is no logical interpretation on a high-resolution printer.

Property

PID

Type

Default

Description

lineColor

448

MSOCLR

black

Color of line

lineOpacity

449

LONG

1<<16

Not implemented

lineBackColor

450

MSOCLR

white

Background color

lineCrMod

451

MSOCLR

undefined

Modification for BW views

lineType

452

MSOLINETYPE

Solid

Type of line

lineFillBlip

453

IMsoBlip*

NULL

Pattern/texture

lineFillBlipName

454

WCHAR*

NULL

Blip file name

lineFillBlipFlags

455

MSOBLIPFLAGS

Comment

Blip flags

lineFillWidth

456

LONG

0

How big (A units) to make a metafile texture.

lineFillHeight

457

LONG

0

lineFillDztype

458

MSODZTYPE

Default

How to interpret fillWidth/Height numbers.

lineWidth

459

LONG

9525

A units; 1pt == 12700 EMUs

lineMiterLimit

460

LONG

8<<16

ratio (16.16) of width

lineStyle

461

MSOLINESTYLE

Simple

Draw parallel lines?

lineDashing

462

MSOLINEDASHING

Solid

Can be overridden by:

lineDashStyle

463

IMsoArray

NULL

As Win32 ExtCreatePen

lineStartArrowhead

464

MSOLINEEND

NoEnd

Arrow at start

lineEndArrowhead

465

MSOLINEEND

NoEnd

Arrow at end

lineStartArrowWidth

466

MSOLINEENDWIDTH

MediumWidthArrow

Arrow at start

lineStartArrowLength

467

MSOLINEENDLENGTH

MediumLenArrow

Arrow at end

lineEndArrowWidth

468

MSOLINEENDWIDTH

MediumWidthArrow

Arrow at start

lineEndArrowLength

469

MSOLINEENDLENGTH

MediumLenArrow

Arrow at end

lineJoinStyle

470

MSOLINEJOIN

JoinRound

How to join lines

lineEndCapStyle

471

MSOLINECAP

EndCapFlat

How to end lines

fArrowheadsOK

507

BOOL

FALSE

Allow arrowheads if prop. is set

fLine

508

BOOL

TRUE

Any line?

fHitTestLine

509

BOOL

TRUE

Should we hit test lines?

lineFillShape

510

BOOL

TRUE

Register pattern on shape

fNoLineDrawDash

511

BOOL

FALSE

Draw a dashed line if no line


< > < >

Shadow Style

The interpretation of the transform properties depends on the type of shadow:

msoshadowOffset, msoshadowDouble:

Only the offset is used. It is interpreted as an absolute offset expressed in EMUs. The default corresponds to 1/36" in both X and Y (2 or 3 pixels on screen depending on monitor resolution). The offset is relative to the drawing axes (as msoshadowDrawing below, not msoshadowRich) so a shadow offset to the bottom right of the drawing is still offset (by the same amount) to the bottom right if the shape is rotated. The "double" case causes two shadows to be drawn, the first (lower) at the second offset and in the shadowHighlightColor. If the second offset is 0,0 it defaults to being the inverse of the first.

msoshadowRich:

The offsets and transformation properties are in absolute units measured relative to the shape on the drawing - the shadow moves with the shape, but anisotropic scaling of the shape changes the proportions of the shadow, not its angles. Compare with the following where such scaling scales the shadow in proportion too, thus changes the angle between (e.g.) a vertical line in the shape and it's shadow.

msoshadowShape:

The offsets and transformation properties are relative to the shape; 1.0 corresponds to the shape width/height as appropriate. The shadow is cast relative to the shape then scaled with the shape, so it moves with the shape. The units are simple numbers (ratios of the G unit space effectively). This transformation type is unnatural in real world terms, but behaves nicely in geometric terms. The offset elements of the property set are treated as fixed-point 16.16 values.

msoshadowDrawing:

A rich shadow cast onto a plane in drawing space. The transform is applied to the drawing coordinates of the shape and is thus expressed in EMUs. This shadow type enables creation of shadows from multiple objects, however the shadows may overlap higher (different) objects if the shadow plane and shape drawing planes overlap on the screen.

The shadowWeight parameter is used as in the perspective property set to apply addiitonal scaling to the perspective parameters - these are divided by the weight.

Shadow transformations are independent of the perspective transformation applied to a shape - either hte perspective transformation or the shadow transformation is used as appropriate.

Property

PID

Type

Default

Description

shadowType

512

MSOSHADOWTYPE

Offset

Type of effect

shadowColor

513

MSOCLR

0x808080

Foreground color

shadowHighlight

514

MSOCLR

0xCBCBCB

Embossed color

shadowCrMod

515

MSOCLR

undefined

Modification for BW views

shadowOpacity

516

LONG

1<<16

Fixed 16.16

shadowOffsetX

517

LONG

25400

Offset shadow

shadowOffsetY

518

LONG

25400

Offset shadow

shadowSecondOffsetX

519

LONG

0

Double offset shadow

shadowSecondOffsetY

520

LONG

0

Double offset shadow

shadowScaleXToX

521

LONG

1<<16

16.16

shadowScaleYToX

522

LONG

0

16.16

shadowScaleXToY

523

LONG

0

16.16

shadowScaleYToY

524

LONG

1<<16

16.16

shadowPerspectiveX

525

LONG

0

16.16 / weight

shadowPerspectiveY

526

LONG

0

16.16 / weight

shadowWeight

527

LONG

1<<8

scaling factor

shadowOriginX

528

LONG

0

shadowOriginY

529

LONG

0

fShadow

574

BOOL

FALSE

Any shadow?

fshadowObscured

575

BOOL

FALSE

Excel5-style shadow


< > < >

Perspective Style

This is just a 2D transformation matrix (3x3). Specifying peculiar values will cause the shape to render completely outside its geometry - normally clients will constrain the values to get reasonable results. The transformation may be applied at various times as the geometry is processed, this affects the behavior of the perspective which results in the same way as the corresponding shadow perspective types.

msoxformAbsolute

Equivalent to msoshadowRich

msoxformShape

Equivalent to msoshadowShape

msoxformDrawing

Equivalent to msoshadowDrawing


In the case of perspective the msoxformShape form is the default - the perspective will then scale proportionally with the overall shape scaling.

All parameters except the weight and offset elements are 16.16 fixed-point numbers. The offset is interpreted according to the perspective type, if the type is msoxformShape then the offset is assumed to be a 16.16 fixed point value, otherwise it is assumed to be an integral value (effectively a number of EMUs). The weight acts as an additional divisor for the perspectivePerspectiveX/Y elements - the values in the transformation matrix are obtained by dividing the property values by the weight, the default value of 256 gives a useful range of values for the msoxformShape case, for the other cases the weight should normally be around 1 to 256 times the size of the shape in the coordinate space.

Property

PID

Type

Default

Description

perspectiveType

576

MSOXFORMTYPE

Shape

Where transform applies

perspectiveOffsetX

577

LONG

0

The LONG values define a transformation matrix, effectively, each value is scaled by the perspectiveWeight parameter.

perspectiveOffsetY

578

LONG

0

perspectiveScaleXToX

579

LONG

1<<16

perspectiveScaleYToX

580

LONG

0

perspectiveScaleXToY

581

LONG

0

perspectiveScaleYToY

582

LONG

1<<16

perspectivePerspectiveX

583

LONG

0

perspectivePerspectiveY

584

LONG

0

perspectiveWeight

585

LONG

1<<8

Scaling factor

perspectiveOriginX

586

LONG

1<<15

perspectiveOriginY

587

LONG

1<<15

fPerspective

639

BOOL

FALSE

On/off


< > < >

3D Object

Material properties of a 3D object. A 3D effect overrides the fill and line effects and corresponding colors. Extrusion depths are always specified in absolute units.

Property

PID

Type

Default

Description

c3DSpecularAmt

640

LONG

0

Fixed-point 16.16

c3DDiffuseAmt

641

LONG

65536

Fixed-point 16.16

c3DShininess

642

LONG

5

Default gives OK results

c3DEdgeThickness

643

LONG

12700

Specular edge thickness

c3DExtrudeForward

644

LONG

0

Distance of extrusion in EMUs

c3DExtrudeBackward

645

LONG

457200

c3DExtrudePlane

646

LONG

0

Extrusion direction

c3DExtrusionColor

647

MSOCLR

FillThenLine

Basic color of extruded part of shape; the lighting model used will determine the exact shades used when rendering.

c3DCrMod

648

MSOCLR

undefined

Modification for BW views

f3D

700

BOOL

FALSE

Does this shape have a 3D effect?

fc3DMetallic

701

BOOL

0

Use metallic specularity?

fc3DUseExtrusionColor

702

BOOL

FALSE

fc3DLightFace

703

BOOL

TRUE


< > < >

3D Style

Properties of a 3D view; note that distances are in drawing units.

Property

PID

Type

Default

Description

c3DYRotationAngle

704

LONG

0

degrees (16.16) about y axis

c3DXRotationAngle

705

LONG

0

degrees (16.16) about x axis

c3DRotationAxisX

706

LONG

100

These specify the rotation axis; only their relative magnitudes matter.

c3DRotationAxisY

707

LONG

0

c3DRotationAxisZ

708

LONG

0

c3DRotationAngle

709

LONG

0

degrees (16.16) about axis

c3DRotationCenterX

710

LONG

0

rotation center x (16.16 or g-units)

c3DRotationCenterY

711

LONG

0

rotation center y (16.16 or g-units)

c3DRotationCenterZ

712

LONG

0

rotation center z (absolute (emus))

c3DRenderMode

713

MSO3DRENDERMODE

FullRender

Full,wireframe, or bcube

c3DTolerance

714

LONG

30000

pixels (16.16)

c3DXViewpoint

715

LONG

1250000

X view point (emus)

c3DYViewpoint

716

LONG

-1250000

Y view point (emus)

c3DZViewpoint

717

LONG

9000000

Z view distance (emus)

c3DOriginX

718

LONG

32768

c3DOriginY

719

LONG

-32768

c3DSkewAngle

720

LONG

-8847360

degree (16.16) skew angle

c3DSkewAmount

721

LONG

50

Percentage skew amount

c3DAmbientIntensity

722

LONG

20000

Fixed point intensity

c3DKeyX

723

LONG

50000

Key light source direc-

c3DKeyY

724

LONG

0

tion; only their relative

c3DKeyZ

725

LONG

10000

magnitudes matter

c3DKeyIntensity

726

LONG

38000

Fixed point intensity

c3DFillX

727

LONG

-50000

Fill light source direc-

c3DFillY

728

LONG

0

tion; only their relative

c3DFillZ

729

LONG

10000

magnitudes matter

c3DFillIntensity

730

LONG

38000

Fixed point intensity

fc3DConstrainRotation

763

BOOL

TRUE

fc3DRotationCenterAuto

764

BOOL

FALSE

fc3DParallel

765

BOOL

1

Parallel projection?

fc3DKeyHarsh

766

BOOL

1

Is key lighting harsh?

fc3DFillHarsh

767

BOOL

0

Is fill lighting harsh?


< > < >

Shape

Miscellaneous properties of a single shape which do not apply to group shapes.

Property

PID

Type

Default

Description

hspMaster

769

MSOHSP

NULL

master shape

cxstyle

771

MSOCXSTYLE

None

Type of connector

bWMode

772

MSOBWMODE

Automatic

Settings for modifications to be made when in different forms of black-and-white mode.

bWModePureBW

773

MSOBWMODE

Automatic

bWModeBW

774

MSOBWMODE

Automatic

fOleIcon

826

BOOL

FALSE

For OLE objects, whether the object is in icon form

fPreferRelativeResize

827

BOOL

FALSE

For UI only. Prefer relative resizing.

fLockShapeType

828

BOOL

FALSE

Lock the shape type (don't allow Change Shape)

fDeleteAttachedObject

830

BOOL

FALSE

fBackground

831

BOOL

FALSE

If TRUE, this is the background shape.


< > < >

Callout

Properties of a callout shape.

Property

PID

Type

Default

Description

spcot

832

MSOSPCOT

TwoSegment

Callout type

dxyCalloutGap

833

LONG

1/12 inch

Distance from box to first point.(EMUs)

spcoa

834

MSOSPCOA

Any

Callout angle

spcod

835

MSOSPCOD

Specified

Callout drop type

dxyCalloutDropSpecified

836

LONG

9 points

if msospcodSpecified, the actual drop distance

dxyCalloutLengthSpecified

837

LONG

0

if fCalloutLengthSpecified, the actual distance

fCallout

889

BOOL

FALSE

Is the shape a callout?

fCalloutAccentBar

890

BOOL

FALSE

does callout have accent bar

fCalloutTextBorder

891

BOOL

TRUE

does callout have a text border

fCalloutMinusX

892

BOOL

FALSE

fCalloutMinusY

893

BOOL

FALSE

fCalloutDropAuto

894

BOOL

FALSE

If true, then we occasionally invert the drop distance

fCalloutLengthSpecified

895

BOOL

FALSE

if true, we look at dxyCalloutLengthSpecified


< > < >

Group Shape

Miscellaneous shape properties that can apply to group shapes.

Property

PID

Type

Default

Description

wzName

896

WCHAR*

NULL

Shape Name (present only if explicitly set)

wzDescription

897

WCHAR*

NULL

alternate text

pihlShape

898

IHlink*

NULL

The hyperlink in the shape.

pWrapPolygonVertices

899

IMsoArray

NULL

The polygon that text will be wrapped around (Word)

dxWrapDistLeft

900

LONG

1/8 inch

Left wrapping distance from text (Word)

dyWrapDistTop

901

LONG

0

Top wrapping distance from text (Word)

dxWrapDistRight

902

LONG

1/8 inch

Right wrapping distance from text (Word)

dyWrapDistBottom

903

LONG

0

Bottom wrapping distance from text (Word)

lidRegroup

904

LONG

0

Regroup ID

fEditedWrap

953

BOOL

FALSE

Has the wrap polygon been edited?

fBehindDocument

954

BOOL

FALSE

Word-only (shape is behind text)

fOnDblClickNotify

955

BOOL

FALSE

Notify client on a double click

fIsButton

956

BOOL

FALSE

A button shape (i.e., clicking performs an action). Set for shapes with attached hyperlinks or macros.

fOneD

957

BOOL

FALSE

1D adjustment

fHidden

958

BOOL

FALSE

Do not display

fPrint

959

BOOL

TRUE

Print this shape


< > < >

Appendix A: Change History

Date

Change

1/11/96

Created the document. Left work to be done in the BStore and Complex shape properties.

1/23/97

Extensively updated and reorganized document. Added overview and shape hierarchy information. Added more complete shape property information.

4/15/97

Add details on compression of Metafile Blips. See section "Metafile/PICT Blips"


< > < >

Appendix B: Colors

Colors are always saved as four-byte LONG values. If the high byte is zero, then the low three bytes contain a normal RGB COLORREF. Otherwise, the value of the high byte is used as a bitfield of flags (notice that the values below are the indices of the bits that are set).

typedef enum
   {
   msocolorFlagPaletteIndex,  // PALETTEINDEX macro
   msocolorFlagPaletteRGB,    // PALETTERGB macro
   msocolorFlagSystemRGB,     // MSOSYSTEMRGB
   msocolorFlagSchemeIndex,   // MSOSCHEMECOLOR
   msocolorFlagSysIndex,      // MSOSYSCOLOR
   } MSOCOLORINDEX;
Windows defines the first two. The third (SystemRGB) is a flag that it set on an otherwise normal RGB value to indicate to the rendering engine to bypass its normal halftone dithering process and just render the color directly using Windows.

The presence of either of the last two flags indicates that the low three bytes are an index into a predefined array of colors. For SchemeIndex colors, the host application provides the translation to RGB colors when necessary (PowerPoint and Excel both use this). SysIndex colors are indices into colors tracked by Escher itself:

typedef enum
   {
   msosyscolorButtonFace,          // COLOR_BTNFACE
   msosyscolorWindowText,          // COLOR_WINDOWTEXT
   msosyscolorMenu,                // COLOR_MENU
   msosyscolorHighlight,           // COLOR_HIGHLIGHT
   msosyscolorHighlightText,       // COLOR_HIGHLIGHTTEXT
   msosyscolorCaptionText,         // COLOR_CAPTIONTEXT
   msosyscolorActiveCaption,       // COLOR_ACTIVECAPTION
   msosyscolorButtonHighlight,     // COLOR_BTNHIGHLIGHT
   msosyscolorButtonShadow,        // COLOR_BTNSHADOW
   msosyscolorButtonText,          // COLOR_BTNTEXT
   msosyscolorGrayText,            // COLOR_GRAYTEXT
   msosyscolorInactiveCaption,     // COLOR_INACTIVECAPTION
   msosyscolorInactiveCaptionText, // COLOR_INACTIVECAPTIONTEXT
   msosyscolorInfoBackground,      // COLOR_INFOBK
   msosyscolorInfoText,            // COLOR_INFOTEXT
   msosyscolorMenuText,            // COLOR_MENUTEXT
   msosyscolorScrollbar,           // COLOR_SCROLLBAR
   msosyscolorWindow,              // COLOR_WINDOW
   msosyscolorWindowFrame,         // COLOR_WINDOWFRAME
   msosyscolor3DLight,             // COLOR_3DLIGHT
   msosyscolorMax,                 // Count of system colors

   msocolorFillColor =0xF0,  // Use the fillColor property
   msocolorLineOrFillColor,  // Use the line color only if there is a line
   msocolorLineColor,        // Use the lineColor property
   msocolorShadowColor,      // Use the shadow color
   msocolorThis,             // Use this color (only valid as described below)
   msocolorFillBackColor,    // Use the fillBackColor property
   msocolorLineBackColor,    // Use the lineBackColor property
   msocolorFillThenLine,     // Use the fillColor unless no fill and line
   msocolorIndexMask =0xFF,  // Extract the color index

   msocolorProcessMask      =0xFFFF00, // All the processing bits
   msocolorModificationMask =0x0F00,   // Just the function
   msocolorModFlagMask      =0xF000,   // Just the additional flags
   msocolorDarken           =0x0100,   // Darken color by parameter/255
   msocolorLighten          =0x0200,   // Lighten color by parameter/255
   msocolorAdd              =0x0300,   // Add grey level RGB(param,param,param)
   msocolorSubtract         =0x0400,   // Subtract grey level RGB(p,p,p)
   msocolorReverseSubtract  =0x0500,   // Subtract from grey level RGB(p,p,p)
   /* In the following "black" means maximum component value, white minimum.
      The operation is per component, to guarantee white combine with
   msocolorGray */
   msocolorBlackWhite       =0x0600,   // Black if < uParam, else white (>=)
   msocolorInvert           =0x2000,   // Invert color (at the *end*)
   msocolorInvert128        =0x4000,   // Invert by toggling the top bit
   msocolorGray             =0x8000,   // Make the color gray (before the above!)
   msocolorBParamMask       =0xFF0000, // Parameter used as above
   msocolorBParamShift =16,            // To extract the parameter value
   }
MSOSYSCOLORINDEX;
< > < >

Appendix C: Shape Types

Internally, a shape type is defined as a fixed set of property values, the most important being the geometry of the shape (the pVertices property, etc.). Each shape stores in itself only those properties that differ from its shape type. When a shape is asked for a property that isn't in its local table, it looks in the shape type's table. If the shape type doesn't define a value for the property, then the property's default value is used.

In the file format, shapes store their shape types in the instance field of the msofbtSp record.

typedef enum
   {
   msosptMin = 0,
   msosptNotPrimitive = msosptMin,
   msosptRectangle = 1,
   msosptRoundRectangle = 2,
   msosptEllipse = 3,
   msosptDiamond = 4,
   msosptIsocelesTriangle = 5,
   msosptRightTriangle = 6,
   msosptParallelogram = 7,
   msosptTrapezoid = 8,
   msosptHexagon = 9,
   msosptOctagon = 10,
   msosptPlus = 11,
   msosptStar = 12,
   msosptArrow = 13,
   msosptThickArrow = 14,
   msosptHomePlate = 15,
   msosptCube = 16,
   msosptBalloon = 17,
   msosptSeal = 18,
   msosptArc = 19,
   msosptLine = 20,
   msosptPlaque = 21,
   msosptCan = 22,
   msosptDonut = 23,
   msosptTextSimple = 24,
   msosptTextOctagon = 25,
   msosptTextHexagon = 26,
   msosptTextCurve = 27,
   msosptTextWave = 28,
   msosptTextRing = 29,
   msosptTextOnCurve = 30,
   msosptTextOnRing = 31,
   msosptStraightConnector1 = 32,
   msosptBentConnector2 = 33,
   msosptBentConnector3 = 34,
   msosptBentConnector4 = 35,
   msosptBentConnector5 = 36,
   msosptCurvedConnector2 = 37,
   msosptCurvedConnector3 = 38,
   msosptCurvedConnector4 = 39,
   msosptCurvedConnector5 = 40,
   msosptCallout1 = 41,
   msosptCallout2 = 42,
   msosptCallout3 = 43,
   msosptAccentCallout1 = 44,
   msosptAccentCallout2 = 45,
   msosptAccentCallout3 = 46,
   msosptBorderCallout1 = 47,
   msosptBorderCallout2 = 48,
   msosptBorderCallout3 = 49,
   msosptAccentBorderCallout1 = 50,
   msosptAccentBorderCallout2 = 51,
   msosptAccentBorderCallout3 = 52,
   msosptRibbon = 53,
   msosptRibbon2 = 54,
   msosptChevron = 55,
   msosptPentagon = 56,
   msosptNoSmoking = 57,
   msosptSeal8 = 58,
   msosptSeal16 = 59,
   msosptSeal32 = 60,
   msosptWedgeRectCallout = 61,
   msosptWedgeRRectCallout = 62,
   msosptWedgeEllipseCallout = 63,
   msosptWave = 64,
   msosptFoldedCorner = 65,
   msosptLeftArrow = 66,
   msosptDownArrow = 67,
   msosptUpArrow = 68,
   msosptLeftRightArrow = 69,
   msosptUpDownArrow = 70,
   msosptIrregularSeal1 = 71,
   msosptIrregularSeal2 = 72,
   msosptLightningBolt = 73,
   msosptHeart = 74,
   msosptPictureFrame = 75,
   msosptQuadArrow = 76,
   msosptLeftArrowCallout = 77,
   msosptRightArrowCallout = 78,
   msosptUpArrowCallout = 79,
   msosptDownArrowCallout = 80,
   msosptLeftRightArrowCallout = 81,
   msosptUpDownArrowCallout = 82,
   msosptQuadArrowCallout = 83,
   msosptBevel = 84,
   msosptLeftBracket = 85,
   msosptRightBracket = 86,
   msosptLeftBrace = 87,
   msosptRightBrace = 88,
   msosptLeftUpArrow = 89,
   msosptBentUpArrow = 90,
   msosptBentArrow = 91,
   msosptSeal24 = 92,
   msosptStripedRightArrow = 93,
   msosptNotchedRightArrow = 94,
   msosptBlockArc = 95,
   msosptSmileyFace = 96,
   msosptVerticalScroll = 97,
   msosptHorizontalScroll = 98,
   msosptCircularArrow = 99,
   msosptNotchedCircularArrow = 100,
   msosptUturnArrow = 101,
   msosptCurvedRightArrow = 102,
   msosptCurvedLeftArrow = 103,
   msosptCurvedUpArrow = 104,
   msosptCurvedDownArrow = 105,
   msosptCloudCallout = 106,
   msosptEllipseRibbon = 107,
   msosptEllipseRibbon2 = 108,
   msosptFlowChartProcess = 109,
   msosptFlowChartDecision = 110,
   msosptFlowChartInputOutput = 111,
   msosptFlowChartPredefinedProcess = 112,
   msosptFlowChartInternalStorage = 113,
   msosptFlowChartDocument = 114,
   msosptFlowChartMultidocument = 115,
   msosptFlowChartTerminator = 116,
   msosptFlowChartPreparation = 117,
   msosptFlowChartManualInput = 118,
   msosptFlowChartManualOperation = 119,
   msosptFlowChartConnector = 120,
   msosptFlowChartPunchedCard = 121,
   msosptFlowChartPunchedTape = 122,
   msosptFlowChartSummingJunction = 123,
   msosptFlowChartOr = 124,
   msosptFlowChartCollate = 125,
   msosptFlowChartSort = 126,
   msosptFlowChartExtract = 127,
   msosptFlowChartMerge = 128,
   msosptFlowChartOfflineStorage = 129,
   msosptFlowChartOnlineStorage = 130,
   msosptFlowChartMagneticTape = 131,
   msosptFlowChartMagneticDisk = 132,
   msosptFlowChartMagneticDrum = 133,
   msosptFlowChartDisplay = 134,
   msosptFlowChartDelay = 135,
   msosptTextPlainText = 136,
   msosptTextStop = 137,
   msosptTextTriangle = 138,
   msosptTextTriangleInverted = 139,
   msosptTextChevron = 140,
   msosptTextChevronInverted = 141,
   msosptTextRingInside = 142,
   msosptTextRingOutside = 143,
   msosptTextArchUpCurve = 144,
   msosptTextArchDownCurve = 145,
   msosptTextCircleCurve = 146,
   msosptTextButtonCurve = 147,
   msosptTextArchUpPour = 148,
   msosptTextArchDownPour = 149,
   msosptTextCirclePour = 150,
   msosptTextButtonPour = 151,
   msosptTextCurveUp = 152,
   msosptTextCurveDown = 153,
   msosptTextCascadeUp = 154,
   msosptTextCascadeDown = 155,
   msosptTextWave1 = 156,
   msosptTextWave2 = 157,
   msosptTextWave3 = 158,
   msosptTextWave4 = 159,
   msosptTextInflate = 160,
   msosptTextDeflate = 161,
   msosptTextInflateBottom = 162,
   msosptTextDeflateBottom = 163,
   msosptTextInflateTop = 164,
   msosptTextDeflateTop = 165,
   msosptTextDeflateInflate = 166,
   msosptTextDeflateInflateDeflate = 167,
   msosptTextFadeRight = 168,
   msosptTextFadeLeft = 169,
   msosptTextFadeUp = 170,
   msosptTextFadeDown = 171,
   msosptTextSlantUp = 172,
   msosptTextSlantDown = 173,
   msosptTextCanUp = 174,
   msosptTextCanDown = 175,
   msosptFlowChartAlternateProcess = 176,
   msosptFlowChartOffpageConnector = 177,
   msosptCallout90 = 178,
   msosptAccentCallout90 = 179,
   msosptBorderCallout90 = 180,
   msosptAccentBorderCallout90 = 181,
   msosptLeftRightUpArrow = 182,
   msosptSun = 183,
   msosptMoon = 184,
   msosptBracketPair = 185,
   msosptBracePair = 186,
   msosptSeal4 = 187,
   msosptDoubleWave = 188,
   msosptActionButtonBlank = 189,
   msosptActionButtonHome = 190,
   msosptActionButtonHelp = 191,
   msosptActionButtonInformation = 192,
   msosptActionButtonForwardNext = 193,
   msosptActionButtonBackPrevious = 194,
   msosptActionButtonEnd = 195,
   msosptActionButtonBeginning = 196,
   msosptActionButtonReturn = 197,
   msosptActionButtonDocument = 198,
   msosptActionButtonSound = 199,
   msosptActionButtonMovie = 200,
   msosptHostControl = 201,
   msosptTextBox = 202,
   msosptMax,
   msosptNil = 0x0FFF,
 } MSOSPT;
< > < >

Appendix D: Miscellaneous Enumerated Types

// MSOSHAPEPATH
typedef enum
   {
   msoshapeLines,        // A line of straight segments
   msoshapeLinesClosed,  // A closed polygonal object
   msoshapeCurves,       // A line of Bezier curve segments
   msoshapeCurvesClosed, // A closed shape with curved edges
   msoshapeComplex,      // pSegmentInfo must be non-empty
   } MSOSHAPEPATH;

// MSOWRAPMODE
typedef enum
   {
   msowrapSquare,
   msowrapByPoints,
   msowrapNone,
   msowrapTopBottom,
   msowrapThrough,
   } MSOWRAPMODE;

// MSOBWMODE
typedef enum
   {
   msobwColor,          // only used for predefined shades
   msobwAutomatic,      // depends on object type
   msobwGrayScale,      // shades of gray only
   msobwLightGrayScale, // shades of light gray only
   msobwInverseGray,    // dark gray mapped to light gray, etc.
   msobwGrayOutline,    // pure gray and white
   msobwBlackTextLine,  // black text and lines, all else grayscale
   msobwHighContrast,   // pure black and white mode (no grays)
   msobwBlack,          // solid black
   msobwWhite,          // solid white
   msobwDontShow,       // object not drawn
   msobwNumModes        // number of Black and white modes
   } MSOBWMODE;

// MSOANCHOR
typedef enum
   {
   msoanchorTop, 
   msoanchorMiddle, 
   msoanchorBottom, 
   msoanchorTopCentered, 
   msoanchorMiddleCentered, 
   msoanchorBottomCentered,
   msoanchorTopBaseline,
   msoanchorBottomBaseline,
   msoanchorTopCenteredBaseline,
   msoanchorBottomCenteredBaseline
   } MSOANCHOR;

// MSOCDIR
typedef enum
   {
   msocdir0,       // Right
   msocdir90,      // Down
   msocdir180,     // Left
   msocdir270      // Up
   } MSOCDIR;

// MSOCXSTYLE  connector style
typedef enum
   {
   msocxstyleStraight = 0,
   msocxstyleBent,
   msocxstyleCurved,
   msocxstyleNone
   } MSOCXSTYLE;

// MSOTXFL -- text flow
typedef enum 
   {
   msotxflHorzN,           // Horizontal non-@
   msotxflTtoBA,           // Top to Bottom @-font
   msotxflBtoT,            // Bottom to Top non-@
   msotxflTtoBN,           // Top to Bottom non-@
   msotxflHorzA,           // Horizontal @-font
   msotxflVertN,           // Vertical, non-@
   } MSOTXFL;

// MSOTXDIR - text direction (needed for Bi-Di support)
typedef enum
   {
   msotxdirLTR,           // left-to-right text direction
   msotxdirRTL,           // right-to-left text direction
    msotxdirContext,      // context text direction
    } MSOTXDIR;

// MSOSPCOT -- Callout Type 
typedef enum
   {
   msospcotRightAngle = 1,
   msospcotOneSegment = 2,
   msospcotTwoSegment = 3,
   msospcotThreeSegment = 4,
   } MSOSPCOT;

// MSOSPCOA -- Callout Angle
typedef enum
   {
   msospcoaAny,
   msospcoa30,
   msospcoa45,
   msospcoa60,
   msospcoa90,
   msospcoa0,
   } MSOSPCOA;

// MSOSPCOD -- Callout Drop
typedef enum
   {
   msospcodTop,
   msospcodCenter,
   msospcodBottom,
   msospcodSpecified,
   } MSOSPCOD;

// MSOGEOTEXTALIGN  WordArt alignment
typedef enum
   {
   msoalignTextStretch,      /* Stretch each line of text to fit width. */
   msoalignTextCenter,       /* Center text on width. */
   msoalignTextLeft,         /* Left justify. */
   msoalignTextRight,        /* Right justify. */
   msoalignTextLetterJust,   /* Spread letters out to fit width. */
   msoalignTextWordJust,     /* Spread words out to fit width. */
   msoalignTextInvalid       /* Invalid */
   } MSOGEOTEXTALIGN;

// MSOBLIPFLAGS  flags for pictures
typedef enum
   {
   msoblipflagDefault = 0,
   msoblipflagComment = 0,   // Blip name is a comment
   msoblipflagFile,          // Blip name is a file name
   msoblipflagURL,           // Blip name is a full URL
   msoblipflagType = 3,      // Mask to extract type
   /* Or the following flags with any of the above. */
   msoblipflagDontSave = 4,  // A "dont" is the depression in the metal
                             // body work of an automobile caused when a
                             // cyclist violently thrusts his or her nose
                             // at it, thus a DontSave is another name for
                             // a cycle lane.
   msoblipflagDoNotSave = 4, // For those who prefer English
   msoblipflagLinkToFile = 8,
   } MSOBLIPFLAGS;

// MSO3DRENDERMODE
typedef enum
   {
   msoFullRender,      // Generate a full rendering
   msoWireframe,       // Generate a wireframe
   msoBoundingCube,    // Generate a bounding cube
   } MSO3DRENDERMODE;

// MSOXFORMTYPE
typedef enum
   {
   msoxformAbsolute,   // Apply transform in absolute space centered on shape
   msoxformShape,      // Apply transform to shape geometry
   msoxformDrawing     // Apply transform in drawing space
   } MSOXFORMTYPE;

// MSOSHADOWTYPE
typedef enum
   {
   msoshadowOffset,    // N pixel offset shadow
   msoshadowDouble,    // Use second offset too
   msoshadowRich,      // Rich perspective shadow (cast relative to shape)
   msoshadowShape,     // Rich perspective shadow (cast in shape space)
   msoshadowDrawing,   // Perspective shadow cast in drawing space
   msoshadowEmbossOrEngrave,
   } MSOSHADOWTYPE;

// MSODZTYPE - the type of a (length) measurement
typedef enum
   {
   msodztypeMin          = 0,
   msodztypeDefault      = 0,  // Default size, ignore the values
   msodztypeA            = 1,  // Values are in EMUs
   msodztypeV            = 2,  // Values are in pixels
   msodztypeShape        = 3,  // Values are 16.16 fractions of shape size
   msodztypeFixedAspect  = 4,  // Aspect ratio is fixed
   msodztypeAFixed       = 5,  // EMUs, fixed aspect ratio
   msodztypeVFixed       = 6,  // Pixels, fixed aspect ratio
   msodztypeShapeFixed   = 7,  // Proportion of shape, fixed aspect ratio
   msodztypeFixedAspectEnlarge
                         = 8,  // Aspect ratio is fixed, favor larger size
   msodztypeAFixedBig    = 9,  // EMUs, fixed aspect ratio
   msodztypeVFixedBig    = 10, // Pixels, fixed aspect ratio
   msodztypeShapeFixedBig= 11, // Proportion of shape, fixed aspect ratio
   msodztypeMax         = 11
   } MSODZTYPE;

// MSOFILLTYPE
typedef enum
   {
   msofillSolid,             // Fill with a solid color
   msofillPattern,           // Fill with a pattern (bitmap)
   msofillTexture,           // A texture (pattern with its own color map)
   msofillPicture,           // Center a picture in the shape
   msofillShade,             // Shade from start to end points
   msofillShadeCenter,       // Shade from bounding rectangle to end point
   msofillShadeShape,        // Shade from shape outline to end point
   msofillShadeScale,        // Similar to msofillShade, but the fillAngle
                             // is additionally scaled by the aspect ratio of
                             // the shape. If shape is square, it is the
                             // same as msofillShade.
   msofillShadeTitle,        // special type - shade to title ---  for PP 
   msofillBackground         // Use the background fill color/pattern
   } MSOFILLTYPE;

// MSOSHADETYPE  how to interpret the colors in a shaded fill.
typedef enum
   {
   msoshadeNone  = 0,        // Interpolate without correction between RGBs
   msoshadeGamma = 1,        // Apply gamma correction to colors
   msoshadeSigma = 2,        // Apply a sigma transfer function to position
   msoshadeBand  = 4,        // Add a flat band at the start of the shade
   msoshadeOneColor = 8,     // This is a one color shade

   /* A parameter for the band or sigma function can be stored in the top
      16 bits of the value - this is a proportion of *each* band of the
      shade to make flat (or the approximate equal value for a sigma
      function).  NOTE: the parameter is not used for the sigma function,
      instead a built in value is used.  This value should not be changed
      from the default! */
   msoshadeParameterShift = 16,
   msoshadeParameterMask  = 0xffff0000,

   msoshadeDefault = (msoshadeGamma|msoshadeSigma|
                     (16384<<msoshadeParameterShift))
   } MSOSHADETYPE;

//   MSOLINESTYLE - compound line style
typedef enum
   {
   msolineSimple,            // Single line (of width lineWidth)
   msolineDouble,            // Double lines of equal width
   msolineThickThin,         // Double lines, one thick, one thin
   msolineThinThick,         // Double lines, reverse order
   msolineTriple             // Three lines, thin, thick, thin
   } MSOLINESTYLE;

// MSOLINETYPE - how to "fill" the line contour
typedef enum
   {
   msolineSolidType,         // Fill with a solid color
   msolinePattern,           // Fill with a pattern (bitmap)
   msolineTexture,           // A texture (pattern with its own color map)
   msolinePicture            // Center a picture in the shape
   } MSOLINETYPE;

// MSOLINEDASHING - dashed line style
typedef enum
   {
   msolineSolid,              // Solid (continuous) pen
   msolineDashSys,            // PS_DASH system   dash style
   msolineDotSys,             // PS_DOT system   dash style
   msolineDashDotSys,         // PS_DASHDOT system dash style
   msolineDashDotDotSys,      // PS_DASHDOTDOT system dash style
   msolineDotGEL,             // square dot style
   msolineDashGEL,            // dash style
   msolineLongDashGEL,        // long dash style
   msolineDashDotGEL,         // dash short dash
   msolineLongDashDotGEL,     // long dash short dash
   msolineLongDashDotDotGEL   // long dash short dash short dash
   } MSOLINEDASHING;

// MSOLINEEND - line end effect
typedef enum
   {
   msolineNoEnd,
   msolineArrowEnd,
   msolineArrowStealthEnd,
   msolineArrowDiamondEnd,
   msolineArrowOvalEnd,
   msolineArrowOpenEnd,
   } MSOLINEEND;

// MSOLINEENDWIDTH - size of arrowhead
typedef enum
   {
   msolineNarrowArrow,
   msolineMediumWidthArrow,
   msolineWideArrow
   } MSOLINEENDWIDTH;

//   MSOLINEENDLENGTH - size of arrowhead
typedef enum
   {
   msolineShortArrow,
   msolineMediumLenArrow,
   msolineLongArrow
   } MSOLINEENDLENGTH;

//   MSOLINEJOIN - line join style.
typedef enum
   {
   msolineJoinBevel,     // Join edges by a straight line
   msolineJoinMiter,     // Extend edges until they join
   msolineJoinRound      // Draw an arc between the two edges
   } MSOLINEJOIN;

//   MSOLINECAP - line cap style (applies to ends of dash segments too).
typedef enum
   {
   msolineEndCapRound,   // Rounded ends - the default
   msolineEndCapSquare,  // Square protrudes by half line width
   msolineEndCapFlat     // Line ends at end point
   } MSOLINECAP;