emf.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * Dump an Enhanced Meta File
  3. *
  4. * Copyright 2005 Mike McCormack
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "config.h"
  21. #include <stdio.h>
  22. #include <fcntl.h>
  23. #include <stdarg.h>
  24. #include "winedump.h"
  25. #include "windef.h"
  26. #include "winbase.h"
  27. #include "wingdi.h"
  28. #include "gdiplusenums.h"
  29. typedef struct
  30. {
  31. WORD Type;
  32. WORD Flags;
  33. DWORD Size;
  34. DWORD DataSize;
  35. } EmfPlusRecordHeader;
  36. static const char *debugstr_wn(const WCHAR *wstr, unsigned int n)
  37. {
  38. static char buf[80];
  39. char *p;
  40. unsigned int i;
  41. if (!wstr) return "(null)";
  42. i = 0;
  43. p = buf;
  44. *p++ = '\"';
  45. while (i < n && i < sizeof(buf) - 2 && wstr[i])
  46. {
  47. if (wstr[i] < 127) *p++ = wstr[i];
  48. else *p++ = '.';
  49. i++;
  50. }
  51. *p++ = '\"';
  52. *p = 0;
  53. return buf;
  54. }
  55. static unsigned int read_int(const unsigned char *buffer)
  56. {
  57. return buffer[0]
  58. + (buffer[1]<<8)
  59. + (buffer[2]<<16)
  60. + (buffer[3]<<24);
  61. }
  62. #define EMRCASE(x) case x: printf("%-20s %08x\n", #x, length); break
  63. #define EMRPLUSCASE(x) case x: printf(" %-20s %04x %08x %08x\n", #x, header->Flags, header->Size, header->DataSize); break
  64. static unsigned offset = 0;
  65. static int dump_emfrecord(void)
  66. {
  67. const unsigned char* ptr;
  68. unsigned int type, length, i;
  69. ptr = PRD(offset, 8);
  70. if (!ptr) return -1;
  71. type = read_int(ptr);
  72. length = read_int(ptr + 4);
  73. switch(type)
  74. {
  75. case EMR_HEADER:
  76. {
  77. const ENHMETAHEADER *header = PRD(offset, sizeof(*header));
  78. printf("%-20s %08x\n", "EMR_HEADER", length);
  79. printf("bounds (%d,%d - %d,%d) frame (%d,%d - %d,%d) signature %#x version %#x bytes %#x records %#x\n"
  80. "handles %#x reserved %#x palette entries %#x px %dx%d mm %dx%d μm %dx%d opengl %d description %s\n",
  81. header->rclBounds.left, header->rclBounds.top, header->rclBounds.right, header->rclBounds.bottom,
  82. header->rclFrame.left, header->rclFrame.top, header->rclFrame.right, header->rclFrame.bottom,
  83. header->dSignature, header->nVersion, header->nBytes, header->nRecords, header->nHandles, header->sReserved,
  84. header->nPalEntries, header->szlDevice.cx, header->szlDevice.cy, header->szlMillimeters.cx,
  85. header->szlMillimeters.cy, header->szlMicrometers.cx, header->szlMicrometers.cy, header->bOpenGL,
  86. debugstr_wn((LPCWSTR)((const BYTE *)header + header->offDescription), header->nDescription));
  87. break;
  88. }
  89. EMRCASE(EMR_POLYBEZIER);
  90. EMRCASE(EMR_POLYGON);
  91. EMRCASE(EMR_POLYLINE);
  92. EMRCASE(EMR_POLYBEZIERTO);
  93. EMRCASE(EMR_POLYLINETO);
  94. EMRCASE(EMR_POLYPOLYLINE);
  95. EMRCASE(EMR_POLYPOLYGON);
  96. EMRCASE(EMR_SETWINDOWEXTEX);
  97. EMRCASE(EMR_SETWINDOWORGEX);
  98. EMRCASE(EMR_SETVIEWPORTEXTEX);
  99. EMRCASE(EMR_SETVIEWPORTORGEX);
  100. EMRCASE(EMR_SETBRUSHORGEX);
  101. EMRCASE(EMR_EOF);
  102. EMRCASE(EMR_SETPIXELV);
  103. EMRCASE(EMR_SETMAPPERFLAGS);
  104. EMRCASE(EMR_SETMAPMODE);
  105. EMRCASE(EMR_SETBKMODE);
  106. EMRCASE(EMR_SETPOLYFILLMODE);
  107. EMRCASE(EMR_SETROP2);
  108. EMRCASE(EMR_SETSTRETCHBLTMODE);
  109. EMRCASE(EMR_SETTEXTALIGN);
  110. EMRCASE(EMR_SETCOLORADJUSTMENT);
  111. EMRCASE(EMR_SETTEXTCOLOR);
  112. EMRCASE(EMR_SETBKCOLOR);
  113. EMRCASE(EMR_OFFSETCLIPRGN);
  114. EMRCASE(EMR_MOVETOEX);
  115. EMRCASE(EMR_SETMETARGN);
  116. EMRCASE(EMR_EXCLUDECLIPRECT);
  117. case EMR_INTERSECTCLIPRECT:
  118. {
  119. const EMRINTERSECTCLIPRECT *clip = PRD(offset, sizeof(*clip));
  120. printf("%-20s %08x\n", "EMR_INTERSECTCLIPRECT", length);
  121. printf("rect %d,%d - %d, %d\n",
  122. clip->rclClip.left, clip->rclClip.top,
  123. clip->rclClip.right, clip->rclClip.bottom);
  124. break;
  125. }
  126. EMRCASE(EMR_SCALEVIEWPORTEXTEX);
  127. EMRCASE(EMR_SCALEWINDOWEXTEX);
  128. EMRCASE(EMR_SAVEDC);
  129. EMRCASE(EMR_RESTOREDC);
  130. EMRCASE(EMR_SETWORLDTRANSFORM);
  131. EMRCASE(EMR_MODIFYWORLDTRANSFORM);
  132. EMRCASE(EMR_SELECTOBJECT);
  133. EMRCASE(EMR_CREATEPEN);
  134. EMRCASE(EMR_CREATEBRUSHINDIRECT);
  135. EMRCASE(EMR_DELETEOBJECT);
  136. EMRCASE(EMR_ANGLEARC);
  137. EMRCASE(EMR_ELLIPSE);
  138. EMRCASE(EMR_RECTANGLE);
  139. EMRCASE(EMR_ROUNDRECT);
  140. EMRCASE(EMR_ARC);
  141. EMRCASE(EMR_CHORD);
  142. EMRCASE(EMR_PIE);
  143. EMRCASE(EMR_SELECTPALETTE);
  144. EMRCASE(EMR_CREATEPALETTE);
  145. EMRCASE(EMR_SETPALETTEENTRIES);
  146. EMRCASE(EMR_RESIZEPALETTE);
  147. EMRCASE(EMR_REALIZEPALETTE);
  148. EMRCASE(EMR_EXTFLOODFILL);
  149. EMRCASE(EMR_LINETO);
  150. EMRCASE(EMR_ARCTO);
  151. EMRCASE(EMR_POLYDRAW);
  152. EMRCASE(EMR_SETARCDIRECTION);
  153. EMRCASE(EMR_SETMITERLIMIT);
  154. EMRCASE(EMR_BEGINPATH);
  155. EMRCASE(EMR_ENDPATH);
  156. EMRCASE(EMR_CLOSEFIGURE);
  157. EMRCASE(EMR_FILLPATH);
  158. EMRCASE(EMR_STROKEANDFILLPATH);
  159. EMRCASE(EMR_STROKEPATH);
  160. EMRCASE(EMR_FLATTENPATH);
  161. EMRCASE(EMR_WIDENPATH);
  162. EMRCASE(EMR_SELECTCLIPPATH);
  163. EMRCASE(EMR_ABORTPATH);
  164. case EMR_GDICOMMENT:
  165. {
  166. printf("%-20s %08x\n", "EMR_GDICOMMENT", length);
  167. /* Handle EMF+ records */
  168. if (length >= 16 && !memcmp((char*)PRD(offset + 12, sizeof(unsigned int)), "EMF+", 4))
  169. {
  170. const EmfPlusRecordHeader *header;
  171. const unsigned int *data_size;
  172. offset += 8;
  173. length -= 8;
  174. data_size = PRD(offset, sizeof(*data_size));
  175. printf("data size = %x\n", *data_size);
  176. offset += 8;
  177. length -= 8;
  178. while (length >= sizeof(*header))
  179. {
  180. header = PRD(offset, sizeof(*header));
  181. switch(header->Type)
  182. {
  183. EMRPLUSCASE(EmfPlusRecordTypeInvalid);
  184. EMRPLUSCASE(EmfPlusRecordTypeHeader);
  185. EMRPLUSCASE(EmfPlusRecordTypeEndOfFile);
  186. EMRPLUSCASE(EmfPlusRecordTypeComment);
  187. EMRPLUSCASE(EmfPlusRecordTypeGetDC);
  188. EMRPLUSCASE(EmfPlusRecordTypeMultiFormatStart);
  189. EMRPLUSCASE(EmfPlusRecordTypeMultiFormatSection);
  190. EMRPLUSCASE(EmfPlusRecordTypeMultiFormatEnd);
  191. EMRPLUSCASE(EmfPlusRecordTypeObject);
  192. EMRPLUSCASE(EmfPlusRecordTypeClear);
  193. EMRPLUSCASE(EmfPlusRecordTypeFillRects);
  194. EMRPLUSCASE(EmfPlusRecordTypeDrawRects);
  195. EMRPLUSCASE(EmfPlusRecordTypeFillPolygon);
  196. EMRPLUSCASE(EmfPlusRecordTypeDrawLines);
  197. EMRPLUSCASE(EmfPlusRecordTypeFillEllipse);
  198. EMRPLUSCASE(EmfPlusRecordTypeDrawEllipse);
  199. EMRPLUSCASE(EmfPlusRecordTypeFillPie);
  200. EMRPLUSCASE(EmfPlusRecordTypeDrawPie);
  201. EMRPLUSCASE(EmfPlusRecordTypeDrawArc);
  202. EMRPLUSCASE(EmfPlusRecordTypeFillRegion);
  203. EMRPLUSCASE(EmfPlusRecordTypeFillPath);
  204. EMRPLUSCASE(EmfPlusRecordTypeDrawPath);
  205. EMRPLUSCASE(EmfPlusRecordTypeFillClosedCurve);
  206. EMRPLUSCASE(EmfPlusRecordTypeDrawClosedCurve);
  207. EMRPLUSCASE(EmfPlusRecordTypeDrawCurve);
  208. EMRPLUSCASE(EmfPlusRecordTypeDrawBeziers);
  209. EMRPLUSCASE(EmfPlusRecordTypeDrawImage);
  210. EMRPLUSCASE(EmfPlusRecordTypeDrawImagePoints);
  211. EMRPLUSCASE(EmfPlusRecordTypeDrawString);
  212. EMRPLUSCASE(EmfPlusRecordTypeSetRenderingOrigin);
  213. EMRPLUSCASE(EmfPlusRecordTypeSetAntiAliasMode);
  214. EMRPLUSCASE(EmfPlusRecordTypeSetTextRenderingHint);
  215. EMRPLUSCASE(EmfPlusRecordTypeSetTextContrast);
  216. EMRPLUSCASE(EmfPlusRecordTypeSetInterpolationMode);
  217. EMRPLUSCASE(EmfPlusRecordTypeSetPixelOffsetMode);
  218. EMRPLUSCASE(EmfPlusRecordTypeSetCompositingMode);
  219. EMRPLUSCASE(EmfPlusRecordTypeSetCompositingQuality);
  220. EMRPLUSCASE(EmfPlusRecordTypeSave);
  221. EMRPLUSCASE(EmfPlusRecordTypeRestore);
  222. EMRPLUSCASE(EmfPlusRecordTypeBeginContainer);
  223. EMRPLUSCASE(EmfPlusRecordTypeBeginContainerNoParams);
  224. EMRPLUSCASE(EmfPlusRecordTypeEndContainer);
  225. EMRPLUSCASE(EmfPlusRecordTypeSetWorldTransform);
  226. EMRPLUSCASE(EmfPlusRecordTypeResetWorldTransform);
  227. EMRPLUSCASE(EmfPlusRecordTypeMultiplyWorldTransform);
  228. EMRPLUSCASE(EmfPlusRecordTypeTranslateWorldTransform);
  229. EMRPLUSCASE(EmfPlusRecordTypeScaleWorldTransform);
  230. EMRPLUSCASE(EmfPlusRecordTypeRotateWorldTransform);
  231. EMRPLUSCASE(EmfPlusRecordTypeSetPageTransform);
  232. EMRPLUSCASE(EmfPlusRecordTypeResetClip);
  233. EMRPLUSCASE(EmfPlusRecordTypeSetClipRect);
  234. EMRPLUSCASE(EmfPlusRecordTypeSetClipPath);
  235. EMRPLUSCASE(EmfPlusRecordTypeSetClipRegion);
  236. EMRPLUSCASE(EmfPlusRecordTypeOffsetClip);
  237. EMRPLUSCASE(EmfPlusRecordTypeDrawDriverString);
  238. EMRPLUSCASE(EmfPlusRecordTypeStrokeFillPath);
  239. EMRPLUSCASE(EmfPlusRecordTypeSerializableObject);
  240. EMRPLUSCASE(EmfPlusRecordTypeSetTSGraphics);
  241. EMRPLUSCASE(EmfPlusRecordTypeSetTSClip);
  242. EMRPLUSCASE(EmfPlusRecordTotal);
  243. default:
  244. printf(" unknown EMF+ record %x %04x %08x\n", header->Type, header->Flags, header->Size);
  245. break;
  246. }
  247. if (length<sizeof(*header) || header->Size%4)
  248. return -1;
  249. length -= sizeof(*header);
  250. offset += sizeof(*header);
  251. for (i=0; i<header->Size-sizeof(*header); i+=4)
  252. {
  253. if (i%16 == 0)
  254. printf(" ");
  255. if (!(ptr = PRD(offset, 4))) return -1;
  256. length -= 4;
  257. offset += 4;
  258. printf("%08x ", read_int(ptr));
  259. if ((i % 16 == 12) || (i + 4 == header->Size - sizeof(*header)))
  260. printf("\n");
  261. }
  262. }
  263. return 0;
  264. }
  265. break;
  266. }
  267. EMRCASE(EMR_FILLRGN);
  268. EMRCASE(EMR_FRAMERGN);
  269. EMRCASE(EMR_INVERTRGN);
  270. EMRCASE(EMR_PAINTRGN);
  271. case EMR_EXTSELECTCLIPRGN:
  272. {
  273. const EMREXTSELECTCLIPRGN *clip = PRD(offset, sizeof(*clip));
  274. const RGNDATA *data = (const RGNDATA *)clip->RgnData;
  275. DWORD i, rc_count = 0;
  276. const RECT *rc;
  277. if (length >= sizeof(*clip) + sizeof(*data))
  278. rc_count = data->rdh.nCount;
  279. printf("%-20s %08x\n", "EMR_EXTSELECTCLIPRGN", length);
  280. printf("mode %d, rects %d\n", clip->iMode, rc_count);
  281. for (i = 0, rc = (const RECT *)data->Buffer; i < rc_count; i++, rc++)
  282. printf(" (%d,%d)-(%d,%d)", rc->left, rc->top, rc->right, rc->bottom);
  283. if (rc_count != 0) printf("\n");
  284. break;
  285. }
  286. EMRCASE(EMR_BITBLT);
  287. case EMR_STRETCHBLT:
  288. {
  289. const EMRSTRETCHBLT *blt = PRD(offset, sizeof(*blt));
  290. const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blt + blt->offBmiSrc);
  291. printf("%-20s %08x\n", "EMR_STRETCHBLT", length);
  292. printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
  293. "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
  294. blt->rclBounds.left, blt->rclBounds.top, blt->rclBounds.right, blt->rclBounds.bottom,
  295. blt->xDest, blt->yDest, blt->cxDest, blt->cyDest,
  296. blt->xSrc, blt->ySrc, blt->cxSrc, blt->cySrc, blt->dwRop,
  297. blt->xformSrc.eM11, blt->xformSrc.eM12, blt->xformSrc.eM21,
  298. blt->xformSrc.eM22, blt->xformSrc.eDx, blt->xformSrc.eDy,
  299. blt->crBkColorSrc, blt->iUsageSrc, blt->offBmiSrc, blt->cbBmiSrc,
  300. blt->offBitsSrc, blt->cbBitsSrc);
  301. printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
  302. "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
  303. bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
  304. bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
  305. bmih->biClrUsed, bmih->biClrImportant);
  306. break;
  307. }
  308. EMRCASE(EMR_MASKBLT);
  309. EMRCASE(EMR_PLGBLT);
  310. EMRCASE(EMR_SETDIBITSTODEVICE);
  311. EMRCASE(EMR_STRETCHDIBITS);
  312. case EMR_EXTCREATEFONTINDIRECTW:
  313. {
  314. const EMREXTCREATEFONTINDIRECTW *pf = PRD(offset, sizeof(*pf));
  315. const LOGFONTW *plf = &pf->elfw.elfLogFont;
  316. printf("%-20s %08x\n", "EMR_EXTCREATEFONTINDIRECTW", length);
  317. printf("(%d %d %d %d %x out %d clip %x quality %d charset %d) %s %s %s %s\n",
  318. plf->lfHeight, plf->lfWidth,
  319. plf->lfEscapement, plf->lfOrientation,
  320. plf->lfPitchAndFamily,
  321. plf->lfOutPrecision, plf->lfClipPrecision,
  322. plf->lfQuality, plf->lfCharSet,
  323. debugstr_wn(plf->lfFaceName, LF_FACESIZE),
  324. plf->lfWeight > 400 ? "Bold" : "",
  325. plf->lfItalic ? "Italic" : "",
  326. plf->lfUnderline ? "Underline" : "");
  327. break;
  328. }
  329. EMRCASE(EMR_EXTTEXTOUTA);
  330. case EMR_EXTTEXTOUTW:
  331. {
  332. const EMREXTTEXTOUTW *etoW = PRD(offset, sizeof(*etoW));
  333. const int *dx = (const int *)((const BYTE *)etoW + etoW->emrtext.offDx);
  334. printf("%-20s %08x\n", "EMR_EXTTEXTOUTW", length);
  335. printf("bounds (%d,%d - %d,%d) mode %#x x_scale %f y_scale %f pt (%d,%d) rect (%d,%d - %d,%d) flags %#x, %s\n",
  336. etoW->rclBounds.left, etoW->rclBounds.top, etoW->rclBounds.right, etoW->rclBounds.bottom,
  337. etoW->iGraphicsMode, etoW->exScale, etoW->eyScale,
  338. etoW->emrtext.ptlReference.x, etoW->emrtext.ptlReference.y,
  339. etoW->emrtext.rcl.left, etoW->emrtext.rcl.top,
  340. etoW->emrtext.rcl.right, etoW->emrtext.rcl.bottom,
  341. etoW->emrtext.fOptions,
  342. debugstr_wn((LPCWSTR)((const BYTE *)etoW + etoW->emrtext.offString), etoW->emrtext.nChars));
  343. printf("dx_offset %u {", etoW->emrtext.offDx);
  344. for (i = 0; i < etoW->emrtext.nChars; ++i)
  345. {
  346. printf("%d", dx[i]);
  347. if (i != etoW->emrtext.nChars - 1)
  348. putchar(',');
  349. }
  350. printf("}\n");
  351. break;
  352. }
  353. EMRCASE(EMR_POLYBEZIER16);
  354. EMRCASE(EMR_POLYGON16);
  355. EMRCASE(EMR_POLYLINE16);
  356. EMRCASE(EMR_POLYBEZIERTO16);
  357. EMRCASE(EMR_POLYLINETO16);
  358. EMRCASE(EMR_POLYPOLYLINE16);
  359. EMRCASE(EMR_POLYPOLYGON16);
  360. EMRCASE(EMR_POLYDRAW16);
  361. EMRCASE(EMR_CREATEMONOBRUSH);
  362. EMRCASE(EMR_CREATEDIBPATTERNBRUSHPT);
  363. EMRCASE(EMR_EXTCREATEPEN);
  364. EMRCASE(EMR_POLYTEXTOUTA);
  365. EMRCASE(EMR_POLYTEXTOUTW);
  366. EMRCASE(EMR_SETICMMODE);
  367. EMRCASE(EMR_CREATECOLORSPACE);
  368. EMRCASE(EMR_SETCOLORSPACE);
  369. EMRCASE(EMR_DELETECOLORSPACE);
  370. EMRCASE(EMR_GLSRECORD);
  371. EMRCASE(EMR_GLSBOUNDEDRECORD);
  372. EMRCASE(EMR_PIXELFORMAT);
  373. EMRCASE(EMR_DRAWESCAPE);
  374. EMRCASE(EMR_EXTESCAPE);
  375. EMRCASE(EMR_STARTDOC);
  376. EMRCASE(EMR_SMALLTEXTOUT);
  377. EMRCASE(EMR_FORCEUFIMAPPING);
  378. EMRCASE(EMR_NAMEDESCAPE);
  379. EMRCASE(EMR_COLORCORRECTPALETTE);
  380. EMRCASE(EMR_SETICMPROFILEA);
  381. EMRCASE(EMR_SETICMPROFILEW);
  382. case EMR_ALPHABLEND:
  383. {
  384. const EMRALPHABLEND *blend = PRD(offset, sizeof(*blend));
  385. const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blend + blend->offBmiSrc);
  386. printf("%-20s %08x\n", "EMR_ALPHABLEND", length);
  387. printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
  388. "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
  389. blend->rclBounds.left, blend->rclBounds.top, blend->rclBounds.right, blend->rclBounds.bottom,
  390. blend->xDest, blend->yDest, blend->cxDest, blend->cyDest,
  391. blend->xSrc, blend->ySrc, blend->cxSrc, blend->cySrc, blend->dwRop,
  392. blend->xformSrc.eM11, blend->xformSrc.eM12, blend->xformSrc.eM21,
  393. blend->xformSrc.eM22, blend->xformSrc.eDx, blend->xformSrc.eDy,
  394. blend->crBkColorSrc, blend->iUsageSrc, blend->offBmiSrc, blend->cbBmiSrc,
  395. blend->offBitsSrc, blend->cbBitsSrc);
  396. printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
  397. "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
  398. bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
  399. bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
  400. bmih->biClrUsed, bmih->biClrImportant);
  401. break;
  402. }
  403. EMRCASE(EMR_SETLAYOUT);
  404. EMRCASE(EMR_TRANSPARENTBLT);
  405. EMRCASE(EMR_RESERVED_117);
  406. EMRCASE(EMR_GRADIENTFILL);
  407. EMRCASE(EMR_SETLINKEDUFI);
  408. EMRCASE(EMR_SETTEXTJUSTIFICATION);
  409. EMRCASE(EMR_COLORMATCHTOTARGETW);
  410. EMRCASE(EMR_CREATECOLORSPACEW);
  411. default:
  412. printf("%u %08x\n", type, length);
  413. break;
  414. }
  415. if ( (length < 8) || (length % 4) )
  416. return -1;
  417. length -= 8;
  418. offset += 8;
  419. for(i=0; i<length; i+=4)
  420. {
  421. if (i%16 == 0)
  422. printf(" ");
  423. if (!(ptr = PRD(offset, 4))) return -1;
  424. offset += 4;
  425. printf("%08x ", read_int(ptr));
  426. if ( (i % 16 == 12) || (i + 4 == length))
  427. printf("\n");
  428. }
  429. return 0;
  430. }
  431. enum FileSig get_kind_emf(void)
  432. {
  433. const ENHMETAHEADER* hdr;
  434. hdr = PRD(0, sizeof(*hdr));
  435. if (hdr && hdr->iType == EMR_HEADER && hdr->dSignature == ENHMETA_SIGNATURE)
  436. return SIG_EMF;
  437. return SIG_UNKNOWN;
  438. }
  439. void emf_dump(void)
  440. {
  441. offset = 0;
  442. while (!dump_emfrecord());
  443. }