TRACE.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2009 OpenFX Development Team
00004 -- */
00005 
00006 /*  TRACE.C  DLL to trace round image file by hand */
00007 
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <math.h>
00011 #include <setjmp.h>
00012 #include <windows.h>
00013 #include <commctrl.h>
00014 
00015 #include "struct.h"
00016 #include "callback.h"
00017 #include "dstruct.h"
00018 
00019 #include "trace.h"
00020 
00021 typedef struct tagMENUHELPDATA{
00022   int iCode;
00023   char *str;
00024 } MENUHELPDATA;
00025 
00026 #if __X__MIPS__
00027 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00028 #endif
00029 
00030 #define DESELECTED 0
00031 #define SELECTED   1
00032 
00033 #define FI_DIB 0
00034 #define FI_GIF 1
00035 #define FI_TGA 2
00036 //#define FI_CEL 3
00037 #define PALVERSION  0x300
00038 #define MAXPALETTE  256
00039 #define MAXTEXT     256
00040 
00041 extern short read_gif_image(char *, short);
00042 extern unsigned char p_red[],p_green[],p_blue[];
00043 extern int colourmap_size,x_size,y_size,gif_iLace;
00044 
00045 static HWND      hParent,hInfo;
00046 static HINSTANCE hThisInstance;
00047 static HPALETTE  hpalCurrent    = NULL;         /* Handle to current palette            */
00048 static HBITMAP   hbmCurrent     = NULL;         /* Handle to current memory BITMAP      */
00049 static RGBQUAD   *pRgb          = NULL;
00050 static LPSTR     lpBitmapHeader = NULL;
00051 static LPSTR     lpBitmapBits   = NULL;
00052 
00053 #define BOUND(x,min,max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
00054 #define SWAP(x,y)   ((x)^=(y)^=(x)^=(y))
00055 #define MIN(x,y) (((x) <= (y)) : x ? y)
00056 #define StartWait() hcurSave = SetCursor(LoadCursor(NULL,IDC_WAIT))
00057 #define EndWait()   SetCursor(hcurSave)
00058 /* macro to determine if resource is a DIB */
00059 #define ISDIB(bft) ((bft) == BFT_BITMAP)
00060 /* Macro to align given value to the closest DWORD (unsigned long ) */
00061 #define ALIGNULONG(i)   ((i+3)/4*4)
00062 /* Macro to determine to round off the given value to the closest byte */
00063 #define WIDTHBYTES(i)   ((i+31)/32*4)
00064 
00065 static char *szViewClass="OFX:TraceClass";
00066 static char ghFilename[255];
00067 static SYSTEM_INFO sys_info;
00068 static int DisplayWidth,DisplayHeight,DisplayBits,DisplayPlanes,
00069            xScreen,yScreen,rowcount,rowinc,x4_size,file_format=FI_GIF;
00070 static LPSTR pixels;
00071 static POINT ptSize;
00072 static DWORD fdwStyle = WS_POPUP | WS_CAPTION | ! WS_SYSMENU |
00073                         WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;
00074 static HCURSOR hcurSave;
00075 
00076 static int pen=0,stretched=1,tracetool=0;
00077 static long Lv= -1,Fv= -1,Nv=0,Ne=0;
00078 static struct TVLIST {BOOL inc; int x,y; long id;}  *TVlist=NULL;
00079 static struct TELIST {BOOL inc; int v1,v2;}         *TElist=NULL;
00080 #define NMENUHELPDATA 12
00081 static MENUHELPDATA MenuHelpData[NMENUHELPDATA]={
00082   0xFFFF,             "   ",
00083   IDM_PEN_RED,        "Draw vertices  and edges with RED pen",
00084   IDM_PEN_WHITE,      "Draw vertices  and edges with WHITE pen",
00085   IDM_PEN_BLACK,      "Draw vertices  and edges with BLACK pen",
00086   IDM_PEN_CYAN,       "Draw vertices  and edges with CYAN pen",
00087   IDM_ADD,            "Click to add vertex, click RIGHT button to end sequence",
00088   IDM_MOVE,           "Click on vertex to pick it up, drag to new position, click to put it down",
00089   IDM_DELETE,         "Click on vertex to delete it",
00090   IDM_INSERT,         "Click on vertex to break in two edges attached to vertex",
00091   IDM_EXIT,           "Finish and make the draw edges and vertices",
00092   IDM_ABORT,          "Cancel the function and to NOT make the edges and vertices",
00093   IDM_STRETCH,        "Stretch the image to fill the window or draw it actual size"
00094 };
00095 
00096 static int identify_file_format(void);
00097 static int ErrMsg(char *sz,...);
00098 static void PutMsg(char *s);
00099 static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam);
00100 static BOOL MenuCommand(HWND hWnd, WORD id);
00101 static int identify_file_format(void);
00102 static void FreeDib(void);
00103 static void SizeWindow(HWND hWnd);
00104 static HPALETTE CreateImagePalette(LPBITMAPINFOHEADER lpbi);
00105 static WORD NumColours(LPBITMAPINFOHEADER lpbi);
00106 static void AppPaint(HWND hWnd, HDC hDC, int x, int y);
00107 static HBITMAP BitmapFromDib(LPSTR lpHeader,LPSTR lpBits,HPALETTE hpal);
00108 //static int celview(HWND hWnd,char *filename);
00109 static BOOL Viewer(void);
00110 static void DrawRubberLine(HWND hwnd, int x, int y);
00111 static void DrawRubberLines(HWND hwnd, int x, int y);
00112 static void DrawList(HWND hwnd, HDC hDC);
00113 static void AddTraceVertex(int x,int y);
00114 static int GetVertexAtCursor(int x, int y);
00115 static void MoveVertex(HWND hWnd, int x, int y);
00116 static void TraceSubdivide(long v);
00117 static void BuildFromTrace(HWND hWnd);
00118 
00119 static BOOL Viewer(void){
00120  MSG msg;
00121  HWND hDesktopWnd,hWnd;
00122  HDC hDCcaps;
00123  WNDCLASS wndclass;
00124  TVlist=NULL; TElist=NULL; Nv=0; Ne=0;
00125  hDesktopWnd = GetDesktopWindow();
00126  hDCcaps     = GetDC(hDesktopWnd);
00127  DisplayWidth= GetDeviceCaps(hDCcaps,HORZRES);
00128  DisplayHeight= GetDeviceCaps(hDCcaps,VERTRES);
00129  DisplayBits= GetDeviceCaps(hDCcaps,BITSPIXEL);
00130  DisplayPlanes= GetDeviceCaps(hDCcaps,PLANES);
00131  ReleaseDC(hDesktopWnd,hDCcaps);
00132  GetSystemInfo(&sys_info);
00133  wndclass.style         = 0;
00134  wndclass.lpfnWndProc   = (WNDPROC)MainWndProc;
00135  wndclass.cbClsExtra    = 0 ;
00136  wndclass.cbWndExtra    = 0 ;
00137  wndclass.hInstance     = hThisInstance ;
00138  wndclass.hIcon         = NULL;
00139  wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
00140  wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
00141  wndclass.lpszMenuName  = "tracemenu" ;
00142  wndclass.lpszClassName = szViewClass;
00143  if (!RegisterClass (&wndclass))  return FALSE ;
00144  xScreen = GetSystemMetrics (SM_CXSCREEN) ;
00145  yScreen = GetSystemMetrics (SM_CYSCREEN) ;
00146  hWnd = CreateWindow(
00147         szViewClass,
00148         "Image Trace Utility",
00149         fdwStyle,
00150         25,
00151         25,
00152         xScreen-50,
00153         yScreen-50,
00154         hParent,
00155         NULL,
00156         hThisInstance,
00157         NULL) ;
00158  if(hWnd == NULL)return FALSE;
00159  ShowWindow (hWnd,SW_SHOWNA);
00160  PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_DRAWIT,0);
00161  while(GetMessage (&msg,NULL,0,0)){
00162    TranslateMessage (&msg);
00163    DispatchMessage (&msg);
00164  }
00165  DestroyWindow(hWnd);
00166  UnregisterClass(wndclass.lpszClassName,wndclass.hInstance);
00167  if(TVlist != NULL)X__Free(TVlist); TVlist=NULL; Nv=0;
00168  if(TElist != NULL)X__Free(TElist); TElist=NULL; Ne=0;
00169  return TRUE;
00170 }
00171 
00172 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,
00173                              LPARAM lParam){
00174  static BOOL bToolCaptured=FALSE;
00175  static HCURSOR hCursorSave;
00176  static POINT LastPt;
00177  PAINTSTRUCT ps;
00178  HDC hDC;
00179  int i;
00180  RECT rc;
00181  POINT pt;
00182  switch (iMessage) {
00183    case WM_DESTROY:
00184     FreeDib();
00185     break;
00186   case WM_COMMAND:
00187     return MenuCommand(hWnd,LOWORD(wParam));
00188     break;
00189   case WM_MENUSELECT: {
00190       HMENU hmenu;
00191       UINT fuFlags,uItem,id;
00192       hmenu=(HMENU)lParam;
00193       fuFlags=(UINT)HIWORD(wParam);
00194       uItem=(UINT)LOWORD(wParam);
00195       id=0;
00196       if(fuFlags == 0xFFFF)id=0;
00197       else if(fuFlags & MF_POPUP){;}
00198       else{
00199         for(i=0;i<NMENUHELPDATA;i++){
00200           if(uItem == MenuHelpData[i].iCode){id=(UINT)i; break;}
00201         }
00202       }
00203       SendMessage(hInfo,SB_SETTEXT,(WPARAM)0,(LPARAM)MenuHelpData[id].str);
00204     }
00205     break;
00206   case WM_RBUTTONUP:
00207     if(!bToolCaptured)break;
00208     if(tracetool == 1)DrawRubberLine(hWnd,LOWORD(lParam),HIWORD(lParam));
00209     if(tracetool == 2){
00210       DrawRubberLines(hWnd,LOWORD(lParam),HIWORD(lParam));
00211       MoveVertex(hWnd,LOWORD(lParam),HIWORD(lParam));
00212     }
00213     SetCursor(hCursorSave);
00214     ClipCursor(NULL);
00215     ReleaseCapture();
00216     bToolCaptured=FALSE;
00217     Lv= -1;
00218     break;
00219   case WM_LBUTTONDOWN:
00220     if(tracetool == 0 || bToolCaptured)break;
00221     else if(tracetool == 2){
00222       if((Fv=GetVertexAtCursor(LOWORD(lParam),HIWORD(lParam))) < 0)break;
00223     }
00224     else if(tracetool == 3){ /* delete */
00225       if((Fv=GetVertexAtCursor(LOWORD(lParam),HIWORD(lParam))) >= 0){
00226         if(Ne > 0 && TElist != NULL)for(i=0;i<Ne;i++){
00227           if(TElist[i].v1 == Fv || TElist[i].v2 == Fv)TElist[i].inc=FALSE;
00228         }
00229         TVlist[Fv].inc=FALSE;
00230         InvalidateRect(hWnd,NULL,FALSE);
00231         Fv= -1;
00232       }
00233       break;
00234     }
00235     else if(tracetool == 4){ /* subdivide */
00236       if((Fv=GetVertexAtCursor(LOWORD(lParam),HIWORD(lParam))) >= 0){
00237         TraceSubdivide(Fv);
00238         InvalidateRect(hWnd,NULL,FALSE);
00239         Fv= -1;
00240       }
00241       break;
00242     }
00243     bToolCaptured=TRUE;
00244     SetCapture(hWnd);
00245     hCursorSave=SetCursor(LoadCursor(NULL,IDC_SIZE));
00246     GetClientRect(hWnd,&rc);
00247     pt.x=rc.left; pt.y=rc.top;
00248     ClientToScreen(hWnd,&pt);
00249     rc.left=pt.x; rc.top=pt.y;
00250     pt.x=rc.right; pt.y=rc.bottom;
00251     ClientToScreen(hWnd,&pt);
00252     rc.right=pt.x; rc.bottom=pt.y;
00253     ClipCursor(&rc);
00254     break;
00255   case WM_MOUSEMOVE:
00256     if(!bToolCaptured)break;
00257     if(tracetool == 1){
00258       DrawRubberLine(hWnd,(int)LastPt.x,(int)LastPt.y);
00259       LastPt.x=LOWORD(lParam); LastPt.y=HIWORD(lParam);
00260       DrawRubberLine(hWnd,(int)LastPt.x,(int)LastPt.y);
00261     }
00262     if(tracetool == 2){
00263       DrawRubberLines(hWnd,(int)LastPt.x,(int)LastPt.y);
00264       LastPt.x=LOWORD(lParam); LastPt.y=HIWORD(lParam);
00265       DrawRubberLines(hWnd,(int)LastPt.x,(int)LastPt.y);
00266     }
00267     break;
00268   case WM_LBUTTONUP:
00269     if(!bToolCaptured)break;
00270     if(tracetool == 1){ /* add */
00271       LastPt.x=LOWORD(lParam); LastPt.y=HIWORD(lParam);
00272       if(Lv >= 0)DrawRubberLine(hWnd,(int)LastPt.x,(int)LastPt.y);
00273       AddTraceVertex((int)LOWORD(lParam),(int)HIWORD(lParam));
00274       DrawList(hWnd,NULL);
00275       DrawRubberLine(hWnd,(int)LastPt.x,(int)LastPt.y);
00276     }
00277     else if(tracetool == 2){ /* move */
00278       if(Lv < 0){
00279         Lv=Fv; Fv=-1;
00280         LastPt.x=LOWORD(lParam); LastPt.y=HIWORD(lParam);
00281         DrawRubberLines(hWnd,(int)LastPt.x,(int)LastPt.y);
00282       }
00283       else{
00284         DrawRubberLines(hWnd,LOWORD(lParam),HIWORD(lParam));
00285         MoveVertex(hWnd,LOWORD(lParam),HIWORD(lParam));
00286         SetCursor(hCursorSave);
00287         ClipCursor(NULL);
00288         ReleaseCapture();
00289         bToolCaptured=FALSE;
00290         Lv= -1;
00291       }
00292     }
00293     break;
00294   case WM_PAINT:
00295     hDC = BeginPaint(hWnd, &ps);
00296     AppPaint(hWnd,hDC,0,0);
00297     DrawList(hWnd,hDC);
00298     EndPaint(hWnd,&ps);
00299     break ;
00300   case WM_SIZE:
00301     InvalidateRect(hWnd,NULL,FALSE);
00302     return 0;
00303   case WM_QUERYNEWPALETTE:{
00304       HDC hDC;
00305       HPALETTE hpalT;
00306       if(hpalCurrent == NULL)break;
00307       hDC=GetDC(hWnd);
00308       hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00309       if(RealizePalette (hDC) > 0)InvalidateRect (hWnd, (LPRECT) (NULL),FALSE);
00310       SelectPalette(hDC,hpalT,FALSE);
00311       ReleaseDC(hWnd,hDC);
00312       return TRUE;
00313     }
00314   case WM_PALETTECHANGED:
00315     if ((HWND)wParam != hWnd ){
00316       HDC hDC;
00317       HPALETTE hpalT;
00318       if(hpalCurrent == NULL)break;
00319       hDC=GetDC(hWnd);
00320       hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00321       if(RealizePalette (hDC) > 0)InvalidateRect (hWnd, (LPRECT) (NULL),FALSE);
00322       SelectPalette(hDC,hpalT,FALSE);
00323       ReleaseDC(hWnd,hDC);
00324     }
00325     break;
00326   default:
00327       return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
00328  }
00329  return 0L ;
00330 }
00331 
00332 BOOL MenuCommand (HWND hWnd, WORD id){
00333  int i;
00334  char lpMessage[MAXTEXT],lpCaption[64];
00335  switch (id) {
00336    case IDM_DRAWIT:
00337      StartWait();
00338      file_format=identify_file_format();
00339      switch(file_format){
00340        case FI_GIF:
00341          if(gifview(hWnd,ghFilename))InvalidateRect (hWnd, NULL, FALSE);
00342          else PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_ABORT,0);
00343          break;
00344        case FI_TGA:
00345          if(tgaview(hWnd,ghFilename))InvalidateRect (hWnd, NULL, FALSE);
00346          else PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_ABORT,0);
00347          break;
00348        //case FI_CEL:
00349        //  if(celview(hWnd,ghFilename))InvalidateRect (hWnd, NULL, FALSE);
00350        //  else PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_ABORT,0);
00351        //  break;
00352        default:
00353        case FI_DIB:
00354          if(bmpview(hWnd,ghFilename))InvalidateRect (hWnd, NULL, FALSE);
00355          else PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_ABORT,0);
00356          break;
00357          break;
00358      }
00359      EndWait();
00360      break;
00361    case IDM_PEN_RED  : pen=0; goto PENID;
00362    case IDM_PEN_WHITE: pen=1; goto PENID;
00363    case IDM_PEN_BLACK: pen=2; goto PENID;
00364    case IDM_PEN_CYAN : pen=3; goto PENID;
00365      PENID:
00366      CheckMenuItem(GetMenu(hWnd),IDM_PEN_RED,MF_UNCHECKED);
00367      CheckMenuItem(GetMenu(hWnd),IDM_PEN_WHITE,MF_UNCHECKED);
00368      CheckMenuItem(GetMenu(hWnd),IDM_PEN_BLACK,MF_UNCHECKED);
00369      CheckMenuItem(GetMenu(hWnd),IDM_PEN_CYAN,MF_UNCHECKED);
00370      if(pen == 0)CheckMenuItem(GetMenu(hWnd),IDM_PEN_RED,MF_CHECKED);
00371      if(pen == 1)CheckMenuItem(GetMenu(hWnd),IDM_PEN_WHITE,MF_CHECKED);
00372      if(pen == 2)CheckMenuItem(GetMenu(hWnd),IDM_PEN_BLACK,MF_CHECKED);
00373      if(pen == 3)CheckMenuItem(GetMenu(hWnd),IDM_PEN_CYAN,MF_CHECKED);
00374      DrawList(hWnd,NULL);
00375      break;
00376    case IDM_STRETCH:
00377      stretched ^= 1;
00378      if(stretched)ModifyMenu(GetMenu(hWnd),IDM_STRETCH,MF_BYCOMMAND|MF_STRING,
00379                 IDM_STRETCH,"&Actual Size");
00380      else ModifyMenu(GetMenu(hWnd),IDM_STRETCH,MF_BYCOMMAND|MF_STRING,
00381                 IDM_STRETCH,"&Stretch to fit");
00382      InvalidateRect (hWnd, (LPRECT) (NULL), FALSE);
00383      break;
00384    case IDM_ADD:
00385      Lv= -1;
00386      EnableMenuItem(GetMenu(hWnd),IDM_ADD,MF_GRAYED);
00387      EnableMenuItem(GetMenu(hWnd),IDM_MOVE,MF_ENABLED);
00388      EnableMenuItem(GetMenu(hWnd),IDM_DELETE,MF_ENABLED);
00389      EnableMenuItem(GetMenu(hWnd),IDM_INSERT,MF_ENABLED);
00390      DrawMenuBar(hWnd);
00391      tracetool=1;
00392      break;
00393    case IDM_MOVE:
00394      Lv= -1;
00395      EnableMenuItem(GetMenu(hWnd),IDM_ADD,MF_ENABLED);
00396      EnableMenuItem(GetMenu(hWnd),IDM_MOVE,MF_GRAYED);
00397      EnableMenuItem(GetMenu(hWnd),IDM_DELETE,MF_ENABLED);
00398      EnableMenuItem(GetMenu(hWnd),IDM_INSERT,MF_ENABLED);
00399      DrawMenuBar(hWnd);
00400      tracetool=2;
00401      break;
00402    case IDM_DELETE:
00403      Lv= -1;
00404      EnableMenuItem(GetMenu(hWnd),IDM_ADD,MF_ENABLED);
00405      EnableMenuItem(GetMenu(hWnd),IDM_MOVE,MF_ENABLED);
00406      EnableMenuItem(GetMenu(hWnd),IDM_DELETE,MF_GRAYED);
00407      EnableMenuItem(GetMenu(hWnd),IDM_INSERT,MF_ENABLED);
00408      DrawMenuBar(hWnd);
00409      tracetool=3;
00410      break;
00411    case IDM_INSERT:
00412      Lv= -1;
00413      EnableMenuItem(GetMenu(hWnd),IDM_ADD,MF_ENABLED);
00414      EnableMenuItem(GetMenu(hWnd),IDM_MOVE,MF_ENABLED);
00415      EnableMenuItem(GetMenu(hWnd),IDM_DELETE,MF_ENABLED);
00416      EnableMenuItem(GetMenu(hWnd),IDM_INSERT,MF_GRAYED);
00417      DrawMenuBar(hWnd);
00418      tracetool=4;
00419      break;
00420    case IDM_EXIT:
00421      BuildFromTrace(hWnd);
00422    case IDM_ABORT:
00423      PostQuitMessage(0);
00424      break;
00425    default:
00426      break;
00427  }
00428  return TRUE;
00429 }
00430 
00431 static void FreeDib(void){
00432  if (hpalCurrent) DeleteObject(hpalCurrent);
00433  if (hbmCurrent)  DeleteObject(hbmCurrent);
00434  if(lpBitmapBits   != NULL)X__Free((char *)lpBitmapBits);
00435  if(lpBitmapHeader != NULL)X__Free((char *)lpBitmapHeader);
00436  lpBitmapHeader = NULL;
00437  lpBitmapBits   = NULL;
00438  hpalCurrent    = NULL;
00439  hbmCurrent     = NULL;
00440  pRgb           = NULL;
00441 }
00442 
00443 static int identify_file_format(void){
00444  int ff=FI_DIB;
00445  strupr(ghFilename);
00446  if     (strstr(ghFilename,".GIF"))ff=FI_GIF;
00447  //else if(strstr(ghFilename,".CEL"))ff=FI_CEL;
00448  else if(strstr(ghFilename,".TGA"))ff=FI_TGA;
00449  else if(strstr(ghFilename,".DIB") ||
00450          strstr(ghFilename,".BMP") ||
00451          strstr(ghFilename,".RLE"))ff=FI_DIB;
00452  return ff;
00453 }
00454 
00455 static int ErrMsg(char *sz,...){
00456  char ach[128];
00457  va_list arg_ptr;
00458  va_start(arg_ptr,sz);
00459  vsprintf(ach,sz,arg_ptr);   /* Format the string */
00460  va_end(arg_ptr);
00461  MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00462  return FALSE;
00463 }
00464 
00465 static void PutMsg(char *s){
00466  MessageBox (NULL,s, "Trace", MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00467 }
00468 
00469 static void SizeWindow(HWND hWnd){
00470  char Title[120];
00471  RECT  Rectangle;
00472  int   dx,dy;
00473  POINT pt;
00474  LPBITMAPINFOHEADER bi;
00475  if((bi=(LPBITMAPINFOHEADER)lpBitmapHeader) == NULL)return;
00476  sprintf(Title,
00477           "%s (%s %ldx%ldx%ld)",
00478           "View",
00479           ghFilename,
00480           (long)x_size,  //(long)bi->biWidth,
00481           (long)bi->biHeight,
00482           (long)bi->biBitCount);
00483  SetWindowText(hWnd,Title);
00484  InvalidateRect(hWnd,NULL,FALSE);
00485 }
00486 
00487 int out_line(unsigned char *linepixels, int linelen){
00488  register long l;
00489  l = (long)(y_size - 1 - rowcount)*(long)(x4_size);
00490  memcpy(pixels + l, linepixels, linelen);
00491  rowcount+=abs(rowinc);
00492  if(rowcount >= y_size){
00493   if     (rowinc == -8){rowinc=8; rowcount=4;}
00494   else if(rowinc ==  8){rowinc=4; rowcount=2;}
00495   else if(rowinc ==  4){rowinc=2; rowcount=1;}
00496  }
00497  return 0;
00498 }
00499 
00500 static int gifview(HWND hWnd,char *temp){
00501  int i;
00502  long imagesize;
00503  LPBITMAPINFOHEADER lpbi;
00504  FreeDib();
00505  rowcount=0;
00506  rowinc=1;
00507  if(read_gif_image(temp,1) < 0){
00508    ErrMsg("'%ls' is NOT a valid GIF file", (LPSTR)temp);
00509    return 0;
00510  }
00511  if(gif_iLace)rowinc = -8;
00512  x4_size = ALIGNULONG(x_size);
00513  lpBitmapHeader = (LPSTR)X__Malloc((long)sizeof(BITMAPINFOHEADER)
00514                                 +256L*sizeof(RGBQUAD));
00515  if(lpBitmapHeader == NULL){
00516    ErrMsg("Out of memory");
00517    return 0;
00518  }
00519  lpbi=(LPBITMAPINFOHEADER)lpBitmapHeader;
00520  lpbi->biSize=sizeof(BITMAPINFOHEADER);
00521  lpbi->biWidth=(DWORD)x4_size;
00522  lpbi->biHeight=(DWORD)y_size;
00523  lpbi->biPlanes=1;
00524  lpbi->biBitCount=8;
00525  lpbi->biCompression=BI_RGB;
00526  imagesize = lpbi->biSizeImage = (DWORD)x4_size*(DWORD)y_size;
00527  lpbi->biXPelsPerMeter=0;
00528  lpbi->biYPelsPerMeter=0;
00529  lpbi->biClrUsed=256;
00530  lpbi->biClrImportant=256;
00531  pRgb=(RGBQUAD *)((LPSTR)lpbi + lpbi->biSize);
00532  for(i=0;i<256;i++){
00533    pRgb[i].rgbRed = p_red[i] << 2;
00534    pRgb[i].rgbGreen = p_green[i] << 2;
00535    pRgb[i].rgbBlue = p_blue[i] << 2;
00536  }
00537  hpalCurrent=CreateImagePalette(lpbi);
00538  lpBitmapBits=(LPSTR)X__Malloc(imagesize);
00539  if(lpBitmapBits == NULL){
00540    ErrMsg("Out of memory");
00541    FreeDib();
00542    return 0;
00543  }
00544  memset(lpBitmapBits,0,imagesize);
00545  pixels=lpBitmapBits;
00546  if(read_gif_image(temp,0) < 0){
00547    PutMsg("Error reading GIF file");
00548    FreeDib();
00549    return 0;
00550  }
00551  hbmCurrent=BitmapFromDib(lpBitmapHeader,lpBitmapBits,hpalCurrent);
00552  if(hbmCurrent == NULL)ErrMsg("Could not create bitmap");
00553  SizeWindow(hWnd);
00554  return 1;
00555 }
00556 
00557 static int bmpview(HWND hWnd,char *temp){
00558  int i,nc,bits;
00559  long imagesize;
00560  LPBITMAPINFOHEADER lpbi;
00561  BITMAPFILEHEADER bmfh;
00562  FILE *t24;
00563  FreeDib();
00564  lpBitmapHeader = (LPSTR)X__Malloc((long)sizeof(BITMAPINFOHEADER)
00565                                 +256L*sizeof(RGBQUAD));
00566  if(lpBitmapHeader == NULL){
00567    ErrMsg("Out of memory");
00568    return 0;
00569  }
00570  lpbi=(LPBITMAPINFOHEADER)lpBitmapHeader;
00571  lpbi->biSize=sizeof(BITMAPINFOHEADER);
00572  pRgb=(RGBQUAD *)((LPSTR)lpbi + lpbi->biSize);
00573  t24=fopen((char *)temp,"rb");
00574  if(t24 == NULL)return 0;
00575  fread((char *)&bmfh,sizeof(BITMAPFILEHEADER),1,t24);
00576  fread((char *)lpbi,sizeof(BITMAPINFOHEADER),1,t24);
00577  if(lpbi->biClrUsed != 0)nc=lpbi->biClrUsed;
00578  else{
00579    bits = lpbi->biBitCount;
00580    switch (bits){
00581      case 1:    nc=2;   break;
00582      case 4:    nc=16;  break;
00583      case 8:    nc=256; break;
00584      default:   nc=0;   break;
00585    }
00586  }
00587  x_size=lpbi->biWidth; 
00588  y_size=lpbi->biHeight;
00589  x4_size = ALIGNULONG(x_size);
00590  imagesize=bmfh.bfSize-bmfh.bfOffBits;
00591 //{char ttt[256]; sprintf(ttt,"x=%ld y=%ld nc=%ld  imagesize=%ld",x_size,y_size,nc,imagesize);
00592 //MessageBox(NULL,ttt,"Image",MB_OK);}
00593  if(nc > 0)fread((char *)pRgb,nc*sizeof(RGBQUAD),1,t24);
00594  if((lpBitmapBits=(unsigned char *)X__Malloc(imagesize)) == NULL){
00595    fclose(t24);
00596    FreeDib();
00597    return 0;
00598  }
00599  memset(lpBitmapBits,0,imagesize);
00600  fread((char *)lpBitmapBits,imagesize,1,t24);
00601  fclose(t24);
00602  hpalCurrent=CreateImagePalette(lpbi);
00603  hbmCurrent=BitmapFromDib(lpBitmapHeader,lpBitmapBits,hpalCurrent);
00604  if(hbmCurrent == NULL)ErrMsg("Could not create bitmap");
00605  SizeWindow(hWnd);
00606  return 1;
00607 }
00608 
00609 static HPALETTE CreateImagePalette(LPBITMAPINFOHEADER lpbi){
00610  LOGPALETTE *pPal;
00611  HPALETTE   hpal = NULL;
00612  WORD       nNumColors;
00613  BYTE       red;
00614  BYTE       green;
00615  BYTE       blue;
00616  int        i;
00617  RGBQUAD    *pRgb;
00618  if(lpbi == NULL)return NULL;
00619  if(lpbi->biSize != sizeof(BITMAPINFOHEADER))return NULL;
00620  /* Get a pointer to the color table and the number of colors in it */
00621  pRgb = (RGBQUAD *)((LPSTR)lpbi + (WORD)lpbi->biSize);
00622  nNumColors = NumColours(lpbi);
00623  if(nNumColors){
00624    pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
00625    if(pPal == NULL)return NULL;
00626    pPal->palNumEntries = nNumColors;
00627    pPal->palVersion    = PALVERSION;
00628    /* Fill in the palette entries from the DIB color table and
00629     * create a logical color palette. */
00630    for (i = 0; i < nNumColors; i++){
00631        pPal->palPalEntry[i].peRed   = pRgb[i].rgbRed;
00632        pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
00633        pPal->palPalEntry[i].peBlue  = pRgb[i].rgbBlue;
00634        pPal->palPalEntry[i].peFlags = (BYTE)0;
00635    }
00636    hpal = CreatePalette(pPal);
00637    LocalFree((HANDLE)pPal);
00638  }
00639  else if (lpbi->biBitCount == 24){
00640    /* A 24 bitcount DIB has no color table entries so, set the number of
00641     * to the maximum value (256). */
00642    nNumColors = MAXPALETTE;
00643    pPal=(LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
00644    if(pPal == NULL)return NULL;
00645    pPal->palNumEntries = nNumColors;
00646    pPal->palVersion    = PALVERSION;
00647    red = green = blue = 0;
00648    /* Generate 256 (= 8*8*4) RGB combinations to fill the palette entries. */
00649    for (i = 0; i < pPal->palNumEntries; i++){
00650        pPal->palPalEntry[i].peRed   = red;
00651        pPal->palPalEntry[i].peGreen = green;
00652        pPal->palPalEntry[i].peBlue  = blue;
00653        pPal->palPalEntry[i].peFlags = (BYTE)0;
00654        if (!(red += 32))if (!(green += 32)) blue += 64;
00655    }
00656    hpal = CreatePalette(pPal);
00657    LocalFree((HANDLE)pPal);
00658  }
00659  return hpal;
00660 }
00661 
00662 static WORD NumColours(LPBITMAPINFOHEADER lpbi){
00663  WORD bits;
00664  if (lpbi->biClrUsed != 0)return (WORD)lpbi->biClrUsed;
00665  bits = lpbi->biBitCount;
00666  switch (bits){
00667   case 1:    return 2;
00668   case 4:    return 16;
00669   case 8:    return 256;
00670   default:   return 0; /* A 24 bitcount DIB has no color table */
00671  }
00672 }
00673 
00674 static void AppPaint(HWND hWnd,HDC hDC,int x,int y){
00675  RECT rc;
00676  HPALETTE hpalT;
00677  POINT Origin;
00678  HDC hDCbits;
00679  BITMAP bm;
00680  GetClientRect(hWnd,&rc);
00681  if(hpalCurrent != NULL){
00682    hpalT = SelectPalette(hDC,hpalCurrent,FALSE);
00683    RealizePalette (hDC);
00684    if(hbmCurrent != NULL){ /* compatible bit map exists; its quicker, use it */
00685      hDCbits = CreateCompatibleDC(hDC);
00686      GetObject(hbmCurrent,sizeof(BITMAP),(LPSTR)&bm);
00687      SelectObject(hDCbits,hbmCurrent);
00688      if(stretched && (GetDeviceCaps(hDC,RASTERCAPS) & RC_STRETCHBLT) ==  RC_STRETCHBLT)
00689        StretchBlt(hDC,0,0,rc.right,rc.bottom,hDCbits,0,0,
00690                     bm.bmWidth,bm.bmHeight,SRCCOPY);
00691      else{
00692         PatBlt(hDC,0,0,rc.right,rc.bottom,PATCOPY);
00693         BitBlt(hDC,0,0,bm.bmWidth,bm.bmHeight,hDCbits,0,0,SRCCOPY);
00694      }
00695      DeleteDC(hDCbits);
00696    }
00697    else {
00698      if(lpBitmapHeader != NULL && lpBitmapBits != NULL){
00699        StretchDIBits(hDC,
00700                        0,0,
00701                        rc.right,
00702                        rc.top,
00703                        0,0,
00704                        (WORD)((LPBITMAPINFOHEADER)lpBitmapHeader)->biWidth,
00705                        (WORD)((LPBITMAPINFOHEADER)lpBitmapHeader)->biHeight,
00706                        lpBitmapBits,
00707                        (LPBITMAPINFO)lpBitmapHeader,
00708                        DIB_RGB_COLORS,
00709                        SRCCOPY);
00710      }
00711    }
00712    SelectPalette(hDC,hpalT,FALSE);
00713  }
00714 }
00715 
00716 static HBITMAP BitmapFromDib(LPSTR lpHeader,LPSTR lpBits,HPALETTE hpal){
00717  HDC       hdc;         /* make BITMAP from a memory DIB */
00718  HBITMAP   hbm;
00719  HPALETTE  hpalT;
00720  if (lpHeader == NULL || lpBits == NULL)return NULL;
00721  hdc = GetDC(NULL);
00722  if(hpal != NULL){
00723    hpalT = SelectPalette(hdc,hpal,FALSE);
00724    RealizePalette(hdc);
00725  }
00726  hbm = CreateDIBitmap(hdc,
00727                 (LPBITMAPINFOHEADER)lpHeader,
00728                 (LONG)CBM_INIT,
00729                 lpBits,
00730                 (LPBITMAPINFO)lpHeader,
00731                 DIB_RGB_COLORS );
00732  if(hpalCurrent)SelectPalette(hdc,hpalT,FALSE);
00733  ReleaseDC(NULL,hdc);
00734  return hbm;
00735 }
00736 
00737 
00738 static void DrawRubberLine(HWND hwnd, int x, int y){
00739  HPEN hOldPen,MyPen;
00740  int oldROP;
00741  HDC hDClocal;
00742  if(Lv < 0)return;
00743  hDClocal=GetDC(hwnd);
00744  if(pen == 0)MyPen=CreatePen(PS_SOLID,0,RGB(255,0,0));
00745  if(pen == 1)MyPen=CreatePen(PS_SOLID,0,RGB(255,255,255));
00746  if(pen == 2)MyPen=CreatePen(PS_SOLID,0,RGB(0,0,0));
00747  if(pen == 3)MyPen=CreatePen(PS_SOLID,0,RGB(0,255,255));
00748  hOldPen=SelectObject(hDClocal,MyPen);
00749  oldROP=SetROP2(hDClocal,R2_NOT);
00750  MoveToEx(hDClocal,x,y,NULL);
00751  LineTo(hDClocal,TVlist[Lv].x,TVlist[Lv].y);
00752  SetROP2(hDClocal,oldROP);
00753  SelectObject(hDClocal,hOldPen);
00754  DeleteObject(MyPen);
00755  ReleaseDC(hwnd,hDClocal);
00756 }
00757 
00758 static void DrawRubberLines(HWND hwnd, int x, int y){
00759  int i,v1,v2;
00760  HPEN hOldPen;
00761  int oldROP;
00762  HDC hDClocal;
00763  if(Lv < 0 || Ne == 0)return;
00764  hDClocal=GetDC(hwnd);
00765  hOldPen=SelectObject(hDClocal,GetStockObject(WHITE_PEN));
00766  oldROP=SetROP2(hDClocal,R2_NOT);
00767  for(i=0;i<Ne;i++){
00768    if(!TElist[i].inc)continue;
00769    v1=TElist[i].v1; v2=TElist[i].v2;
00770    if(TVlist[v1].inc && v1 == Lv){
00771      MoveToEx(hDClocal,x,y,NULL);
00772      LineTo(hDClocal,TVlist[v2].x,TVlist[v2].y);
00773    }
00774    else if(TVlist[v2].inc && v2 == Lv){
00775      MoveToEx(hDClocal,x,y,NULL);
00776      LineTo(hDClocal,TVlist[v1].x,TVlist[v1].y);
00777    }
00778  }
00779  SetROP2(hDClocal,oldROP);
00780  SelectObject(hDClocal,hOldPen);
00781  ReleaseDC(hwnd,hDClocal);
00782 }
00783 
00784 static void DrawList(HWND hwnd, HDC hDC){
00785  int i,x,y;
00786  HPEN hOldPen,MyPen;
00787  HBRUSH hOldBrush;
00788  HDC hDClocal;
00789  if(hDC == NULL){
00790    hDClocal=GetDC(hwnd);
00791  }
00792  else hDClocal=hDC;
00793  if(pen == 0)MyPen=CreatePen(PS_SOLID,0,RGB(255,0,0));
00794  if(pen == 1)MyPen=CreatePen(PS_SOLID,0,RGB(255,255,255));
00795  if(pen == 2)MyPen=CreatePen(PS_SOLID,0,RGB(0,0,0));
00796  if(pen == 3)MyPen=CreatePen(PS_SOLID,0,RGB(0,255,255));
00797  hOldPen=SelectObject(hDClocal,MyPen);
00798  hOldBrush=SelectObject(hDClocal,GetStockObject(BLACK_BRUSH));
00799  if(Ne > 0 && TElist != NULL){
00800    for(i=0;i<Ne;i++){
00801      if(!TElist[i].inc)continue;
00802      x=TVlist[TElist[i].v1].x; y=TVlist[TElist[i].v1].y;
00803      MoveToEx(hDClocal,x,y,NULL);
00804      x=TVlist[TElist[i].v2].x; y=TVlist[TElist[i].v2].y;
00805      LineTo(hDClocal,x,y);
00806    }
00807  }
00808  if(Nv > 0 && TVlist != NULL){
00809    for(i=0;i<Nv;i++)if(TVlist[i].inc)Rectangle(hDClocal,
00810       TVlist[i].x-2,TVlist[i].y-2,TVlist[i].x+2,TVlist[i].y+2);
00811  }
00812  SelectObject(hDClocal,hOldPen);
00813  SelectObject(hDClocal,hOldBrush);
00814  DeleteObject(MyPen);
00815  if(hDC == NULL){
00816    ReleaseDC(hwnd,hDClocal);
00817  }
00818 }
00819 
00820 static void AddTraceVertex(int x,int y){
00821  int i,id,found=0,flag=0;
00822  struct TVLIST *v;
00823  struct TELIST *e;
00824  if(Nv > 0){
00825    for(i=0;i<Nv;i++){
00826      if(TVlist[i].inc && abs(x-TVlist[i].x) < 4 && abs(y-TVlist[i].y) < 4){
00827        found=1;
00828        if(Lv >= 0)flag=1;
00829        id=i;
00830      }
00831    }
00832  }
00833  if(!found){
00834    if(TVlist == NULL){
00835      if((v=(struct TVLIST *)X__Malloc(sizeof(struct TVLIST))) == NULL)return;
00836    }
00837    else{
00838      if((v=(struct TVLIST *)X__Realloc(TVlist,(Nv+1)*sizeof(struct TVLIST))) == NULL)return;
00839    }
00840    TVlist=v;
00841    v[Nv].x=x; v[Nv].y=y; v[Nv].inc=TRUE;
00842    id=Nv;
00843    Nv++;
00844  }
00845  if(Lv < 0){
00846    Lv=id;
00847  }
00848  else{
00849    if(TElist == NULL){
00850      if((e=(struct TELIST *)X__Malloc(sizeof(struct TELIST))) == NULL)return;
00851    }
00852    else{
00853      if((e=(struct TELIST *)X__Realloc(TElist,(Ne+1)*sizeof(struct TELIST))) == NULL)return;
00854    }
00855    TElist=e;
00856    e[Ne].v1=id; e[Ne].v2=Lv; e[Ne].inc=TRUE;
00857    Lv=id;
00858    Ne++;
00859  }
00860  if(flag)Lv= -1;
00861 }
00862 
00863 static void MoveVertex(HWND hWnd,int x, int y){
00864  if(Lv < 0)return;
00865  TVlist[Lv].x=x; TVlist[Lv].y=y;
00866  InvalidateRect(hWnd,NULL,FALSE);
00867  return;
00868 }
00869 
00870 int GetVertexAtCursor(int x, int y){
00871  int i,id= -1;
00872  if(Nv > 0)for(i=0;i<Nv;i++){
00873    if(TVlist[i].inc && abs(x-TVlist[i].x) < 4 && abs(y-TVlist[i].y) < 4)id=i;
00874  }
00875  return id;
00876 }
00877 
00878 static void TraceSubdivide(long vv){
00879  struct TVLIST *v;
00880  struct TELIST *e;
00881  int ne1,i,x,y;
00882  if(Nv == 0 || Ne == 0 || TVlist == NULL || TElist == NULL)return;
00883  ne1=Ne; for(i=0;i<ne1;i++){
00884    if(!TElist[i].inc)continue;
00885    x=(TVlist[TElist[i].v1].x+TVlist[TElist[i].v2].x)/2;
00886    y=(TVlist[TElist[i].v1].y+TVlist[TElist[i].v2].y)/2;
00887    if(TElist[i].v1 == vv){
00888      if((v=(struct TVLIST *)X__Realloc(TVlist,(Nv+1)*sizeof(struct TVLIST))) == NULL)return;
00889      TVlist=v; v[Nv].x=x; v[Nv].y=y; v[Nv].inc=TRUE;
00890      TElist[i].v1=Nv;
00891      if((e=(struct TELIST *)X__Realloc(TElist,(Ne+1)*sizeof(struct TELIST))) == NULL)return;
00892      TElist=e; e[Ne].v1=Nv; e[Ne].v2=vv; e[Ne].inc=TRUE;
00893      Ne++;
00894      Nv++;
00895    }
00896    else if(TElist[i].v2 == vv){
00897      if((v=(struct TVLIST *)X__Realloc(TVlist,(Nv+1)*sizeof(struct TVLIST))) == NULL)return;
00898      TVlist=v; v[Nv].x=x; v[Nv].y=y; v[Nv].inc=TRUE;
00899      TElist[i].v2=Nv;
00900      if((e=(struct TELIST *)X__Realloc(TElist,(Ne+1)*sizeof(struct TELIST))) == NULL)return;
00901      TElist=e; e[Ne].v1=Nv; e[Ne].v2=vv; e[Ne].inc=TRUE;
00902      Ne++;
00903      Nv++;
00904    }
00905  }
00906 }
00907 
00908 static void BuildFromTrace(HWND hWnd){
00909  RECT rc;
00910  long Scale,v1,v2;
00911  int i,vc=0,ec=0;
00912  GetClientRect(hWnd,&rc);
00913  if(Nv == 0 || TVlist == NULL)return;
00914  Scale=100;
00915  for(i=0;i<Nv;i++){
00916    if(TVlist[i].inc)vc++;
00917    TVlist[i].id = -1;
00918  }
00919  if(vc == 0)return;
00920  UpdateVertexHeap(Nvert+vc);
00921  for(i=0;i<Nv;i++){
00922    if(!TVlist[i].inc)continue;
00923    CreateVertex();
00924    (MainVp+Nvert-1)->xyz[0]=TVlist[i].x*Scale;
00925    (MainVp+Nvert-1)->xyz[1]=NpointerY;
00926    (MainVp+Nvert-1)->xyz[2]=(rc.bottom-TVlist[i].y)*Scale;
00927    TVlist[i].id=Nvert-1; /* use to point to actual vertex */
00928  }
00929  if(Ne == 0)return;
00930  for(i=0;i<Ne;i++)if(TVlist[i].inc)ec++;
00931  if(ec == 0)return;
00932  UpdateEdgeHeap(Nedge+vc);
00933  for(i=0;i<Ne;i++){
00934    if(!TElist[i].inc)continue;
00935    v1=TVlist[TElist[i].v1].id; v2=TVlist[TElist[i].v2].id;
00936    if(v1 >= 0 && v2 >= 0)CreateEdge(v1,v2);
00937  }
00938 }
00939 
00940 //#include "..\render2\flc.h"
00941 
00942 #include "trace1.c"
00943 
00944 #if __WATCOMC__
00945 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00946 #else
00947 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00948 #endif
00949   switch (dwReason) {
00950     case DLL_PROCESS_ATTACH: {
00951 #if __X__MIPS__
00952       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00953 //      MessageBox (GetFocus(),"Trace attaching","Debug",MB_OK);
00954 #endif
00955       hThisInstance=hDLL;
00956       break;
00957     }
00958     case DLL_PROCESS_DETACH:
00959 #if __X__MIPS__
00960       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00961 //      MessageBox (GetFocus(),"Trace detaching","Debug",MB_OK);
00962 #endif
00963       break;
00964   }
00965   return TRUE;
00966 }
00967 
00968 #if __SC__
00969 #pragma startaddress(DllMain)
00970 #endif
00971 
00972 BOOL _TraceOutline(
00973  HWND parent_window, HWND info_window,
00974  char *filename,X__STRUCTURE *lpX__in){
00975  tracetool=0;
00976  hParent=parent_window;
00977  hInfo=info_window;
00978  lpEVI=lpX__in;
00979 #include "keyfile.c"
00980  strcpy(ghFilename,filename);
00981  return Viewer();
00982 }

Generated on Sun Apr 27 14:20:12 2014 for OpenFX by  doxygen 1.5.6