home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_16 / EMF / Formator.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  7.8 KB  |  321 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   : formator.cpp                                                         //
  10. //  Description: Text output stream with Win32 data type support                     //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <assert.h>
  19. #include <tchar.h>
  20. #include <fstream.h>
  21.  
  22. #include "OutPipe.h"
  23. #include "Formator.h"
  24.  
  25.  
  26. void KWinPipe::AddColor(COLORREF color)
  27. {
  28.     if ( color & 0xFF000000 )
  29.         WriteHex(color);
  30.     else
  31.     {
  32.         Write("RGB("); WriteHex(GetRValue(color));
  33.         Put(',');      WriteHex(GetGValue(color));
  34.         Put(',');      WriteHex(GetBValue(color));
  35.         Put(')');
  36.     }
  37. }
  38.  
  39.  
  40. const DicItem Dic_HatchStyles[] =
  41. {
  42.     pair(HS_BDIAGONAL), 
  43.     pair(HS_CROSS), 
  44.     pair(HS_DIAGCROSS), 
  45.     pair(HS_FDIAGONAL), 
  46.     pair(HS_HORIZONTAL), 
  47.     pair(HS_VERTICAL),
  48.     dummyitem
  49. };
  50.  
  51.  
  52. const DicItem Dic_BrushStyle [] =
  53. {
  54.     pair(BS_SOLID),
  55.     pair(BS_NULL),
  56.     pair(BS_HOLLOW),
  57.     pair(BS_HATCHED),
  58.     pair(BS_PATTERN),
  59.     pair(BS_INDEXED),
  60.     pair(BS_DIBPATTERN),
  61.     pair(BS_DIBPATTERNPT),
  62.     pair(BS_PATTERN8X8),
  63.     pair(BS_DIBPATTERN8X8),
  64.     pair(BS_MONOPATTERN),
  65.     dummyitem
  66. };
  67.  
  68.  
  69. // EMRCREATEBRUSHINDIRECT: BS_SOLID, BS_HOLLOW, BS_NULL, or BS_HATCHED value. 
  70. void KWinPipe::AddBrush(const LOGBRUSH * logbrush, bool create)
  71. {
  72.     assert(logbrush);
  73.  
  74.     if ( create )
  75.         switch ( logbrush->lbStyle )
  76.         {
  77.             case BS_SOLID:
  78.                 if ( logbrush->lbColor == 0 )
  79.                     Write("GetStockObject(BLACK_BRUSH)");
  80.                 else if ( logbrush->lbColor == RGB(0xFF, 0xFF, 0xFF) )
  81.                     Write("GetStockObject(WHITE_BRUSH)");
  82.                 else
  83.                     Format(_T("CreateSolidBrush(#c)"), (const long *) & logbrush->lbColor);
  84.                 break;
  85.  
  86.             case BS_NULL:
  87.                 Write("GetStockObject(NULL_BRUSH)");
  88.                 break;
  89.  
  90.             case BS_HATCHED:
  91.                 Write("CreateHatchBrush(");
  92.                 Write(logbrush->lbHatch, Dic_HatchStyles);
  93.                 Format(_T(", #c)"), (const long *) & logbrush->lbColor);
  94.                 break;
  95.  
  96.             default:
  97.                 assert(false);
  98.         }
  99.     else
  100.     {
  101.         Format(_T("{ %L, #c"), logbrush, Dic_BrushStyle);
  102.         Format(_T(",%L}"), & logbrush->lbHatch, Dic_HatchStyles);
  103.     }
  104. }
  105.  
  106.  
  107. void KWinPipe::AddRegion(unsigned long size, const RGNDATA * rgn)
  108. {
  109.     assert(rgn);
  110.  
  111.     if ( rgn->rdh.nCount == 1 )
  112.         Format(_T("hRegion = CreateRectRgn(%d,%d,%d,%d);"), rgn->Buffer);
  113.     else
  114.     {
  115.         assert( rgn->rdh.nCount != 0);
  116.  
  117.         Format(_T("const RECT Rgn_%n[] = "), NULL);
  118.         
  119.         WriteArray(rgn, rgn->rdh.nCount + 2, sizeof(RECT));
  120.         Write(";");
  121.  
  122.         Newline();
  123.         
  124.         long size = sizeof(RGNDATAHEADER) + rgn->rdh.nCount * 4;
  125.         Format(_T("hRegion = ExtCreateRegion(NULL, %d, (const RGNDATA *) Rgn_%n);"), & size);
  126.     }
  127. }
  128.  
  129.     
  130. const DicItem Dic_StockObjects[] =
  131. {
  132.     pair(WHITE_BRUSH),
  133.     pair(LTGRAY_BRUSH),
  134.     pair(GRAY_BRUSH),
  135.     pair(DKGRAY_BRUSH),
  136.     pair(BLACK_BRUSH),
  137.     pair(NULL_BRUSH),
  138.     pair(HOLLOW_BRUSH),
  139.     pair(WHITE_PEN),
  140.     pair(BLACK_PEN),
  141.     pair(NULL_PEN),
  142.     pair(OEM_FIXED_FONT),
  143.     pair(ANSI_FIXED_FONT),
  144.     pair(ANSI_VAR_FONT),
  145.     pair(SYSTEM_FONT),
  146.     pair(DEVICE_DEFAULT_FONT),
  147.     pair(DEFAULT_PALETTE),
  148.     pair(SYSTEM_FIXED_FONT),
  149.     pair(DEFAULT_GUI_FONT),
  150.     dummyitem
  151. };
  152.  
  153.  
  154. const long * KWinPipe::Pound(char tag, const long * data, const DicItem * dic)
  155. {
  156.     long len = 0;
  157.  
  158.     switch ( tag )
  159.     {
  160.         case 'B': Write("(const BITMAPINFO *) & BMI_"); WriteDec(m_curBMI); // BITMAPINFO reference
  161.                   break;
  162.  
  163.         case 'b': Write("Bits_"); WriteDec(m_curDIB);  // DIB bits reference
  164.                   break;
  165.     
  166.         case 'C': AddBrush((const LOGBRUSH *) data, true);  len=sizeof(LOGBRUSH); break;
  167.         case 'R': AddBrush((const LOGBRUSH *) data, false); len=sizeof(LOGBRUSH); break;
  168.  
  169.         case 'c': AddColor(data[0]); len=0;        // colorref    
  170.                   break;
  171.  
  172.         case 'o': if ( * data > 0 )              // decimal object index or stock object, move
  173.                   {
  174.                       Write("hObj[");
  175.                       WriteDec(data[0]);
  176.                       Put(']');
  177.                   }
  178.                   else
  179.                   {
  180.                       Write("GetStockObject(");
  181.                       Write(data[0] & 0xFFFF, Dic_StockObjects);
  182.                       Put(')');
  183.                   }    
  184.                   len = 4;
  185.                     break;
  186.  
  187.         case 'p': WriteArray(& data[5], data[4]*2, sizeof(short)); break;
  188.         case 'P': WriteArray(& data[5], data[4]*2, sizeof(long));  break;
  189.  
  190.         default: assert(false);
  191.     }
  192.  
  193.     return (const long *) ( (const char *) data + len);
  194. }
  195.  
  196.  
  197. bool KWinPipe::SaveDIB(const BITMAPINFO * bmi, long bmisize, const void * bits, long bitsize)
  198. {
  199.     assert( (unsigned) bmi + bmisize == (unsigned) bits);
  200.  
  201.     if ( m_PackedDIBCache.Match(bmisize+bitsize, bmi, m_curPackedDIB) )
  202.         return false;
  203.  
  204.     ofstream dib;
  205.  
  206.     TCHAR name[MAX_PATH];
  207.  
  208.     wsprintf(name, _T("c:\\dib_%d.bmp"), m_curPackedDIB+1);
  209. #ifndef _UNICODE
  210.     dib.open(name);
  211. #endif
  212.     dib.setmode(filebuf::binary);
  213.     
  214.     BITMAPFILEHEADER header;
  215.     memset(& header, 0, sizeof(header));
  216.     header.bfType    = 0x4D42;
  217.     header.bfSize    = sizeof(header) + bmisize + bitsize;
  218.     header.bfOffBits = sizeof(header) + bmisize;
  219.  
  220.     dib.write((const char *)& header, sizeof(header));
  221.     dib.write((const char *)bmi,    bmisize);
  222.     dib.write((const char *)bits,    bitsize);
  223.     dib.close();
  224.  
  225.     wsprintf(name, _T("static KDIB Dib_%d; Dib_%d.Load(IDB_BITMAP%d);"),
  226.         m_curPackedDIB+1, m_curPackedDIB+1, m_curPackedDIB+1);
  227.  
  228.     Write(name);
  229.  
  230.     return true;
  231. }
  232.  
  233.  
  234. bool KWinPipe::AddDIB(const void * header, 
  235.                        long bmioffset, long bmisize,
  236.                        long bitoffset, long bitsize,
  237.                        TCHAR format[], bool pack)
  238. {
  239.     const BITMAPINFO * bmi = (const BITMAPINFO *) ((const char *) header + bmioffset);
  240.     const char       * bit = (const char *) header + bitoffset;
  241.  
  242.     wsprintf(format, _T("%dx%dx%d"), bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 
  243.         bmi->bmiHeader.biBitCount);
  244.     
  245.     if ( m_bOpened )
  246.         return SaveDIB(bmi, bmisize, bit, bitsize);
  247.     else
  248.         return false;
  249. /*
  250.     if ( ( bitsize > 1024 ) || pack ) // write to external file
  251.     {
  252.         SaveDIB(bmi, bmisize, bit, bitsize);
  253.         return;
  254.     }
  255.     
  256.     // bmisize may be too big sometimes
  257.     int palettesize = ( bmisize - sizeof(BITMAPINFOHEADER) ) / sizeof(bmi->bmiColors[0]);
  258.  
  259.     if ( palettesize > (1 << bmi->bmiHeader.biBitCount) )
  260.         palettesize = 1 << bmi->bmiHeader.biBitCount;
  261.  
  262.     if ( pack || ! m_BMICache.Match(bmisize, bmi, m_curBMI) )
  263.     {
  264.         Newline();
  265.  
  266.         if ( pack )
  267.         {
  268.             m_curBMI ++;
  269.             Write("const DIB_");
  270.             WriteDec((long) ( 1 << bmi->bmiHeader.biBitCount) );
  271.         }
  272.         else if ( palettesize<=1 )
  273.             Write("const BITMAPINFO");
  274.         else
  275.         {
  276.             Write("const BITMAPINFO");
  277.             WriteDec((long) palettesize);
  278.         }
  279.  
  280.         Write(" BMI_"); 
  281.         WriteDec(m_curBMI);
  282.         
  283.         Format(" = { { %d, %d,%d,%D,%D,%d,%d,%d,%d,%d,%d }", bmi);
  284.  
  285.         if ( bmisize > sizeof(BITMAPINFOHEADER) )
  286.         {
  287.             Write(", { ");
  288.             
  289.             for (int i=0; i<palettesize; i++)
  290.             {
  291.                 if (i)
  292.                     Put(',');
  293.  
  294.                 WriteArray(& bmi->bmiColors[i], 4, 1);
  295.             }
  296.             Put('}');
  297.         }
  298.  
  299.         if ( pack )
  300.             Put(' ');
  301.         else
  302.             Write(" };");
  303.     }
  304.  
  305.     if ( pack || ! m_DIBCache.Match(bitsize, bit, m_curDIB) )
  306.     {
  307.         if (pack)
  308.             m_curDIB++;
  309.         else
  310.         {
  311.             Newline();
  312.  
  313.             Format("const unsigned long Bits_%d[]=", & m_curDIB);
  314.         }
  315.  
  316.         WriteArray((const char *) header + bitoffset, bitsize/4, 4, false);
  317.         Put(';');
  318.     }
  319. */
  320. }
  321.