Hosted by uCoz

Microsoft Windows Metafile

Microsoft Windows Metafile Format (WMF) используется для хранения векторных и растровых изображений и графических данных в памяти или в дисковых файлах. Векторные данные хранимые WMF-файлом описывают команды Microsoft Windows Graphics Device Interface (GDI). Система интерпретирует и воспроизводит эти команды в контексте отображения, используя Windows API функцию PlayMetaFile(). Растровые изображения в WMF файле могут содержаться в формате Microsoft Device Dependent Bitmap (DDB), или Device Independent Bitmap (DIB).

В Windows, метафайлы обычно создаются и воспроизводятся в памяти. Если данные метафайла слишком велики, что бы держать их в памяти, или должены быть сохранены прежде, чем приложение завершилось, то они могут быть записаны на диск в формате WMF или EMF и воспроизведены обратно с диска. Максимальный размер метафайла – 4 Гб.

WMF – это базовый 16-битный формат, который появлялся в Windows 2.0. Формат EMF является 32-битной дополненной переработкой формата WMF. EMF расширил функциональное назначение WMF, включая цветную палитру и полную поддержку для всех 32-битовых команд GDI. Win32 API (Windows 95 и Windows NT) и 32-битный OLE поддерживает как WMF, так и EMF файлы. Win16 API и 16-битный OLE поддерживает только WMF.

Хотя формат Windows Metafile поддерживают большое количество приложений, работающих на других платформах, основное его назначение – это обмен графической информацией между Windows приложениями. Например, Adobe's Encapsulated PostScript (EPS) поддерживает использование включенного Windows Metafile, когда требуется сохранить векторные данные.

При использовании метафайлов в Windows или OS/2, нет необходимости писать специальные программы для выполнения грамматического разбора их содержимого, можно вызывать имеющиеся в Windows API функции. Поскольку есть обширная документация Microsoft и IBM по использованию метафайлов в Windows и OS/2, эта статья рассмотрит структуру и синтаксический анализ метафайлов без использования Windows API.

Все структуры данных и определения типов данных связанные с файлами WMF находятся в заголовочном файле WINDOWS.H. Для Win32 SDK определения WMF и EMF содержатся в WINUSER.H WINGDI.H. Оба этих SDK пригодны для всех C и C++ компиляторов, которые поддерживают разработку Windows приложений.

Структура Файлов

Метафайл состоит из одного или двух информационных заголовков и массива переменной длины, который содержит информацию о реальных GDI командах.

Есть четыре разновидности метафайлов standard, placeable, clipboard, и enhanced.

Метафайлы standardсодержат 18-байтовый заголовок WMF, после которого следуют одна или более записей GDI команд. Последняя запись в файле содержит информацию, указывающую, что достигнут конец данных.

Рисунок Microsoft Windows Metafile-1: Standard metafile format

Метафайлыplaceableсодержат дополнительный 22-байтовый заголовок, который содержит информацию, описывающую положение изображения на устройстве отображения. После него следует стандартный 18-байтовый заголовок WMF и командные записи GDI.

Figure Microsoft Windows Metafile-2: Placeable metafile format

Метафайлы clipboardсодержат дополнительный 8-байтовый (Win16) или 16-байтовый заголовок (Win32), который предшествует стандартному заголовку метафайла и описывает режим отображения и размер изображения.

Figure Microsoft Windows Metafile-3: Clipboard metafile format

Enhancedметафайлы, как и предыдущие, содержат записи GDI команд, но с другим заголовком, являющимся объединением заголовков placeable и clipboard метафайлов. EMF заголовок также содержит строку описания файла и программируемую палитру.

Figure Microsoft Windows Metafile-4: Enhanced metafile format

Описание заголовков

Стандартный заголовок Windows metafile занимает 18 байт и его стуктура выглядит следующим образом:

typedef struct _WindowsMetaHeader
{
  WORD  FileType;       /* Расположение метафайла (0=память, 1=диск) */
  WORD  HeaderSize;     /* Размер заголовка в словах (WORDS) (всегда = 9) */
  WORD  Version;        /* Версия Microsoft Windows */
  DWORD FileSize;       /* Общий размер метафайла в словах */
  WORD  NumOfObjects;   /* Количество объектов в файле */
  DWORD MaxRecordSize;  /* Размер самой большой записи в словах */
  WORD  NumOfParams;    /* Не используется (всегда 0) */
} WMFHEAD;

FileTypeсодержит флаг, указывающий местоположение данных метафайла. FileType=0 указывает, что метафайл находится в памяти,FileType=1 указывает, что метафайл находится на диске.

HeaderSizeсодержит размер заголовка метафайла в словах, и всегда равно 9.

Versionуказывает версию Microsoft Windows создавшую этот метафайл. Это значение должно быть всегда указано. Например, в метафайле созданном Windows 3.0 and 3.1, Version=0x0300.

FileSizeопределяет общий размер файла в словах.

NumOfObjects определяет количество объектов в файле.

MaxRecordSizeопределяет максимально возможный размер объекта, содержащегося в файле.

NumOfParams не используется. Всегда имеет значение 0.

Placeable метафайлы были разработаны корпорацией Aldus, как нестандартный путь указать параметры отображения на устройстве отображения. Placeable метафайлы широко распространены, но не поддерживаются Windows API. Для воспроизведения placeable метафайла используя Windows API необходимо переделать его заголовок. Каждый Placeable заголовок содержит 22 байта и выглядит следующим образом:


typedef struct _PlaceableMetaHeader
{
  DWORD Key;           /* Ключик (всегда 9AC6CDD7h) */
  WORD  Handle;        /* (всегда 0) */
  SHORT Left;          /* Левая координата */
  SHORT Top;           /* Верхняя координата */
  SHORT Right;         /* Правая координата */
  SHORT Bottom;        /* Нижняя координата */
  WORD  Inch;          /* Кол-во логических единиц в дюйме */
  DWORD Reserved;      /* Не используется (всегда 0) */
  WORD  Checksum;      /* Контрольная сумма для предыдущих 10 слов */
} PLACEABLEMETAHEADER;

Key содержит специальное значение, идентифицируцие заголовок и всегда равное 9AC6CDD7h.

Handle исспользуется при расположении метафайла в памяти. Когда файл находится на диске, всегда равен 0.

Left, Top, Right, and Bottom содержит координаты изображения на устройстве отображения в логических единицах. (1 логическая единица 1/1440 дюйма, 720 логических единиц = 1/2 дюйма).

Inchсодержит количество логических единиц в дюйме для данного изображения. Обычно это 1440 логических единиц в дюйме.

Reserved не используется и всегда = 0.

Checksumсодержит контрольную сумму предыдущих 10 слов заголовка. Вычисляется посредством XOR кодирования:

PLACEABLEMETAHEADER pmh; 
pmh.Checksum = 0;
pmh.Checksum ^= (pmh.Key & 0x0000FFFFUL);
pmh.Checksum ^= ((pmh.Key & 0xFFFF0000UL) >> 16);
pmh.Checksum ^= pmh.Handle; 
pmh.Checksum ^= pmh.Left;
pmh.Checksum ^= pmh.Top; 
pmh.Checksum ^= pmh.Right;
pmh.Checksum ^= pmh.Bottom; 
pmh.Checksum ^= pmh.Inch;
pmh.Checksum ^= (pmh.Reserved & 0x0000FFFFUL);
pmh.Checksum ^= ((pmh.Reserved & 0xFFFF0000UL) >> 16);
или: PLACEABLEMETAHEADER *pmh; WORD *ptr; pmh->Checksum = 0; for (ptr = (WORD *) pmh; ptr < (WORD *)pmh->Checksum; ptr++) pmh->Checksum ^= *ptr;

Clipboardметафайлы используют формат заголовка стандартных метафайлов, но ему предшествует 8- или 16-байтный заголовок:


typedef struct _Clipboard16MetaHeader
{
  SHORT MappingMode; /* Units used to playback metafile */
  SHORT Width;       /* Width of the metafile */
  SHORT Height;      /* Height of the metafile */
  WORD  Handle;      /* Handle to the metafile in memory */
} CLIPBOARD16METAHEADER;

typedef struct _Clipboard32MetaHeader
{
  LONG  MappingMode; /* Единицы, использующиеся для отображения */
  LONG  Width;       /* Ширина */
  LONG  Height;      /* Высота */
  DWORD Handle;      /* Указатель на область памяти */
} CLIPBOARD32METAHEADER;

MappingMode указывает тип координат для отбражения. Может принимать следующие значения:

Значение

Mapping Mode

Одна логическая единица

1

Text

Один пиксел

2

Low Metric

0.1 миллиметра

3

High Metric

0.01 миллиметра

4

Low English

0.01 дюйм

5

High English

0.001 дюйм

6

Twips

1/1440 дюйма

7

Isotropic

Определяется приложением (aspect ratio preserved)

8

Anisotropic

Определяется приложением (aspect ratio not preserved)

Width и Height размер изображения с учетом значения MappingMode

Enhancedметафайлы являются новой и расширенной 32-битной версией стандартных метафайлов. Только 32-разрядный Windows API (Win32) поддерживает EMF файлы.

Строковые данные в EMF файлах используют Unicode кодировку.

Заголовок EMF содержит 80 байт и выглядит так:


typedef struct _EnhancedMetaHeader
{
    DWORD RecordType;       /* Тип записи */
    DWORD RecordSize;       /* Размер записи в байтах */
    LONG  BoundsLeft;       /* Левая граница */
    LONG  BoundsRight;      /* Правая граница */
    LONG  BoundsTop;        /* Верхняя граница */
    LONG  BoundsBottom;     /* Нижняя граница */
    LONG  FrameLeft;        /* Left side of inclusive picture frame */
    LONG  FrameRight;       /* Right side of inclusive picture frame */
    LONG  FrameTop;         /* Top side of inclusive picture frame */
    LONG  FrameBottom;      /* Bottom side of inclusive picture frame */
    DWORD Signature;        /* ID (Всегда 0x464D4520) */
    DWORD Version;          /* Версия метафайла */
    DWORD Size;             /* Размер файла  в байтах */
    DWORD NumOfRecords;     /* Количество записей в файле */
    WORD  NumOfHandles;     /* Number of handles in the handle table */
    WORD  Reserved;         /* Не используется (Всегда 0) */
    DWORD SizeOfDescrip;    /* Размер строки описания в словах */
    DWORD OffsOfDescrip;    /* Смещение строки описания */
    DWORD NumPalEntries;    /* Количество цветов в палитре */
    LONG  WidthDevPixels;   /* Ширина устройства в пикселях */
    LONG  HeightDevPixels;  /* Высота устройства в пикселях */
    LONG  WidthDevMM;       /* Ширина устройства в миллиметрах */
    LONG  HeightDevMM;      /* Высота устройства в миллиметрах */
	//Если версия Windows >= 4 то есть еще поля
    DWORD   cbPixelFormat;      // размер PIXELFORMATDESCRIPTOR
                                //Равен 0 если структура отсутствует
    DWORD   offPixelFormat;     // сммещение PIXELFORMATDESCRIPTOR
                                // Равен 0 если структура отсутсвует
    DWORD   bOpenGL;            // 1 если OpenGL присутствуют
                                // команды OpenGL
} ENHANCEDMETAHEADER;

RecordType идентифицирует EMF запись. Для заголовка всегда 00000001h.

RecordSizeразмер заголовка в байтах.

BoundsLeft, BoundsRight, BoundsTop, и BoundsBottom указывает размер изображения в координатах X, Y, ширина, и высота. BoundsTop и BoundsBottom должны быть больше чем BoundsLeft и BoundsRight соответственно.

FrameLeft, FrameRight, FrameTop, и FrameBottom указывает размер страницы включающей изображение в координатах X, Y, ширина, и высота.FrameTop и FrameBottom должны быть больше чемFrameLeft и FrameRight соответственно.

Signature идентификатор. Всегда равен 0x464D4520.

Version версия EMF файла. Версия 1.0 выглядит как 0x00000100.

Size размер файла в байтах.

NumOfRecords< количество записей метафайла, влючая заголовочную запись.

NumOfHandlesколичество заголовков, используемых метафайлом при размещении его в памяти. Всегда равен 0 для дисковых файлов.

Reserved не используется. Всегда 0.

SizeOfDescrip количество 16-битных Unicode символов строки описания, включая все NULL символы. Если параметр равен 0, то строки описания в файле нет.

OffsOfDescrip положение строки описания от начала файла. Если параметр равен 0, то строки описания в файле нет.

NumPalEntries количество цветов в палитре. Палитра, если она присутствует должна находиться в конечной записи файла. Если парамет равен 0, палитра отсутствует.

WidthDevPixels и HeightDevPixels ширина и высота устройства отображения в пикселах.

WidthDevMM и HeightDevMM ширина и высота устройства отображения в миллиметрах.

Строка описанния EMF файла.

Строка описания EMF файла представляет собой набор Unicode символов. Размер строки практически не ограничен (может содержать более 2 билионов символов). Формат строки является "double NULL-terminated" где каждый первый 0 является признаком конца подстроки. Типичная строка оописания выглядит следующим образом:

"Pain Paint 1.5\0Eating at Polly's\0\0"

Структура Записей стандартных Метафайлов

После заголовка всех типов метафайлов следуют записи описания данных. Структура записей METARECORD описана в файле WINDOWS.H и выглядит следующим образом:


typedef struct _StandardMetaRecord
{
    DWORD Size;          /* общий размер записи в словах */
    WORD  Function;      /* Номер функции */
    WORD  Parameters[];  /* Параметры функции */
} WMFRECORD;

Size общий размер записи в словах, включая поляSize и Function. Минимальное значение для этого поля равно 3.

Function номер GDI функции вызываемой для воспроизведения записи. Младший байт указывает номер функции, старший – количество параметров функции в словах. Например, значение 0x0213 указывает на функцию LineTo() (0x13) и на то, что функции необходимо два параметра.

Параметры, используемые функцией, следуют в обратном порядке. Например, функции LineTo() необходимы параметры X и Y, но в записи они следуют, как Y и X.

Все параметры при сохранении метафайла приведены к типу WORD, Поэтому необходимо преобразовать их тип перед использованием в функции.

Последняя запись метафайлов всегда содержит функцию с номером 0000h, поле Size равно 0003h, отсутствует массив параметров. Эта запись является заглушкой и показывает, что достигнут конец данных. (Q99334)

Например, запись, описывающая функцию LineTo должна отобразить линию от текущей точки до точки, описанной в записи:

Size           5        /* 5 слов в записи */
Function       0x0213   /* номер функции LineTo */
Parameters[0]  50       /* координата Y */
Parameters[1]  100      /* координата X */

Эти данные приведут к вызову GDI функции LineTo():

LineTo(hDC, 100, 5);    

Некоторые функции содержат не только массив параметров, но и структуры с данными. Например, запись, описывающая функцию BitBlt использует сохраненное растровое изображениев формате Device Dependent Bitmap (DDB). Структура записи BitBlt в метафайлах Windows 2.x выглядит следующим образом:


typedef struct _BitBltRecord
{
    DWORD     Size;             /* Размер записи в словах */
    WORD      Function;         /* Номер функции (0x0922) */
    WORD      RasterOp;        /* старшее слово растровой операции */
    WORD      YSrcOrigin;       /* Y-координата источника */
    WORD      XSrcOrigin;       /* X-координата источника */
    WORD      YDest;            /* ширина отображения */
    WORD      XDest;            /* высота отображения */
    WORD      YDestOrigin;      /* Y-координата отображения */
    WORD      XDestOrigin;      /* X-координата отображения */
    /* DDB Bitmap */
    DWORD     Width;            /* ширина растра в пикселях */
    DWORD     Height;           /* высота растра в строках */
    DWORD     BytesPerLine;     /* разрешение */
    WORD      NumColorPlanes;   /* количество цветов в палитре */
    WORD      BitsPerPixel;     /* количество бит на пиксель */
	RGBTRIPLE Bitmap[];         /* растр */
} BITBLTRECORD;

Массив bitmap состоит из структур RGBTRIPLE:


typedef struct _RGBTriple
{
    BYTE Red;
    BYTE Green;
    BYTE Blue;
} RGBTRIPLE;

DDB формат поддерживается Windows 2.x но не совместим с Windows 3.0 и старше. Windows 3.0 описывает функцию DibBitBlt и Device Independent Bitmap (DIB):


typedef struct _DibBitBltRecord
{
DWORD     Size;             /* Размер записи в словах */
    WORD      Function;         /* Номер функции (0x0922) */
    WORD      RasterOp;         /* старшее слово растровой операции */
    WORD      YSrcOrigin;       /* Y-координата источника */
    WORD      XSrcOrigin;       /* X-координата источника */
    WORD      YDest;            /* ширина отображения */
    WORD      XDest;            /* высота отображения */
    WORD      YDestOrigin;      /* Y-координата отображения */
    WORD      XDestOrigin;      /* X-координата отображения */
    /* DIB Bitmap */
	DWORD     Width;            /* ширина растра в пикселях */
    DWORD     Height;           /* высота растра в строках */
    DWORD     BytesPerLine;     /* разрешение */
    WORD      NumColorPlanes;   /* количество цветов в палитре */
    WORD      BitsPerPixel;     /* количество бит на пиксель */
    DWORD   Compression;      /* Формат сжатия */
    DWORD   SizeImage;        /* Размер растра в байтах */
    LONG    XPelsPerMeter;    /* расрешение по горизонтали */
    LONG    YPelsPerMeter;    /* разрешение по вертикали */
    DWORD   ClrUsed;          /* Количетсво используемых  цветов */
    DWORD   ClrImportant;     /* Количество важных цветов */
    RGBQUAD Bitmap[];         /* растр */
} DIBBITBLTRECORD;

Массив bitmapсостоит из структур RGBQUAD:


typedef struct _RGBQuad
{
    BYTE Red;
    BYTE Green;
    BYTE Blue;
    BYTE Reserved;
} RGBQUAD;

Другая специфическая запись метафайлов, заслуживающая внимание это Escape (0x0626). API Windows 3.x поддерживает 64 escape-последовательностей, которые могут содержаться в метафайле. Но на практике каждая escape-последовательность работает по разному, в зависимости от типа принтера.

Ниже приведен список GDI функций, поддержка которых в метафайлах была изменена с Microsoft Windows 3.0:

AnimatePalette
BitBlt
CreatePalette
CreatePatternBrush
DeleteObject
DibBitBlt
DibCreatePatternBrush
DibStretchBlt
RealizePalette
ResizePalette
StretchBlt

Не все GDI функции могут быть использованы в метафайлах, а только те, которые используют заголовок устройства отображения в качестве первого параметра.

Структура записей Enhanced метафайлов

Enhanced метафайлы имеют свою собственную структуру, которая похожа на структуру записей стандартных метафайолв, но является полностью 32-разрядной:


typedef struct _EnhancedMetaRecord
{
    DWORD Function;      /* Номер функции  (определено в WINGDI.H) */
    DWORD Size;          /* Общий размер записи в байтах */
    DWORD Parameters[];   /* параметры */
} EMFRECORD;

Фунции, поддерживаемые EMFописаны в WINDOWS.H и начинаются с преффикса EMR_*.

Size общий размер записи в байтах, включая поля Size и Function. Минимальное значение равно 8.

Parameters массив параметров, используемых GDI функцией. Параметры следуют в обратном порядке, чем в вызове функции. Например, два параметра для LineTo(X, Y) будут следовать, как Y и X.

EMF метафайл может состоять из любых из 97 типов записей, но 2 типа должны присутствовать обязательно. Это заголовочная запись (1) и Заглушка (14).

Запись

Номер

Запись

Номер

EMR_ABORTPATH

68

EMR_POLYLINE

4

EMR_ANGLEARC

41

EMR_POLYLINE16

87

EMR_ARC

45

EMR_POLYLINETO

6

EMR_ARCTO

55

EMR_POLYLINETO16

89

EMR_BEGINPATH

59

EMR_POLYPOLYGON

8

EMR_BITBLT

76

EMR_POLYPOLYGON16

91

EMR_CHORD

46

EMR_POLYPOLYLINE

7

EMR_CLOSEFIGURE

61

EMR_POLYPOLYLINE16

90

EMR_CREATEBRUSHINDIRECT

39

EMR_POLYTEXTOUTA

96

EMR_CREATEDIBPATTERNBRUSHPT

94

EMR_POLYTEXTOUTW

97

EMR_CREATEMONOBRUSH

93

EMR_REALIZEPALETTE

52

EMR_CREATEPALETTE

49

EMR_RECTANGLE

43

EMR_CREATEPEN

38

EMR_RESIZEPALETTE

51

EMR_DELETEOBJECT

40

EMR_RESTOREDC

34

EMR_ELLIPSE

42

EMR_ROUNDRECT

44

EMR_ENDPATH

60

EMR_SAVEDC

33

EMR_EOF

14

EMR_SCALEVIEWPORTEXTEX

31

EMR_EXCLUDECLIPRECT

29

EMR_SCALEWINDOWEXTEX

32

EMR_EXTCREATEFONTINDIRECTW

82

EMR_SELECTCLIPPATH

67

EMR_EXTCREATEPEN

95

EMR_SELECTOBJECT

37

EMR_EXTFLOODFILL

53

EMR_SELECTPALETTE

48

EMR_EXTSELECTCLIPRGN

75

EMR_SETARCDIRECTION

57

EMR_EXTTEXTOUTA

83

EMR_SETBKCOLOR

25

EMR_EXTTEXTOUTW

84

EMR_SETBKMODE

18

EMR_FILLPATH

62

EMR_SETBRUSHORGEX

13

EMR_FILLRGN

71

EMR_SETCOLORADJUSTMENT

23

EMR_FLATTENPATH

65

EMR_SETDIBITSTODEVICE

80

EMR_FRAMERGN

72

EMR_SETMAPMODE

17

EMR_GDICOMMENT

70

EMR_SETMAPPERFLAGS

16

EMR_HEADER

1

EMR_SETMETARGN

28

EMR_INTERSECTCLIPRECT

30

EMR_SETMITERLIMIT

58

EMR_INVERTRGN

73

EMR_SETPALETTEENTRIES

50

EMR_LINETO

54

EMR_SETPIXELV

15

EMR_MASKBLT

78

EMR_SETPOLYFILLMODE

19

EMR_MODIFYWORLDTRANSFORM

36

EMR_SETROP2

20

EMR_MOVETOEX

27

EMR_SETSTRETCHBLTMODE

21

EMR_OFFSETCLIPRGN

26

EMR_SETTEXTALIGN

22

EMR_PAINTRGN

74

EMR_SETTEXTCOLOR

24

EMR_PIE

47

EMR_SETVIEWPORTEXTEX

11

EMR_PLGBLT

79

EMR_SETVIEWPORTORGEX

12

EMR_POLYBEZIER

2

EMR_SETWINDOWEXTEX

9

EMR_POLYBEZIER16

85

EMR_SETWINDOWORGEX

10

EMR_POLYBEZIERTO

5

EMR_SETWORLDTRANSFORM

35

EMR_POLYBEZIERTO16

88

EMR_STRETCHBLT

77

EMR_POLYDRAW

56

EMR_STRETCHDIBITS

81

EMR_POLYDRAW16

92

EMR_STROKEANDFILLPATH

63

EMR_POLYGON

3

EMR_STROKEPATH

64

EMR_POLYGON16

86

EMR_WIDENPATH

66

Таблица цветов

EMF файл также может содержать таблицу цветов, используемую при отображении изображения. По умолчанию, файл не содержит таблицу цветов и использует системную палитру.

Поле NumPalEntries заголовка EMF файла указывает на количество цветов в таблице и равно 0 если таблица отсутствует. Если таблица присутствует, то она находится в конечной записи-заглушке:


typedef struct _EndOfRecord
{
    DWORD  Function;        /* Номер функции (14) */
    DWORD  Size;            /* Размер записи в байтах */
    DWORD  NumPalEntries;   /* ККоличество  цветов палитре */
    DWORD  OffPalEntries;   /* Смещение первого  цвета */
    PALENT Palette[];       /* Палитра */
    DWORD  OffToEOF;        /* Смещение  о тначала записи */
} ENDOFRECORD;

Function Номер функции. Для заглушки всегда равен 14.

Size общий размер записи в байтах. Для записи не содержаещй палитры равен 20.

NumPalEntries количество цветов в палитре. Значение переписывается из поля NumPalEntries заголовка.

OffPalEntries указывает позицию первого значения палитры от начала записи.

Palette массив стурктур PALENT. Поле отсутвует, если палитры нет.

OffToEOF смещение от начала записи. Равно значению поля Size.

Структура PALENT:


typedef struct _PaletteEntry
{
    BYTE Red;       /* */
    BYTE Green;     /* */
    BYTE Blue;      /* */
    BYTE Flags;     /* */
} PALENT;

Red, Green, и Blue содержат цветовые компоненты определения цвета.

Flags может принимать значения:

0x01

цвет используется для анимации

0x02

 

0x04

Цвет не соответствует системной палитре

GDI Comment

Одной из важных особенностей EMF формата является возможность использования скрытых данных в файле. В отличие от escape-последовательностей WMF, комментарий GDI может содержать любой тип данных, полностью независящий от внешних устройств

GDICOMMENT запись имеет формат:


typedef struct _GdiCommentRecord
{
    DWORD   Function;      /* Номер функции (70) */
    DWORD   Size;          /* Размер записи в байтах */
    DWORD   SizeOfData;    /* Размер данных в байтах */
    BYTE    Data[];        /* Комментарий */        
} GDICOMMENTRECORD;

Function номер функции. Для GDI комментария всегда равен 70.

Size Общий размер записи в байтах. Для пустой записи комментария равен 12

SizeOfData Размер записи Data в байтах.

Data сам комментарий.

GDI комментарии могут содержать несколько определенных типов комментариев:

Тип комментария

Содержимое

Public

Содержит метафайл

BeginGroup/EndGroup

Содержит коллекцию метафайлов и строк описания

Multiformats

Содержит метафайл и Encapsulated PostScript данные

Заголовок Public комментария выглядит следующим образом:


typedef struct _GdiCommentMetafile
{
    DWORD Identifier;       /* ID комментария(0x43494447) */
    DWORD Comment;          /* ID типа комментария (0x80000001) */
    DWORD Version;          /* Версия метафайла */
    DWORD Checksum;         /* Контрольная сумма метафайла */
    DWORD Flags;            /* Флаг (0) */
    DWORD Size;             /* Размер данных в байтах */
} GDICOMMENTMETAFILE;

Identifier содержит значение 0x43494447 идентифицирующее комментарий.

Comment содержит значение 0x80000001 идентифицирующее структуру Public комментария

Version содержит значение версии метафайла. Обычно это 0x00000001.

Checksum контрольная сумма данных метафайла.

Flags всегда содержит 0.

Size Размер данных метафайла в байтах.

BeginGroup / EndGroup комментарии содержат один или несколько EMF объектов. BeginGroup указывает начало списка, EMF записей, и заканчивается EndGroup структурой. Такие группы могут быть вложенными.


typedef struct _GdiCommentBeginGroup
{
    DWORD Identifier;       /* ID комментария(0x43494447) */
    DWORD Comment;          /* BeginGroup ID (0x00000002) */
    LONG  BoundsLeft;       /* Левая точка  прямоугольника */
    LONG  BoundsRight;      /* Правая точка прямоугольника */
    LONG  BoundsTop;        /* Верхняя точка прямоугольника */
    LONG  BoundsBottom;     /* Нижняя точка прямоугольника */
    DWORD SizeOfDescrip;    /* Количество символов в описании */     
} GDICOMMENTBEGINGROUP;

Identifier содержит значение 0x43494447 идентифицирующее комментарий

Comment содержит значение 0x00000002 идентифицирующее структуру BeginGroup комментария.

BoundsLeft, BoundsRight, BoundsTop, и BoundsBottom определяют область вывода изображения.

SizeOfDescrip количество Unicode символов строки описания. Строка,если она присутствует, должна следовать сразу за заголовком. Поле равно 0, если строки нет.

EndGroup содержит только идентификационный заголовок без данных:


typedef struct _GdiCommentEndGroup
{
    DWORD Identifier;       /* комментария ID (0x43494447) */
    DWORD Comment;          /* EndGroup ID (0x00000003) */
} GDICOMMENTENDGROUP;

Identifier содержит значение 0x43494447 идентифицирующее комментарий.

Comment содержит значение 0x00000003 идентифицирующее структуру EndGroup комментария.

Multiformats комментарий используется для хранения метафайлов и Encapsulated PostScript (EPS) данных. Этот комментарий начинается с заголовка, затем идет одно или последовательност изображений:


typedef struct _GdiCommentMultiFormats
{
    DWORD Identifier;       /* ID комментария(0x43494447) */
    DWORD Comment;          /* Multiformats ID (0x40000004) */
LONG  BoundsLeft;       /* Левая точка  прямоугольника */
    LONG  BoundsRight;      /* Правая точка прямоугольника */
    LONG  BoundsTop;        /* Верхняя точка прямоугольника */
    LONG  BoundsBottom;     /* Нижняя точка прямоугольника */
    DWORD NumFormats;       /* Количество объектов в структуре */
    EMRFORMAT Data[];       /* Массим объектов */
} GDICOMMENTMULTIFORMATS

Identifier содержит значение 0x43494447 идентифицирующее комментарий.

Comment содержит значение 0x40000004 идентифицирующее структуру Multiformats комментария.

BoundsLeft, BoundsRight, BoundsTop, и BoundsBottom определяют область вывода изображения.

NumFormats кличество структур EMRFORMAT.

Data сами структуры EMRFORMAT.


typedef struct _EmrFormat
{
    DWORD Signature;    /* Идентификатор формата */
    DWORD Version;      /* Версия формата */
    DWORD Data;         /* Размер данных в байтах */
    DWORD OffsetToData; /* Смещение в байтах */
} EMRFORMAT;

Signature содержит значение 0x464D4520 идентифицирующее структуру метафайла, и значение 0x46535045 идентифицирующее Encapsulated PostScript файл.

Version версия данных. Для EPS содержит версию EPS файла. Для EMF обычно равно 0x00000001.

Data размер содержащейся структуры в байтах.

OffsetToData содержит смещение данных относительно начала структуры GDICOMMENTMULTIFORMATS.


Copyright © 1996, 1994 O'Reilly & Associates, Inc. All Rights Reserved.