home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / ogl / mfutils.cpp < prev    next >
C/C++ Source or Header  |  2002-12-18  |  32KB  |  1,088 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        mfutils.cpp
  3. // Purpose:     Metafile utillities
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     12/07/98
  7. // RCS-ID:      $Id: mfutils.cpp,v 1.4.2.1 2002/12/18 06:13:00 RD Exp $
  8. // Copyright:   (c) Julian Smart
  9. // Licence:       wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "mfutils.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WX_PRECOMP
  24. #include <wx/wx.h>
  25. #endif
  26.  
  27. #include <wx/metafile.h>
  28. #include <wx/utils.h>
  29.  
  30. #include <wx/ogl/mfutils.h>
  31. #include <stdio.h>
  32.  
  33. static char _buf[1024]; // a temp buffer to use inplace of wxBuffer, which is deprecated.
  34.  
  35. static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
  36.   'C', 'D', 'E', 'F' };
  37.  
  38. static void DecToHex(int dec, char *buf)
  39. {
  40.   int firstDigit = (int)(dec/16.0);
  41.   int secondDigit = (int)(dec - (firstDigit*16.0));
  42.   buf[0] = hexArray[firstDigit];
  43.   buf[1] = hexArray[secondDigit];
  44.   buf[2] = 0;
  45. }
  46.  
  47. // 16-bit unsigned integer
  48. static unsigned int getshort(FILE *fp)
  49. {
  50.   int c, c1;
  51.   c = getc(fp);  c1 = getc(fp);
  52.   unsigned int res = ((unsigned int) c) + (((unsigned int) c1) << 8);
  53.   return res;
  54. }
  55.  
  56. // 16-bit signed integer
  57. static int getsignedshort(FILE *fp)
  58. {
  59.   int c, c1;
  60.   c = getc(fp);  c1 = getc(fp);
  61.   int testRes = ((unsigned int) c) + (((unsigned int) c1) << 8);
  62.   unsigned long res1 = ((unsigned int) c) + (((unsigned int) c1) << 8);
  63.   int res = 0;
  64.   if (res1 > 32767)
  65.     res = (int)(res1 - 65536);
  66.   else
  67.     res = (int)(res1);
  68.   return res;
  69. }
  70.  
  71. // 32-bit integer
  72. static long getint(FILE *fp)
  73. {
  74.   int c, c1, c2, c3;
  75.   c = getc(fp);  c1 = getc(fp);  c2 = getc(fp);  c3 = getc(fp);
  76.   long res = (long)((long) c) +
  77.          (((long) c1) << 8) +
  78.      (((long) c2) << 16) +
  79.      (((long) c3) << 24);
  80.   return res;
  81. }
  82.  
  83.  
  84. /* Placeable metafile header
  85. struct mfPLACEABLEHEADER {
  86.     DWORD    key;         // 32-bit
  87.     HANDLE    hmf;         // 16-bit
  88.     RECT    bbox;        // 4x16 bit
  89.     WORD    inch;        // 16-bit
  90.     DWORD    reserved;    // 32-bit
  91.     WORD    checksum;    // 16-bit
  92. };
  93. */
  94.  
  95. wxMetaRecord::~wxMetaRecord(void)
  96. {
  97.   if (points) delete[] points;
  98.   if (stringParam) delete[] stringParam;
  99. }
  100.  
  101. wxXMetaFile::wxXMetaFile(const wxChar *file)
  102. {
  103.   ok = FALSE;
  104.   top = 0.0;
  105.   bottom = 0.0;
  106.   left = 0.0;
  107.   right = 0.0;
  108.  
  109.   if (file)
  110.     ok = ReadFile(file);
  111. }
  112.  
  113. /*
  114.   Handle table       gdiObjects
  115.   ------------       ----------
  116.   [0]                  wxPen
  117.   [1]----param2---     wxBrush
  118.   [2]             |    wxFont
  119.   [3]             | -> wxPen
  120.  
  121.  The handle table works as follows.
  122.  When a GDI object is created whilst reading in the
  123.  metafile, the (e.g.) createpen record is added to the
  124.  first free entry in the handle table. The createpen
  125.  record's param1 is a pointer to the actual wxPen, and
  126.  its param2 is the index into the gdiObjects list, which only
  127.  grows and never shrinks (unlike the handle table.)
  128.  
  129.  When SelectObject(index) is found, the index in the file
  130.  refers to the position in the handle table. BUT we then
  131.  set param2 to be the position of the wxPen in gdiObjects,
  132.  i.e. to param2 of the CreatePen record, itself found in
  133.  the handle table.
  134.  
  135.  When an object is deleted, the entry in the handletable is
  136.  NULLed but the gdiObjects entry is not removed (no point, and
  137.  allows us to create all GDI objects in advance of playing the
  138.  metafile).
  139. */
  140.  
  141.  
  142. static wxMetaRecord *HandleTable[100];
  143. static int HandleTableSize = 0;
  144.  
  145. void DeleteMetaRecordHandle(int index)
  146. {
  147.   HandleTable[index] = NULL;
  148. }
  149.  
  150. int AddMetaRecordHandle(wxMetaRecord *record)
  151. {
  152.   for (int i = 0; i < HandleTableSize; i++)
  153.     if (!HandleTable[i])
  154.     {
  155.       HandleTable[i] = record;
  156.       return i;
  157.     }
  158.   // No free spaces in table, so append.
  159.  
  160.   HandleTable[HandleTableSize] = record;
  161.   HandleTableSize ++;
  162.   return (HandleTableSize - 1);
  163. }
  164.  
  165. bool wxXMetaFile::ReadFile(const wxChar *file)
  166. {
  167.   HandleTableSize = 0;
  168.  
  169.   FILE *handle = wxFopen(file, wxT("rb"));
  170.   if (!handle) return FALSE;
  171.  
  172.   // Read placeable metafile header, if any
  173.   long key = getint(handle);
  174.  
  175.   if (key == (long) 0x9AC6CDD7)
  176.   {
  177.     long hmf = getshort(handle);
  178.     int iLeft, iTop, iRight, iBottom;
  179.     iLeft = getsignedshort(handle);
  180.     iTop = getsignedshort(handle);
  181.     iRight = getsignedshort(handle);
  182.     iBottom = getsignedshort(handle);
  183.  
  184.     left = (double)iLeft;
  185.     top = (double)iTop;
  186.     right = (double)iRight;
  187.     bottom = (double)iBottom;
  188.  
  189.     int inch = getshort(handle);
  190.     long reserved = getint(handle);
  191.     int checksum = getshort(handle);
  192. /*
  193.       double widthInUnits = (double)right - left;
  194.       double heightInUnits = (double)bottom - top;
  195.       *width = (int)((widthInUnits*1440.0)/inch);
  196.       *height = (int)((heightInUnits*1440.0)/inch);
  197. */
  198.   }
  199.   else rewind(handle);
  200.  
  201.   // Read METAHEADER
  202.   int mtType = getshort(handle);
  203.  
  204.   if (mtType != 1 && mtType != 2)
  205.   {
  206.     fclose(handle);
  207.     return FALSE;
  208.   }
  209.  
  210.   int mtHeaderSize = getshort(handle);
  211.   int mtVersion = getshort(handle);
  212.  
  213.   if (mtVersion != 0x0300 && mtVersion != 0x0100)
  214.   {
  215.     fclose(handle);
  216.     return FALSE;
  217.   }
  218.  
  219.   long mtSize = getint(handle);
  220.   int mtNoObjects = getshort(handle);
  221.   long mtMaxRecord = getint(handle);
  222.   int mtNoParameters = getshort(handle);
  223.  
  224.   while (!feof(handle))
  225.   {
  226.     long rdSize = getint(handle);      // 4 bytes
  227.     int rdFunction = getshort(handle); // 2 bytes
  228.     if (feof(handle))
  229.       break;
  230.  
  231.     switch (rdFunction)
  232.     {
  233.       case META_SETBKCOLOR:
  234.       {
  235.         wxMetaRecord *rec = new wxMetaRecord(META_SETBKCOLOR);
  236.         long colorref = getint(handle); // COLORREF
  237.         rec->param1 = GetRValue(colorref);
  238.         rec->param2 = GetGValue(colorref);
  239.         rec->param3 = GetBValue(colorref);
  240.         metaRecords.Append(rec);
  241.         break;
  242.       }
  243.       case META_SETBKMODE:
  244.       {
  245.         wxMetaRecord *rec = new wxMetaRecord(META_SETBKMODE);
  246.         rec->param1 = getshort(handle); // Background mode
  247.         if (rec->param1 == OPAQUE) rec->param1 = wxSOLID;
  248.         else rec->param1 = wxTRANSPARENT;
  249.         metaRecords.Append(rec);
  250.         break;
  251.       }
  252.       case META_SETMAPMODE:
  253.       {
  254.         wxMetaRecord *rec = new wxMetaRecord(META_SETMAPMODE);
  255.         rec->param1 = getshort(handle);
  256.         metaRecords.Append(rec);
  257.         break;
  258.       }
  259. //      case META_SETROP2:
  260. //      case META_SETRELABS:
  261. //      case META_SETPOLYFILLMODE:
  262. //      case META_SETSTRETCHBLTMODE:
  263. //      case META_SETTEXTCHAREXTRA:
  264.       case META_SETTEXTCOLOR:
  265.       {
  266.         wxMetaRecord *rec = new wxMetaRecord(META_SETTEXTCOLOR);
  267.         long colorref = getint(handle); // COLORREF
  268.         rec->param1 = GetRValue(colorref);
  269.         rec->param2 = GetGValue(colorref);
  270.         rec->param3 = GetBValue(colorref);
  271.         metaRecords.Append(rec);
  272.         break;
  273.       }
  274. //      case META_SETTEXTJUSTIFICATION:
  275.       case META_SETWINDOWORG:
  276.       {
  277.         wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWORG);
  278.         rec->param2 = getshort(handle);
  279.         rec->param1 = getshort(handle);
  280.         metaRecords.Append(rec);
  281.         break;
  282.       }
  283.       case META_SETWINDOWEXT:
  284.       {
  285.         wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWEXT);
  286.         rec->param2 = getshort(handle);
  287.         rec->param1 = getshort(handle);
  288.         metaRecords.Append(rec);
  289.         break;
  290.       }
  291. //      case META_SETVIEWPORTORG:
  292. //      case META_SETVIEWPORTEXT:
  293. //      case META_OFFSETWINDOWORG:
  294. //      case META_SCALEWINDOWEXT:
  295. //      case META_OFFSETVIEWPORTORG:
  296. //      case META_SCALEVIEWPORTEXT:
  297.       case META_LINETO:
  298.       {
  299.         wxMetaRecord *rec = new wxMetaRecord(META_LINETO);
  300.         rec->param1 = getshort(handle); // x1
  301.         rec->param2 = getshort(handle); // y1
  302.         metaRecords.Append(rec);
  303.         break;
  304.       }
  305.       case META_MOVETO:
  306.       {
  307.         wxMetaRecord *rec = new wxMetaRecord(META_MOVETO);
  308.         rec->param1 = getshort(handle); // x1
  309.         rec->param2 = getshort(handle); // y1
  310.         metaRecords.Append(rec);
  311.         break;
  312.       }
  313.       case META_EXCLUDECLIPRECT:
  314.       {
  315.         wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT);
  316.         rec->param4 = getshort(handle); // y2
  317.         rec->param3 = getshort(handle); // x2
  318.         rec->param2 = getshort(handle); // y1
  319.         rec->param1 = getshort(handle); // x1
  320.         metaRecords.Append(rec);
  321.         break;
  322.       }
  323.       case META_INTERSECTCLIPRECT:
  324.       {
  325.         wxMetaRecord *rec = new wxMetaRecord(META_INTERSECTCLIPRECT);
  326.         rec->param4 = getshort(handle); // y2
  327.         rec->param3 = getshort(handle); // x2
  328.         rec->param2 = getshort(handle); // y1
  329.         rec->param1 = getshort(handle); // x1
  330.         metaRecords.Append(rec);
  331.         break;
  332.       }
  333. //      case META_ARC: // DO!!!
  334.       case META_ELLIPSE:
  335.       {
  336.         wxMetaRecord *rec = new wxMetaRecord(META_ELLIPSE);
  337.         rec->param4 = getshort(handle); // y2
  338.         rec->param3 = getshort(handle); // x2
  339.         rec->param2 = getshort(handle); // y1
  340.         rec->param1 = getshort(handle); // x1
  341.         metaRecords.Append(rec);
  342.         break;
  343.       }
  344. //      case META_FLOODFILL:
  345. //      case META_PIE: // DO!!!
  346.       case META_RECTANGLE:
  347.       {
  348.         wxMetaRecord *rec = new wxMetaRecord(META_RECTANGLE);
  349.         rec->param4 = getshort(handle); // y2
  350.         rec->param3 = getshort(handle); // x2
  351.         rec->param2 = getshort(handle); // y1
  352.         rec->param1 = getshort(handle); // x1
  353.         metaRecords.Append(rec);
  354.         break;
  355.       }
  356.       case META_ROUNDRECT:
  357.       {
  358.         wxMetaRecord *rec = new wxMetaRecord(META_ROUNDRECT);
  359.         rec->param6 = getshort(handle); // width
  360.         rec->param5 = getshort(handle); // height
  361.         rec->param4 = getshort(handle); // y2
  362.         rec->param3 = getshort(handle); // x2
  363.         rec->param2 = getshort(handle); // y1
  364.         rec->param1 = getshort(handle); // x1
  365.         metaRecords.Append(rec);
  366.         break;
  367.       }
  368. //      case META_PATBLT:
  369. //      case META_SAVEDC:
  370.       case META_SETPIXEL:
  371.       {
  372.         wxMetaRecord *rec = new wxMetaRecord(META_SETPIXEL);
  373.         rec->param1 = getshort(handle); // x1
  374.         rec->param2 = getshort(handle); // y1
  375.         rec->param3 = getint(handle);   // COLORREF
  376.         metaRecords.Append(rec);
  377.         break;
  378.       }
  379. //      case META_OFFSETCLIPRGN:
  380.       case META_TEXTOUT:
  381.       {
  382.         wxMetaRecord *rec = new wxMetaRecord(META_TEXTOUT);
  383.         int count = getshort(handle);
  384.         rec->stringParam = new wxChar[count+1];
  385.         fread((void *)rec->stringParam, sizeof(wxChar), count, handle);
  386.         rec->stringParam[count] = 0;
  387.         rec->param2 = getshort(handle); // Y
  388.         rec->param1 = getshort(handle); // X
  389.         metaRecords.Append(rec);
  390.         break;
  391.       }
  392. /*
  393.       case META_EXTTEXTOUT:
  394.       {
  395.         wxMetaRecord *rec = new wxMetaRecord(META_EXTTEXTOUT);
  396.         int cellSpacing = getshort(handle);
  397.         int count = getshort(handle);
  398.         rec->stringParam = new char[count+1];
  399.         fread((void *)rec->stringParam, sizeof(char), count, handle);
  400.         rec->stringParam[count] = 0;
  401.         // Rectangle
  402.         int rectY2 = getshort(handle);
  403.         int rectX2 = getshort(handle);
  404.         int rectY1 = getshort(handle);
  405.         int rectX1 = getshort(handle);
  406.         int rectType = getshort(handle);
  407.         rec->param2 = getshort(handle); // Y
  408.         rec->param1 = getshort(handle); // X
  409.         metaRecords.Append(rec);
  410.         break;
  411.       }
  412. */
  413. //      case META_BITBLT:
  414. //      case META_STRETCHBLT:
  415.       case META_POLYGON:
  416.       {
  417.         wxMetaRecord *rec = new wxMetaRecord(META_POLYGON);
  418.         rec->param1 = getshort(handle);
  419.         rec->points = new wxRealPoint[(int)rec->param1];
  420.         for (int i = 0; i < rec->param1; i++)
  421.         {
  422.           rec->points[i].x = getshort(handle);
  423.           rec->points[i].y = getshort(handle);
  424.         }
  425.  
  426.         metaRecords.Append(rec);
  427.         break;
  428.       }
  429.       case META_POLYLINE:
  430.       {
  431.         wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE);
  432.         rec->param1 = (long)getshort(handle);
  433.         rec->points = new wxRealPoint[(int)rec->param1];
  434.         for (int i = 0; i < rec->param1; i++)
  435.         {
  436.           rec->points[i].x = getshort(handle);
  437.           rec->points[i].y = getshort(handle);
  438.         }
  439.  
  440.         metaRecords.Append(rec);
  441.         break;
  442.       }
  443. //      case META_ESCAPE:
  444. //      case META_RESTOREDC:
  445. //      case META_FILLREGION:
  446. //      case META_FRAMEREGION:
  447. //      case META_INVERTREGION:
  448. //      case META_PAINTREGION:
  449. //      case META_SELECTCLIPREGION: // DO THIS!
  450.       case META_SELECTOBJECT:
  451.       {
  452.         wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT);
  453.         rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list
  454.         metaRecords.Append(rec);
  455.         // param2 gives the index into gdiObjects, which is different from
  456.         // the index into the handle table.
  457.         rec->param2 = HandleTable[(int)rec->param1]->param2;
  458.         break;
  459.       }
  460. //      case META_SETTEXTALIGN:
  461. //      case META_DRAWTEXT:
  462. //      case META_CHORD:
  463. //      case META_SETMAPPERFLAGS:
  464. //      case META_EXTTEXTOUT:
  465. //      case META_SETDIBTODEV:
  466. //      case META_SELECTPALETTE:
  467. //      case META_REALIZEPALETTE:
  468. //      case META_ANIMATEPALETTE:
  469. //      case META_SETPALENTRIES:
  470. //      case META_POLYPOLYGON:
  471. //      case META_RESIZEPALETTE:
  472. //      case META_DIBBITBLT:
  473. //      case META_DIBSTRETCHBLT:
  474.       case META_DIBCREATEPATTERNBRUSH:
  475.       {
  476.         wxMetaRecord *rec = new wxMetaRecord(META_DIBCREATEPATTERNBRUSH);
  477.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  478.  
  479.         metaRecords.Append(rec);
  480.         gdiObjects.Append(rec);
  481.         AddMetaRecordHandle(rec);
  482.         rec->param2 = (long)(gdiObjects.Number() - 1);
  483.         break;
  484.       }
  485. //      case META_STRETCHDIB:
  486. //      case META_EXTFLOODFILL:
  487. //      case META_RESETDC:
  488. //      case META_STARTDOC:
  489. //      case META_STARTPAGE:
  490. //      case META_ENDPAGE:
  491. //      case META_ABORTDOC:
  492. //      case META_ENDDOC:
  493.       case META_DELETEOBJECT:
  494.       {
  495.         int index = getshort(handle);
  496.         DeleteMetaRecordHandle(index);
  497.         break;
  498.       }
  499.       case META_CREATEPALETTE:
  500.       {
  501.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE);
  502.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  503.  
  504.         metaRecords.Append(rec);
  505.         gdiObjects.Append(rec);
  506.         AddMetaRecordHandle(rec);
  507.         rec->param2 = (long)(gdiObjects.Number() - 1);
  508.         break;
  509.       }
  510.       case META_CREATEBRUSH:
  511.       {
  512.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSH);
  513.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  514.         metaRecords.Append(rec);
  515.         gdiObjects.Append(rec);
  516.         AddMetaRecordHandle(rec);
  517.         rec->param2 = (long)(gdiObjects.Number() - 1);
  518.         break;
  519.       }
  520.       case META_CREATEPATTERNBRUSH:
  521.       {
  522.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEPATTERNBRUSH);
  523.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  524.         metaRecords.Append(rec);
  525.         gdiObjects.Append(rec);
  526.         AddMetaRecordHandle(rec);
  527.         rec->param2 = (long)(gdiObjects.Number() - 1);
  528.         break;
  529.       }
  530.       case META_CREATEPENINDIRECT:
  531.       {
  532.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEPENINDIRECT);
  533.         int msStyle = getshort(handle); // Style: 2 bytes
  534.         int x = getshort(handle); // X:     2 bytes
  535.         int y = getshort(handle); // Y:     2 bytes
  536.         long colorref = getint(handle); // COLORREF 4 bytes
  537.  
  538.         int style;
  539.         if (msStyle == PS_DOT)
  540.           style = wxDOT;
  541.         else if (msStyle == PS_DASH)
  542.           style = wxSHORT_DASH;
  543.         else if (msStyle == PS_NULL)
  544.           style = wxTRANSPARENT;
  545.         else style = wxSOLID;
  546.  
  547.         wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
  548.         rec->param1 = (long)wxThePenList->FindOrCreatePen(colour, x, style);
  549.         metaRecords.Append(rec);
  550.         gdiObjects.Append(rec);
  551.  
  552.         AddMetaRecordHandle(rec);
  553.         rec->param2 = (long)(gdiObjects.Number() - 1);
  554.  
  555.         // For some reason, the size of this record is sometimes 9 words!!!
  556.         // instead of the usual 8. So read 2 characters extra.
  557.         if (rdSize == 9)
  558.         {
  559.           (void) getshort(handle);
  560.         }
  561.         break;
  562.       }
  563.       case META_CREATEFONTINDIRECT:
  564.       {
  565.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEFONTINDIRECT);
  566.         int lfHeight = getshort(handle);    // 2 bytes
  567.         int lfWidth = getshort(handle);     // 2 bytes
  568.         int lfEsc = getshort(handle);       // 2 bytes
  569.         int lfOrient = getshort(handle);    // 2 bytes
  570.         int lfWeight = getshort(handle);    // 2 bytes
  571.         char lfItalic = getc(handle);       // 1 byte
  572.         char lfUnderline = getc(handle);    // 1 byte
  573.         char lfStrikeout = getc(handle);    // 1 byte
  574.         char lfCharSet = getc(handle);      // 1 byte
  575.         char lfOutPrecision = getc(handle); // 1 byte
  576.         char lfClipPrecision = getc(handle); // 1 byte
  577.         char lfQuality = getc(handle);      // 1 byte
  578.         char lfPitchAndFamily = getc(handle);   // 1 byte (18th)
  579.         char lfFacename[32];
  580.         // Read the rest of the record, which is total record size
  581.         // minus the number of bytes already read (18 record, 6 metarecord
  582.         // header)
  583.         fread((void *)lfFacename, sizeof(char), (int)((2*rdSize) - 18 - 6), handle);
  584.  
  585.         int family;
  586.         if (lfPitchAndFamily & FF_MODERN)
  587.           family = wxMODERN;
  588.         else if (lfPitchAndFamily & FF_MODERN)
  589.           family = wxMODERN;
  590.         else if (lfPitchAndFamily & FF_ROMAN)
  591.           family = wxROMAN;
  592.         else if (lfPitchAndFamily & FF_SWISS)
  593.           family = wxSWISS;
  594.         else if (lfPitchAndFamily & FF_DECORATIVE)
  595.           family = wxDECORATIVE;
  596.         else
  597.           family = wxDEFAULT;
  598.  
  599.         int weight;
  600.         if (lfWeight == 300)
  601.           weight = wxLIGHT;
  602.         else if (lfWeight == 400)
  603.           weight = wxNORMAL;
  604.         else if (lfWeight == 900)
  605.           weight = wxBOLD;
  606.         else weight = wxNORMAL;
  607.  
  608.         int style;
  609.         if (lfItalic != 0)
  610.           style = wxITALIC;
  611.         else
  612.           style = wxNORMAL;
  613.  
  614.         // About how many pixels per inch???
  615.         int logPixelsY = 100;
  616.         int pointSize = (int)(lfHeight*72.0/logPixelsY);
  617.  
  618.         wxFont *theFont =
  619.           wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (lfUnderline != 0));
  620.  
  621.         rec->param1 = (long) theFont;
  622.         metaRecords.Append(rec);
  623.         gdiObjects.Append(rec);
  624.         AddMetaRecordHandle(rec);
  625.         rec->param2 = (long)(gdiObjects.Number() - 1);
  626.         break;
  627.       }
  628.       case META_CREATEBRUSHINDIRECT:
  629.       {
  630.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSHINDIRECT);
  631.         int msStyle = getshort(handle); // Style: 2 bytes
  632.         long colorref = getint(handle);   // COLORREF: 4 bytes
  633.         int hatchStyle = getshort(handle); // Hatch style 2 bytes
  634.  
  635.         int style;
  636.         switch (msStyle)
  637.         {
  638.           case BS_HATCHED:
  639.           {
  640.             switch (hatchStyle)
  641.             {
  642.               case HS_BDIAGONAL:
  643.                 style = wxBDIAGONAL_HATCH;
  644.                 break;
  645.               case HS_DIAGCROSS:
  646.                 style = wxCROSSDIAG_HATCH;
  647.                 break;
  648.               case HS_FDIAGONAL:
  649.                 style = wxFDIAGONAL_HATCH;
  650.                 break;
  651.               case HS_HORIZONTAL:
  652.                 style = wxHORIZONTAL_HATCH;
  653.                 break;
  654.               case HS_VERTICAL:
  655.                 style = wxVERTICAL_HATCH;
  656.                 break;
  657.               default:
  658.               case HS_CROSS:
  659.                 style = wxCROSS_HATCH;
  660.                 break;
  661.             }
  662.             break;
  663.           }
  664.           case BS_SOLID:
  665.           default:
  666.             style = wxSOLID;
  667.             break;
  668.         }
  669.         if (msStyle == PS_DOT)
  670.           style = wxDOT;
  671.         else if (msStyle == PS_DASH)
  672.           style = wxSHORT_DASH;
  673.         else if (msStyle == PS_NULL)
  674.           style = wxTRANSPARENT;
  675.         else style = wxSOLID;
  676.  
  677.         wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
  678.         rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(colour, style);
  679.         metaRecords.Append(rec);
  680.         gdiObjects.Append(rec);
  681.         AddMetaRecordHandle(rec);
  682.         rec->param2 = (long)(gdiObjects.Number() - 1);
  683.         break;
  684.       }
  685.       case META_CREATEBITMAPINDIRECT:
  686.       {
  687.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAPINDIRECT);
  688.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  689.  
  690.         metaRecords.Append(rec);
  691.         gdiObjects.Append(rec);
  692.         AddMetaRecordHandle(rec);
  693.         rec->param2 = (long)(gdiObjects.Number() - 1);
  694.         break;
  695.       }
  696.       case META_CREATEBITMAP:
  697.       {
  698.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAP);
  699.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  700.  
  701.         metaRecords.Append(rec);
  702.         gdiObjects.Append(rec);
  703.         AddMetaRecordHandle(rec);
  704.         rec->param2 = (long)(gdiObjects.Number() - 1);
  705.         break;
  706.       }
  707.       case META_CREATEREGION:
  708.       {
  709.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEREGION);
  710.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  711.  
  712.         metaRecords.Append(rec);
  713.         gdiObjects.Append(rec);
  714.         AddMetaRecordHandle(rec);
  715.         rec->param2 = (long)(gdiObjects.Number() - 1);
  716.         break;
  717.       }
  718.       default:
  719.       {
  720.         fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
  721.         break;
  722.       }
  723.     }
  724.   }
  725.   fclose(handle);
  726.   return TRUE;
  727. }
  728.  
  729. wxXMetaFile::~wxXMetaFile(void)
  730. {
  731.   wxNode *node = metaRecords.First();
  732.   while (node)
  733.   {
  734.     wxMetaRecord *rec = (wxMetaRecord *)node->Data();
  735.     delete rec;
  736.     wxNode *next = node->Next();
  737.     delete node;
  738.     node = next;
  739.   }
  740. }
  741.  
  742. bool wxXMetaFile::SetClipboard(int width, int height)
  743. {
  744.   return FALSE;
  745. }
  746.  
  747. bool wxXMetaFile::Play(wxDC *dc)
  748. {
  749.   wxNode *node = metaRecords.First();
  750.   while (node)
  751.   {
  752.     wxMetaRecord *rec = (wxMetaRecord *)node->Data();
  753.     int rdFunction = rec->metaFunction;
  754.  
  755.     switch (rdFunction)
  756.     {
  757.       case META_SETBKCOLOR:
  758.       {
  759.         break;
  760.       }
  761.       case META_SETBKMODE:
  762.       {
  763.         break;
  764.       }
  765.       case META_SETMAPMODE:
  766.       {
  767.         break;
  768.       }
  769. //      case META_SETROP2:
  770. //      case META_SETRELABS:
  771. //      case META_SETPOLYFILLMODE:
  772. //      case META_SETSTRETCHBLTMODE:
  773. //      case META_SETTEXTCHAREXTRA:
  774.       case META_SETTEXTCOLOR:
  775.       {
  776.         break;
  777.       }
  778. //      case META_SETTEXTJUSTIFICATION:
  779.       case META_SETWINDOWORG:
  780.       {
  781.         break;
  782.       }
  783.       case META_SETWINDOWEXT:
  784.       {
  785.         break;
  786.       }
  787. //      case META_SETVIEWPORTORG:
  788. //      case META_SETVIEWPORTEXT:
  789. //      case META_OFFSETWINDOWORG:
  790. //      case META_SCALEWINDOWEXT:
  791. //      case META_OFFSETVIEWPORTORG:
  792. //      case META_SCALEVIEWPORTEXT:
  793.       case META_LINETO:
  794.       {
  795.         long x1 = rec->param1;
  796.         long y1 = rec->param2;
  797.         dc->DrawLine((long) lastX, (long) lastY, x1, y1);
  798.         break;
  799.       }
  800.       case META_MOVETO:
  801.       {
  802.         lastX = (double)rec->param1;
  803.         lastY = (double)rec->param2;
  804.         break;
  805.       }
  806.       case META_EXCLUDECLIPRECT:
  807.       {
  808.         break;
  809.       }
  810.       case META_INTERSECTCLIPRECT:
  811.       {
  812.         break;
  813.       }
  814. //      case META_ARC: // DO!!!
  815.       case META_ELLIPSE:
  816.       {
  817.         break;
  818.       }
  819. //      case META_FLOODFILL:
  820. //      case META_PIE: // DO!!!
  821.       case META_RECTANGLE:
  822.       {
  823.         dc->DrawRectangle((long)rec->param1, (long)rec->param2,
  824.                           (long)rec->param3 - rec->param1,
  825.                           (long)rec->param4 - rec->param2);
  826.         break;
  827.       }
  828.       case META_ROUNDRECT:
  829.       {
  830.         dc->DrawRoundedRectangle((long)rec->param1, (long)rec->param2,
  831.                           (long)rec->param3 - rec->param1,
  832.                           (long)rec->param4 - rec->param2,
  833.                           (long)rec->param5);
  834.         break;
  835.       }
  836. //      case META_PATBLT:
  837. //      case META_SAVEDC:
  838.       case META_SETPIXEL:
  839.       {
  840. //        rec->param1 = getshort(handle); // x1
  841. //        rec->param2 = getshort(handle); // y1
  842. //        rec->param3 = getint(handle);   // COLORREF
  843.         break;
  844.       }
  845. //      case META_OFFSETCLIPRGN:
  846.       case META_TEXTOUT:
  847.       {
  848. /*
  849.         int count = getshort(handle);
  850.         rec->stringParam = new char[count+1];
  851.         fread((void *)rec->stringParam, sizeof(char), count, handle);
  852.         rec->stringParam[count] = 0;
  853.         rec->param2 = getshort(handle); // Y
  854.         rec->param1 = getshort(handle); // X
  855. */
  856.         break;
  857.       }
  858. //      case META_BITBLT:
  859. //      case META_STRETCHBLT:
  860.       case META_POLYGON:
  861.       {
  862. /*
  863.         rec->param1 = getshort(handle);
  864.         rec->points = new wxRealPoint[(int)rec->param1];
  865.         for (int i = 0; i < rec->param1; i++)
  866.         {
  867.           rec->points[i].x = getshort(handle);
  868.           rec->points[i].y = getshort(handle);
  869.         }
  870. */
  871.         break;
  872.       }
  873.       case META_POLYLINE:
  874.       {
  875. /*
  876.         wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE);
  877.         rec->param1 = (long)getshort(handle);
  878.         rec->points = new wxRealPoint[(int)rec->param1];
  879.         for (int i = 0; i < rec->param1; i++)
  880.         {
  881.           rec->points[i].x = getshort(handle);
  882.           rec->points[i].y = getshort(handle);
  883.         }
  884. */
  885.         break;
  886.       }
  887. //      case META_ESCAPE:
  888. //      case META_RESTOREDC:
  889. //      case META_FILLREGION:
  890. //      case META_FRAMEREGION:
  891. //      case META_INVERTREGION:
  892. //      case META_PAINTREGION:
  893. //      case META_SELECTCLIPREGION: // DO THIS!
  894.       case META_SELECTOBJECT:
  895.       {
  896. /*
  897.         wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT);
  898.         rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list
  899. */
  900.         break;
  901.       }
  902. //      case META_SETTEXTALIGN:
  903. //      case META_DRAWTEXT:
  904. //      case META_CHORD:
  905. //      case META_SETMAPPERFLAGS:
  906. //      case META_EXTTEXTOUT:
  907. //      case META_SETDIBTODEV:
  908. //      case META_SELECTPALETTE:
  909. //      case META_REALIZEPALETTE:
  910. //      case META_ANIMATEPALETTE:
  911. //      case META_SETPALENTRIES:
  912. //      case META_POLYPOLYGON:
  913. //      case META_RESIZEPALETTE:
  914. //      case META_DIBBITBLT:
  915. //      case META_DIBSTRETCHBLT:
  916.       case META_DIBCREATEPATTERNBRUSH:
  917.       {
  918. /*
  919.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  920. */
  921.         break;
  922.       }
  923. //      case META_STRETCHDIB:
  924. //      case META_EXTFLOODFILL:
  925. //      case META_RESETDC:
  926. //      case META_STARTDOC:
  927. //      case META_STARTPAGE:
  928. //      case META_ENDPAGE:
  929. //      case META_ABORTDOC:
  930. //      case META_ENDDOC:
  931. //      case META_DELETEOBJECT: // DO!!
  932.       case META_CREATEPALETTE:
  933.       {
  934. /*
  935.         wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE);
  936.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  937. */
  938.         break;
  939.       }
  940.       case META_CREATEBRUSH:
  941.       {
  942. /*
  943.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  944. */
  945.         break;
  946.       }
  947.       case META_CREATEPATTERNBRUSH:
  948.       {
  949. /*
  950.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  951. */
  952.         break;
  953.       }
  954.       case META_CREATEPENINDIRECT:
  955.       {
  956. /*
  957.         int msStyle = getshort(handle); // Style: 2 bytes
  958.         int x = getshort(handle); // X:     2 bytes
  959.         int y = getshort(handle); // Y:     2 bytes
  960.         int colorref = getint(handle); // COLORREF 4 bytes
  961.  
  962.         int style;
  963.         if (msStyle == PS_DOT)
  964.           style = wxDOT;
  965.         else if (msStyle == PS_DASH)
  966.           style = wxSHORT_DASH;
  967.         else if (msStyle == PS_NULL)
  968.           style = wxTRANSPARENT;
  969.         else style = wxSOLID;
  970.  
  971.         wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
  972.         rec->param1 = (long)wxThePenList->FindOrCreatePen(&colour, x, style);
  973. */
  974.         break;
  975.       }
  976.       case META_CREATEFONTINDIRECT:
  977.       {
  978. /*
  979.         int lfHeight = getshort(handle);
  980.         int lfWidth = getshort(handle);
  981.         int lfEsc = getshort(handle);
  982.         int lfOrient = getshort(handle);
  983.         int lfWeight = getshort(handle);
  984.         char lfItalic = getc(handle);
  985.         char lfUnderline = getc(handle);
  986.         char lfStrikeout = getc(handle);
  987.         char lfCharSet = getc(handle);
  988.         char lfOutPrecision = getc(handle);
  989.         char lfClipPrecision = getc(handle);
  990.         char lfQuality = getc(handle);
  991.         char lfPitchAndFamily = getc(handle);
  992.         char lfFacename[32];
  993.         fread((void *)lfFacename, sizeof(char), 32, handle);
  994.  
  995.         int family;
  996.         if (lfPitchAndFamily & FF_MODERN)
  997.           family = wxMODERN;
  998.         else if (lfPitchAndFamily & FF_MODERN)
  999.           family = wxMODERN;
  1000.         else if (lfPitchAndFamily & FF_ROMAN)
  1001.           family = wxROMAN;
  1002.         else if (lfPitchAndFamily & FF_SWISS)
  1003.           family = wxSWISS;
  1004.         else if (lfPitchAndFamily & FF_DECORATIVE)
  1005.           family = wxDECORATIVE;
  1006.         else
  1007.           family = wxDEFAULT;
  1008.  
  1009.         int weight;
  1010.         if (lfWeight == 300)
  1011.           weight = wxLIGHT;
  1012.         else if (lfWeight == 400)
  1013.           weight = wxNORMAL;
  1014.         else if (lfWeight == 900)
  1015.           weight = wxBOLD;
  1016.         else weight = wxNORMAL;
  1017.  
  1018.         int style;
  1019.         if ((bool)lfItalic)
  1020.           style = wxITALIC;
  1021.         else
  1022.           style = wxNORMAL;
  1023.  
  1024.         // About how many pixels per inch???
  1025.         int logPixelsY = 100;
  1026.         int pointSize = (int)(lfHeight*72.0/logPixelsY);
  1027.  
  1028.         wxFont *theFont =
  1029.           wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (bool)lfUnderline);
  1030.  
  1031.         rec->param1 = (long)theFont;
  1032. */
  1033.         break;
  1034.       }
  1035.       case META_CREATEBRUSHINDIRECT:
  1036.       {
  1037. /*
  1038.         int msStyle = getshort(handle); // Style: 2 bytes
  1039.         int colorref = getint(handle);   // COLORREF: 4 bytes
  1040.         int hatchStyle = getshort(handle); // Hatch style 2 bytes
  1041.  
  1042.         int style;
  1043.         if (msStyle == PS_DOT)
  1044.           style = wxDOT;
  1045.         else if (msStyle == PS_DASH)
  1046.           style = wxSHORT_DASH;
  1047.         else if (msStyle == PS_NULL)
  1048.           style = wxTRANSPARENT;
  1049.         else style = wxSOLID;
  1050.  
  1051.         wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
  1052.         rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(&colour, wxSOLID);
  1053. */
  1054.         break;
  1055.       }
  1056.       case META_CREATEBITMAPINDIRECT:
  1057.       {
  1058. /*
  1059.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  1060. */
  1061.         break;
  1062.       }
  1063.       case META_CREATEBITMAP:
  1064.       {
  1065. /*
  1066.         fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
  1067. */
  1068.         break;
  1069.       }
  1070.       case META_CREATEREGION:
  1071.       {
  1072.         dc->DestroyClippingRegion();
  1073. /*
  1074.         rec->param1 = getshort(handle); // Style: 2 bytes
  1075. */
  1076.         break;
  1077.       }
  1078.       default:
  1079.       {
  1080.         break;
  1081.       }
  1082.     }
  1083.     node = node->Next();
  1084.   }
  1085.   return TRUE;
  1086. }
  1087.  
  1088.