home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_16 / EMF / EmfDC.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-16  |  25.5 KB  |  918 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : emfdc.cpp                                                             //
  10. //  Description: EMF decompiler                                                         //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define  STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16. #define _WIN32_WINNT 0x0500
  17. #define WINVER         0x500
  18.  
  19. #include <windows.h>
  20. #include <assert.h>
  21. #include <commctrl.h>
  22. #include <fstream.h>
  23.  
  24. #include "..\..\include\treeview.h"
  25. #include "..\..\include\mmfile.h"
  26.  
  27. #include "EmfDC.h"
  28. #include "Formator.h"
  29. #include "OutPipe.h"
  30.  
  31. #include "resource.h"
  32.  
  33.  
  34. const DicItem Dic_BkMode[] =
  35. {
  36.     pair(OPAQUE),
  37.     pair(TRANSPARENT),
  38.     dummyitem
  39. };
  40.  
  41.  
  42. const DicItem Dic_ArcDirection[] =
  43. {
  44.     pair(AD_COUNTERCLOCKWISE),
  45.     pair(AD_CLOCKWISE),
  46.     dummyitem
  47. };
  48.  
  49.  
  50. const DicItem Dic_PolyFillMode[] =
  51. {
  52.     pair(ALTERNATE),
  53.     pair(WINDING),
  54.     dummyitem
  55. };
  56.  
  57.  
  58. const DicItem Dic_MapMode[] =
  59. {
  60.     pair(MM_ANISOTROPIC), 
  61.     pair(MM_HIENGLISH), 
  62.     pair(MM_HIMETRIC), 
  63.     pair(MM_ISOTROPIC), 
  64.     pair(MM_LOENGLISH), 
  65.     pair(MM_LOMETRIC), 
  66.     pair(MM_TEXT), 
  67.     pair(MM_TWIPS),
  68.     dummyitem
  69. };
  70.  
  71.  
  72. const DicItem Dic_StretchBltMode[] =
  73.     pair(STRETCH_ANDSCANS), 
  74.     pair(STRETCH_DELETESCANS), 
  75.     pair(STRETCH_ORSCANS),
  76.     pair(STRETCH_HALFTONE), 
  77.     pair(BLACKONWHITE),
  78.     pair(COLORONCOLOR),
  79.     pair(HALFTONE),
  80.     pair(WHITEONBLACK),
  81.     dummyitem
  82. };
  83.  
  84.  
  85. const DicItem Dic_ICMMode [] =
  86. {
  87.     pair(ICM_ON),
  88.     pair(ICM_OFF),
  89.     pair(ICM_QUERY),
  90.     dummyitem
  91. };
  92.  
  93.  
  94. const DicItem Dic_RegionOper [] =
  95. {
  96.     pair(RGN_AND),
  97.     pair(RGN_XOR),
  98.     pair(RGN_COPY), 
  99.     pair(RGN_DIFF), 
  100.     pair(RGN_OR),
  101.     dummyitem
  102. };
  103.  
  104.  
  105. const DicItem Dic_TransCombineMode [] =
  106. {
  107.     pair(MWT_IDENTITY),
  108.     pair(MWT_LEFTMULTIPLY),
  109.     pair(MWT_RIGHTMULTIPLY),
  110.     dummyitem
  111. };
  112.  
  113.  
  114. const DicItem Dic_ROP2 [] =
  115. {
  116.     pair(R2_BLACK), 
  117.     pair(R2_COPYPEN), 
  118.     pair(R2_MASKNOTPEN), 
  119.     pair(R2_MASKPEN), 
  120.     pair(R2_MASKPENNOT),
  121.     pair(R2_MERGENOTPEN), 
  122.     pair(R2_MERGEPEN), 
  123.     pair(R2_MERGEPENNOT), 
  124.     pair(R2_NOP), 
  125.     pair(R2_NOT), 
  126.     pair(R2_NOTCOPYPEN), 
  127.     pair(R2_NOTMASKPEN), 
  128.     pair(R2_NOTMERGEPEN), 
  129.     pair(R2_NOTXORPEN), 
  130.     pair(R2_WHITE), 
  131.     pair(R2_XORPEN),
  132.     dummyitem
  133. };
  134.  
  135.  
  136. const DicItem Dic_FloodFillMode [] =
  137. {
  138.     pair(FLOODFILLBORDER),
  139.     pair(FLOODFILLSURFACE),
  140.     dummyitem
  141. };
  142.  
  143.  
  144. const DicItem Dic_PenStyle[] =
  145. {
  146. //    tripod(PS_COSMETIC,     PS_TYPE_MASK),
  147.     tripod(PS_GEOMETRIC,    PS_TYPE_MASK),
  148.  
  149.     tripod(PS_SOLID,        PS_STYLE_MASK),
  150.     tripod(PS_DASH,            PS_STYLE_MASK),
  151.     tripod(PS_DOT,            PS_STYLE_MASK),
  152.     tripod(PS_DASHDOT,        PS_STYLE_MASK),
  153.     tripod(PS_DASHDOTDOT,    PS_STYLE_MASK),
  154.     tripod(PS_NULL,            PS_STYLE_MASK),
  155.     tripod(PS_INSIDEFRAME,    PS_STYLE_MASK),
  156.     tripod(PS_USERSTYLE,    PS_STYLE_MASK),
  157.     tripod(PS_ALTERNATE,    PS_STYLE_MASK),
  158.  
  159. //    tripod(PS_ENDCAP_ROUND, PS_ENDCAP_MASK),
  160.     tripod(PS_ENDCAP_SQUARE,PS_ENDCAP_MASK),
  161.     tripod(PS_ENDCAP_FLAT,  PS_ENDCAP_MASK),
  162.     
  163. //    tripod(PS_JOIN_ROUND,   PS_JOIN_MASK),
  164.     tripod(PS_JOIN_BEVEL,   PS_JOIN_MASK),
  165.     tripod(PS_JOIN_MITER,   PS_JOIN_MASK),
  166.     
  167.     dummyitem
  168. };
  169.  
  170.  
  171. const DicItem Dic_ROP3[] =
  172. {
  173.     pair(BLACKNESS), 
  174.     pair(DSTINVERT), 
  175.     pair(MERGECOPY), 
  176.     pair(MERGEPAINT), 
  177.     pair(NOTSRCCOPY), 
  178.     pair(NOTSRCERASE), 
  179.     pair(PATCOPY), 
  180.     pair(PATINVERT), 
  181.     pair(PATPAINT), 
  182.     pair(SRCAND), 
  183.     pair(SRCCOPY), 
  184.     pair(SRCERASE), 
  185.     pair(SRCINVERT), 
  186.     pair(SRCPAINT), 
  187.     pair(WHITENESS), 
  188.     dummyitem
  189. };
  190.  
  191.  
  192. const DicItem Dic_DIBColor [] =
  193. {
  194.     pair(DIB_PAL_COLORS),
  195. //    pair(DIB_PAL_INDICES),
  196.     pair(DIB_RGB_COLORS),
  197.     dummyitem
  198. };
  199.  
  200. typedef struct
  201. {
  202.     unsigned      type;
  203.  
  204.     const TCHAR * funcname;
  205.     const DicItem * dic;
  206. }    EmrInfo;
  207.  
  208.  
  209. const DicItem Dic_TextAlign [] = 
  210. {
  211.     tripod(TA_NOUPDATECP,     0x01),
  212.     tripod(TA_UPDATECP,       0x01),
  213.  
  214.     tripod(TA_LEFT,              0x06),
  215.     tripod(TA_RIGHT,          0x06),
  216.     tripod(TA_CENTER,         0x06),
  217.  
  218.     tripod(TA_TOP,            0x18),
  219.     tripod(TA_BOTTOM,         0x18),
  220.     tripod(TA_BASELINE,       0x18),
  221.  
  222.     tripod(TA_RTLREADING,     0x100),
  223.  
  224.     dummyitem
  225. };
  226.  
  227.  
  228. const DicItem Dic_ExtTextOption [] = 
  229. {
  230.     tripod(ETO_OPAQUE,            ETO_OPAQUE),
  231.     tripod(ETO_CLIPPED,            ETO_CLIPPED),
  232.     tripod(ETO_GLYPH_INDEX,        ETO_GLYPH_INDEX),
  233.     tripod(ETO_RTLREADING,        ETO_RTLREADING),
  234.     tripod(ETO_NUMERICSLOCAL,    ETO_NUMERICSLOCAL),
  235.     tripod(ETO_NUMERICSLATIN,    ETO_NUMERICSLATIN),
  236.     tripod(ETO_IGNORELANGUAGE,    ETO_IGNORELANGUAGE),
  237.     tripod(ETO_PDY,                ETO_PDY),
  238.     dummyitem
  239. };
  240.  
  241.  
  242. const EmrInfo Pattern [] = 
  243. {
  244.     { EMR_SETWINDOWEXTEX          , "SetWindowExtEx"        "(hDC, %d, %d, NULL);" },
  245.     { EMR_SETWINDOWORGEX          , "SetWindowOrgEx"        "(hDC, %d, %d, NULL);" },
  246.     { EMR_SETVIEWPORTEXTEX        , "SetViewportExtEx"        "(hDC, %d, %d, NULL);" },
  247.     { EMR_SETVIEWPORTORGEX        , "SetViewportOrgEx"        "(hDC, %d, %d, NULL);" },
  248.     { EMR_SCALEVIEWPORTEXTEX      , "ScaleViewportExtEx"    "(hDC, %d, %d, %d, %d, NULL);" },
  249.     { EMR_SCALEWINDOWEXTEX        , "ScaleWindowExtEx"        "(hDC, %d, %d, %d, %d, NULL);" },
  250.     { EMR_SETLAYOUT                  , "SetLayout"                "(hDC, %d)" },
  251.     { EMR_SETMETARGN              , "SetMetaRgn"            "(hDC);" },
  252.         
  253.     { EMR_BEGINPATH               , "BeginPath"                "(hDC);" },
  254.     { EMR_ENDPATH                 , "EndPath"                "(hDC);" },
  255.     { EMR_ABORTPATH               , "AbortPath"                "(hDC);" },
  256.     { EMR_FLATTENPATH             , "FlattenPath"            "(hDC);" },
  257.     { EMR_WIDENPATH               , "WidenPath"                "(hDC);" },
  258.     { EMR_CLOSEFIGURE             , "CloseFigure"            "(hDC);" },
  259.     { EMR_FILLPATH                , "FillPath"                "(hDC);" },
  260.     { EMR_STROKEANDFILLPATH       , "StrokeAndFillPath"        "(hDC);" },
  261.     { EMR_STROKEPATH              , "StrokePath"            "(hDC);" },
  262.     { EMR_SAVEDC                  , "SaveDC"                "(hDC);" },
  263.     { EMR_RESTOREDC               , "RestoreDC"                "(hDC, %d);" },
  264.     
  265.     { EMR_CREATEPEN               , "#o=CreatePen(%L, %d%_, #c);", Dic_PenStyle },
  266.     { EMR_CREATEBRUSHINDIRECT     , "#o=#C;" },
  267.     { EMR_EXTCREATEFONTINDIRECTW  , "#o=CreateFont(%d,%d,%d,%d,%d,%b,%b,%b,%b,%b,%b,%b,%b,%S);" },
  268.     { EMR_CREATEPALETTE           , "#o=CreatePalette(LOGPALETTE {%D,%D,...});" },
  269.     
  270.     { EMR_SELECTOBJECT            , "SelectObject(hDC, #o);" },
  271.     { EMR_SELECTPALETTE           , "SelectPalette(hDC, (HPALETTE)#o, TRUE);" },
  272.     { EMR_SETCOLORSPACE           , "SetColorSpace(hDC, #o);" },
  273.     { EMR_DELETEOBJECT            , "DeleteObject(#o);" },
  274.     { EMR_DELETECOLORSPACE        , "DeleteColorSpace(#o);" },
  275.     
  276.     { EMR_SETTEXTCOLOR            , "SetTextColor(hDC, #c);" },
  277.     { EMR_SETBKCOLOR              , "SetBkColor(hDC, #c);" },
  278.     { EMR_SETBRUSHORGEX           , "SetBrushOrgEx(hDC, %d, %d, NULL);" },
  279.     { EMR_SELECTCLIPPATH          , "SelectClipPath(hDC, %L);", Dic_RegionOper },
  280.     { EMR_SETTEXTALIGN            , "SetTextAlign(hDC, %L);", Dic_TextAlign },
  281.     
  282.     { EMR_SETBKMODE               , "SetBkMode(hDC, %L);",            Dic_BkMode },
  283.     { EMR_SETARCDIRECTION         , "SetArcDirection(hDC, %L);",        Dic_ArcDirection },
  284.     { EMR_SETPOLYFILLMODE         , "SetPolyFillMode(hDC, %L);",        Dic_PolyFillMode },
  285.     { EMR_SETMAPMODE              , "SetMapMode(hDC, %L);",            Dic_MapMode },
  286.     { EMR_SETSTRETCHBLTMODE       , "SetStretchBltMode(hDC, %L);",    Dic_StretchBltMode },
  287.     { EMR_SETMAPPERFLAGS          , "SetMapperFlags(hDC, %d);" },
  288.     { EMR_SETICMMODE              , "SetICMMode(hDC, %d);",          Dic_ICMMode },
  289.     { EMR_SETROP2                 , "SetROP2(hDC, %L);",             Dic_ROP2 },
  290.  
  291.     { EMR_SETMITERLIMIT           , "SetMiterLimit(hDC, %f);" },
  292.     { EMR_SETWORLDTRANSFORM       , "SetWorldTransform(hDC, %f, %f, %f, %f, %f, %f);" }, 
  293.     { EMR_MODIFYWORLDTRANSFORM    , "ModifyWorldTransform(hDC, %f, %f, %f, %f, %f, %f, %L);", Dic_TransCombineMode },
  294.     
  295.     { EMR_REALIZEPALETTE          , "RealizePalette(hDC);" },
  296.     { EMR_RESIZEPALETTE           , "ResizePalette(hDC, #o, %d);" },
  297.     
  298.     { EMR_OFFSETCLIPRGN           , "OffsetClipRgn(hDC, %d, %d);" },
  299.     { EMR_EXCLUDECLIPRECT         , "ExcludeClipRect(hDC, %d, %d, %d, %d);" },
  300.     { EMR_INTERSECTCLIPRECT       , "IntersectClipRect(hDC, %d, %d, %d, %d);" },
  301.     
  302.     { EMR_SETPIXELV               , "SetPixelV(hDC, %d, %d, #c);" },
  303.     { EMR_MOVETOEX                , "MoveToEx(hDC, %d, %d, NULL);" },
  304.     { EMR_LINETO                  , "LineTo(hDC, %d, %d);" },
  305.     { EMR_RECTANGLE               , "Rectangle(hDC, %d, %d, %d, %d);" },
  306.     { EMR_ELLIPSE                 , "Ellipse(hDC, %d, %d, %d, %d);" },
  307.     { EMR_ROUNDRECT               , "RoundRect(hDC, %d, %d, %d, %d, %d, %d);" },
  308.     { EMR_PIE                     , "Pie(hDC, %d, %d, %d, %d, %d, %d, %d, %d);" },
  309.     { EMR_ARC                     , "Arc(hDC, %d, %d, %d, %d, %d, %d, %d, %d);" },
  310.     { EMR_CHORD                   , "Chord(hDC, %d, %d, %d, %d, %d, %d, %d, %d);" },
  311.     { EMR_ARCTO                   , "ArcTo(hDC, %d, %d, %d, %d, %d, %d, %d, %d);" },
  312.     { EMR_ANGLEARC                , "AngleArc(hDC, %d, %d, %d, %f, %f);" },
  313.     { EMR_EXTFLOODFILL            , "ExtFloodFill(hDC, %d, %d, #c, %L);", Dic_FloodFillMode },
  314.     
  315.     { EMR_POLYLINE16              , "\nstatic const POINT Points_%n[]=#p;\n"     "Polyline(hDC, Points_%n, %4);" },
  316.     { EMR_POLYLINETO16            , "\nstatic const POINT Points_%n[]=#p;\n"   "PolylineTo(hDC, Points_%n, %4);" },
  317.     { EMR_POLYBEZIER16            , "\nstatic const POINT Points_%n[]=#p;\n"   "PolyBezier(hDC, Points_%n, %4);" },
  318.     { EMR_POLYBEZIERTO16          , "\nstatic const POINT Points_%n[]=#p;\n" "PolyBezierTo(hDC, Points_%n, %4);" },
  319.     { EMR_POLYGON16               , "\nstatic const POINT Points_%n[]=#p;\n"      "Polygon(hDC, Points_%n, %4);" },
  320.     
  321.     { EMR_POLYLINE                , "\nstatic const POINT Points_%n[]=#P;\n"     "Polyline(hDC, Points_%n, %4);" },
  322.     { EMR_POLYLINETO              , "\nstatic const POINT Points_%n[]=#P;\n"   "PolylineTo(hDC, Points_%n, %4);" },
  323.     { EMR_POLYBEZIER              , "\nstatic const POINT Points_%n[]=#P;\n"   "PolyBezier(hDC, Points_%n, %4);" },
  324.     { EMR_POLYBEZIERTO            , "\nstatic const POINT Points_%n[]=#P;\n" "PolyBezierTo(hDC, Points_%n, %4);" },
  325.     { EMR_POLYGON                 , "\nstatic const POINT Points_%n[]=#P;\n"      "Polygon(hDC, Points_%n, %4);" },
  326.     
  327.     //////////////////
  328. //  { EMR_HEADER                  , "// Header" },
  329.     
  330.       { EMR_POLYDRAW16              , "PolyDraw16" },
  331.     
  332.     { EMR_EOF                     , "// EMREOF(%d, %d, %d)" },
  333.     { EMR_SETCOLORADJUSTMENT      , "SetColorAdjustment" },
  334.     { EMR_SETPALETTEENTRIES       , "SetPaletteEntries" },
  335.     { EMR_POLYDRAW                , "PolyDraw" },
  336.     
  337.     { EMR_GDICOMMENT              , "// GdiComment(%d, %c%c%c%c, 0x%x)" },
  338.     { EMR_FILLRGN                 , "FillRgn" },
  339.     { EMR_FRAMERGN                , "FrameRgn" },
  340.     { EMR_INVERTRGN               , "InvertRgn" },
  341.     { EMR_PAINTRGN                , "PaintRgn" },
  342.     { EMR_MASKBLT                 , "MaskBlt" },
  343.     { EMR_PLGBLT                  , "PlgBlt" },
  344.     { EMR_SETDIBITSTODEVICE       , "SetDIBSToDevice" },
  345.     { EMR_CREATEDIBPATTERNBRUSHPT , "CreateDIBPatternBrushPT" },
  346.     { EMR_POLYTEXTOUTA            , "PolyTextOutA" },
  347.     { EMR_POLYTEXTOUTW            , "PolyTextOutW" },
  348.     { EMR_CREATECOLORSPACE        , "CreateColorSpace" },
  349.     { EMR_GLSRECORD               , "GlsRecord" },
  350.     { EMR_GLSBOUNDEDRECORD        , "GlsBOundedRecord" },
  351.     { EMR_PIXELFORMAT             , "PixelFormat" },
  352.  
  353.     { EMR_COLORCORRECTPALETTE      , "ColorCorrectPalette" },
  354.     { EMR_SETICMPROFILEA          , "SetICMProfileA" },
  355.     { EMR_SETICMPROFILEW          , "SetICMProfileW" },
  356.     { EMR_ALPHABLEND              , "AlphaBlend" },
  357.     { EMR_TRANSPARENTBLT          , "TransParentBlt" },
  358.     { EMR_GRADIENTFILL              , "GradientFill" },
  359.  
  360. //    { EMR_DRAWESCAPE              , "DrawEscape" },
  361. //    { EMR_EXTESCAPE               , "ExtEscape" },
  362. //    { EMR_STARTDOC                , "StartDoc" },
  363. //    { EMR_FORCEUFIMAPPING         , "ForceEuFiMapping" },
  364. //    { EMR_NAMEDESCAPE              , "NamedEscape" },
  365. //    { EMR_TRANSPARENTDIB          , "TransParentDIB" },
  366. //    { EMR_SETLINKEDUFIS           , "SetLinkEDUFIS" },
  367. //    { EMR_SETTEXTJUSTIFICATION    , "SetTextJustification" }
  368. //  { EMR_EXTSELECTCLIPRGN        , "ExtSelectClipRgn" },
  369. //    { EMR_SMALLTEXTOUT            , "TextOut" },
  370. //    { EMR_CREATEMONOBRUSH         , "CreateMonoBrush" },
  371.     
  372. };
  373.  
  374. typedef struct
  375. {
  376.     EMR    emr;     
  377.     POINTL ptlReference;     
  378.     DWORD  nChars;     
  379.     DWORD  fOptions;     
  380.     DWORD  iGraphicsMode;
  381.     FLOAT  exScale;
  382.     FLOAT  eyScale;
  383.     char   Text[1];
  384. } EMRSMALLTEXTOUT;
  385.           
  386.  
  387. inline const void * Offset(const void * base, long ofst)
  388. {
  389.     return (const void *) ( (const char *) base + ofst);
  390. }
  391.  
  392. const TCHAR Format_ENHMETAHEADER [] =
  393.     "4iType: %d\0" 
  394.     "4nSize: %d\0" 
  395.     "grclBounds: { %d, %d, %d, %d}\0"
  396.     "grclFrame: { %d, %d, %d, %d}\0" 
  397.     "4dSignature: 0x%08x\0" 
  398.     "4nVersion: 0x%x\0" 
  399.     "4nBytes: %d\0" 
  400.     "4nRecords: %d\0"
  401.     "2nHandles: %d\0"
  402.     "2sReserved: %d\0" 
  403.     "4nDescription: %d\0" 
  404.     "4offDescription: %d\0" 
  405.     "4nPalEntries: %d\0" 
  406.     "8szlDevice: { %d, %d }\0" 
  407.     "8szlMillimeters: { %d, %d }\0"
  408.     "4cbPixelFormat: %d\0"
  409.     "4offPixelFormat: %d\0"
  410.     "4bOpenGL: %d\0"
  411.     "8szMicroMeters: { %d, %d }\0";
  412.  
  413.  
  414.  
  415. bool KEmfDC::Decode(const EMR * emr, KTreeView * pTree)
  416. {
  417.     if ( pTree && emr->iType==EMR_HEADER )
  418.     {
  419.         pTree->InsertTree(TVI_LAST, TVI_ROOT, "1: ENHMETAHEADER", Format_ENHMETAHEADER, emr);
  420.         return true;
  421.     }
  422.  
  423.     const TCHAR * rslt = DecodeRecord(emr);
  424.  
  425.     if ( pTree )
  426.     {
  427.         TCHAR temp[1024];
  428.  
  429.         m_nSeq ++;
  430.         wsprintf(temp, "%d: ", m_nSeq);
  431.         _tcscat(temp, rslt);
  432.  
  433.         wsprintf(temp + _tcslen(temp), ", %d bytes", emr->nSize);
  434.         
  435.         pTree->InsertItem(temp);
  436.     }
  437.  
  438.     return true;
  439. }
  440.  
  441.  
  442. const TCHAR * KEmfDC::DecodeRecord(const EMR * emr)
  443. {
  444.     fmt.Newline();
  445.  
  446.     for (int i=0; i< sizeof(Pattern)/sizeof(Pattern[0]); i++)
  447.         if ( Pattern[i].type == emr->iType)
  448.         {
  449.             fmt.Format(Pattern[i].funcname, (const long *) & emr[1], Pattern[i].dic);
  450.             
  451.             return fmt.m_buffer;
  452.         }
  453.  
  454.     switch ( emr->iType )
  455.     {        
  456.         case EMR_HEADER:
  457.             fmt.Write("// Header");
  458.             break;
  459.  
  460.         case EMR_BITBLT:
  461.             {
  462.                 EMRBITBLT  * bitblt = (EMRBITBLT *) emr;
  463.  
  464.                 if ( bitblt->cbBitsSrc==0 ) // no bitmap
  465.                     fmt.Format("PatBlt(hDC,%d,%d,%d,%d,", & bitblt->xDest);
  466.                 else
  467.                 {
  468.                     fmt.Format("BitBlt(hDC,%d,%d,%d,%d,", & bitblt->xDest);
  469.  
  470.                 //    assert(false);
  471.                     fmt.Write("hMemDC");
  472.                 
  473.                     fmt.Format(",%d,%d,", & bitblt->xSrc);
  474.                 }
  475.  
  476.                 fmt.Write(Lookup(bitblt->dwRop, Dic_ROP3));
  477.                 fmt.Write(");");
  478.             }
  479.             break;
  480.  
  481.         case EMR_STRETCHBLT:
  482.             {
  483.                 EMRSTRETCHBLT * cmd = (EMRSTRETCHBLT *) emr;
  484.  
  485.                 if ( cmd->cbBitsSrc==0 ) // no bitmap
  486.                     fmt.Format("PatBlt(hDC,%d,%d,%d,%d,", & cmd->xDest);
  487.                 else
  488.                 {
  489.                     TCHAR format[64];
  490.  
  491.                     fmt.AddDIB( cmd, 
  492.                             cmd->offBmiSrc,  cmd->cbBmiSrc,
  493.                             cmd->offBitsSrc, cmd->cbBitsSrc,
  494.                             format, false);
  495.                 
  496.                     fmt.Newline();
  497.                     fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
  498.                     fmt.Format(",%d,%d",                   & cmd->cxDest);
  499.                     fmt.Format(", %d,%d,",                   & cmd->xSrc);
  500.  
  501.                     if ( ! fmt.IsOpen() )
  502.                     {
  503.                         fmt.Format("%d,%d, pBits, pBMI",       & cmd->cxSrc);
  504.                         fmt.Write(format);
  505.                     }
  506.                     else
  507.                         fmt.Format("%d,%d, #b, #B",               & cmd->cxSrc);
  508.                     
  509.                     fmt.Format(", %L,", & cmd->iUsageSrc, Dic_DIBColor);
  510.                 }
  511.                 
  512.                 fmt.Write(Lookup(cmd->dwRop, Dic_ROP3));
  513.                 fmt.Write(");");
  514.             }
  515.             break;
  516.  
  517.         case EMR_EXTSELECTCLIPRGN:
  518.             {
  519.                 EMREXTSELECTCLIPRGN * extselectcliprgn = (EMREXTSELECTCLIPRGN *) emr;
  520.  
  521.                 if ( extselectcliprgn->cbRgnData == 0 )
  522.                     fmt.Write("SelectClipRgn(hDC, NULL);");
  523.                 else
  524.                 {
  525.                     fmt.AddRegion(extselectcliprgn->cbRgnData, (const RGNDATA *) & extselectcliprgn->RgnData);
  526.                     
  527.                     fmt.Newline();
  528.                     fmt.Format("ExtSelectClipRgn(hDC, hRegion, %L);", & extselectcliprgn->iMode, Dic_RegionOper);
  529.  
  530.                     fmt.Newline();
  531.                     fmt.Write("DeleteObject(hRegion);");
  532.                 }
  533.             }
  534.             break;
  535.  
  536. /*        case EMR_SMALLTEXTOUT:
  537.             {
  538.                 EMRSMALLTEXTOUT * smalltextout = (EMRSMALLTEXTOUT *) emr;
  539.  
  540.                 fmt.Format("ExtTextOutA(hDC, %d,%d,",
  541.                             & smalltextout->ptlReference.x);
  542.  
  543.                 fmt.WriteDec(smalltextout->fOptions & 0xFC00);
  544.                 fmt.Write(",NULL,");
  545.                 fmt.WriteString(smalltextout->Text, smalltextout->nChars, false);
  546.                 fmt.Write(",");
  547.                 fmt.WriteDec(smalltextout->nChars);
  548.                 fmt.Write(",NULL);");
  549.             }
  550.             break;
  551. */            
  552.         case EMR_EXTTEXTOUTA:
  553.         case EMR_EXTTEXTOUTW:
  554.             {
  555.                 EMREXTTEXTOUTW * cmd = (EMREXTTEXTOUTW *) emr;
  556.  
  557.                 if ( (cmd->emrtext.offDx!=0) && (cmd->emrtext.nChars!=0) )
  558.                 {
  559.                     fmt.Format("const int Dx_%m[]=", NULL);
  560.                     fmt.WriteArray(Offset(emr, cmd->emrtext.offDx), cmd->emrtext.nChars, sizeof(long));
  561.                     fmt.Put(';');
  562.  
  563.                     fmt.Newline();
  564.                 }
  565.  
  566.                 if (cmd->emrtext.fOptions & ( ETO_CLIPPED | ETO_OPAQUE) )
  567.                 {
  568.                     fmt.Format("const RECT Rect_%n={%d,%d,%d,%d};", & cmd->emrtext.rcl);
  569.                     fmt.Newline();
  570.                 }
  571.  
  572.                 if (emr->iType == EMR_EXTTEXTOUTA)
  573.                     fmt.Write("ExtTextOutA");
  574.                 else
  575.                     fmt.Write("ExtTextOutW");
  576.                 
  577.                 fmt.Format("(hDC, %d,%d,", & cmd->emrtext.ptlReference);
  578.                 
  579.                 if ( cmd->emrtext.fOptions == 0)
  580.                     fmt.Put('0');
  581.                 else
  582.                     fmt.Write(cmd->emrtext.fOptions, Dic_ExtTextOption);
  583.                 
  584.                 fmt.Put(',');
  585.                 
  586.                 if (cmd->emrtext.fOptions & (ETO_CLIPPED | ETO_OPAQUE) )
  587.                     fmt.Format("& Rect_%n,", NULL);
  588.                 else
  589.                     fmt.Write("NULL,");
  590.  
  591.                 if (emr->iType == EMR_EXTTEXTOUTW)
  592.                     fmt.Put('L');
  593.  
  594.                 if (emr->iType == EMR_EXTTEXTOUTA)
  595.                     fmt.WriteString(Offset(emr, cmd->emrtext.offString), cmd->emrtext.nChars, false);
  596.                 else
  597.                     fmt.WriteString(Offset(emr, cmd->emrtext.offString), cmd->emrtext.nChars, true);
  598.  
  599.                 fmt.Write(",");
  600.                 fmt.WriteDec(cmd->emrtext.nChars);
  601.  
  602.                 if ( (cmd->emrtext.offDx!=0) && (cmd->emrtext.nChars!=0) )
  603.                     fmt.Format(",Dx_%m);", NULL);
  604.                 else
  605.                     fmt.Write(",NULL);");
  606.             }
  607.             break;
  608.  
  609.         case EMR_POLYPOLYGON16:
  610.         case EMR_POLYPOLYLINE16:
  611.         case EMR_POLYPOLYGON:
  612.         case EMR_POLYPOLYLINE:
  613.             {
  614.                 EMRPOLYPOLYGON * polypolygon = ( EMRPOLYPOLYGON *) emr;
  615.  
  616.                 fmt.Format("static const int Count_%n[]=", 0);
  617.                 fmt.WriteArray( polypolygon->aPolyCounts, polypolygon->nPolys, sizeof(polypolygon->aPolyCounts[0]));
  618.                 fmt.Put(';');
  619.  
  620.                 fmt.Newline();
  621.                 fmt.Format("static const int Vertex_%m[]=", 0);
  622.  
  623.                 switch ( emr->iType )
  624.                 {
  625.                     case EMR_POLYPOLYGON16:
  626.                     case EMR_POLYPOLYLINE16:
  627.                         fmt.WriteArray(& polypolygon->aPolyCounts[polypolygon->nPolys], polypolygon->cptl * 2, sizeof(short));
  628.                         break;
  629.  
  630.                     case EMR_POLYPOLYGON:
  631.                     case EMR_POLYPOLYLINE:
  632.                         fmt.WriteArray(& polypolygon->aPolyCounts[polypolygon->nPolys], polypolygon->cptl * 2, sizeof(long));
  633.                         break;
  634.                 }
  635.                 
  636.                 fmt.Put(';');
  637.  
  638.                 fmt.Newline();
  639.     
  640.                 switch ( emr->iType )
  641.                 {
  642.                     case EMR_POLYPOLYGON16:
  643.                     case EMR_POLYPOLYGON:
  644.                         fmt.Write("PolyPolygon");
  645.                         break;
  646.  
  647.                     case EMR_POLYPOLYLINE16:
  648.                     case EMR_POLYPOLYLINE:
  649.                         fmt.Write("PolyPolyline");
  650.                         break;
  651.                 }
  652.                 fmt.Format("(hDC, (const POINT *) Vertex_%m, Count_%n, %d);", & polypolygon->nPolys);
  653.             }
  654.             break;
  655.  
  656.         case EMR_STRETCHDIBITS:
  657.             {
  658.                 EMRSTRETCHDIBITS * cmd = (EMRSTRETCHDIBITS *) emr;
  659.  
  660.                 TCHAR format[64];
  661.  
  662.                 fmt.Newline();
  663.  
  664.                 bool newdib = fmt.AddDIB( cmd, 
  665.                                     cmd->offBmiSrc,  cmd->cbBmiSrc,
  666.                                     cmd->offBitsSrc, cmd->cbBitsSrc,
  667.                                     format, false);
  668.                 
  669.                 if ( ! fmt.IsOpen() )
  670.                 {
  671.                     fmt.Newline();
  672.                     fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
  673.                     fmt.Format(",%d,%d",                   & cmd->cxDest);
  674.  
  675.                     fmt.Format(", %d,%d,%d,%d, pBits, pBMI",    & cmd->xSrc);
  676.                     fmt.Write(format);
  677.                 }
  678.                 else
  679.                 {
  680.                     if ( newdib )
  681.                     {
  682.                         fmt.Write("// ");
  683.                         fmt.Write(format);
  684.                         fmt.Newline();
  685.                     }
  686.  
  687.                     TCHAR temp[32];
  688.                     wsprintf(temp, "Dib_%d.", fmt.m_curPackedDIB+1);
  689.                     fmt.Write(temp);
  690.  
  691.                     fmt.Format("StretchDIBits(hDC, %d,%d", & cmd->xDest);
  692.                     fmt.Format(",%d,%d",                   & cmd->cxDest);
  693.                     fmt.Format(", %d,%d,%d,%d",               & cmd->xSrc);
  694.                 }
  695.  
  696.                 fmt.Format(", %L", & cmd->iUsageSrc, Dic_DIBColor);
  697.                 fmt.Format(", %L);", & cmd->dwRop,    Dic_ROP3);
  698.             }
  699.             break;
  700.  
  701.         case EMR_CREATEMONOBRUSH:
  702.             {
  703.                 EMRCREATEMONOBRUSH * cmd = (EMRCREATEMONOBRUSH *) emr;
  704.  
  705.                 assert( (cmd->offBmi + cmd->cbBmi) == cmd->offBits);
  706.  
  707.                 fmt.Format("const unsigned long DIB_%n[]=", NULL);
  708.                 fmt.WriteArray(Offset(cmd, cmd->offBmi), (cmd->cbBmi + cmd->cbBits)/sizeof(long), sizeof(long), false);
  709.                 fmt.Put(';');
  710.                 
  711.                 fmt.Newline();
  712.                 fmt.Format("#o=CreateDIBPatternBrushPt((const BITMAPINFO *) DIB_%n,%L);", & cmd->ihBrush, Dic_DIBColor);
  713.             }
  714.             break;
  715.  
  716.         case EMR_EXTCREATEPEN:
  717.             {
  718.                 EMREXTCREATEPEN * cmd = (EMREXTCREATEPEN *) emr;
  719.  
  720.                 fmt.Format("static const LOGBRUSH LogBrush_%m = #R;", & cmd->elp.elpBrushStyle);
  721.                 
  722.                 fmt.Newline();
  723.                 fmt.Format("#o=ExtCreatePen(", & cmd->ihPen);
  724.  
  725.                 assert(cmd->cbBmi == 0);
  726.                 assert(cmd->cbBits == 0);
  727.  
  728.                 fmt.Write(Lookup(cmd->elp.elpPenStyle, Dic_PenStyle));
  729.                 fmt.Put(',');
  730.                 fmt.WriteDec(cmd->elp.elpWidth);
  731.                 
  732.                 fmt.Format(",& LogBrush_%m,%d,NULL);", & cmd->elp.elpNumEntries);
  733.             }
  734.             break;
  735.  
  736.         default:            
  737.             fmt.Format("// Unknown record [%d]", & emr->iType);
  738.     }
  739.  
  740.     return fmt.m_buffer;
  741. }
  742.  
  743.  
  744. // Decompile from an EMF file
  745. bool KEmfDC::DeCompile(const TCHAR * outfile, const char * FileName, 
  746.                   KTreeView * pTree, HENHMETAFILE & hEmf)
  747. {
  748.     if ( ! Open(FileName) )
  749.         return false;
  750.     
  751.     return DeCompileBuffer(outfile, m_View, pTree, hEmf);
  752. }
  753.  
  754.  
  755. // Decompile from an EMF object
  756. bool KEmfDC::DeCompile(const TCHAR * outfile, HENHMETAFILE hEmf, KTreeView * pTree)
  757. {
  758.     int size = GetEnhMetaFileBits(hEmf, 0, NULL);
  759.  
  760.     if ( size<=0 )
  761.         return false;
  762.  
  763.     BYTE * pBits = new BYTE[size];
  764.  
  765.     HCURSOR hOld = SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT)));
  766.  
  767.     GetEnhMetaFileBits(hEmf, size, pBits);
  768.     bool rslt = DeCompileBuffer(outfile, pBits, pTree, hEmf);
  769.  
  770.     DestroyCursor(SetCursor(hOld));
  771.  
  772.     delete [] pBits;
  773.  
  774.     return rslt;
  775. }
  776.  
  777.  
  778. bool IsEMFHeader(const void * buffer)
  779. {
  780.     try
  781.     {
  782.         const ENHMETAHEADER * header = (const ENHMETAHEADER *) buffer;
  783.  
  784.         return ( (header->iType      == EMR_HEADER) && 
  785.                  (header->nVersion   == 0x10000)    &&
  786.                  (header->dSignature == ENHMETA_SIGNATURE) );
  787.     }
  788.     catch (...)
  789.     {
  790.         return false;
  791.     }
  792.  
  793.     return false;
  794. }
  795.  
  796.  
  797. extern HINSTANCE hModule;
  798.  
  799. // main entry for decompiling from a memory buffer
  800. bool KEmfDC::DeCompileBuffer(const TCHAR * outfilename, const void * buffer, KTreeView * pTree, HENHMETAFILE & hEmf)
  801. {
  802.     const EMR * emr = (const EMR *) buffer;
  803.     
  804.     // if not normal EMF file
  805.     while ( ! IsEMFHeader(emr) )
  806.     {
  807.         if ( IsEMFHeader(emr+1) )
  808.         {
  809.             emr ++;
  810.  
  811.             if ( hEmf==NULL )
  812.                 hEmf = SetEnhMetaFileBits(emr[-1].nSize, (const BYTE *) emr);
  813.             
  814.             break;
  815.         }
  816.         else
  817.             emr = (const EMR *) ( ( const char * ) emr + emr->nSize );
  818.     }
  819.  
  820.     const ENHMETAHEADER * pHeader = (const ENHMETAHEADER *) emr;
  821.     
  822.     if ( pTree==NULL )
  823.     {
  824.         fmt.Open(outfilename);
  825.  
  826.         HRSRC hRsc = FindResource(hModule, MAKEINTRESOURCE(IDR_PRE), RT_RCDATA);
  827.         
  828.         if ( hRsc )
  829.         {
  830.             HGLOBAL hResData  = LoadResource(hModule, hRsc);
  831.             const char * pPgm = (const char *) LockResource(hResData);
  832.  
  833.             fmt.Write(pPgm);
  834.         }
  835.  
  836.         fmt.Indent(1);
  837.         fmt.Newline(); fmt.Write("HGDIOBJ hObj["); fmt.WriteDec((long) pHeader->nHandles); fmt.Write("] = { NULL };");
  838.         fmt.Newline();
  839.     }
  840.     m_nSeq = 1;
  841.  
  842.     bool bOptimize = false;
  843.  
  844.     // enumuerate all EMF records
  845.     while ( (emr->iType>=EMR_MIN) && (emr->iType<=EMR_MAX) )
  846.     {
  847.         bool rslt = true;
  848.  
  849.         if ( bOptimize )
  850.         {
  851.             const EMR * next = (const EMR *) ( ( const char * ) emr + emr->nSize );
  852.  
  853.             if ( next->iType == emr->iType )
  854.                 switch ( emr->iType )
  855.                 {
  856.                     case EMR_SETWINDOWORGEX:
  857.                     case EMR_SETWINDOWEXTEX:
  858.                     case EMR_SETVIEWPORTORGEX:
  859.                     case EMR_SETVIEWPORTEXTEX:
  860.                     case EMR_SETTEXTCOLOR:
  861.                     case EMR_SETBKCOLOR:
  862.                     case EMR_SETBRUSHORGEX:
  863.                     case EMR_SELECTCLIPPATH:
  864.                     case EMR_SETTEXTALIGN:
  865.         
  866.                     case EMR_SETBKMODE:
  867.                     case EMR_SETARCDIRECTION:
  868.                     case EMR_SETPOLYFILLMODE:
  869.                     case EMR_SETMAPMODE:
  870.                     case EMR_SETSTRETCHBLTMODE:
  871.                     case EMR_SETMAPPERFLAGS:
  872.                     case EMR_SETICMMODE:
  873.                     case EMR_SETROP2:
  874.  
  875.                     case EMR_SETMITERLIMIT:
  876.                     case EMR_SETWORLDTRANSFORM:
  877.                     case EMR_MOVETOEX:
  878.                         fmt.Write("/* */");
  879.                         break;
  880.                 
  881.                     default:
  882.                         rslt = Decode(emr, pTree);
  883.                 }
  884.             else 
  885.                 rslt = Decode(emr, pTree);
  886.         }
  887.         else
  888.             rslt = Decode(emr, pTree);
  889.         
  890.         if (! rslt ) 
  891.             break;
  892.  
  893.         if ( emr->iType== EMR_EOF )
  894.             break;
  895.  
  896.         emr = (const EMR *) ( ( const char * ) emr + emr->nSize );
  897.     }
  898.     
  899.     if ( pTree==NULL )
  900.     {
  901.         fmt.Indent(-1);
  902.  
  903.         HRSRC hRsc = FindResource(hModule, MAKEINTRESOURCE(IDR_POST), RT_RCDATA);
  904.         
  905.         if ( hRsc )
  906.         {
  907.             HGLOBAL hResData  = LoadResource(hModule, hRsc);
  908.             const char * pPgm = (const char *) LockResource(hResData);
  909.  
  910.             fmt.Write(pPgm);
  911.         }
  912.  
  913.         fmt.Close();
  914.     }
  915.     
  916.     return true;
  917. }