home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / windxy.zip / DXFDRAW.C < prev    next >
Text File  |  1990-11-25  |  11KB  |  432 lines

  1. #include <windows.h>
  2. #include <math.h>
  3. #include "windxf.h"
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6.  
  7. extern HWND GBL_hwnd;
  8. extern HDC mfhdc;
  9. extern HDC GBL_hdc;
  10.  
  11. typedef struct {
  12.    int   number;
  13.    char  marker[80];
  14.    } DXF_STATE;
  15.  
  16. #define  NUM_STATES  30
  17.  
  18. DXF_STATE statetab[] =  { 0,"SECTION",  /* Section Begin      1 */
  19.                           2,"HEADER",   /* Header             2 */
  20.                           0,"ENDSEC",   /* End Section        3 */
  21.                           2,"TABLES",   /* Tables section     4 */
  22.                           0,"TABLE",    /* Table Begin        5 */
  23.                           2,"VPORT",    /* Viewport           6 */
  24.                           70,"#",       /* 70 with a count    7 */
  25.                           0,"ENDTAB",   /* End of table       8 */
  26.                           9,"$EXTMIN",  /* Min Extents        9 */
  27.                           9,"$EXTMAX",  /* Max Extents        10 */
  28.                           10,"#",       /* X coord            11 */
  29.                           20,"#",       /* Y coord            12 */
  30.                           2,"ENTITIES", /* Entities           13 */
  31.                           11,"#",       /* X2 coord           14 */
  32.                           21,"#",       /* Y2 coord           15 */
  33.                           0,"LINE",     /* Line Entity        16 */
  34.                           0,"ATTDEF",   /* Attribute Def      17 */
  35.                           8, "#",       /* Layer Name         18 */
  36.                           40,"#",       /* Height             19 */
  37.                           1, "#",       /* Primary Text       20 */
  38.                           2, "#",       /* Name               21 */
  39.                           3, "#",       /* Other Text         22 */
  40.                           50,"#",       /* Angle              23 */
  41.                           51,"#",       /* Angle              24 */
  42.                           0, "ARC",     /* Arc                25 */
  43.                           0, "POLYLINE",/* Polyline           26 */
  44.                           0, "VERTEX",  /* Vertex             27 */
  45.                           0, "SEQEND",  /* End Sequence       28 */
  46.                           66, "#",      /* Entities Follow    29 */
  47.                           41, "#",      /* End Width          30 */
  48.                           };
  49.  
  50. typedef enum {
  51.    NUMBER,
  52.    MARKER,
  53.    } READ_STATE;
  54.  
  55. READ_STATE  curstate = NUMBER;
  56.  
  57.  
  58. char  layer[256], heightstr[256], textstr[256];
  59. double wx1, wy1, wx2, wy2;
  60. int logextx, logexty;
  61.  
  62. int 
  63. ReadDXF(dxfname)
  64. char * dxfname;
  65. {
  66. int fd;
  67. char  line1[256], line2[256];
  68. int st;
  69. double x, y;
  70. int color;
  71. char msg[256];
  72. int xi,yi;
  73. int lx, ly;
  74.  
  75. int   section_active  = 0;
  76. int   header_active   = 0;
  77. int   entities_active = 0;
  78. int   tables_active   = 0;
  79. int   table_start     = 0;
  80. int   polyline_count  = 0;
  81.  
  82. double height, radius, st_ang, end_ang;
  83.  
  84. MSG msg1;
  85.  
  86. fd = _lopen(dxfname, OF_READ);
  87.  
  88.  
  89. while (1) 
  90.   {
  91.    PeekMessage(&msg1, GBL_hwnd,(WORD)0,(WORD)0,PM_NOREMOVE);
  92.  
  93.    if (getline(line1, 256, fd) == NULL)
  94.       break;
  95.  
  96.    if (getline(line2, 256, fd) == NULL)
  97.       break;
  98.  
  99.    st = dxfstate(line1, line2);
  100.    switch(st)
  101.      {
  102.       case 1: /* Section */
  103.            section_active = 1;
  104.            break;
  105.       case 2: /* Header */
  106.            header_active = 1;
  107.            break;
  108.       case 3: /* End Section */
  109.            section_active = 0;
  110.            /* Whatever section was active, shut it down */
  111.            if (header_active)
  112.              header_active = 0;
  113.            else
  114.            if (entities_active)
  115.              entities_active = 0;
  116.            else
  117.            if (tables_active)
  118.              tables_active = 0;
  119.            break;
  120.  
  121.       case 4: /* Tables Active */
  122.            tables_active = 1;
  123.            break;
  124.       case 5: /* Table */
  125.            table_start = 1;
  126.            break;
  127.       case 8: /* End table */
  128.            table_start = 0;
  129.            break;
  130.       case 9: /* Min Extents */
  131.            get_followxyfloat(fd, &wx1, &wy1);
  132.            break;
  133.       case 10: /* Max Extents */
  134.            get_followxyfloat(fd, &wx2, &wy2);
  135.            color = 7;
  136.  
  137.            /* Now we're ready to set our world coords.
  138.               Adjust the smaller of the axis to form
  139.               a square world coordinate system */
  140.  
  141.            if ( (wy2 - wy1) > (wx2 - wx1) )
  142.              {
  143.               wx2 += (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
  144.               wx1 -= (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
  145.              }
  146.            else
  147.              {
  148.               wy2 += (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
  149.               wy1 -= (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
  150.              }
  151.            break;
  152.  
  153.       case 13: /* Entities */
  154.            entities_active = 1;
  155.            break;
  156.  
  157.       case 16: /* Line Entities */
  158.            if (entities_active)
  159.            {
  160.              get_followxyfloat(fd, &x, &y);
  161.              MapUsertoLog(x,y,&lx,&ly);
  162.              MoveTo(GBL_hdc, lx, ly);
  163.              MoveTo(mfhdc, lx, ly);
  164.              get_followxyfloat(fd, &x, &y);
  165.              MapUsertoLog(x,y,&lx,&ly);
  166.              LineTo(GBL_hdc, lx, ly);
  167.              LineTo(mfhdc, lx, ly);
  168.            }
  169.            break;
  170.  
  171.       case 17: /* Attribute Def */
  172.          get_followline(fd, 18, layer);
  173.          get_followxyfloat(fd, &x, &y);
  174.          get_followline(fd, 19, heightstr);
  175.          height = atof(heightstr);
  176.          get_followline(fd, 20, textstr);
  177.          break;
  178.  
  179.       case 25: /* Arc */
  180.          get_followarc(fd, &x,&y,&radius,&st_ang,&end_ang);
  181.          /* MS Windows doesn't support an arc the way DXF does,
  182.             so we'll leave this one for a future version */
  183.          /* movabs(&x,&y);
  184.          arc(&radius,&end_ang,&st_ang); */
  185.          break;
  186.  
  187.       case 26: /* Polyline */
  188.         if (entities_active)
  189.           {
  190.             get_followline(fd, 18, textstr);
  191.             get_followline(fd, 29, textstr);
  192.             /* Polyline is justing setting us up to read
  193.             vertices */
  194.             polyline_count = 0;
  195.           }
  196.       break;
  197.       case 27: /* Vertex */
  198.       if (entities_active)
  199.        {
  200.          get_followxyfloat(fd, &x, &y);
  201.          MapUsertoLog(x,y,&lx,&ly);
  202.          if (polyline_count==0)
  203.            {
  204.              /* If this is the first vertex, move to it */
  205.              MoveTo(GBL_hdc, lx, ly); 
  206.              MoveTo(mfhdc, lx, ly); 
  207.            }
  208.          else
  209.            {
  210.              /* Line to subsequent vertices */
  211.              LineTo(GBL_hdc, lx, ly); 
  212.              LineTo(mfhdc, lx, ly); 
  213.            }
  214.          polyline_count++;
  215.        }
  216.        break;
  217.  
  218.     case 28: /* Sequence end */
  219.       if (entities_active)
  220.          {
  221.            if (polyline_count > 0)
  222.               polyline_count = 0;
  223.          }
  224.       break;
  225.        } /* end of switch */
  226.    } /* end of while(1) */
  227. _lclose(fd);
  228. return 1;
  229. }
  230.  
  231. int dxfstate(line1, line2)
  232. char * line1;
  233. char * line2;
  234. {
  235. int ctr;
  236. int num;
  237. int l;
  238.  
  239. num = atoi(line1);
  240. l = lstrlen(line2);
  241.  
  242. for (ctr=0; ctr < NUM_STATES; ctr++)
  243.   {
  244.    if ( (statetab[ctr].number == num) &&
  245.         (!lstrcmp(statetab[ctr].marker,line2)))
  246.         return ctr+1;
  247.    if ( (statetab[ctr].number == num) &&
  248.         (!lstrcmp(statetab[ctr].marker,"#")))
  249.         return ctr+1;
  250.   }
  251.  
  252. return -1;
  253. }
  254.  
  255. int
  256. get_followxyfloat(fd, x, y)
  257. int fd;
  258. double * x;
  259. double * y;
  260. {
  261. long pos;
  262. int  ctr, st2;
  263. char line1[256], line2[256];
  264. double p1, p2;
  265.  
  266. char msg[256];
  267.  
  268.  
  269.  pos = _llseek(fd,0L,1);
  270.  ctr = 0;
  271.  while (ctr < 2)
  272.    {
  273.      getline(line1, 256, fd);
  274.      getline(line2, 256, fd);
  275.      st2 = dxfstate(line1, line2);
  276.      if ( (st2 == -1)  || (st2 == 18) )
  277.        continue;
  278.      if ( (st2 == 11) || (st2 == 14) )
  279.       {
  280.        p1 = atof(line2);  
  281.        *x = p1;
  282.        ctr++;
  283.        continue;
  284.       }
  285.      if ( (st2 == 12) || (st2 == 15) )
  286.       {
  287.        p2 = atof(line2); 
  288.        *y = p2;
  289.        ctr++;
  290.        continue;
  291.       }
  292.      _llseek(fd, pos, 0);
  293.    }
  294.  
  295. return 1;
  296. }
  297.  
  298. int
  299. get_followline(fd, st, line)
  300. int fd;
  301. int st;
  302. char * line;
  303. {
  304. long pos;
  305. int  st2;
  306. char line1[256], line2[256];
  307.  
  308.  pos = _llseek(fd,0L,1);
  309.  while (1)
  310.    {
  311.      getline(line1, 256, fd);
  312.      getline(line2, 256, fd);
  313.      st2 = dxfstate(line1, line2);
  314.      if (st2 == -1)
  315.        continue;
  316.      if (st2 == st)
  317.       {
  318.        lstrcpy(line, line2);
  319.        break;
  320.       }
  321.      _llseek(fd, pos, 0);
  322.    }
  323. return 1;
  324. }
  325.  
  326. int
  327. get_followarc(fd, x, y, radius, st_ang, end_ang)
  328. int fd;
  329. double * x;
  330. double * y;
  331. double * radius;
  332. double * st_ang;
  333. double * end_ang;
  334. {
  335. long pos;
  336. int  ctr, st2;
  337. char line1[256], line2[256];
  338.  
  339.  pos = _llseek(fd,0L,1);
  340.  ctr = 0;
  341.  while (ctr < 5)
  342.    {
  343.      getline(line1, 256, fd);
  344.      getline(line2, 256, fd);
  345.      st2 = dxfstate(line1, line2);
  346.      if ( (st2 == -1)  || (st2 == 18) )
  347.        continue;
  348.      if ( (st2 == 11) || (st2 == 14) )
  349.       {
  350.        *x = atof(line2);
  351.        ctr++;
  352.        continue;
  353.       }
  354.      if ( (st2 == 12) || (st2 == 15) )
  355.       {
  356.        *y = atof(line2);
  357.        ctr++;
  358.        continue;
  359.       }
  360.      if ( st2 == 19 )
  361.       {
  362.        *radius = atof(line2);
  363.        ctr++;
  364.        continue;
  365.       }
  366.      if ( st2 == 23 )
  367.       {
  368.        *st_ang = atof(line2);
  369.        ctr++;
  370.        continue;
  371.       }
  372.      if ( st2 == 24 )
  373.       {
  374.        *end_ang = atof(line2);
  375.        ctr++;
  376.        continue;
  377.       }
  378.      _llseek(fd, pos, 0);
  379.    }
  380. return 1;
  381. }
  382.  
  383. /* Windows doesn't support fgets, so we have to write
  384.    our own binary, unbuffered version.  This program could
  385.    be greatly enhanced by implementing a look ahead buffer 
  386.    here */
  387.  
  388. int getline(line, lim, fd) 
  389. char * line;
  390. int lim;
  391. int fd;
  392. {
  393. int ctr;
  394. int nread;
  395. long backup;
  396. long newpos;
  397.  
  398. nread = _lread(fd, line, lim-1);
  399.  
  400. if (nread < lim-1)
  401.  {
  402.   return 0;
  403.  }
  404.  
  405. for (ctr=0; ctr < lim-1; ctr++)
  406.   if ( (line[ctr] == (char)13) &&
  407.        (line[ctr+1] == (char)10) )
  408.        {
  409.         line[ctr] = (char)NULL;
  410.         backup = ctr - lim + 3;
  411.         newpos = _llseek(fd, (long)backup, 1);
  412.         return 1;
  413.        }
  414. line[lim-1] = '\0';
  415.  
  416. /* Should never get here... */
  417. MessageBox(GBL_hwnd, "Didn't hit loop", (LPSTR) NULL, MB_OK);
  418. }
  419.  
  420. /* maps user coordinates to logical device coordinates */
  421. int
  422. MapUsertoLog(x,y,lx,ly)
  423. double  x;
  424. double  y;
  425. int * lx;
  426. int * ly;
  427. {
  428. *lx = (int) (((x-wx1)/(wx2-wx1)) * (double)1000);
  429. *ly = (int) (((y-wy1)/(wy2-wy1)) * (double)1000);
  430. *ly = 1000 - *ly;
  431. }
  432.