home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / plotting / pcgplots / cgm.cpp < prev    next >
C/C++ Source or Header  |  1992-04-24  |  107KB  |  4,539 lines

  1. // C++ .cc file for gplot, CGM-specific classes  -*-c++-*-
  2. // copyright Phil Andrews, Pittsburgh Supercomputing Center, 1992
  3. // all rights reserved
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "cgm.h"
  7. #include "cgmio.h"
  8. #if __MSDOS__
  9. #include "cgmdisp.h"
  10. #else
  11. #include "cgmdisplay.h"
  12. #endif
  13. #ifdef macintosh
  14.  #include <UMacApp.h>
  15.  #pragma segment CGM1
  16. #endif
  17. // error handling function
  18. extern void myError(const char *inMsg, const char *inMsg2=NULL,
  19.             int severity=1);
  20.  
  21.  
  22. ////
  23. // direct colour class
  24. ////
  25. // constructor
  26. ////
  27. dColr::dColr(int inR, int inG, int inB)
  28. {
  29.   values[0] = inR;
  30.   values[1] = inG;
  31.   values[2] = inB;
  32. }
  33. ////
  34. // general colour class
  35. ////
  36. // indexed colour constructor
  37. ////
  38. genColr::genColr(int inIndex, const colrValueExtent *inExtent,
  39.          const colrTable *inTable) 
  40. {
  41.   myIndex = inIndex;
  42.   myType = 0;
  43.   myExtent = inExtent;
  44.   myTable = inTable;
  45. }
  46. ////
  47. // direct colour constructor
  48. ////
  49. genColr::genColr(int inRed, int inGreen, int inBlue,
  50.          const colrValueExtent *inExtent, const colrTable *inTable) 
  51. { // direct colour constructor
  52.   myDC.setValue(0,inRed);    // myDC[0] = inRed;
  53.   myDC.setValue(1,inGreen);  //myDC[1] = inGreen;
  54.   myDC.setValue(2,inBlue);   //myDC[2] = inBlue;
  55.   myIndex = 1;
  56.   myType = 1;
  57.   myExtent = inExtent;
  58.   myTable = inTable;
  59. }
  60. ////
  61. // another direct colour constructor
  62. ////
  63. genColr::genColr(const dColr &inDC,
  64.          const colrValueExtent *inExtent, const colrTable *inTable) 
  65. { // direct colour constructor
  66.   myDC = inDC;
  67.   myIndex = 1;
  68.   myType = 1;
  69.   myExtent = inExtent;
  70.   myTable = inTable;
  71. }
  72. ////
  73. // get float values for the colours
  74. ////
  75. float genColr::r(unsigned i) const
  76. {
  77.   if (i>2) i = 0; // greater than blue ?
  78. //  int useVal = type() ? myDC[i] : myTable->val(myIndex)[i];
  79.   int useVal = type() ? myDC.getValue(i) : myTable->val(myIndex).getValue(i);
  80. //  if (useVal >= myExtent->white[i]) return 1; // max possible
  81. //  if (useVal <= myExtent->black[i]) return 0; // min possible
  82.   if (useVal >= myExtent->white.getValue(i)) return 1; // max possible
  83.   if (useVal <= myExtent->black.getValue(i)) return 0; // min possible
  84.  
  85. // ***  return (float) (useVal - myExtent->black[i]) /
  86. // ***   (myExtent->white[i] - myExtent->black[i]);
  87.   return (float) (useVal - myExtent->black.getValue(i)) /
  88.     (myExtent->white.getValue(i) - myExtent->black.getValue(i));
  89. }
  90. ////
  91. // colour table class
  92. ////
  93. colrTable::colrTable(unsigned int inSize, const colrValueExtent *inExtent,
  94.              unsigned int inStart)
  95. {
  96.   mySize = inSize;
  97.   myExtent = inExtent;
  98.   myStart = inStart;
  99.   myNo = 0;
  100.   values = new dColr[size()];
  101.   initialize(values, mySize);
  102. }
  103. ////
  104. // add one colour
  105. ////
  106. void colrTable::addColr(dColr &inDColr)
  107. {
  108.   if (no() < size()) {
  109.     values[no()] = inDColr; // should check that this works
  110.     ++myNo;
  111.   }
  112. }
  113. ////
  114. // extend the table
  115. ////
  116. void colrTable::extendTable(int newSize)
  117. {
  118.   if (newSize < mySize) return; // nothing to do
  119.   // need more room
  120.   dColr *oldValues = values;
  121.   int oldSize = mySize;
  122.   mySize = newSize;
  123.   values = new dColr[mySize];
  124.   for (int i=0; i<oldSize; ++i) values[i] = oldValues[i];
  125.   initialize(values + i, mySize - oldSize);
  126.   delete oldValues;
  127. }
  128. ////
  129. // initialize values
  130. ////
  131. void colrTable::initialize(dColr *inPtr, int size)
  132. {
  133. //  int rmin = myExtent->black[0]; // min red
  134. //  int gmin = myExtent->black[1]; // min green
  135. //  int bmin = myExtent->black[2]; // min blue
  136. //  int rmax = myExtent->white[0]; // max red
  137. //  int gmax = myExtent->white[1]; // max green
  138. //  int bmax = myExtent->white[2]; // max blue
  139.  
  140.   int rmin = myExtent->black.getValue(0); // min red
  141.   int gmin = myExtent->black.getValue(1); // min green
  142.   int bmin = myExtent->black.getValue(2); // min blue
  143.   int rmax = myExtent->white.getValue(0); // max red
  144.   int gmax = myExtent->white.getValue(1); // max green
  145.   int bmax = myExtent->white.getValue(2); // max blue
  146.  
  147.   int index = 0;
  148.   if (index < size) {inPtr->set(rmax, gmax, bmax); ++index; ++inPtr;} // white
  149.   if (index < size) {inPtr->set(rmin, gmin, bmin); ++index; ++inPtr;} // black
  150.   if (index < size) {inPtr->set(rmax, gmin, bmin); ++index; ++inPtr;} // red
  151.   if (index < size) {inPtr->set(rmin, gmax, bmin); ++index; ++inPtr;} // green
  152.   if (index < size) {inPtr->set(rmin, gmin, bmax); ++index; ++inPtr;} // blue
  153.   if (index < size) {inPtr->set(rmax, gmax, bmin); ++index; ++inPtr;} // yellow
  154.   if (index < size) {inPtr->set(rmax, gmin, bmax); ++index; ++inPtr;} // magent
  155.   if (index < size) {inPtr->set(rmin, gmax, bmax); ++index; ++inPtr;} // cyan
  156.   if (index < size) {inPtr->set(rmax, gmax/2, bmin); ++index; ++inPtr;} // or
  157.   if (index < size) {inPtr->set(rmax, gmin, bmax/2); ++index; ++inPtr;}
  158.   for (int i=index; i<size; ++i) {
  159.     inPtr->set(rmin, gmin, bmin); // black
  160.     ++inPtr;
  161.   }
  162. }
  163. ////
  164. // incorporate a new table
  165. ////
  166. void colrTable::addTable(colrTable *inTable)
  167. {
  168.   if ((inTable->start() + inTable->no()) > (start() + size())) { // need room
  169.     extendTable(inTable->start() + inTable->no() - start());
  170.   }
  171.   for (int i=0; i<inTable->no(); ++i) {
  172.     values[inTable->start() - start() + i] = inTable->val(i);
  173.   }
  174. }
  175. ////
  176. // get float values for the colours
  177. ////
  178. const float *colrTable::r(unsigned index) const
  179. {
  180.   int i, useVal;
  181.   static float rValues[3];
  182.   if (index>=mySize) index = 0; // off the end
  183.   ////
  184.   // fill out the r, g, b values
  185.   for (i=0; i<3; ++i) {
  186. //    useVal = values[index][i];
  187.     useVal = values[index].getValue(i);
  188. //    if (useVal >= myExtent->white[i]) {
  189.     if (useVal >= myExtent->white.getValue(i)) {
  190.       rValues[i] = 1; // max possible
  191. //    } else if (useVal <= myExtent->black[i]) {
  192.     } else if (useVal <= myExtent->black.getValue(i)) {
  193.       rValues[i] = 0; // min possible
  194.     } else {
  195. //      rvalues[i] = (float) (useVal - myExtent->black[i]) /
  196. //    (myExtent->white[i] - myExtent->black[i]);
  197.       rValues[i] = (float) (useVal - myExtent->black.getValue(i)) /
  198.     (myExtent->white.getValue(i) - myExtent->black.getValue(i));
  199.     }
  200.   }
  201.   return rValues;
  202. }
  203. ////
  204. // vdc pts class
  205. ////
  206. // constructor for 2 integer points (used for rectangles)
  207. ////
  208. vdcPts::vdcPts(int x1, int y1, int x2, int y2) 
  209. {
  210.   int *intPtr = new int[4];
  211.   intPtr[0] = x1;
  212.   intPtr[1] = y1;
  213.   intPtr[2] = x2;
  214.   intPtr[3] = y2;
  215.   noPts = 2;
  216.   myType = 0; // integer
  217.   myPtr = intPtr;
  218.   next=NULL;
  219. }
  220. ////
  221. // constructor for 2 float points (used for rectangles)
  222. ////
  223. vdcPts::vdcPts(double x1, double y1, double x2, double y2) 
  224. {
  225.   float *floatPtr = new float[4];
  226.   floatPtr[0] = x1;
  227.   floatPtr[1] = y1;
  228.   floatPtr[2] = x2;
  229.   floatPtr[3] = y2;
  230.   noPts = 2;
  231.   myType = 1; // float
  232.   myPtr = floatPtr;
  233.   next=NULL;
  234. }
  235. ////
  236. // return the width of the points
  237. ////
  238. float vdcPts::width() const
  239. {
  240.   float minX, maxX;
  241.   int i;
  242.   if (!noPts) return 0; // no points
  243.  
  244.   if (myType) { // real vdc's
  245.     float *floatPtr = (float *) myPtr;
  246.     minX = maxX = floatPtr[0];
  247.     for (i=2; i<2 * noPts; i += 2) {
  248.       if (minX > floatPtr[i]) minX = floatPtr[i];
  249.       if (maxX < floatPtr[i]) maxX = floatPtr[i];
  250.     }
  251.   } else { // integer VDC's
  252.     int *intPtr = (int *) myPtr;
  253.     minX = maxX = intPtr[0];
  254.     for (i=2; i<2 * noPts; i += 2) {
  255.       if (minX > intPtr[i]) minX = intPtr[i];
  256.       if (maxX < intPtr[i]) maxX = intPtr[i];
  257.     }
  258.   }
  259.     return maxX - minX;
  260. }
  261. ////
  262. // return the height of the points
  263. ////
  264. float vdcPts::height()  const
  265. {
  266.   float maxY, minY;
  267.   int i;
  268.   if (!noPts) return 0; // no points
  269.  
  270.   if (myType) { // real vdc's
  271.     float *floatPtr = (float *) myPtr;
  272.     minY = maxY = floatPtr[1];
  273.     for (i=3; i<2 * noPts; i += 2) {
  274.       if (minY > floatPtr[i]) minY = floatPtr[i];
  275.       if (maxY < floatPtr[i]) maxY = floatPtr[i];
  276.     }
  277.   } else { // integer VDC's
  278.     int *intPtr = (int *) myPtr;
  279.     minY = maxY = intPtr[1];
  280.     for (i=3; i<2 * noPts; i += 2) {
  281.       if (minY > intPtr[i]) minY = intPtr[i];
  282.       if (maxY < intPtr[i]) maxY = intPtr[i];
  283.     }
  284.   }
  285.   return maxY - minY;
  286. }
  287. ////
  288. // return the max Y of the points
  289. ////
  290. float vdcPts::maxY()  const
  291. {
  292.   float myMax;
  293.   int i;
  294.   if (!noPts) return 0; // no points
  295.  
  296.   if (myType) { // real vdc's
  297.     float *floatPtr = (float *) myPtr;
  298.     myMax = floatPtr[1];
  299.     for (i=3; i<2 * noPts; i += 2) {
  300.       if (myMax < floatPtr[i]) myMax = floatPtr[i];
  301.     }
  302.   } else { // integer VDC's
  303.     int *intPtr = (int *) myPtr;
  304.     myMax = intPtr[1];
  305.     for (i=3; i<2 * noPts; i += 2) {
  306.       if (myMax < intPtr[i]) myMax = intPtr[i];
  307.     }
  308.   }
  309.   return myMax;
  310. }
  311. ////
  312. // return the min Y of the points
  313. ////
  314. float vdcPts::minY()  const
  315. {
  316.   float myMin;
  317.   int i;
  318.   if (!noPts) return 0; // no points
  319.  
  320.   if (myType) { // real vdc's
  321.     float *floatPtr = (float *) myPtr;
  322.     myMin = floatPtr[1];
  323.     for (i=3; i<2 * noPts; i += 2) {
  324.       if (myMin > floatPtr[i]) myMin = floatPtr[i];
  325.     }
  326.   } else { // integer VDC's
  327.     int *intPtr = (int *) myPtr;
  328.     myMin = intPtr[1];
  329.     for (i=3; i<2 * noPts; i += 2) {
  330.       if (myMin > intPtr[i]) myMin = intPtr[i];
  331.     }
  332.   }
  333.   return myMin;
  334. }
  335. ////
  336. // return the max X of the points
  337. ////
  338. float vdcPts::maxX()  const
  339. {
  340.   float myMax;
  341.   int i;
  342.   if (!noPts) return 0; // no points
  343.  
  344.   if (myType) { // real vdc's
  345.     float *floatPtr = (float *) myPtr;
  346.     myMax = floatPtr[0];
  347.     for (i=2; i<2 * noPts; i += 2) {
  348.       if (myMax < floatPtr[i]) myMax = floatPtr[i];
  349.     }
  350.   } else { // integer VDC's
  351.     int *intPtr = (int *) myPtr;
  352.     myMax = intPtr[0];
  353.     for (i=2; i<2 * noPts; i += 2) {
  354.       if (myMax < intPtr[i]) myMax = intPtr[i];
  355.     }
  356.   }
  357.   return myMax;
  358. }
  359. ////
  360. // return the min X of the points
  361. ////
  362. float vdcPts::minX()  const
  363. {
  364.   float myMin;
  365.   int i;
  366.   if (!noPts) return 0; // no points
  367.  
  368.   if (myType) { // real vdc's
  369.     float *floatPtr = (float *) myPtr;
  370.     myMin = floatPtr[0];
  371.     for (i=2; i<2 * noPts; i += 2) {
  372.       if (myMin > floatPtr[i]) myMin = floatPtr[i];
  373.     }
  374.   } else { // integer VDC's
  375.     int *intPtr = (int *) myPtr;
  376.     myMin = intPtr[0];
  377.     for (i=2; i<2 * noPts; i += 2) {
  378.       if (myMin > intPtr[i]) myMin = intPtr[i];
  379.     }
  380.   }
  381.   return myMin;
  382. }
  383. ////
  384. // scale the points by a constant factor
  385. ////
  386. void vdcPts::scale(float inScale)
  387. {
  388.   int i;
  389.   if (myType) {
  390.     float *floatPtr = (float *) myPtr;
  391.     for (i=0; i<2*noPts; ++i) floatPtr[i] *= inScale;
  392.   } else {
  393.     int *intPtr = (int *) myPtr;
  394.     for (i=0; i<2*noPts; ++i) intPtr[i] = (int) (inScale * intPtr[i]);
  395.   }
  396. }
  397. ////
  398. // shift the points in x and y direction
  399. ////
  400. void vdcPts::shift(float xShift, float yShift)
  401. {
  402.   int i;
  403.   if (myType) {
  404.     float *floatPtr = (float *) myPtr;
  405.     for (i=0; i<noPts; ++i) {
  406.       floatPtr[2*i] += xShift;
  407.       floatPtr[2*i+1] += yShift;
  408.     }
  409.   } else {
  410.     int *intPtr = (int *) myPtr;
  411.     for (i=0; i<noPts; ++i) {
  412.       intPtr[2*i] += (int) xShift;
  413.       intPtr[2*i+1] += (int) yShift;
  414.     }
  415.   }
  416. }
  417. ////
  418. // the basic text class
  419. ////
  420. const int genText::finalFlag = 1;
  421. const int genText::restrictedFlag = 1<<1;
  422. const int genText::appendFlag = 1<<2;
  423. ////
  424. // basic cgm class
  425. ////
  426. // constructor
  427. ////
  428. baseCGM::baseCGM(cgmContainer *inOwner, baseCGM *inPrev, baseCGM *inNext)
  429. {
  430.   prev = inPrev; // inititalize pointers
  431.   next = inNext;
  432.   owner = inOwner;
  433.   if (prev) prev->next = this; // link pointers
  434.   if (next) next->prev = this;
  435. }
  436. ////
  437. // destructor
  438. ////
  439. baseCGM::~baseCGM() 
  440. {
  441.   if (prev) prev->next = next; // relink pointers
  442.   if (next) next->prev = prev;
  443. }
  444. ////
  445. // output in a CGM format
  446. ////
  447. int baseCGM::cgmOut(cgmOutput *inOut)
  448. {
  449.   inOut->startCmd(this);
  450.   inOut->endCmd();
  451.   return 1;
  452. }
  453. ////
  454. // default output to a display
  455. ////
  456. int baseCGM::display(baseDisplay*)
  457. {
  458.   return 1;
  459. }
  460. ////
  461. // the Delimiter class
  462. ////
  463. const int cgmDelimiter::myClass = 0;
  464. ////
  465. // Begin Metafile
  466. ////
  467. const int cgmBeginMetafile::myElement = 1;
  468. const char *cgmBeginMetafile::myName = "BegMf";
  469. ////
  470. // constructor
  471. ////
  472. cgmBeginMetafile::cgmBeginMetafile(cgmContainer *inOwner, cgmInput *cgmIn,
  473.                    baseCGM *inPrev, baseCGM *inNext)
  474. : cgmDelimiter(inOwner, inPrev, inNext)
  475. {
  476.   mfName = cgmIn->getString(mfNameSize);
  477. }
  478. ////
  479. // destructor
  480. ////
  481. cgmBeginMetafile::~cgmBeginMetafile()
  482. {
  483.   if (mfNameSize) delete mfName;
  484. }
  485. ////
  486. // output in a CGM format
  487. ////
  488. int cgmBeginMetafile::cgmOut(cgmOutput *inOut)
  489. {
  490.   inOut->startCmd(this);
  491.   inOut->outString(mfNameSize ? mfName : "");
  492.   inOut->endCmd();
  493.   return 1;
  494. }
  495. ////
  496. // display output
  497. ////
  498. int cgmBeginMetafile::display(baseDisplay *inDisplay)
  499. {
  500.   inDisplay->newMF();
  501.   if (inDisplay->fileDefaults() && mfOwner()->defaults()) {
  502.     // display wants to get defaults replacement at beginning of metafile
  503.     mfOwner()->displayDefaults(inDisplay);
  504.   }
  505.   return 1;
  506. }
  507. /////
  508. // End Metafile
  509. ////
  510. const int cgmEndMetafile::myElement = 2;
  511. const int cgmEndMetafileMyElement =2;
  512. const char *cgmEndMetafile::myName = "EndMf";
  513. ////
  514. // constructor
  515. ////
  516. cgmEndMetafile::cgmEndMetafile(cgmContainer *inOwner, cgmInput*,
  517.                    baseCGM *inPrev, baseCGM *inNext)
  518. : cgmDelimiter(inOwner, inPrev, inNext) // constructor
  519. {
  520. }
  521. int cgmEndMetafile::cgmOut(cgmOutput *inOut) // output in a CGM format
  522. {
  523.   return inOut->startCmd(this) && inOut->endCmd();
  524. }
  525. ////
  526. // display output
  527. ////
  528. int cgmEndMetafile::display(baseDisplay *inDisplay)
  529. {
  530.   inDisplay->endMF();
  531.   return 1;
  532. }
  533. ////
  534. // Begin Picture
  535. ////
  536. const int cgmBeginPicture::myElement = 3;
  537. const int cgmBeginPictureMyElement = 3;
  538. const char *cgmBeginPicture::myName = "BegPic";
  539. ////
  540. // constructor
  541. ////
  542. cgmBeginPicture::cgmBeginPicture(cgmContainer *inOwner, cgmInput *cgmIn,
  543.                  baseCGM *inPrev, baseCGM *inNext)
  544. : cgmDelimiter(inOwner, inPrev, inNext) // constructor
  545. {
  546.   picName = cgmIn->getString(picNameSize);
  547. }
  548. ////
  549. // alternate constructor
  550. ////
  551. cgmBeginPicture::cgmBeginPicture(cgmContainer *inOwner, const char *inStr,
  552.                  int strSize, baseCGM *inPrev, baseCGM *inNext)
  553. : cgmDelimiter(inOwner, inPrev, inNext) // constructor
  554. {
  555.   picNameSize = strSize;
  556.   if (picNameSize) {
  557.     picName = new char [picNameSize + 1];
  558.     for (int i=0; i<picNameSize; ++i) picName[i] = inStr[i];
  559.     picName[i] = 0;
  560.   } else picName = NULL;
  561. }
  562. ////
  563. // destructor
  564. ////
  565. cgmBeginPicture::~cgmBeginPicture()
  566. {
  567.   if (picNameSize) delete picName;
  568. }
  569. ////
  570. // output in a CGM format
  571. ////
  572. int cgmBeginPicture::cgmOut(cgmOutput *inOut) 
  573. {
  574.   inOut->startCmd(this);
  575.   inOut->outString(picNameSize ? picName : "");
  576.   inOut->endCmd();
  577.   return 1;
  578. }
  579. ////
  580. // display output
  581. ////
  582. int cgmBeginPicture::display(baseDisplay *inDisplay)
  583. {
  584.   inDisplay->newPic();
  585.   inDisplay->startPic();
  586.   if (inDisplay->picDefaults() && mfOwner()->defaults()) {
  587.     // display wants to get defaults replacement at each picture
  588.     mfOwner()->displayDefaults(inDisplay);
  589.   }
  590.   return 1;
  591. }
  592. ////
  593. // Begin Picture Body
  594. ////
  595. const int cgmBeginPictureBody::myElement = 4;
  596. const char *cgmBeginPictureBody::myName = "BegPicBody";
  597. ////
  598. // constructor
  599. ////
  600. cgmBeginPictureBody::cgmBeginPictureBody(cgmContainer *inOwner, cgmInput*,
  601.                      baseCGM *inPrev, baseCGM *inNext)
  602. : cgmDelimiter(inOwner, inPrev, inNext)
  603. {
  604. }
  605. ////
  606. // output in a CGM format
  607. ////
  608. int cgmBeginPictureBody::cgmOut(cgmOutput *inOut)
  609. {
  610.   inOut->startCmd(this);
  611.   inOut->endCmd();
  612.   return 1;
  613. }
  614. ////
  615. // display output
  616. ////
  617. int cgmBeginPictureBody::display(baseDisplay *inDisplay)
  618. {
  619.   inDisplay->newPicBody
  620.     (owner->vdcExtent()->width(), owner->vdcExtent()->height(),
  621.     -owner->vdcExtent()->minX(), -owner->vdcExtent()->minY());
  622.   inDisplay->clearScreen();
  623.   return 1;
  624. }
  625. ////
  626. // End Picture
  627. ////
  628. const int cgmEndPicture::myElement = 5;
  629. const int cgmEndPictureMyElement = 5;
  630.  
  631. const char *cgmEndPicture::myName = "EndPic";
  632. ////
  633. // constructor
  634. ////
  635. cgmEndPicture::cgmEndPicture(cgmContainer *inOwner, cgmInput*,
  636.                  baseCGM *inPrev, baseCGM *inNext)
  637. : cgmDelimiter(inOwner, inPrev, inNext)
  638. {
  639. }
  640. ////
  641. // output in a CGM format
  642. ////
  643. int cgmEndPicture::cgmOut(cgmOutput *inOut)
  644. {
  645.   inOut->startCmd(this);
  646.   inOut->endCmd();
  647.   return 1;
  648. }
  649. ////
  650. // display output
  651. ////
  652. int cgmEndPicture::display(baseDisplay *inDisplay)
  653. {
  654.   inDisplay->endPic();
  655.   return 1;
  656. }
  657. ////
  658. // the Metafile Descriptor class
  659. ////
  660. const int cgmMetafileDescriptor::myClass = 1;
  661. ////
  662. // Metafile Version
  663. ////
  664. const int cgmMetafileVersion::myElement = 1;
  665. const char *cgmMetafileVersion::myName = "MFVersion";
  666. ////
  667. // constructor
  668. ////
  669. cgmMetafileVersion::cgmMetafileVersion(cgmContainer *inOwner, cgmInput *cgmIn,
  670.                        baseCGM *inPrev, baseCGM *inNext)
  671. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  672. {
  673.   versionNumber = cgmIn->getInt();
  674.   mfOwner()->versionCmd = this;
  675. }
  676. ////
  677. // output in a CGM format
  678. ////
  679. int cgmMetafileVersion::cgmOut(cgmOutput *inOut)
  680. {
  681.   inOut->startCmd(this);
  682.   inOut->outInt(versionNumber);
  683.   inOut->endCmd();
  684.   return 1;
  685. }
  686. #ifdef macintosh
  687.  #pragma segment CGM2
  688. #endif
  689. ////
  690. // Metafile Description
  691. ////
  692. const int cgmMetafileDescription::myElement = 2;
  693. const char *cgmMetafileDescription::myName = "MFDesc";
  694. ////
  695. // constructor
  696. ////
  697. cgmMetafileDescription::
  698. cgmMetafileDescription(cgmContainer *inOwner, cgmInput *cgmIn,
  699.                baseCGM *inPrev, baseCGM *inNext)
  700. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  701. {
  702.   mfDescription = cgmIn->getString(mfDescriptionSize);
  703.   mfOwner()->descriptionCmd = this;
  704. }
  705. ////
  706. // destructor
  707. ////
  708. cgmMetafileDescription::~cgmMetafileDescription()
  709. {
  710.   if (mfDescriptionSize) delete mfDescription;
  711. }
  712. ////
  713. // output in a CGM format
  714. ////
  715. int cgmMetafileDescription::cgmOut(cgmOutput *inOut)
  716. {
  717.   inOut->startCmd(this);
  718.   inOut->outString(mfDescriptionSize ? mfDescription : "");
  719.   inOut->endCmd();
  720.   return 1;
  721. }
  722. ////
  723. // VDC Type
  724. ////
  725. const int cgmVdcType::myElement = 3;
  726. const int cgmVdcTypeMyElement = 3;
  727.  
  728. const char *cgmVdcType::myName = "VDCType";
  729. //// 
  730. // aids for parsing
  731. //// 
  732. const char *tmpVdcTypeList[] = {"INTEGER", "REAL"};
  733. const char **cgmVdcType::typeList = tmpVdcTypeList;
  734. const int cgmVdcType::typeListSize =
  735. sizeof(tmpVdcTypeList) / sizeof(tmpVdcTypeList[0]);
  736. //// 
  737. // constructor
  738. ////
  739. cgmVdcType::cgmVdcType(cgmContainer *inOwner, cgmInput *cgmIn,
  740.                baseCGM *inPrev, baseCGM *inNext)
  741. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  742. {
  743.   mfOwner()->vdcTypeCmd = this;
  744.   myType = cgmIn->getType(typeList, typeListSize);
  745. }
  746. //// 
  747. // output in a CGM format
  748. //// 
  749. int cgmVdcType::cgmOut(cgmOutput *inOut)
  750. {
  751.   inOut->startCmd(this);
  752.   inOut->outType(typeList, myType);
  753.   inOut->endCmd();
  754.   return 1;
  755. }
  756. //// 
  757. // Integer Precision
  758. //// 
  759. const int cgmIntegerPrec::myElement = 4;
  760. const int cgmIntegerPrecMyElement = 4;
  761. const char *cgmIntegerPrec::myName = "IntegerPrec";
  762. //// 
  763. // constructor
  764. //// 
  765. cgmIntegerPrec::cgmIntegerPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  766.                    baseCGM *inPrev, baseCGM *inNext)
  767. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  768. {
  769.   cgmIn->getIntPrec(&thisPrec);
  770. }
  771. //// 
  772. // output in a CGM format
  773. //// 
  774. int cgmIntegerPrec::cgmOut(cgmOutput *inOut)
  775. {
  776.   inOut->startCmd(this);
  777.   inOut->outIntPrec(&thisPrec);
  778.   inOut->endCmd();
  779.   return 1;
  780. }
  781. //// 
  782. // Real Precision
  783. //// 
  784. const int cgmRealPrec::myElement = 5;
  785. const int cgmRealPrecMyElement = 5;
  786. const char *cgmRealPrec::myName = "RealPrec";
  787. //// 
  788. // constructor
  789. //// 
  790. cgmRealPrec::cgmRealPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  791.              baseCGM *inPrev, baseCGM *inNext)
  792. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  793. {
  794.   cgmIn->getRealPrec(&thisPrec);
  795. }
  796. //// 
  797. // output in a CGM format
  798. //// 
  799. int cgmRealPrec::cgmOut(cgmOutput *inOut)
  800. {
  801.   inOut->startCmd(this);
  802.   inOut->outRealPrec(&thisPrec);
  803.   inOut->endCmd();
  804.   return 1;
  805. }
  806. //// 
  807. // Index Precision
  808. //// 
  809. const int cgmIndexPrec::myElement = 6;
  810. const int cgmIndexPrecMyElement = 6;
  811. const char *cgmIndexPrec::myName = "IndexPrec";
  812. //// 
  813. // constructor
  814. //// 
  815. cgmIndexPrec::cgmIndexPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  816.                baseCGM *inPrev, baseCGM *inNext)
  817. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  818. {
  819.   cgmIn->getIntPrec(&thisPrec);
  820. }
  821. //// 
  822. // output in a CGM format
  823. //// 
  824. int cgmIndexPrec::cgmOut(cgmOutput *inOut)
  825. {
  826.   inOut->startCmd(this);
  827.   inOut->outIntPrec(&thisPrec);
  828.   inOut->endCmd();
  829.   return 1;
  830. }
  831. //// 
  832. // Colour Precision
  833. //// 
  834. const int cgmColrPrec::myElement = 7;
  835. const int cgmColrPrecMyElement = 7;
  836. const char *cgmColrPrec::myName = "ColrPrec";
  837. //// 
  838. // constructor
  839. //// 
  840. cgmColrPrec::cgmColrPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  841.              baseCGM *inPrev, baseCGM *inNext)
  842. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  843. {
  844.   cgmIn->getIntPrec(&thisPrec);
  845. }
  846. //// 
  847. // output in a CGM format
  848. //// 
  849. int cgmColrPrec::cgmOut(cgmOutput *inOut)
  850. {
  851.   inOut->startCmd(this);
  852.   inOut->outIntPrec(&thisPrec);
  853.   inOut->endCmd();
  854.   return 1;
  855. }
  856. //// 
  857. // Colour Index Precision
  858. //// 
  859. const int cgmColrIndexPrec::myElement = 8;
  860. const int cgmColrIndexPrecMyElement = 8;
  861. const char *cgmColrIndexPrec::myName = "ColrIndexPrec";
  862. //// 
  863. // constructor
  864. //// 
  865. cgmColrIndexPrec::cgmColrIndexPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  866.                    baseCGM *inPrev, baseCGM *inNext) 
  867. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  868. {
  869.   cgmIn->getIntPrec(&thisPrec);
  870. }
  871. //// 
  872. // output in a CGM format
  873. //// 
  874. int cgmColrIndexPrec::cgmOut(cgmOutput *inOut)
  875. {
  876.   inOut->startCmd(this);
  877.   inOut->outIntPrec(&thisPrec);
  878.   inOut->endCmd();
  879.   return 1;
  880. }
  881. //// 
  882. // Max Colour Index
  883. //// 
  884. const int cgmMaxColrIndex::myElement = 9;
  885. const char *cgmMaxColrIndex::myName = "MaxColrIndex";
  886. //// 
  887. // constructor
  888. //// 
  889. cgmMaxColrIndex::cgmMaxColrIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  890.                  baseCGM *inPrev, baseCGM *inNext) 
  891. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  892. {
  893.   mfOwner()->maxColrIndexCmd = this;
  894.   // maxIndexValue = cgmIn->getInt();
  895.   maxIndexValue = cgmIn->getCI();
  896. }
  897. //// 
  898. // output in a CGM format
  899. //// 
  900. int cgmMaxColrIndex::cgmOut(cgmOutput *inOut)
  901. {
  902.   inOut->startCmd(this);
  903.   inOut->outInt(maxIndexValue);
  904.   inOut->endCmd();
  905.   return 1;
  906. }
  907. //// 
  908. // Colour Value Extent
  909. //// 
  910. const int cgmColrValueExtent::myElement = 10;
  911. const char *cgmColrValueExtent::myName = "ColrValueExt";
  912. //// 
  913. // constructor
  914. //// 
  915. cgmColrValueExtent::cgmColrValueExtent(cgmContainer *inOwner,cgmInput *cgmIn,
  916.                        baseCGM *inPrev, baseCGM *inNext) 
  917. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  918. {
  919.   mfOwner()->colrValueExtentCmd = this;
  920.   cgmIn->getDColr(myExtent.black);
  921.   cgmIn->getDColr(myExtent.white);
  922. }
  923. //// 
  924. // output in a CGM format
  925. //// 
  926. int cgmColrValueExtent::cgmOut(cgmOutput *inOut)
  927. {
  928.   inOut->startCmd(this);
  929.   inOut->outDColr(myExtent.white);
  930.   inOut->outDColr(myExtent.black);
  931.   inOut->endCmd();
  932.   return 1;
  933. }
  934. //// 
  935. // Metafile Element List
  936. //// 
  937. const int cgmMetafileElementList::myElement = 11;
  938. const char *cgmMetafileElementList::myName = "MFElemList";
  939. //// 
  940. // constructor
  941. //// 
  942. cgmMetafileElementList::
  943. cgmMetafileElementList(cgmContainer *inOwner, cgmInput *cgmIn,
  944.                baseCGM *inPrev, baseCGM *inNext) 
  945. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  946. {
  947.   // fix later
  948. }
  949. //// 
  950. // output in a CGM format
  951. //// 
  952. int cgmMetafileElementList::cgmOut(cgmOutput *inOut)
  953. {
  954.   inOut->startCmd(this);
  955.   inOut->endCmd();
  956.   return 1;
  957. }
  958. //// 
  959. // Metafile Defaults Replacement
  960. //// 
  961. const int cgmMetafileDefaultsReplacement::myElement = 12;
  962. const char *cgmMetafileDefaultsReplacement::myName = "BegMFDefaults";
  963. const char *cgmMetafileDefaultsReplacement::endName = "EndMFDefaults";
  964. //// 
  965. // constructor
  966. //// 
  967. cgmMetafileDefaultsReplacement::
  968. cgmMetafileDefaultsReplacement(cgmContainer *inOwner, cgmInput *cgmIn,
  969.                    baseCGM *inPrev, baseCGM *inNext)
  970. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  971. {
  972.   myDefaults = cgmIn->getDefaults(mfOwner()); // get the set of defaults
  973.   ////
  974.   // add them to the metafile list, 
  975.   mfOwner()->addDefaults(myDefaults); 
  976. }
  977. //// 
  978. // output in a CGM format
  979. //// 
  980. int cgmMetafileDefaultsReplacement::cgmOut(cgmOutput *inOut)
  981. { // output in a CGM format
  982.   inOut->startCmd(this);
  983.   inOut->outDefaults(myDefaults);
  984.   inOut->endCmd();
  985.   return 1;
  986. }
  987. ////
  988. // Font List
  989. ////
  990. const int cgmFontList::myElement = 13;
  991. const char *cgmFontList::myName = "FontList";
  992. ////
  993. // constructor
  994. ////
  995. cgmFontList::cgmFontList(cgmContainer *inOwner, cgmInput *cgmIn,
  996.              baseCGM *inPrev,  baseCGM *inNext)
  997. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  998. {
  999.   noFonts = 0;
  1000. }
  1001. ////
  1002. // output in a CGM format
  1003. ////
  1004. int cgmFontList::cgmOut(cgmOutput *inOut)
  1005.   inOut->startCmd(this);
  1006.   inOut->endCmd();
  1007.   return 1;
  1008. }
  1009. ////
  1010. // Character Set List
  1011. ////
  1012. const int cgmCharacterSetList::myElement = 14;
  1013. const char *cgmCharacterSetList::myName = "CharSetList";
  1014. ////
  1015. // constructor
  1016. ////
  1017. cgmCharacterSetList::
  1018. cgmCharacterSetList(cgmContainer *inOwner, cgmInput *cgmIn,
  1019.             baseCGM *inPrev, baseCGM *inNext)
  1020. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  1021. {
  1022.   noSets = 0;
  1023. }
  1024. ////
  1025. // output in a CGM format
  1026. ////
  1027. int cgmCharacterSetList::cgmOut(cgmOutput *inOut)
  1028.   inOut->startCmd(this);
  1029.   inOut->endCmd();
  1030.   return 1;
  1031. }
  1032. ////
  1033. // Character Coding Announcer
  1034. ////
  1035. const int cgmCharacterCodingAnnouncer::myElement = 15;
  1036. const char *cgmCharacterCodingAnnouncer::myName = "CharCoding";
  1037. ////
  1038. // aids for parsing
  1039. //// 
  1040. const char *tmpCodingList[] = {"BASIC7BIT", "BASIC8BIT", "EXTD7BIT",
  1041. "EXTD8BIT"};
  1042. const char **cgmCharacterCodingAnnouncer::typeList = tmpCodingList;
  1043. const int cgmCharacterCodingAnnouncer::typeListSize =
  1044. sizeof(tmpCodingList) / sizeof(tmpCodingList[0]);
  1045. ////
  1046. // constructor
  1047. ////
  1048. cgmCharacterCodingAnnouncer::
  1049. cgmCharacterCodingAnnouncer(cgmContainer *inOwner, cgmInput *cgmIn,
  1050.                 baseCGM *inPrev, baseCGM *inNext)
  1051. : cgmMetafileDescriptor(inOwner, inPrev, inNext)
  1052. {
  1053.   announcer = cgmIn->getType(typeList, typeListSize);
  1054. }
  1055. ////
  1056. // output CGM format
  1057. ////
  1058. int cgmCharacterCodingAnnouncer::cgmOut(cgmOutput *inOut)
  1059.   inOut->startCmd(this);
  1060.   inOut->outType(typeList, announcer);
  1061.   inOut->endCmd();
  1062.   return 1;
  1063. }
  1064. ////
  1065. // the Picture Descriptor class
  1066. ////
  1067. const int cgmPictureDescriptor::myClass = 2;
  1068. ////
  1069. // Scaling Mode
  1070. ////
  1071. const int cgmScalingMode::myElement = 1;
  1072. const char *cgmScalingMode::myName = "ScaleMode";
  1073. ////
  1074. // aids for parsing
  1075. //// 
  1076. const char *tmpScalingList[] = {"ABSTRACT", "METRIC"};
  1077. const char **cgmScalingMode::typeList = tmpScalingList;
  1078. const int cgmScalingMode::typeListSize =
  1079. sizeof(tmpScalingList) / sizeof(tmpScalingList[0]);
  1080. //// 
  1081. // constructor
  1082. ////
  1083. cgmScalingMode::cgmScalingMode(cgmContainer *inOwner, cgmInput *cgmIn,
  1084.                    baseCGM *inPrev, baseCGM *inNext)
  1085. : cgmPictureDescriptor(inOwner, inPrev, inNext)
  1086. {
  1087.   owner->scalingCmd = this;
  1088.   mode = cgmIn->getType(typeList, typeListSize);
  1089.   if (mode) factor = cgmIn->getFP(); // always floating point
  1090.   else factor = 1; // for safety
  1091. }
  1092. ////
  1093. // output CGM format
  1094. ////
  1095. int cgmScalingMode::cgmOut(cgmOutput *inOut) 
  1096.   inOut->startCmd(this);
  1097.   inOut->outType(typeList, mode);
  1098.   if (mode) inOut->outReal(factor);
  1099.   inOut->endCmd();
  1100.   return 1;
  1101. }
  1102. ////
  1103. // Colour Selection Mode
  1104. ////
  1105. const int cgmColrMode::myElement = 2;
  1106. const char *cgmColrMode::myName = "ColrMode";
  1107. ////
  1108. // aids for parsing
  1109. //// 
  1110. const char *tmpColrList[] = {"INDEXED", "DIRECT"};
  1111. const char **cgmColrMode::typeList = tmpColrList;
  1112. const int cgmColrMode::typeListSize =
  1113. sizeof(tmpColrList) / sizeof(tmpColrList[0]);
  1114. //// 
  1115. // constructor
  1116. //// 
  1117. cgmColrMode::cgmColrMode(cgmContainer *inOwner, cgmInput *cgmIn,
  1118.              baseCGM *inPrev, baseCGM *inNext)
  1119. : cgmPictureDescriptor(inOwner, inPrev, inNext)
  1120. {
  1121.   owner->colrModeCmd = this;
  1122.   mode = cgmIn->getType(typeList, typeListSize);
  1123. }
  1124. //// 
  1125. // output CGM format
  1126. //// 
  1127. int cgmColrMode::cgmOut(cgmOutput *inOut)
  1128.   inOut->startCmd(this);
  1129.   inOut->outType(typeList, mode);
  1130.   inOut->endCmd();
  1131.   return 1;
  1132. }
  1133. ////
  1134. // Line Width Specification Mode
  1135. ////
  1136. const int cgmLineWidthMode::myElement = 3;
  1137. const char *cgmLineWidthMode::myName = "LineWidthMode";
  1138. ////
  1139. // aids for parsing
  1140. //// 
  1141. const char *tmpAbS[] = {"ABSTRACT", "SCALED"};
  1142. const char **cgmLineWidthMode::typeList = tmpAbS;
  1143. const int cgmLineWidthMode::typeListSize =
  1144. sizeof(tmpAbS) / sizeof(tmpAbS[0]);
  1145. ////
  1146. // constructor
  1147. ////
  1148. cgmLineWidthMode::cgmLineWidthMode(cgmContainer *inOwner, cgmInput *cgmIn,
  1149.                    baseCGM *inPrev, baseCGM *inNext)
  1150. : cgmPictureDescriptor(inOwner, inPrev, inNext)
  1151. {
  1152.   owner->lineModeCmd = this;
  1153.   mode = cgmIn->getType(typeList, typeListSize);
  1154. }
  1155. int cgmLineWidthMode::cgmOut(cgmOutput *inOut) // output CGM format
  1156.   inOut->startCmd(this);
  1157.   inOut->outType(typeList, mode);
  1158.   inOut->endCmd();
  1159.   return 1;
  1160. }
  1161. ////
  1162. // Marker Size Specification Mode
  1163. ////
  1164. const int cgmMarkerSizeMode::myElement = 4;
  1165. const char *cgmMarkerSizeMode::myName = "MarkerSizeMode";
  1166. ////
  1167. // aids for parsing
  1168. //// 
  1169. const char **cgmMarkerSizeMode::typeList = tmpAbS;
  1170. const int cgmMarkerSizeMode::typeListSize =
  1171. sizeof(tmpAbS) / sizeof(tmpAbS[0]);
  1172. ////
  1173. // constructor
  1174. ////
  1175. cgmMarkerSizeMode::cgmMarkerSizeMode(cgmContainer *inOwner, cgmInput *cgmIn,
  1176.                      baseCGM *inPrev, baseCGM *inNext)
  1177. : cgmPictureDescriptor(inOwner, inPrev, inNext)
  1178. {
  1179.   mode = cgmIn->getType(typeList, typeListSize);
  1180.   owner->markerModeCmd = this;
  1181. }
  1182. ////
  1183. // output CGM format
  1184. ////
  1185. int cgmMarkerSizeMode::cgmOut(cgmOutput *inOut)
  1186.   inOut->startCmd(this);
  1187.   inOut->outType(typeList, mode);
  1188.   inOut->endCmd();
  1189.   return 1;
  1190. }
  1191. ////
  1192. // Edge Width Specification Mode
  1193. ////
  1194. const int cgmEdgeWidthMode::myElement = 5;
  1195. const char *cgmEdgeWidthMode::myName = "EdgeWidthMode";
  1196. ////
  1197. // aids for parsing
  1198. //// 
  1199. const char **cgmEdgeWidthMode::typeList = tmpAbS;
  1200. const int cgmEdgeWidthMode::typeListSize =
  1201. sizeof(tmpAbS) / sizeof(tmpAbS[0]);
  1202. ////
  1203. // constructor
  1204. ////
  1205. cgmEdgeWidthMode::cgmEdgeWidthMode(cgmContainer *inOwner, cgmInput *cgmIn,
  1206.                    baseCGM *inPrev, baseCGM *inNext)
  1207. : cgmPictureDescriptor(inOwner, inPrev, inNext)
  1208. {
  1209.   mode = cgmIn->getType(typeList, typeListSize);
  1210.   owner->edgeModeCmd = this;
  1211. }
  1212. ////
  1213. // output CGM format
  1214. ////
  1215. int cgmEdgeWidthMode::cgmOut(cgmOutput *inOut) 
  1216.   inOut->startCmd(this);
  1217.   inOut->outType(typeList, mode);
  1218.   inOut->endCmd();
  1219.   return 1;
  1220. }
  1221. ////
  1222. // VDC extent
  1223. ////
  1224. const int cgmVdcExtent::myElement = 6;
  1225. const char *cgmVdcExtent::myName = "VDCExt";
  1226. ////
  1227. // constructor
  1228. ////
  1229. cgmVdcExtent::cgmVdcExtent(cgmContainer *inOwner, cgmInput *cgmIn,
  1230.                baseCGM *inPrev, baseCGM *inNext)
  1231. : cgmPictureDescriptor(inOwner, inPrev, inNext) 
  1232. {
  1233.   myPts = cgmIn->getVdcPts(2);
  1234.   owner->vdcExtentCmd = this;
  1235. }
  1236. ////
  1237. // destructor
  1238. ////
  1239. cgmVdcExtent::~cgmVdcExtent() { 
  1240.   if (myPts) delete myPts;
  1241. }
  1242. ////
  1243. // output CGM format
  1244. ////
  1245. int cgmVdcExtent::cgmOut(cgmOutput *inOut) 
  1246.   inOut->startCmd(this);
  1247.   inOut->outVdcPts(myPts);
  1248.   inOut->endCmd();
  1249.   return 1;
  1250. }
  1251. ////
  1252. // Background Colour
  1253. ////
  1254. const int cgmBackgroundColr::myElement = 7;
  1255. const char *cgmBackgroundColr::myName = "BackColr";
  1256. ////
  1257. // constructor
  1258. ////
  1259. cgmBackgroundColr::cgmBackgroundColr(cgmContainer *inOwner, cgmInput *cgmIn, baseCGM *inPrev,
  1260.                      baseCGM *inNext)
  1261. : cgmPictureDescriptor(inOwner, inPrev, inNext) 
  1262. {
  1263.   cgmIn->getDColr(background);
  1264. }
  1265. ////
  1266. // output CGM format
  1267. ////
  1268. int cgmBackgroundColr::cgmOut(cgmOutput *inOut) 
  1269.   inOut->startCmd(this);
  1270.   inOut->outDColr(background);
  1271.   inOut->endCmd();
  1272.   return 1;
  1273. }
  1274. ////
  1275. // display output
  1276. ////
  1277. int cgmBackgroundColr::display(baseDisplay *inDisplay)
  1278. {
  1279.   genColr genBack(background, owner->colrExtent(), owner->colrs());
  1280.   ////
  1281.   // send a general colour for convenience
  1282.   inDisplay->backColr(genBack);
  1283.   return 1;
  1284. }
  1285. #ifdef macintosh
  1286.  #pragma segment CGM3
  1287. #endif
  1288. ////
  1289. // the Control class
  1290. ////
  1291. const int cgmControl::myClass = 3;
  1292. ////
  1293. // VDC Integer Precision
  1294. ////
  1295. const int cgmVdcInteger::myElement = 1;
  1296. const int cgmVdcIntegerMyElement = 1;
  1297. const char *cgmVdcInteger::myName = "VDCIntegerPrec";
  1298. ////
  1299. // constructor
  1300. ////
  1301. cgmVdcInteger::cgmVdcInteger(cgmContainer *inOwner, cgmInput *cgmIn,
  1302.                  baseCGM *inPrev, baseCGM *inNext) 
  1303. : cgmControl(inOwner, inPrev, inNext)
  1304. {
  1305.   cgmIn->getIntPrec(&thisPrec);
  1306. }
  1307. ////
  1308. // output CGM format
  1309. ////
  1310. int cgmVdcInteger::cgmOut(cgmOutput *inOut)
  1311.   inOut->startCmd(this);
  1312.   inOut->outIntPrec(&thisPrec);
  1313.   inOut->endCmd();
  1314.   return 1;
  1315. }
  1316. ////
  1317. // VDC Real Precision
  1318. ////
  1319. const int cgmVdcReal::myElement = 2;
  1320. const int cgmVdcRealMyElement = 2;
  1321. const char *cgmVdcReal::myName = "VDCRealPrec";
  1322. ////
  1323. // constructor
  1324. ////
  1325. cgmVdcReal::cgmVdcReal(cgmContainer *inOwner, cgmInput *cgmIn,
  1326.                baseCGM *inPrev, baseCGM *inNext) 
  1327. : cgmControl(inOwner, inPrev, inNext)
  1328. {
  1329.   cgmIn->getRealPrec(&thisPrec);
  1330. }
  1331. ////
  1332. // output CGM format
  1333. ////
  1334. int cgmVdcReal::cgmOut(cgmOutput *inOut) 
  1335.   inOut->startCmd(this);
  1336.   inOut->outRealPrec(&thisPrec);
  1337.   inOut->endCmd();
  1338.   return 1;
  1339. }
  1340. ////
  1341. // auxiliary colour
  1342. ////
  1343. const int cgmAuxColr::myElement = 3;
  1344. const char *cgmAuxColr::myName = "AuxColr";
  1345. ////
  1346. // constructor
  1347. ////
  1348. cgmAuxColr::cgmAuxColr(cgmContainer *inOwner, cgmInput *cgmIn,
  1349.                baseCGM *inPrev, baseCGM *inNext)
  1350. : cgmControl(inOwner, inPrev, inNext)
  1351. {
  1352.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  1353.               owner->colrs());
  1354. }
  1355. ////
  1356. // output in a CGM format
  1357. ////
  1358. int cgmAuxColr::cgmOut(cgmOutput *inOut)
  1359. {
  1360.   inOut->startCmd(this);
  1361.   inOut->outColr(myColr);
  1362.   inOut->endCmd();
  1363.   return 1;
  1364. }
  1365. ////
  1366. // transparency
  1367. ////
  1368. const int cgmTransparency::myElement = 4;
  1369. const char *cgmTransparency::myName = "Transparency";
  1370. //// 
  1371. // aids for parsing
  1372. //// 
  1373. const char *tmpTransparencyList[] = {"OFF", "ON"};
  1374. const char **cgmTransparency::typeList = tmpTransparencyList;
  1375. const int cgmTransparency::typeListSize =
  1376. sizeof(tmpTransparencyList) / sizeof(tmpTransparencyList[0]);
  1377. //// 
  1378. // constructor
  1379. ////
  1380. cgmTransparency::cgmTransparency(cgmContainer *inOwner, cgmInput *cgmIn,
  1381.                  baseCGM *inPrev, baseCGM *inNext)
  1382. : cgmControl(inOwner, inPrev, inNext)
  1383. {
  1384.   myType = cgmIn->getType(typeList, typeListSize);
  1385. }
  1386. //// 
  1387. // output in a CGM format
  1388. //// 
  1389. int cgmTransparency::cgmOut(cgmOutput *inOut)
  1390. {
  1391.   inOut->startCmd(this);
  1392.   inOut->outType(typeList, myType);
  1393.   inOut->endCmd();
  1394.   return 1;
  1395. }
  1396. ////
  1397. // display output
  1398. ////
  1399. int cgmTransparency::display(baseDisplay *inDisplay)
  1400. {
  1401.   inDisplay->transparency(myType);
  1402.   return 1;
  1403. }
  1404. ////
  1405. // clip rectangle
  1406. ////
  1407. const int cgmClipRect::myElement = 5;
  1408. const char *cgmClipRect::myName = "ClipRect";
  1409. ////
  1410. // constructor
  1411. ////
  1412. cgmClipRect::cgmClipRect(cgmContainer *inOwner, cgmInput *cgmIn,
  1413.              baseCGM *inPrev, baseCGM *inNext)
  1414. : cgmControl(inOwner, inPrev, inNext)
  1415. {
  1416.   myPts = cgmIn->getVdcPts(2);
  1417. }
  1418. ////
  1419. // output in a CGM format
  1420. ////
  1421. int cgmClipRect::cgmOut(cgmOutput *inOut)
  1422. {
  1423.   inOut->startCmd(this);
  1424.   inOut->outVdcPts(myPts);
  1425.   inOut->endCmd();
  1426.   return 1;
  1427. }
  1428. ////
  1429. // display output
  1430. ////
  1431. int cgmClipRect::display(baseDisplay *inDisplay)
  1432. {
  1433.   inDisplay->clipRect(myPts);
  1434.   return 1;
  1435. }
  1436. ////
  1437. // clip indicator
  1438. ////
  1439. const int cgmClip::myElement = 6;
  1440. const char *cgmClip::myName = "Clip";
  1441. //// 
  1442. // aids for parsing
  1443. //// 
  1444. const char *tmpClipList[] = {"OFF", "ON"};
  1445. const char **cgmClip::typeList = tmpClipList;
  1446. const int cgmClip::typeListSize =
  1447. sizeof(tmpClipList) / sizeof(tmpClipList[0]);
  1448. //// 
  1449. // constructor
  1450. ////
  1451. cgmClip::cgmClip(cgmContainer *inOwner, cgmInput *cgmIn,
  1452.                  baseCGM *inPrev, baseCGM *inNext)
  1453. : cgmControl(inOwner, inPrev, inNext)
  1454. {
  1455.   myType = cgmIn->getType(typeList, typeListSize);
  1456. }
  1457. //// 
  1458. // output in a CGM format
  1459. //// 
  1460. int cgmClip::cgmOut(cgmOutput *inOut)
  1461. {
  1462.   inOut->startCmd(this);
  1463.   inOut->outType(typeList, myType);
  1464.   inOut->endCmd();
  1465.   return 1;
  1466. }
  1467. ////
  1468. // display output
  1469. ////
  1470. int cgmClip::display(baseDisplay *inDisplay)
  1471. {
  1472.   inDisplay->clip(myType);
  1473.   return 1;
  1474. }
  1475. ////
  1476. // the Graphical Primitive class
  1477. ////
  1478. const int cgmGraphicalPrimitive::myClass = 4;
  1479. ////
  1480. // Polyline
  1481. ////
  1482. const int cgmPolyline::myElement = 1;
  1483. const char *cgmPolyline::myName = "Line";
  1484. ////
  1485. // constructor
  1486. ////
  1487. cgmPolyline::cgmPolyline(cgmContainer *inOwner, cgmInput *cgmIn,
  1488.              baseCGM *inPrev, baseCGM *inNext)
  1489. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) 
  1490. {
  1491.   myPts = cgmIn->getVdcPts();
  1492. }
  1493. ////
  1494. // destructor
  1495. ////
  1496. cgmPolyline::~cgmPolyline() { 
  1497.   if (myPts) delete myPts;
  1498. }
  1499. ////
  1500. // output in a CGM format
  1501. ////
  1502. int cgmPolyline::cgmOut(cgmOutput *inOut) 
  1503. {
  1504.   inOut->startCmd(this);
  1505.   inOut->outVdcPts(myPts);
  1506.   inOut->endCmd();
  1507.   return 1;
  1508. }
  1509. ////
  1510. // display output
  1511. ////
  1512. int cgmPolyline::display(baseDisplay *inDisplay)
  1513. {
  1514.   inDisplay->polyline(myPts);
  1515.   return 1;
  1516. }
  1517. ////
  1518. // Disjoint Polyline
  1519. ////
  1520. const int cgmDisPolyline::myElement = 2;
  1521. const char *cgmDisPolyline::myName = "Disjtline";
  1522. ////
  1523. // constructor
  1524. ////
  1525. cgmDisPolyline::cgmDisPolyline(cgmContainer *inOwner, cgmInput *cgmIn,
  1526.                    baseCGM *inPrev, baseCGM *inNext)
  1527. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) 
  1528. {
  1529.   myPts = cgmIn->getVdcPts();
  1530. }
  1531. ////
  1532. // destructor
  1533. ////
  1534. cgmDisPolyline::~cgmDisPolyline() { 
  1535.   if (myPts) delete myPts;
  1536. }
  1537. ////
  1538. // output in a CGM format
  1539. ////
  1540. int cgmDisPolyline::cgmOut(cgmOutput *inOut)
  1541. {
  1542.   inOut->startCmd(this);
  1543.   inOut->outVdcPts(myPts);
  1544.   inOut->endCmd();
  1545.   return 1;
  1546. }
  1547. ////
  1548. // display output
  1549. ////
  1550. int cgmDisPolyline::display(baseDisplay *inDisplay)
  1551. {
  1552.   inDisplay->disPolyline(myPts);
  1553.   return 1;
  1554. }
  1555. ////
  1556. // Polymarker
  1557. ////
  1558. const int cgmPolymarker::myElement = 3;
  1559. const char *cgmPolymarker::myName = "Marker";
  1560. ////
  1561. // constructor
  1562. ////
  1563. cgmPolymarker::cgmPolymarker(cgmContainer *inOwner, cgmInput *cgmIn,
  1564.                  baseCGM *inPrev, baseCGM *inNext)
  1565. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  1566. {
  1567.   myPts = cgmIn->getVdcPts();
  1568. }
  1569. ////
  1570. // destructor
  1571. ////
  1572. cgmPolymarker::~cgmPolymarker() {
  1573.   if (myPts) delete myPts;
  1574. }
  1575. ////
  1576. // output in a CGM format
  1577. ////
  1578. int cgmPolymarker::cgmOut(cgmOutput *inOut) 
  1579. {
  1580.   inOut->startCmd(this);
  1581.   inOut->outVdcPts(myPts);
  1582.   inOut->endCmd();
  1583.   return 1;
  1584. }
  1585. ////
  1586. // display output
  1587. ////
  1588. int cgmPolymarker::display(baseDisplay *inDisplay)
  1589. {
  1590.   inDisplay->polymarker(myPts);
  1591.   return 1;
  1592. }
  1593. ////
  1594. // text
  1595. ////
  1596. const int cgmText::myElement = 4;
  1597. const char *cgmText::myName = "Text";
  1598. //// 
  1599. // aids for parsing
  1600. //// 
  1601. const char *tmpTextList[] = {"NOTFINAL", "FINAL"};
  1602. const char **cgmText::typeList = tmpTextList;
  1603. const int cgmText::typeListSize =
  1604. sizeof(tmpTextList) / sizeof(tmpTextList[0]);
  1605. ////
  1606. // constructor
  1607. ////
  1608. cgmText::cgmText(cgmContainer *inOwner, cgmInput *cgmIn,
  1609.          baseCGM *inPrev, baseCGM *inNext)
  1610. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  1611. {
  1612.   int textSize;
  1613.   vdcPts *myPts = cgmIn->getVdcPts(1);
  1614.   int final = cgmIn->getType(typeList, typeListSize);
  1615.   char *text = cgmIn->getString(textSize);
  1616.   myText = new genText(&(owner->tInfo), final, text, textSize, myPts);
  1617. }
  1618. ////
  1619. // output in a CGM format
  1620. ////
  1621. int cgmText::cgmOut(cgmOutput *inOut)
  1622. {
  1623.   inOut->startCmd(this);
  1624.   inOut->outVdcPts(myText->pos());
  1625.   inOut->outType(typeList, myText->final());
  1626.   inOut->outString(myText->size() ? myText->contents() : "");
  1627.   inOut->endCmd();
  1628.   return 1;
  1629. }
  1630. ////
  1631. // display output
  1632. ////
  1633. int cgmText::display(baseDisplay *inDisplay)
  1634. {
  1635.   inDisplay->text(myText);
  1636.   return 1;
  1637. }
  1638. ////
  1639. // restricted text
  1640. ////
  1641. const int cgmRestrText::myElement = 5;
  1642. const char *cgmRestrText::myName = "RestrText";
  1643. //// 
  1644. // aids for parsing
  1645. //// 
  1646. const char **cgmRestrText::typeList = tmpTextList;
  1647. const int cgmRestrText::typeListSize =
  1648. sizeof(tmpTextList) / sizeof(tmpTextList[0]);
  1649. ////
  1650. // constructor
  1651. ////
  1652. cgmRestrText::cgmRestrText(cgmContainer *inOwner, cgmInput *cgmIn,
  1653.          baseCGM *inPrev, baseCGM *inNext)
  1654. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  1655. {
  1656.   int textSize;
  1657.   maxWidth = cgmIn->getVdc();
  1658.   maxHeight = cgmIn->getVdc();
  1659.   vdcPts *myPts = cgmIn->getVdcPts(1);
  1660.   int final = cgmIn->getType(typeList, typeListSize);
  1661.   char *text = cgmIn->getString(textSize);
  1662.   myText = new genText(&(owner->tInfo), final, text, textSize,
  1663.                myPts, 0, maxHeight, maxWidth);
  1664. }
  1665. ////
  1666. // output in a CGM format
  1667. ////
  1668. int cgmRestrText::cgmOut(cgmOutput *inOut)
  1669. {
  1670.   inOut->startCmd(this);
  1671. //  inOut->outVdc(myText->width());
  1672. //  inOut->outVdc(myText->height());
  1673.   inOut->outVdc(maxWidth);
  1674.   inOut->outVdc(maxHeight);
  1675.   inOut->outVdcPts(myText->pos());
  1676.   inOut->outType(typeList, myText->final());
  1677.   inOut->outString(myText->size() ? myText->contents() : "");
  1678.   inOut->endCmd();
  1679.   return 1;
  1680. }
  1681. ////
  1682. // display output
  1683. ////
  1684. int cgmRestrText::display(baseDisplay *inDisplay)
  1685. {
  1686.   inDisplay->text(myText);
  1687.   return 1;
  1688. }
  1689. ////
  1690. // appended text
  1691. ////
  1692. const int cgmApndText::myElement = 6;
  1693. const char *cgmApndText::myName = "ApndText";
  1694. //// 
  1695. // aids for parsing
  1696. //// 
  1697. const char **cgmApndText::typeList = tmpTextList;
  1698. const int cgmApndText::typeListSize =
  1699. sizeof(tmpTextList) / sizeof(tmpTextList[0]);
  1700. ////
  1701. // constructor
  1702. ////
  1703. cgmApndText::cgmApndText(cgmContainer *inOwner, cgmInput *cgmIn,
  1704.          baseCGM *inPrev, baseCGM *inNext)
  1705. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  1706. {
  1707.   int textSize;
  1708.   int final = cgmIn->getType(typeList, typeListSize);
  1709.   char *text = cgmIn->getString(textSize);
  1710.   myText = new genText(&(owner->tInfo), final, text, textSize);
  1711. }
  1712. ////
  1713. // output in a CGM format
  1714. ////
  1715. int cgmApndText::cgmOut(cgmOutput *inOut)
  1716. {
  1717.   inOut->startCmd(this);
  1718.   inOut->outType(typeList, myText->final());
  1719.   inOut->outString(myText->size() ? myText->contents() : "");
  1720.   inOut->endCmd();
  1721.   return 1;
  1722. }
  1723. ////
  1724. // display output
  1725. ////
  1726. int cgmApndText::display(baseDisplay *inDisplay)
  1727. {
  1728.   inDisplay->text(myText);
  1729.   return 1;
  1730. }
  1731. ////
  1732. // Polygon
  1733. ////
  1734. const int cgmPolygon::myElement = 7;
  1735. const char *cgmPolygon::myName = "Polygon";
  1736. cgmPolygon::cgmPolygon(cgmContainer *inOwner, cgmInput *cgmIn,
  1737.                baseCGM *inPrev, baseCGM *inNext)
  1738. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) // constructor
  1739. {
  1740.   myPts = cgmIn->getVdcPts();
  1741. }
  1742. ////
  1743. // destructor
  1744. ////
  1745. cgmPolygon::~cgmPolygon() {
  1746.   if (myPts) delete myPts;
  1747. }
  1748. ////
  1749. // output in a CGM format
  1750. ////
  1751. int cgmPolygon::cgmOut(cgmOutput *inOut) 
  1752. {
  1753.   inOut->startCmd(this);
  1754.   inOut->outVdcPts(myPts);
  1755.   inOut->endCmd();
  1756.   return 1;
  1757. }
  1758. ////
  1759. // display output
  1760. ////
  1761. int cgmPolygon::display(baseDisplay *inDisplay)
  1762. {
  1763.   inDisplay->polygon(myPts);
  1764.   return 1;
  1765. }
  1766. ////
  1767. // Polygon Set
  1768. ////
  1769. // aids for parsing
  1770. //// 
  1771. const char *tmpPolygonSetList[] = {"INVIS", "VIS", "CLOSEINVIS", "CLOSEVIS"};
  1772. const char **cgmPolygonSet::typeList = tmpPolygonSetList;
  1773. const int cgmPolygonSet::typeListSize =
  1774. sizeof(tmpPolygonSetList) / sizeof(tmpPolygonSetList[0]);
  1775. //// 
  1776. const int cgmPolygonSet::myElement = 8;
  1777. const char *cgmPolygonSet::myName = "PolygonSet";
  1778. cgmPolygonSet::cgmPolygonSet(cgmContainer *inOwner, cgmInput *cgmIn,
  1779.                baseCGM *inPrev, baseCGM *inNext)
  1780. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) // constructor
  1781. {
  1782.   cgmIn->polygonSet(myPts, myFlags);
  1783. }
  1784. ////
  1785. // output in a CGM format
  1786. ////
  1787. int cgmPolygonSet::cgmOut(cgmOutput *inOut) 
  1788. {
  1789.   inOut->startCmd(this);
  1790.   inOut->polygonSet(myPts, myFlags);
  1791.   inOut->endCmd();
  1792.   return 1;
  1793. }
  1794. ////
  1795. // display output
  1796. ////
  1797. int cgmPolygonSet::display(baseDisplay *inDisplay)
  1798. {
  1799.   inDisplay->polygonSet(myPts, myFlags);
  1800.   return 1;
  1801. }
  1802.  
  1803. ////
  1804. // Cell Array class
  1805. ////
  1806. // constructor
  1807. ////
  1808. cellArray::cellArray(int inColMode, const colrValueExtent *inExtent,
  1809.               vdcPts *inCorners, int inNx, int inNy,
  1810.               int inPrec, int inRepMode,
  1811.               const colrTable *inTable)
  1812. {
  1813.   char myString[40];
  1814.   // assign the private variables
  1815.   myColMode = inColMode;
  1816.   myExtent = inExtent;
  1817.   myCorners = inCorners;
  1818.   myNx = inNx;
  1819.   myNy = inNy;
  1820.   ////
  1821.   // check the legality of the precision
  1822.   if ((inPrec != 1) && (inPrec != 2) && (inPrec != 4) && (inPrec != 8) &&
  1823.         (inPrec != 16) && (inPrec != 24) && (inPrec != 32)) {
  1824.      sprintf(myString, "%d", inPrec);
  1825.      myError("illegal cell array precision", myString);
  1826.      myPrec = 8; // default
  1827.   } else myPrec = inPrec;
  1828.   myRepMode = inRepMode;
  1829.   myTable = inTable;
  1830.   ////
  1831.   // how much memory do we need (real men don't pad -- or deal with a pc!!!!)
  1832.   totalBits = (long)inNy * inNx * ((inColMode) ? 3 : 1) * inPrec;
  1833.   totalBytes = (totalBits + 7) / 8;
  1834.  
  1835. #if __MSDOS__
  1836.   if (totalBytes < (long)66000) totalBytes = 66000;
  1837.   hContentsBuffer = GlobalAlloc(GPTR,totalBytes);
  1838.   if (hContentsBuffer)   myContents = (HugePt)GlobalLock(hContentsBuffer);
  1839.   else myContents = NULL;
  1840. #else
  1841.   myContents = new unsigned char[totalBytes];
  1842.   for (int i=0; i<totalBytes; ++i) myContents[i] = 0;
  1843. #endif
  1844.   ////
  1845.   bitsAdded = 0; // no input values yet
  1846. }
  1847.  
  1848. cellArray::~cellArray()
  1849.     {
  1850.     delete myCorners;
  1851. #if __MSDOS__
  1852.   if (hContentsBuffer)
  1853.       {
  1854.       GlobalUnlock(hContentsBuffer);
  1855.       GlobalFree(hContentsBuffer);
  1856.       myContents = NULL;
  1857.       }
  1858. #endif
  1859.  
  1860.   if (myContents)    delete myContents;
  1861.     }
  1862. ////
  1863. // add one value
  1864. ////
  1865. int cellArray::addValue(unsigned int inVal)
  1866. {
  1867.   if ((bitsAdded + myPrec) > totalBits) return 0; // too many bits
  1868.   ////
  1869.   // note that since only valid values of prec are 1,2,4,8,16,24,32
  1870.   // value either fits within one byte or spans several whole bytes
  1871.   // hence we use the most convenient storage format
  1872.   int startByte = (int) (bitsAdded / 8);
  1873.   ////
  1874.   // note use of fallthru in switch statement
  1875.   switch (myPrec) {
  1876.   case 32:
  1877.      myContents[startByte] = 255 & ((inVal & (255 << 24)) >> 24); ++startByte;
  1878.   case 24:
  1879.      myContents[startByte] = 255 & ((inVal & (255 << 16)) >> 16); ++startByte;
  1880.   case 16:
  1881.      myContents[startByte] = 255 & ((inVal & (255 << 8)) >> 8); ++startByte;
  1882.   case 8:
  1883.      myContents[startByte] = 255 & inVal; break;  // end fallthru
  1884.   case 4:
  1885.      myContents[startByte] |= (15 & inVal) << (int) (bitsAdded % 8); break;
  1886.   case 2:
  1887.      myContents[startByte] |= (3 & inVal) << (int) (bitsAdded % 8); break;
  1888.   case 1:
  1889.      myContents[startByte] |= (1 & inVal) << (int) (bitsAdded % 8); break;
  1890.   }
  1891.   bitsAdded += myPrec;
  1892.   return 1;
  1893. }
  1894. ////
  1895. // add multiple values
  1896. ////
  1897. #if __MSDOS__
  1898. int cellArray::addValues(HugePt inPtr, int bitsAlong,  int noValues)
  1899. #else
  1900. int cellArray::addValues(unsigned char *inPtr, int bitsAlong,  int noValues)
  1901. #endif
  1902. {
  1903.   if ((bitsAdded + noValues * myPrec) > totalBits) return 0; // too many bits
  1904.   ////
  1905.   unsigned int inVal;
  1906.   unsigned long inByte, startByte, bitOffset;
  1907.   ////
  1908.   // note use of fallthru in switch statements
  1909.   for (int i=0; i<noValues; ++i) {
  1910.      inVal = 0;
  1911.      inByte = bitsAlong / (long)8;
  1912.      bitOffset = 8 - (myPrec + (bitsAlong % (long)8)); // only used if myprec < 8
  1913.      ////
  1914.      // first get the input value
  1915.      switch (myPrec) {
  1916.      case 32:
  1917.         inVal |= ((unsigned int) inPtr[inByte]) << 24; ++inByte;
  1918.      case 24:
  1919.         inVal |= ((unsigned int) inPtr[inByte]) << 16; ++inByte;
  1920.      case 16:
  1921.         inVal |= ((unsigned int) inPtr[inByte]) << 8; ++inByte;
  1922.      case 8:
  1923.         inVal |= inPtr[inByte]; // end fallthru
  1924.         break;
  1925.      case 4:
  1926.         inVal |= (inPtr[inByte] & (int) (15 << bitOffset)) >> (int) bitOffset;
  1927.         break;
  1928.      case 2:
  1929.         inVal |= (inPtr[inByte] & (int) (3 << bitOffset)) >> (int) bitOffset;
  1930.         break;
  1931.      case 1:
  1932.         inVal |= (inPtr[inByte] & (int) (1 << bitOffset)) >> (int) bitOffset;
  1933.         break;
  1934.      }
  1935.      bitsAlong += myPrec;
  1936.      // now put value into local memory
  1937.      startByte = bitsAdded / (long)8;
  1938.      switch (myPrec) {
  1939.      case 32:
  1940.         myContents[startByte] = 255 & ((inVal & (255 << 24)) >> 24); ++startByte;
  1941.      case 24:
  1942.         myContents[startByte] = 255 & ((inVal & (255 << 16)) >> 16); ++startByte;
  1943.      case 16:
  1944.         myContents[startByte] = 255 & ((inVal & (255 << 8)) >> 8); ++startByte;
  1945.      case 8:
  1946.         myContents[startByte] |= 255 & inVal;  // end fallthru
  1947.      break;
  1948.      case 4:
  1949.         myContents[startByte] |= (15 & inVal) << (int) (bitsAdded % 8);
  1950.         break;
  1951.      case 2:
  1952.         myContents[startByte] |= (3 & inVal) << (int) (bitsAdded % 8);
  1953.         break;
  1954.      case 1:
  1955.         myContents[startByte] |= (1 & inVal) << (int) (bitsAdded % 8);
  1956.         break;
  1957.      }
  1958.      bitsAdded += myPrec;
  1959.   }
  1960.   return 1;
  1961. }
  1962. ////
  1963. // get a single value as set of 3 floats
  1964. ////
  1965. float *cellArray::getFloats(unsigned long inIndex) const
  1966. {
  1967.   static float rValues[3];
  1968.   int i;
  1969.   if (inIndex >= (long)((long)myNx * myNy)) { // outside scope
  1970. //    for (i=0; i<3; ++i) rvalues[i] = 0;
  1971.      for (i=0; i<3; ++i) rValues[i] = 0;
  1972.      return rValues;
  1973.   }
  1974.   int useVal;
  1975.   if (myColMode) { // r,g,b format
  1976.      for (i=0; i<3; ++i) {
  1977.         useVal = getValue(inIndex * 3 + i);
  1978. //      if (useVal >= myExtent->white[i]) {
  1979.         if (useVal >= myExtent->white.getValue(i)) {
  1980.     rValues[i] = 1; // max possible
  1981. //      } else if (useVal <= myExtent->black[i]) {
  1982.         } else if (useVal <= myExtent->black.getValue(i)) {
  1983.     rValues[i] = 0; // min possible
  1984.         } else {
  1985. //    rValues[i] = (float) (useVal - myExtent->black[i]) /
  1986. //      (myExtent->white[i] - myExtent->black[i]);
  1987.     rValues[i] = (float) (useVal - myExtent->black.getValue(i)) /
  1988.       (myExtent->white.getValue(i) - myExtent->black.getValue(i));
  1989.         }
  1990.      }
  1991.   } else { // indexed
  1992.      int useIndex = getValue(inIndex);
  1993.      for (i=0; i<3; ++i) {
  1994. //      useVal = myTable->val(useIndex)[i];
  1995.         useVal = myTable->val(useIndex).getValue(i);
  1996. //      if (useVal >= myExtent->white[i]) {
  1997.         if (useVal >= myExtent->white.getValue(i)) {
  1998.     rValues[i] = 1; // max possible
  1999. //      } else if (useVal <= myExtent->black[i]) {
  2000.         } else if (useVal <= myExtent->black.getValue(i)) {
  2001.     rValues[i] = 0; // min possible
  2002.         } else {
  2003. //    rValues[i] = (float) (useVal - myExtent->black[i]) /
  2004. //      (myExtent->white[i] - myExtent->black[i]);
  2005.     rValues[i] = (float) (useVal - myExtent->black.getValue(i)) /
  2006.       (myExtent->white.getValue(i) - myExtent->black.getValue(i));
  2007.         }
  2008.      }
  2009.   }
  2010.   return rValues;
  2011. }
  2012. ////
  2013. // get one integer value
  2014. ////
  2015. unsigned int cellArray::getValue(unsigned long inIndex) const
  2016. {
  2017.   if (inIndex * myPrec > totalBits) { // outside scope
  2018.      return 0;
  2019.   }
  2020.   unsigned int outInt = 0;
  2021.   unsigned long bitsAlong = inIndex * myPrec;
  2022.   unsigned int bitOffset = (unsigned int) (bitsAlong & 7); // (bitsAlong % 8)
  2023.   unsigned long startByte = bitsAlong / 8;
  2024.   ////
  2025.   // note use of fallthru in switch statement
  2026.   switch (myPrec) {
  2027.   case 32:
  2028.      outInt |= ((unsigned int) myContents[startByte]) << 24; ++startByte;
  2029.   case 24:
  2030.      outInt |= ((unsigned int) myContents[startByte]) << 16; ++startByte;
  2031.   case 16:
  2032.      outInt |= ((unsigned int) myContents[startByte]) << 8; ++startByte;
  2033.   case 8:
  2034.      outInt |= myContents[startByte]; // end fallthru
  2035.      break;
  2036.   case 4:
  2037.      outInt |= (myContents[startByte] & (15 << bitOffset)) >> bitOffset;
  2038.      break;
  2039.   case 2:
  2040.      outInt |= (myContents[startByte] & (3 << bitOffset)) >> bitOffset;
  2041.      break;
  2042.   case 1:
  2043.      outInt |= (myContents[startByte] & (1 << bitOffset)) >> bitOffset;
  2044.      break;
  2045.   }
  2046.   return outInt;
  2047. }
  2048.  
  2049. // decompress
  2050. ////
  2051. void cellArray::decompress()
  2052. {
  2053. }
  2054. ////
  2055. // dump out as a set of grey values
  2056. ////
  2057. void cellArray::fillGrey(unsigned char* &inPtr) const
  2058. {
  2059.   float *myColrs;
  2060.   unsigned char *myPtr = inPtr = new unsigned char [nx() * ny()];
  2061.   for (int i=0; i<ny(); ++i) {
  2062.     for (int j=0; j<nx(); ++j) {
  2063.       myColrs = getFloats(j, i);
  2064.       *(myPtr++) = (unsigned char)
  2065.     (255.99 * (0.3 * myColrs[0] + 0.59 * myColrs[1] + 0.11 * myColrs[2]));
  2066.     }
  2067.   }
  2068. }
  2069. ////
  2070. // dump out as a set of colours
  2071. ////
  2072. void cellArray::fillColr(unsigned char* &inPtr) const
  2073. {
  2074.   float *myColrs;
  2075.   unsigned char *myPtr = inPtr = new unsigned char [nx() * ny() * 3];
  2076.   for (int i=0; i<ny(); ++i) {
  2077.      for (int j=0; j<nx(); ++j) {
  2078.       myColrs = getFloats(j, i);
  2079.       for (int k=0; k<3; ++k) {
  2080.     *(myPtr++) = (unsigned char) (255.99 * myColrs[k]);
  2081.       }
  2082.     }
  2083.   }
  2084. }
  2085.  
  2086. ////
  2087. // Cell Array element
  2088. ////
  2089. const int cgmCellArray::myElement = 9;
  2090. const char *cgmCellArray::myName = "CellArray";
  2091. cgmCellArray::cgmCellArray(cgmContainer *inOwner, cgmInput *cgmIn,
  2092.                baseCGM *inPrev, baseCGM *inNext)
  2093. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) // constructor
  2094. {
  2095.   myCell = cgmIn->getCellArray(owner->colrMode(), owner->colrExtent(),
  2096.                    owner->colrs());
  2097. }
  2098. ////
  2099. // destructor
  2100. ////
  2101. cgmCellArray::~cgmCellArray() {
  2102.   if (myCell) delete myCell;
  2103. }
  2104. ////
  2105. // output in a CGM format
  2106. ////
  2107. int cgmCellArray::cgmOut(cgmOutput *inOut) 
  2108. {
  2109.   inOut->startCmd(this);
  2110.   inOut->outCellArray(myCell);
  2111.   inOut->endCmd();
  2112.   return 1;
  2113. }
  2114. ////
  2115. // display output
  2116. ////
  2117. int cgmCellArray::display(baseDisplay *inDisplay)
  2118. {
  2119.   inDisplay->cells(myCell);
  2120.   return 1;
  2121. }
  2122.  
  2123.  
  2124. ////
  2125. // Generalized Drawing Primitive
  2126. ////
  2127. const int cgmGDP::myElement = 10;
  2128. const char *cgmGDP::myName = "GDP";
  2129. cgmGDP::cgmGDP(cgmContainer *inOwner, cgmInput *cgmIn,
  2130.                baseCGM *inPrev, baseCGM *inNext)
  2131. : cgmGraphicalPrimitive(inOwner, inPrev, inNext) // constructor
  2132. {
  2133. }
  2134. ////
  2135. // output in a CGM format
  2136. ////
  2137. int cgmGDP::cgmOut(cgmOutput *inOut) 
  2138. {
  2139.   inOut->startCmd(this);
  2140.   inOut->endCmd();
  2141.   return 1;
  2142. }
  2143. ////
  2144. // display output
  2145. ////
  2146. int cgmGDP::display(baseDisplay *inDisplay)
  2147. {
  2148. //   inDisplay->GDP(myPts); // fix later
  2149.   return 1;
  2150. }
  2151. ////
  2152. // Rectangle
  2153. ////
  2154. const int cgmRectangle::myElement = 11;
  2155. const char *cgmRectangle::myName = "Rect";
  2156. ////
  2157. // constructor
  2158. ////
  2159. cgmRectangle::cgmRectangle(cgmContainer *inOwner, cgmInput *cgmIn,
  2160.                baseCGM *inPrev, baseCGM *inNext)
  2161. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2162. {
  2163.   myPts = cgmIn->getVdcPts(2);
  2164.   if (myPts->no() != 2) myError("not enough points for rectangle");
  2165. }
  2166. ////
  2167. // destructor
  2168. ////
  2169. cgmRectangle::~cgmRectangle() {
  2170.   if (myPts) delete myPts;
  2171. }
  2172. ////
  2173. // output in a CGM format
  2174. ////
  2175. int cgmRectangle::cgmOut(cgmOutput *inOut)
  2176. {
  2177.   inOut->startCmd(this);
  2178.   inOut->outVdcPts(myPts);
  2179.   inOut->endCmd();
  2180.   return 1;
  2181. }
  2182. ////
  2183. // display output
  2184. ////
  2185. int cgmRectangle::display(baseDisplay *inDisplay)
  2186. {
  2187.   inDisplay->rectangle(myPts);
  2188.   return 1;
  2189. }
  2190. ////
  2191. // Circle
  2192. ////
  2193. const int cgmCircle::myElement = 12;
  2194. const char *cgmCircle::myName = "Circle";
  2195. ////
  2196. // constructor
  2197. ////
  2198. cgmCircle::cgmCircle(cgmContainer *inOwner, cgmInput *cgmIn,
  2199.              baseCGM *inPrev, baseCGM *inNext)
  2200. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2201. {
  2202.   centre = cgmIn->getVdcPts(1);
  2203.   radius = cgmIn->getVdc();
  2204. }
  2205. ////
  2206. // destructor
  2207. ////
  2208. cgmCircle::~cgmCircle() {
  2209.   if (centre) delete centre;
  2210.   if (radius) delete radius;
  2211. }
  2212. ////
  2213. // output in a CGM format
  2214. ////
  2215. int cgmCircle::cgmOut(cgmOutput *inOut)
  2216. {
  2217.   inOut->startCmd(this);
  2218.   inOut->outVdcPts(centre);
  2219.   inOut->outVdc(radius);
  2220.   inOut->endCmd();
  2221.   return 1;
  2222. }
  2223. ////
  2224. // display output
  2225. ////
  2226. int cgmCircle::display(baseDisplay *inDisplay)
  2227. {
  2228.   inDisplay->circle(centre, radius);
  2229.   return 1;
  2230. }
  2231. ////
  2232. // Circular arc, 3 pts
  2233. ////
  2234. const int cgmArc3Pt::myElement = 13;
  2235. const char *cgmArc3Pt::myName = "Arc3Pt";
  2236. ////
  2237. // constructor
  2238. ////
  2239. cgmArc3Pt::cgmArc3Pt(cgmContainer *inOwner, cgmInput *cgmIn,
  2240.              baseCGM *inPrev, baseCGM *inNext)
  2241. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2242. {
  2243.   myPts = cgmIn->getVdcPts(3);
  2244. }
  2245. ////
  2246. // output in a CGM format
  2247. ////
  2248. int cgmArc3Pt::cgmOut(cgmOutput *inOut)
  2249. {
  2250.   inOut->startCmd(this);
  2251.   inOut->outVdcPts(myPts);
  2252.   inOut->endCmd();
  2253.   return 1;
  2254. }
  2255. ////
  2256. // display output
  2257. ////
  2258. int cgmArc3Pt::display(baseDisplay *inDisplay)
  2259. {
  2260.   inDisplay->arc3Pt(myPts, -1); // -1 -> not closed
  2261.   return 1;
  2262. }
  2263. ////
  2264. // Circular arc, 3 pts, closed
  2265. ////
  2266. const int cgmArc3PtClose::myElement = 14;
  2267. const char *cgmArc3PtClose::myName = "Arc3PtClose";
  2268. //// 
  2269. // aids for parsing
  2270. //// 
  2271. const char *tmpCloseList[] = {"PIE", "CHORD"};
  2272. const char **cgmArc3PtClose::typeList = tmpCloseList;
  2273. const int cgmArc3PtClose::typeListSize =
  2274. sizeof(tmpCloseList) / sizeof(tmpCloseList[0]);
  2275. ////
  2276. // constructor
  2277. ////
  2278. cgmArc3PtClose::cgmArc3PtClose(cgmContainer *inOwner, cgmInput *cgmIn,
  2279.              baseCGM *inPrev, baseCGM *inNext)
  2280. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2281. {
  2282.   myPts = cgmIn->getVdcPts(3);
  2283.   myType = cgmIn->getType(typeList, typeListSize);
  2284. }
  2285. ////
  2286. // output in a CGM format
  2287. ////
  2288. int cgmArc3PtClose::cgmOut(cgmOutput *inOut)
  2289. {
  2290.   inOut->startCmd(this);
  2291.   inOut->outVdcPts(myPts);
  2292.   inOut->outType(typeList, myType);
  2293.   inOut->endCmd();
  2294.   return 1;
  2295. }
  2296. ////
  2297. // display output
  2298. ////
  2299. int cgmArc3PtClose::display(baseDisplay *inDisplay)
  2300. {
  2301.   inDisplay->arc3Pt(myPts, myType);
  2302.   return 1;
  2303. }
  2304. ////
  2305. // Circular arc, centre, 2 vectors and a radius
  2306. ////
  2307. const int cgmArcCtr::myElement = 15;
  2308. const char *cgmArcCtr::myName = "ArcCtr";
  2309. ////
  2310. // constructor
  2311. ////
  2312. cgmArcCtr::cgmArcCtr(cgmContainer *inOwner, cgmInput *cgmIn,
  2313.              baseCGM *inPrev, baseCGM *inNext)
  2314. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2315. {
  2316.   myPts = cgmIn->getVdcPts(3);
  2317.   radius =  cgmIn->getVdc();
  2318. }
  2319. ////
  2320. // output in a CGM format
  2321. ////
  2322. int cgmArcCtr::cgmOut(cgmOutput *inOut)
  2323. {
  2324.   inOut->startCmd(this);
  2325.   inOut->outVdcPts(myPts);
  2326.   inOut->outVdc(radius);
  2327.   inOut->endCmd();
  2328.   return 1;
  2329. }
  2330. ////
  2331. // display output
  2332. ////
  2333. int cgmArcCtr::display(baseDisplay *inDisplay)
  2334. {
  2335.   inDisplay->arcCtr(myPts, radius, -1); // -1 -> not closed
  2336.   return 1;
  2337. }
  2338. ////
  2339. // Circular arc, centre, 2 vectors and a radius, closed
  2340. ////
  2341. const int cgmArcCtrClose::myElement = 16;
  2342. const char *cgmArcCtrClose::myName = "ArcCtrClose";
  2343. //// 
  2344. // aids for parsing
  2345. //// 
  2346. const char **cgmArcCtrClose::typeList = tmpCloseList;
  2347. const int cgmArcCtrClose::typeListSize =
  2348. sizeof(tmpCloseList) / sizeof(tmpCloseList[0]);
  2349. ////
  2350. // constructor
  2351. ////
  2352. cgmArcCtrClose::cgmArcCtrClose(cgmContainer *inOwner, cgmInput *cgmIn,
  2353.              baseCGM *inPrev, baseCGM *inNext)
  2354. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2355. {
  2356.   myPts = cgmIn->getVdcPts(3);
  2357.   radius =  cgmIn->getVdc();
  2358.   myType = cgmIn->getType(typeList, typeListSize);
  2359. }
  2360. ////
  2361. // output in a CGM format
  2362. ////
  2363. int cgmArcCtrClose::cgmOut(cgmOutput *inOut)
  2364. {
  2365.   inOut->startCmd(this);
  2366.   inOut->outVdcPts(myPts);
  2367.   inOut->outVdc(radius);
  2368.   inOut->outType(typeList, myType);
  2369.   inOut->endCmd();
  2370.   return 1;
  2371. }
  2372. ////
  2373. // display output
  2374. ////
  2375. int cgmArcCtrClose::display(baseDisplay *inDisplay)
  2376. {
  2377.   inDisplay->arcCtr(myPts, radius, myType); 
  2378.   return 1;
  2379. }
  2380. ////
  2381. // Ellipse, specified by 3 pts
  2382. ////
  2383. const int cgmEllipse::myElement = 17;
  2384. const char *cgmEllipse::myName = "Ellipse";
  2385. ////
  2386. // constructor
  2387. ////
  2388. cgmEllipse::cgmEllipse(cgmContainer *inOwner, cgmInput *cgmIn,
  2389.              baseCGM *inPrev, baseCGM *inNext)
  2390. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2391. {
  2392.   myPts = cgmIn->getVdcPts(3);
  2393. }
  2394. ////
  2395. // output in a CGM format
  2396. ////
  2397. int cgmEllipse::cgmOut(cgmOutput *inOut)
  2398. {
  2399.   inOut->startCmd(this);
  2400.   inOut->outVdcPts(myPts);
  2401.   inOut->endCmd();
  2402.   return 1;
  2403. }
  2404. ////
  2405. // display output
  2406. ////
  2407. int cgmEllipse::display(baseDisplay *inDisplay)
  2408. {
  2409.   inDisplay->ellipse(myPts);
  2410.   return 1;
  2411. }
  2412. ////
  2413. // Elliptical arc, specified by 5 pts
  2414. ////
  2415. const int cgmEllipArc::myElement = 18;
  2416. const char *cgmEllipArc::myName = "EllipArc";
  2417. ////
  2418. // constructor
  2419. ////
  2420. cgmEllipArc::cgmEllipArc(cgmContainer *inOwner, cgmInput *cgmIn,
  2421.              baseCGM *inPrev, baseCGM *inNext)
  2422. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2423. {
  2424.   myPts = cgmIn->getVdcPts(5);
  2425. }
  2426. ////
  2427. // output in a CGM format
  2428. ////
  2429. int cgmEllipArc::cgmOut(cgmOutput *inOut)
  2430. {
  2431.   inOut->startCmd(this);
  2432.   inOut->outVdcPts(myPts);
  2433.   inOut->endCmd();
  2434.   return 1;
  2435. }
  2436. ////
  2437. // display output
  2438. ////
  2439. int cgmEllipArc::display(baseDisplay *inDisplay)
  2440. {
  2441.   inDisplay->ellipArc(myPts, -1);
  2442.   return 1;
  2443. }
  2444. ////
  2445. // Elliptical arc, specified by 5 pts, closed
  2446. ////
  2447. const int cgmEllipArcClose::myElement = 19;
  2448. const char *cgmEllipArcClose::myName = "EllipArcClose";
  2449. //// 
  2450. // aids for parsing
  2451. //// 
  2452. const char **cgmEllipArcClose::typeList = tmpCloseList;
  2453. const int cgmEllipArcClose::typeListSize =
  2454. sizeof(tmpCloseList) / sizeof(tmpCloseList[0]);
  2455. ////
  2456. // constructor
  2457. ////
  2458. cgmEllipArcClose::cgmEllipArcClose(cgmContainer *inOwner, cgmInput *cgmIn,
  2459.              baseCGM *inPrev, baseCGM *inNext)
  2460. : cgmGraphicalPrimitive(inOwner, inPrev, inNext)
  2461. {
  2462.   myPts = cgmIn->getVdcPts(5);
  2463.   myType = cgmIn->getType(typeList, typeListSize);
  2464. }
  2465. ////
  2466. // output in a CGM format
  2467. ////
  2468. int cgmEllipArcClose::cgmOut(cgmOutput *inOut)
  2469. {
  2470.   inOut->startCmd(this);
  2471.   inOut->outVdcPts(myPts);
  2472.   inOut->outType(typeList, myType);
  2473.   inOut->endCmd();
  2474.   return 1;
  2475. }
  2476. ////
  2477. // display output
  2478. ////
  2479. int cgmEllipArcClose::display(baseDisplay *inDisplay)
  2480. {
  2481.   inDisplay->ellipArc(myPts, myType);
  2482.   return 1;
  2483. }
  2484. ////
  2485. // the Attribute class
  2486. ////
  2487. const int cgmAttribute::myClass = 5;
  2488. ////
  2489. // line bundle index
  2490. ////
  2491. const int cgmLineIndex::myElement = 1;
  2492. const char *cgmLineIndex::myName = "LineIndex";
  2493. ////
  2494. // constructor
  2495. ////
  2496. cgmLineIndex::cgmLineIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  2497.                baseCGM *inPrev, baseCGM *inNext)
  2498. : cgmAttribute(inOwner, inPrev, inNext)
  2499. {
  2500.   myIndex = cgmIn->getInt();
  2501. }
  2502. ////
  2503. // output in a CGM format
  2504. ////
  2505. int cgmLineIndex::cgmOut(cgmOutput *inOut)
  2506. {
  2507.   inOut->startCmd(this);
  2508.   inOut->outInt(myIndex);
  2509.   inOut->endCmd();
  2510.   return 1;
  2511. }
  2512. ////
  2513. // display output
  2514. ////
  2515. int cgmLineIndex::display(baseDisplay *inDisplay)
  2516. {
  2517.   inDisplay->lineIndex(myIndex);
  2518.   return 1;
  2519. }
  2520. #ifdef macintosh
  2521.  #pragma segment CGM4
  2522. #endif
  2523. ////
  2524. // line type
  2525. ////
  2526. const int cgmLineType::myElement = 2;
  2527. const char *cgmLineType::myName = "LineType";
  2528. ////
  2529. // constructor
  2530. ////
  2531. cgmLineType::cgmLineType(cgmContainer *inOwner, cgmInput *cgmIn,
  2532.              baseCGM *inPrev, baseCGM *inNext)
  2533. : cgmAttribute(inOwner, inPrev, inNext)
  2534. {
  2535.   myType = cgmIn->getInt();
  2536. }
  2537. ////
  2538. // output in a CGM format
  2539. ////
  2540. int cgmLineType::cgmOut(cgmOutput *inOut)
  2541. {
  2542.   inOut->startCmd(this);
  2543.   inOut->outInt(myType);
  2544.   inOut->endCmd();
  2545.   return 1;
  2546. }
  2547. ////
  2548. // display output
  2549. ////
  2550. int cgmLineType::display(baseDisplay *inDisplay)
  2551. {
  2552.   inDisplay->lineType(myType);
  2553.   return 1;
  2554. }
  2555. ////
  2556. // line width
  2557. ////
  2558. const int cgmLineWidth::myElement = 3;
  2559. const char *cgmLineWidth::myName = "LineWidth";
  2560. ////
  2561. // constructor
  2562. ////
  2563. cgmLineWidth::cgmLineWidth(cgmContainer *inOwner, cgmInput *cgmIn,
  2564.                baseCGM *inPrev, baseCGM *inNext)
  2565. : cgmAttribute(inOwner, inPrev, inNext)
  2566. {
  2567.   myVdcR = (owner->lineMode()) ? new vdcR(cgmIn->getReal()) // scaled
  2568.     : new vdcR(cgmIn->getVdc()); // absolute
  2569. }
  2570. ////
  2571. // destructor
  2572. ////
  2573. cgmLineWidth::~cgmLineWidth()
  2574. {
  2575.   if (myVdcR) delete myVdcR;
  2576. }
  2577. ////
  2578. // output in a CGM format
  2579. ////
  2580. int cgmLineWidth::cgmOut(cgmOutput *inOut)
  2581. {
  2582.   inOut->startCmd(this);
  2583.   if (myVdcR->type()) inOut->outReal(myVdcR->f()); // scaled
  2584.   else inOut->outVdc(myVdcR->v()); // absolute
  2585.   inOut->endCmd();
  2586.   return 1;
  2587. }
  2588. ////
  2589. // display output
  2590. ////
  2591. int cgmLineWidth::display(baseDisplay *inDisplay)
  2592. {
  2593.   inDisplay->lineWidth(myVdcR);
  2594.   return 1;
  2595. }
  2596. ////
  2597. // line colour
  2598. ////
  2599. const int cgmLineColr::myElement = 4;
  2600. const char *cgmLineColr::myName = "LineColr";
  2601. ////
  2602. // constructor
  2603. ////
  2604. cgmLineColr::cgmLineColr(cgmContainer *inOwner, cgmInput *cgmIn,
  2605.                baseCGM *inPrev, baseCGM *inNext)
  2606. : cgmAttribute(inOwner, inPrev, inNext)
  2607. {
  2608.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  2609.               owner->colrs());
  2610. }
  2611. ////
  2612. // output in a CGM format
  2613. ////
  2614. int cgmLineColr::cgmOut(cgmOutput *inOut)
  2615. {
  2616.   inOut->startCmd(this);
  2617.   inOut->outColr(myColr);
  2618.   inOut->endCmd();
  2619.   return 1;
  2620. }
  2621. ////
  2622. // display output
  2623. ////
  2624. int cgmLineColr::display(baseDisplay *inDisplay)
  2625. {
  2626.   if (myColr) inDisplay->lineColr(*myColr);
  2627.   return 1;
  2628. }
  2629. ////
  2630. // Marker bundle index
  2631. ////
  2632. const int cgmMarkerIndex::myElement = 5;
  2633. const char *cgmMarkerIndex::myName = "MarkerIndex";
  2634. ////
  2635. // constructor
  2636. ////
  2637. cgmMarkerIndex::cgmMarkerIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  2638.                baseCGM *inPrev, baseCGM *inNext)
  2639. : cgmAttribute(inOwner, inPrev, inNext)
  2640. {
  2641.   myIndex = cgmIn->getInt();
  2642. }
  2643. ////
  2644. // output in a CGM format
  2645. ////
  2646. int cgmMarkerIndex::cgmOut(cgmOutput *inOut)
  2647. {
  2648.   inOut->startCmd(this);
  2649.   inOut->outInt(myIndex);
  2650.   inOut->endCmd();
  2651.   return 1;
  2652. }
  2653. ////
  2654. // display output
  2655. ////
  2656. int cgmMarkerIndex::display(baseDisplay *inDisplay)
  2657. {
  2658.   inDisplay->markerIndex(myIndex);
  2659.   return 1;
  2660. }
  2661. ////
  2662. // marker type
  2663. ////
  2664. const int cgmMarkerType::myElement = 6;
  2665. const char *cgmMarkerType::myName = "MarkerType";
  2666. ////
  2667. // constructor
  2668. ////
  2669. cgmMarkerType::cgmMarkerType(cgmContainer *inOwner, cgmInput *cgmIn,
  2670.              baseCGM *inPrev, baseCGM *inNext)
  2671. : cgmAttribute(inOwner, inPrev, inNext)
  2672. {
  2673.   myType = cgmIn->getInt();
  2674. }
  2675. ////
  2676. // output in a CGM format
  2677. ////
  2678. int cgmMarkerType::cgmOut(cgmOutput *inOut)
  2679. {
  2680.   inOut->startCmd(this);
  2681.   inOut->outInt(myType);
  2682.   inOut->endCmd();
  2683.   return 1;
  2684. }
  2685. ////
  2686. // display output
  2687. ////
  2688. int cgmMarkerType::display(baseDisplay *inDisplay)
  2689. {
  2690.   inDisplay->markerType(myType);
  2691.   return 1;
  2692. }
  2693. ////
  2694. // marker size
  2695. ////
  2696. const int cgmMarkerSize::myElement = 7;
  2697. const char *cgmMarkerSize::myName = "MarkerSize";
  2698. ////
  2699. // constructor
  2700. ////
  2701. cgmMarkerSize::cgmMarkerSize(cgmContainer *inOwner, cgmInput *cgmIn,
  2702.                  baseCGM *inPrev, baseCGM *inNext)
  2703. : cgmAttribute(inOwner, inPrev, inNext)
  2704. {
  2705.   myVdcR = (owner->markerMode()) ? new vdcR(cgmIn->getReal()) // scaled
  2706.     : new vdcR(cgmIn->getVdc()); // absolute
  2707. }
  2708. ////
  2709. // destructor
  2710. ////
  2711. cgmMarkerSize::~cgmMarkerSize()
  2712. {
  2713.   if (myVdcR) delete myVdcR;
  2714. }
  2715. ////
  2716. // output in a CGM format
  2717. ////
  2718. int cgmMarkerSize::cgmOut(cgmOutput *inOut)
  2719. {
  2720.   inOut->startCmd(this);
  2721.   if (myVdcR->type()) inOut->outReal(myVdcR->f()); // scaled
  2722.   else inOut->outVdc(myVdcR->v()); // absolute
  2723.   inOut->endCmd();
  2724.   return 1;
  2725. }
  2726. ////
  2727. // display output
  2728. ////
  2729. int cgmMarkerSize::display(baseDisplay *inDisplay)
  2730. {
  2731.   inDisplay->markerSize(myVdcR);
  2732.   return 1;
  2733. }
  2734. ////
  2735. // marker colour
  2736. ////
  2737. const int cgmMarkerColr::myElement = 8;
  2738. const char *cgmMarkerColr::myName = "MarkerColr";
  2739. ////
  2740. // constructor
  2741. ////
  2742. cgmMarkerColr::cgmMarkerColr(cgmContainer *inOwner, cgmInput *cgmIn,
  2743.                baseCGM *inPrev, baseCGM *inNext)
  2744. : cgmAttribute(inOwner, inPrev, inNext)
  2745. {
  2746.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  2747.               owner->colrs());
  2748. }
  2749. ////
  2750. // output in a CGM format
  2751. ////
  2752. int cgmMarkerColr::cgmOut(cgmOutput *inOut)
  2753. {
  2754.   inOut->startCmd(this);
  2755.   inOut->outColr(myColr);
  2756.   inOut->endCmd();
  2757.   return 1;
  2758. }
  2759. ////
  2760. // display output
  2761. ////
  2762. int cgmMarkerColr::display(baseDisplay *inDisplay)
  2763. {
  2764.   if (myColr) inDisplay->markerColr(*myColr);
  2765.   return 1;
  2766. }
  2767. ////
  2768. // text bundle index
  2769. ////
  2770. const int cgmTextIndex::myElement = 9;
  2771. const char *cgmTextIndex::myName = "TextIndex";
  2772. ////
  2773. // constructor
  2774. ////
  2775. cgmTextIndex::cgmTextIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  2776.                baseCGM *inPrev, baseCGM *inNext)
  2777. : cgmAttribute(inOwner, inPrev, inNext)
  2778. {
  2779.   myIndex = cgmIn->getInt();
  2780. }
  2781. ////
  2782. // output in a CGM format
  2783. ////
  2784. int cgmTextIndex::cgmOut(cgmOutput *inOut)
  2785. {
  2786.   inOut->startCmd(this);
  2787.   inOut->outInt(myIndex);
  2788.   inOut->endCmd();
  2789.   return 1;
  2790. }
  2791. ////
  2792. // display output
  2793. ////
  2794. int cgmTextIndex::display(baseDisplay *inDisplay)
  2795. {
  2796.   inDisplay->textIndex(myIndex);
  2797.   return 1;
  2798. }
  2799. ////
  2800. // text font index
  2801. ////
  2802. const int cgmFontIndex::myElement = 10;
  2803. const char *cgmFontIndex::myName = "TextFontIndex";
  2804. ////
  2805. // constructor
  2806. ////
  2807. cgmFontIndex::cgmFontIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  2808.                baseCGM *inPrev, baseCGM *inNext)
  2809. : cgmAttribute(inOwner, inPrev, inNext)
  2810. {
  2811.   myIndex = cgmIn->getInt();
  2812. }
  2813. ////
  2814. // output in a CGM format
  2815. ////
  2816. int cgmFontIndex::cgmOut(cgmOutput *inOut)
  2817. {
  2818.   inOut->startCmd(this);
  2819.   inOut->outInt(myIndex);
  2820.   inOut->endCmd();
  2821.   return 1;
  2822. }
  2823. ////
  2824. // display output
  2825. ////
  2826. int cgmFontIndex::display(baseDisplay *inDisplay)
  2827. {
  2828.   inDisplay->fontIndex(myIndex);
  2829.   owner->tInfo.setFont(myIndex);
  2830.   return 1;
  2831. }
  2832. ////
  2833. // Text Precision
  2834. ////
  2835. const int cgmTextPrec::myElement = 11;
  2836. const char *cgmTextPrec::myName = "TextPrec";
  2837. //// 
  2838. // aids for parsing
  2839. //// 
  2840. const char *tmpTextPrecList[] = {"STRING", "CHAR", "STROKE"};
  2841. const char **cgmTextPrec::typeList = tmpTextPrecList;
  2842. const int cgmTextPrec::typeListSize =
  2843. sizeof(tmpTextPrecList) / sizeof(tmpTextPrecList[0]);
  2844. //// 
  2845. // constructor
  2846. ////
  2847. cgmTextPrec::cgmTextPrec(cgmContainer *inOwner, cgmInput *cgmIn,
  2848.                baseCGM *inPrev, baseCGM *inNext)
  2849. : cgmAttribute(inOwner, inPrev, inNext)
  2850. {
  2851.   myType = cgmIn->getType(typeList, typeListSize);
  2852. }
  2853. //// 
  2854. // output in a CGM format
  2855. //// 
  2856. int cgmTextPrec::cgmOut(cgmOutput *inOut)
  2857. {
  2858.   inOut->startCmd(this);
  2859.   inOut->outType(typeList, myType);
  2860.   inOut->endCmd();
  2861.   return 1;
  2862. }
  2863. ////
  2864. // display output
  2865. ////
  2866. int cgmTextPrec::display(baseDisplay *inDisplay)
  2867. {
  2868.   inDisplay->textPrec(myType);
  2869.   owner->tInfo.setPrec(myType);
  2870.   return 1;
  2871. }
  2872. ////
  2873. // character expansion factor
  2874. ////
  2875. const int cgmCharExpan::myElement = 12;
  2876. const char *cgmCharExpan::myName = "CharExpan";
  2877. //// 
  2878. // constructor
  2879. ////
  2880. cgmCharExpan::cgmCharExpan(cgmContainer *inOwner, cgmInput *cgmIn,
  2881.                baseCGM *inPrev, baseCGM *inNext)
  2882. : cgmAttribute(inOwner, inPrev, inNext)
  2883. {
  2884.   factor = cgmIn->getReal();
  2885.   owner->tInfo.setExpan(factor);
  2886. }
  2887. //// 
  2888. // output in a CGM format
  2889. //// 
  2890. int cgmCharExpan::cgmOut(cgmOutput *inOut)
  2891. {
  2892.   inOut->startCmd(this);
  2893.   inOut->outReal(factor);
  2894.   inOut->endCmd();
  2895.   return 1;
  2896. }
  2897. ////
  2898. // display output
  2899. ////
  2900. int cgmCharExpan::display(baseDisplay *inDisplay)
  2901. {
  2902.   inDisplay->charExpan(factor);
  2903.   owner->tInfo.setExpan(factor);
  2904.   return 1;
  2905. }
  2906. ////
  2907. // character spacing
  2908. ////
  2909. const int cgmCharSpace::myElement = 13;
  2910. const char *cgmCharSpace::myName = "CharSpace";
  2911. //// 
  2912. // constructor
  2913. ////
  2914. cgmCharSpace::cgmCharSpace(cgmContainer *inOwner, cgmInput *cgmIn,
  2915.                baseCGM *inPrev, baseCGM *inNext)
  2916. : cgmAttribute(inOwner, inPrev, inNext)
  2917. {
  2918.   spacing = cgmIn->getReal();
  2919. }
  2920. //// 
  2921. // output in a CGM format
  2922. //// 
  2923. int cgmCharSpace::cgmOut(cgmOutput *inOut)
  2924. {
  2925.   inOut->startCmd(this);
  2926.   inOut->outReal(spacing);
  2927.   inOut->endCmd();
  2928.   return 1;
  2929. }
  2930. ////
  2931. // display output
  2932. ////
  2933. int cgmCharSpace::display(baseDisplay *inDisplay)
  2934. {
  2935.   inDisplay->charSpace(spacing);
  2936.   owner->tInfo.setSpace(spacing);
  2937.   return 1;
  2938. }
  2939. ////
  2940. // text colour
  2941. ////
  2942. const int cgmTextColr::myElement = 14;
  2943. const char *cgmTextColr::myName = "TextColr";
  2944. ////
  2945. // constructor
  2946. ////
  2947. cgmTextColr::cgmTextColr(cgmContainer *inOwner, cgmInput *cgmIn,
  2948.                baseCGM *inPrev, baseCGM *inNext)
  2949. : cgmAttribute(inOwner, inPrev, inNext)
  2950. {
  2951.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  2952.               owner->colrs());
  2953. }
  2954. ////
  2955. // output in a CGM format
  2956. ////
  2957. int cgmTextColr::cgmOut(cgmOutput *inOut)
  2958. {
  2959.   inOut->startCmd(this);
  2960.   inOut->outColr(myColr);
  2961.   inOut->endCmd();
  2962.   return 1;
  2963. }
  2964. ////
  2965. // display output
  2966. ////
  2967. int cgmTextColr::display(baseDisplay *inDisplay)
  2968. {
  2969.   if (myColr) {
  2970.     inDisplay->textColr(*myColr);
  2971.     owner->tInfo.setColr(myColr);
  2972.   }
  2973.   return 1;
  2974. }
  2975. ////
  2976. // character height
  2977. ////
  2978. const int cgmCharHeight::myElement = 15;
  2979. const char *cgmCharHeight::myName = "CharHeight";
  2980. //// 
  2981. // constructor
  2982. ////
  2983. cgmCharHeight::cgmCharHeight(cgmContainer *inOwner, cgmInput *cgmIn,
  2984.                baseCGM *inPrev, baseCGM *inNext)
  2985. : cgmAttribute(inOwner, inPrev, inNext)
  2986. {
  2987.   height = cgmIn->getVdc();
  2988. }
  2989. //// 
  2990. // output in a CGM format
  2991. //// 
  2992. int cgmCharHeight::cgmOut(cgmOutput *inOut)
  2993. {
  2994.   inOut->startCmd(this);
  2995.   inOut->outVdc(height);
  2996.   inOut->endCmd();
  2997.   return 1;
  2998. }
  2999. ////
  3000. // display output
  3001. ////
  3002. int cgmCharHeight::display(baseDisplay *inDisplay)
  3003. {
  3004.   owner->tInfo.setHeight(height->f());
  3005.   inDisplay->charHeight(height);
  3006.   return 1;
  3007. }
  3008. ////
  3009. // character orientation
  3010. ////
  3011. const int cgmCharOri::myElement = 16;
  3012. const char *cgmCharOri::myName = "CharOri";
  3013. //// 
  3014. // constructor
  3015. ////
  3016. cgmCharOri::cgmCharOri(cgmContainer *inOwner, cgmInput *cgmIn,
  3017.                baseCGM *inPrev, baseCGM *inNext)
  3018. : cgmAttribute(inOwner, inPrev, inNext)
  3019. {
  3020.  orientation = cgmIn->getVdcPts(2);
  3021. }
  3022. //// 
  3023. // output in a CGM format
  3024. //// 
  3025. int cgmCharOri::cgmOut(cgmOutput *inOut)
  3026. {
  3027.   inOut->startCmd(this);
  3028.   inOut->outVdcPts(orientation);
  3029.   inOut->endCmd();
  3030.   return 1;
  3031. }
  3032. ////
  3033. // display output
  3034. ////
  3035. int cgmCharOri::display(baseDisplay *inDisplay)
  3036. {
  3037.   owner->tInfo.setOrientation(orientation);
  3038.   inDisplay->charOri(orientation);
  3039.   return 1;
  3040. }
  3041. ////
  3042. // Text Path
  3043. ////
  3044. const int cgmTextPath::myElement = 17;
  3045. const char *cgmTextPath::myName = "TextPath";
  3046. //// 
  3047. // aids for parsing
  3048. //// 
  3049. const char *tmpTextPathList[] = {"RIGHT", "LEFT", "UP", "DOWN"};
  3050. const char **cgmTextPath::typeList = tmpTextPathList;
  3051. const int cgmTextPath::typeListSize =
  3052. sizeof(tmpTextPathList) / sizeof(tmpTextPathList[0]);
  3053. //// 
  3054. // constructor
  3055. ////
  3056. cgmTextPath::cgmTextPath(cgmContainer *inOwner, cgmInput *cgmIn,
  3057.                baseCGM *inPrev, baseCGM *inNext)
  3058. : cgmAttribute(inOwner, inPrev, inNext)
  3059. {
  3060.   myType = cgmIn->getType(typeList, typeListSize);
  3061. }
  3062. //// 
  3063. // output in a CGM format
  3064. //// 
  3065. int cgmTextPath::cgmOut(cgmOutput *inOut)
  3066. {
  3067.   inOut->startCmd(this);
  3068.   inOut->outType(typeList, myType);
  3069.   inOut->endCmd();
  3070.   return 1;
  3071. }
  3072. ////
  3073. // display output
  3074. ////
  3075. int cgmTextPath::display(baseDisplay *inDisplay)
  3076. {
  3077.   inDisplay->textPath(myType);
  3078.   owner->tInfo.setPath(myType);
  3079.   return 1;
  3080. }
  3081. ////
  3082. // Text alignment
  3083. ////
  3084. const int cgmTextAlign::myElement = 18;
  3085. const char *cgmTextAlign::myName = "TextAlign";
  3086. //// 
  3087. // aids for parsing
  3088. //// 
  3089. const char *tmpTextAlignList1[] = {"NORMHORIZ", "LEFT", "CTR", "RIGHT",
  3090.                  "CONTHORIZ"};
  3091. const char **cgmTextAlign::typeList1 = tmpTextAlignList1;
  3092. const int cgmTextAlign::typeListSize1 =
  3093. sizeof(tmpTextAlignList1) / sizeof(tmpTextAlignList1[0]);
  3094. const char *tmpTextAlignList2[] = {"NORMVERT", "TOP", "CAP", "HALF",
  3095.                  "BASE", "BOTTOM", "CONTVERT"};
  3096. const char **cgmTextAlign::typeList2 = tmpTextAlignList2;
  3097. const int cgmTextAlign::typeListSize2 =
  3098. sizeof(tmpTextAlignList2) / sizeof(tmpTextAlignList2[0]);
  3099. //// 
  3100. // constructor
  3101. ////
  3102. cgmTextAlign::cgmTextAlign(cgmContainer *inOwner, cgmInput *cgmIn,
  3103.                baseCGM *inPrev, baseCGM *inNext)
  3104. : cgmAttribute(inOwner, inPrev, inNext)
  3105. {
  3106.   int inH = cgmIn->getType(typeList1, typeListSize1);
  3107.   int inV = cgmIn->getType(typeList2, typeListSize2);
  3108.   float inCH = cgmIn->getReal();
  3109.   float inCV = cgmIn->getReal();
  3110.   myAlign = new alignment(inH, inV, inCH, inCV);
  3111. }
  3112. //// 
  3113. // output in a CGM format
  3114. //// 
  3115. int cgmTextAlign::cgmOut(cgmOutput *inOut)
  3116. {
  3117.   inOut->startCmd(this);
  3118.   inOut->outType(typeList1, myAlign->h());
  3119.   inOut->outType(typeList2, myAlign->v());
  3120.   inOut->outReal(myAlign->cH());
  3121.   inOut->outReal(myAlign->cV());
  3122.   inOut->endCmd();
  3123.   return 1;
  3124. }
  3125. ////
  3126. // display output
  3127. ////
  3128. int cgmTextAlign::display(baseDisplay *inDisplay)
  3129. {
  3130.   owner->tInfo.setAlign(myAlign);
  3131.   inDisplay->textAlign(myAlign);
  3132.   return 1;
  3133. }
  3134. ////
  3135. // character set index
  3136. ////
  3137. const int cgmCharSetIndex::myElement = 19;
  3138. const char *cgmCharSetIndex::myName = "CharSetIndex";
  3139. ////
  3140. // constructor
  3141. ////
  3142. cgmCharSetIndex::cgmCharSetIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3143.                baseCGM *inPrev, baseCGM *inNext)
  3144. : cgmAttribute(inOwner, inPrev, inNext)
  3145. {
  3146.   myIndex = cgmIn->getInt();
  3147. }
  3148. ////
  3149. // output in a CGM format
  3150. ////
  3151. int cgmCharSetIndex::cgmOut(cgmOutput *inOut)
  3152. {
  3153.   inOut->startCmd(this);
  3154.   inOut->outInt(myIndex);
  3155.   inOut->endCmd();
  3156.   return 1;
  3157. }
  3158. ////
  3159. // display output
  3160. ////
  3161. int cgmCharSetIndex::display(baseDisplay *inDisplay)
  3162. {
  3163.   inDisplay->charSetIndex(myIndex);
  3164.   return 1;
  3165. }
  3166. ////
  3167. // alternate character set index
  3168. ////
  3169. const int cgmAltCharSetIndex::myElement = 20;
  3170. const char *cgmAltCharSetIndex::myName = "AltCharSetIndex";
  3171. ////
  3172. // constructor
  3173. ////
  3174. cgmAltCharSetIndex::cgmAltCharSetIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3175.                baseCGM *inPrev, baseCGM *inNext)
  3176. : cgmAttribute(inOwner, inPrev, inNext)
  3177. {
  3178.   myIndex = cgmIn->getInt();
  3179. }
  3180. ////
  3181. // output in a CGM format
  3182. ////
  3183. int cgmAltCharSetIndex::cgmOut(cgmOutput *inOut)
  3184. {
  3185.   inOut->startCmd(this);
  3186.   inOut->outInt(myIndex);
  3187.   inOut->endCmd();
  3188.   return 1;
  3189. }
  3190. ////
  3191. // display output
  3192. ////
  3193. int cgmAltCharSetIndex::display(baseDisplay *inDisplay)
  3194. {
  3195.   inDisplay->altCharSetIndex(myIndex);
  3196.   return 1;
  3197. }
  3198. ////
  3199. // fill bundle index
  3200. ////
  3201. const int cgmFillIndex::myElement = 21;
  3202. const char *cgmFillIndex::myName = "FillIndex";
  3203. ////
  3204. // constructor
  3205. ////
  3206. cgmFillIndex::cgmFillIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3207.                baseCGM *inPrev, baseCGM *inNext)
  3208. : cgmAttribute(inOwner, inPrev, inNext)
  3209. {
  3210.   myIndex = cgmIn->getInt();
  3211. }
  3212. ////
  3213. // output in a CGM format
  3214. ////
  3215. int cgmFillIndex::cgmOut(cgmOutput *inOut)
  3216. {
  3217.   inOut->startCmd(this);
  3218.   inOut->outInt(myIndex);
  3219.   inOut->endCmd();
  3220.   return 1;
  3221. }
  3222. ////
  3223. // display output
  3224. ////
  3225. int cgmFillIndex::display(baseDisplay *inDisplay)
  3226. {
  3227.   inDisplay->fillIndex(myIndex);
  3228.   return 1;
  3229. }
  3230. ////
  3231. // interior style
  3232. ////
  3233. const int cgmIntStyle::myElement = 22;
  3234. const char *cgmIntStyle::myName = "IntStyle";
  3235. //// 
  3236. // aids for parsing
  3237. //// 
  3238. const char *tmpIntStyleList[] = {"HOLLOW", "SOLID", "PAT",
  3239.                    "HATCH", "EMPTY"};
  3240. const char **cgmIntStyle::typeList = tmpIntStyleList;
  3241. const int cgmIntStyle::typeListSize =
  3242. sizeof(tmpIntStyleList) / sizeof(tmpIntStyleList[0]);
  3243. //// 
  3244. // constructor
  3245. ////
  3246. cgmIntStyle::cgmIntStyle(cgmContainer *inOwner, cgmInput *cgmIn,
  3247.                baseCGM *inPrev, baseCGM *inNext)
  3248. : cgmAttribute(inOwner, inPrev, inNext)
  3249. {
  3250.   myType = cgmIn->getType(typeList, typeListSize);
  3251. }
  3252. //// 
  3253. // output in a CGM format
  3254. //// 
  3255. int cgmIntStyle::cgmOut(cgmOutput *inOut)
  3256. {
  3257.   inOut->startCmd(this);
  3258.   inOut->outType(typeList, myType);
  3259.   inOut->endCmd();
  3260.   return 1;
  3261. }
  3262. ////
  3263. // display output
  3264. ////
  3265. int cgmIntStyle::display(baseDisplay *inDisplay)
  3266. {
  3267.   inDisplay->intStyle(myType);
  3268.   return 1;
  3269. }
  3270. ////
  3271. // fill colour
  3272. ////
  3273. const int cgmFillColr::myElement = 23;
  3274. const char *cgmFillColr::myName = "FillColr";
  3275. ////
  3276. // constructor
  3277. ////
  3278. cgmFillColr::cgmFillColr(cgmContainer *inOwner, cgmInput *cgmIn,
  3279.                baseCGM *inPrev, baseCGM *inNext)
  3280. : cgmAttribute(inOwner, inPrev, inNext)
  3281. {
  3282.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  3283.               owner->colrs());
  3284. }
  3285. ////
  3286. // output in a CGM format
  3287. ////
  3288. int cgmFillColr::cgmOut(cgmOutput *inOut)
  3289. {
  3290.   inOut->startCmd(this);
  3291.   inOut->outColr(myColr);
  3292.   inOut->endCmd();
  3293.   return 1;
  3294. }
  3295. ////
  3296. // display output
  3297. ////
  3298. int cgmFillColr::display(baseDisplay *inDisplay)
  3299. {
  3300.   if (myColr) inDisplay->fillColr(*myColr);
  3301.   return 1;
  3302. }
  3303. ////
  3304. // hatch index
  3305. ////
  3306. const int cgmHatchIndex::myElement = 24;
  3307. const char *cgmHatchIndex::myName = "HatchIndex";
  3308. ////
  3309. // constructor
  3310. ////
  3311. cgmHatchIndex::cgmHatchIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3312.                baseCGM *inPrev, baseCGM *inNext)
  3313. : cgmAttribute(inOwner, inPrev, inNext)
  3314. {
  3315.   myIndex = cgmIn->getInt();
  3316. }
  3317. ////
  3318. // output in a CGM format
  3319. ////
  3320. int cgmHatchIndex::cgmOut(cgmOutput *inOut)
  3321. {
  3322.   inOut->startCmd(this);
  3323.   inOut->outInt(myIndex);
  3324.   inOut->endCmd();
  3325.   return 1;
  3326. }
  3327. ////
  3328. // display output
  3329. ////
  3330. int cgmHatchIndex::display(baseDisplay *inDisplay)
  3331. {
  3332.   inDisplay->hatchIndex(myIndex);
  3333.   return 1;
  3334. }
  3335. ////
  3336. // pattern index
  3337. ////
  3338. const int cgmPatIndex::myElement = 24;
  3339. const char *cgmPatIndex::myName = "PatIndex";
  3340. ////
  3341. // constructor
  3342. ////
  3343. cgmPatIndex::cgmPatIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3344.                baseCGM *inPrev, baseCGM *inNext)
  3345. : cgmAttribute(inOwner, inPrev, inNext)
  3346. {
  3347.   myIndex = cgmIn->getInt();
  3348. }
  3349. ////
  3350. // output in a CGM format
  3351. ////
  3352. int cgmPatIndex::cgmOut(cgmOutput *inOut)
  3353. {
  3354.   inOut->startCmd(this);
  3355.   inOut->outInt(myIndex);
  3356.   inOut->endCmd();
  3357.   return 1;
  3358. }
  3359. ////
  3360. // display output
  3361. ////
  3362. int cgmPatIndex::display(baseDisplay *inDisplay)
  3363. {
  3364.   inDisplay->patIndex(myIndex);
  3365.   return 1;
  3366. }
  3367. ////
  3368. // Edge bundle index
  3369. ////
  3370. const int cgmEdgeIndex::myElement = 26;
  3371. const char *cgmEdgeIndex::myName = "EdgeIndex";
  3372. ////
  3373. // constructor
  3374. ////
  3375. cgmEdgeIndex::cgmEdgeIndex(cgmContainer *inOwner, cgmInput *cgmIn,
  3376.                baseCGM *inPrev, baseCGM *inNext)
  3377. : cgmAttribute(inOwner, inPrev, inNext)
  3378. {
  3379.   myIndex = cgmIn->getInt();
  3380. }
  3381. ////
  3382. // output in a CGM format
  3383. ////
  3384. int cgmEdgeIndex::cgmOut(cgmOutput *inOut)
  3385. {
  3386.   inOut->startCmd(this);
  3387.   inOut->outInt(myIndex);
  3388.   inOut->endCmd();
  3389.   return 1;
  3390. }
  3391. ////
  3392. // display output
  3393. ////
  3394. int cgmEdgeIndex::display(baseDisplay *inDisplay)
  3395. {
  3396.   inDisplay->edgeIndex(myIndex);
  3397.   return 1;
  3398. }
  3399. ////
  3400. // edge type
  3401. ////
  3402. const int cgmEdgeType::myElement = 27;
  3403. const char *cgmEdgeType::myName = "EdgeType";
  3404. ////
  3405. // constructor
  3406. ////
  3407. cgmEdgeType::cgmEdgeType(cgmContainer *inOwner, cgmInput *cgmIn,
  3408.              baseCGM *inPrev, baseCGM *inNext)
  3409. : cgmAttribute(inOwner, inPrev, inNext)
  3410. {
  3411.   myType = cgmIn->getInt();
  3412. }
  3413. ////
  3414. // output in a CGM format
  3415. ////
  3416. int cgmEdgeType::cgmOut(cgmOutput *inOut)
  3417. {
  3418.   inOut->startCmd(this);
  3419.   inOut->outInt(myType);
  3420.   inOut->endCmd();
  3421.   return 1;
  3422. }
  3423. ////
  3424. // display output
  3425. ////
  3426. int cgmEdgeType::display(baseDisplay *inDisplay)
  3427. {
  3428.   inDisplay->edgeType(myType);
  3429.   return 1;
  3430. }
  3431. #ifdef macintosh
  3432.  #pragma segment CGM5
  3433. #endif
  3434. ////
  3435. // edge width
  3436. ////
  3437. const int cgmEdgeWidth::myElement = 28;
  3438. const char *cgmEdgeWidth::myName = "EdgeWidth";
  3439. ////
  3440. // constructor
  3441. ////
  3442. cgmEdgeWidth::cgmEdgeWidth(cgmContainer *inOwner, cgmInput *cgmIn,
  3443.                baseCGM *inPrev, baseCGM *inNext)
  3444. : cgmAttribute(inOwner, inPrev, inNext)
  3445. {
  3446.   myVdcR = (owner->edgeMode()) ? new vdcR(cgmIn->getReal()) // scaled
  3447.     : new vdcR(cgmIn->getVdc()); // absolute
  3448. }
  3449. ////
  3450. // destructor
  3451. ////
  3452. cgmEdgeWidth::~cgmEdgeWidth()
  3453. {
  3454.   if (myVdcR) delete myVdcR;
  3455. }
  3456. ////
  3457. // output in a CGM format
  3458. ////
  3459. int cgmEdgeWidth::cgmOut(cgmOutput *inOut)
  3460. {
  3461.   inOut->startCmd(this);
  3462.   if (myVdcR->type()) inOut->outReal(myVdcR->f()); // scaled
  3463.   else inOut->outVdc(myVdcR->v()); // absolute
  3464.   inOut->endCmd();
  3465.   return 1;
  3466. }
  3467. ////
  3468. // display output
  3469. ////
  3470. int cgmEdgeWidth::display(baseDisplay *inDisplay)
  3471. {
  3472.   inDisplay->edgeWidth(myVdcR);
  3473.   return 1;
  3474. }
  3475. ////
  3476. // edge colour
  3477. ////
  3478. const int cgmEdgeColr::myElement = 29;
  3479. const char *cgmEdgeColr::myName = "EdgeColr";
  3480. ////
  3481. // constructor
  3482. ////
  3483. cgmEdgeColr::cgmEdgeColr(cgmContainer *inOwner, cgmInput *cgmIn,
  3484.                baseCGM *inPrev, baseCGM *inNext)
  3485. : cgmAttribute(inOwner, inPrev, inNext)
  3486. {
  3487.   myColr = cgmIn->getColr(owner->colrMode(), owner->colrExtent(),
  3488.               owner->colrs());
  3489. }
  3490. ////
  3491. // output in a CGM format
  3492. ////
  3493. int cgmEdgeColr::cgmOut(cgmOutput *inOut)
  3494. {
  3495.   inOut->startCmd(this);
  3496.   inOut->outColr(myColr);
  3497.   inOut->endCmd();
  3498.   return 1;
  3499. }
  3500. ////
  3501. // display output
  3502. ////
  3503. int cgmEdgeColr::display(baseDisplay *inDisplay)
  3504. {
  3505.   if (myColr) inDisplay->edgeColr(*myColr);
  3506.   return 1;
  3507. }
  3508. ////
  3509. // edge visibility
  3510. ////
  3511. const int cgmEdgeVis::myElement = 30;
  3512. const char *cgmEdgeVis::myName = "EdgeVis";
  3513. //// 
  3514. // aids for parsing
  3515. //// 
  3516. const char *tmpEdgeVisList[] = {"OFF", "ON"};
  3517. const char **cgmEdgeVis::typeList = tmpEdgeVisList;
  3518. const int cgmEdgeVis::typeListSize =
  3519. sizeof(tmpEdgeVisList) / sizeof(tmpEdgeVisList[0]);
  3520. //// 
  3521. // constructor
  3522. ////
  3523. cgmEdgeVis::cgmEdgeVis(cgmContainer *inOwner, cgmInput *cgmIn,
  3524.                baseCGM *inPrev, baseCGM *inNext)
  3525. : cgmAttribute(inOwner, inPrev, inNext)
  3526. {
  3527.   myType = cgmIn->getType(typeList, typeListSize);
  3528. }
  3529. //// 
  3530. // output in a CGM format
  3531. //// 
  3532. int cgmEdgeVis::cgmOut(cgmOutput *inOut)
  3533. {
  3534.   inOut->startCmd(this);
  3535.   inOut->outType(typeList, myType);
  3536.   inOut->endCmd();
  3537.   return 1;
  3538. }
  3539. ////
  3540. // display output
  3541. ////
  3542. int cgmEdgeVis::display(baseDisplay *inDisplay)
  3543. {
  3544.   inDisplay->edgeVis(myType);
  3545.   return 1;
  3546. }
  3547. ////
  3548. // fill reference point
  3549. ////
  3550. const int cgmFillRefPt::myElement = 31;
  3551. const char *cgmFillRefPt::myName = "FillRefPt";
  3552. //// 
  3553. // constructor
  3554. ////
  3555. cgmFillRefPt::cgmFillRefPt(cgmContainer *inOwner, cgmInput *cgmIn,
  3556.                baseCGM *inPrev, baseCGM *inNext)
  3557. : cgmAttribute(inOwner, inPrev, inNext)
  3558. {
  3559.  myPts = cgmIn->getVdcPts(1);
  3560. }
  3561. //// 
  3562. // output in a CGM format
  3563. //// 
  3564. int cgmFillRefPt::cgmOut(cgmOutput *inOut)
  3565. {
  3566.   inOut->startCmd(this);
  3567.   inOut->outVdcPts(myPts);
  3568.   inOut->endCmd();
  3569.   return 1;
  3570. }
  3571. ////
  3572. // display output
  3573. ////
  3574. int cgmFillRefPt::display(baseDisplay *inDisplay)
  3575. {
  3576.   inDisplay->fillRefPt(myPts);
  3577.   return 1;
  3578. }
  3579. ////
  3580. // pattern size
  3581. ////
  3582. const int cgmPatSize::myElement = 33;
  3583. const char *cgmPatSize::myName = "PatSize";
  3584. //// 
  3585. // constructor
  3586. ////
  3587. cgmPatSize::cgmPatSize(cgmContainer *inOwner, cgmInput *cgmIn,
  3588.                baseCGM *inPrev, baseCGM *inNext)
  3589. : cgmAttribute(inOwner, inPrev, inNext)
  3590. {
  3591.  myPts = cgmIn->getVdcPts(2);
  3592. }
  3593. //// 
  3594. // output in a CGM format
  3595. //// 
  3596. int cgmPatSize::cgmOut(cgmOutput *inOut)
  3597. {
  3598.   inOut->startCmd(this);
  3599.   inOut->outVdcPts(myPts);
  3600.   inOut->endCmd();
  3601.   return 1;
  3602. }
  3603. ////
  3604. // display output
  3605. ////
  3606. int cgmPatSize::display(baseDisplay *inDisplay)
  3607. {
  3608.   // nothing for now
  3609.   return 1;
  3610. }
  3611. ////
  3612. // pattern table
  3613. ////
  3614. const int cgmPatTable::myElement = 32;
  3615. const char *cgmPatTable::myName = "PatTable";
  3616. //// 
  3617. // constructor
  3618. ////
  3619. cgmPatTable::cgmPatTable(cgmContainer *inOwner, cgmInput *cgmIn,
  3620.                baseCGM *inPrev, baseCGM *inNext)
  3621. : cgmAttribute(inOwner, inPrev, inNext)
  3622. {
  3623.   // fixlater
  3624. }
  3625. //// 
  3626. // output in a CGM format
  3627. //// 
  3628. int cgmPatTable::cgmOut(cgmOutput *inOut)
  3629. {
  3630.   inOut->startCmd(this);
  3631.   // fix later
  3632.   inOut->endCmd();
  3633.   return 1;
  3634. }
  3635. ////
  3636. // display output
  3637. ////
  3638. int cgmPatTable::display(baseDisplay *inDisplay)
  3639. {
  3640.   // fix later
  3641.   return 1;
  3642. }
  3643. ////
  3644. // colour table
  3645. ////
  3646. const int cgmColrTable::myElement = 34;
  3647. const char *cgmColrTable::myName = "ColrTable";
  3648. //// 
  3649. // constructor
  3650. ////
  3651. cgmColrTable::cgmColrTable(cgmContainer *inOwner, cgmInput *cgmIn,
  3652.                baseCGM *inPrev, baseCGM *inNext)
  3653. : cgmAttribute(inOwner, inPrev, inNext)
  3654. {
  3655.  myTable = cgmIn->getColrTable(owner->colrExtent());
  3656.  owner->colrs()->addTable(myTable);
  3657. }
  3658. //// 
  3659. // output in a CGM format
  3660. //// 
  3661. int cgmColrTable::cgmOut(cgmOutput *inOut)
  3662. {
  3663.   inOut->startCmd(this);
  3664.   inOut->outColrTable(myTable);
  3665.   inOut->endCmd();
  3666.   return 1;
  3667. }
  3668. ////
  3669. // display output
  3670. ////
  3671. int cgmColrTable::display(baseDisplay *inDisplay)
  3672. {
  3673.   inDisplay->colrs(myTable);
  3674.   return 1;
  3675. }
  3676. #ifdef macintosh
  3677.  #pragma segment CGM6
  3678. #endif
  3679. ////
  3680. // aspect source flags
  3681. ////
  3682. const int cgmASF::myElement = 35;
  3683. const char *cgmASF::myName = "ASF";
  3684. //// 
  3685. // constructor
  3686. ////
  3687. cgmASF::cgmASF(cgmContainer *inOwner, cgmInput *cgmIn,
  3688.         baseCGM *inPrev, baseCGM *inNext)
  3689. : cgmAttribute(inOwner, inPrev, inNext)
  3690. {
  3691.   // fill out later
  3692. }
  3693. //// 
  3694. // output in a CGM format
  3695. //// 
  3696. int cgmASF::cgmOut(cgmOutput *inOut)
  3697. {
  3698.   inOut->startCmd(this);
  3699.   // fill out later
  3700.   inOut->endCmd();
  3701.   return 1;
  3702. }
  3703. ////
  3704. // the Escape class
  3705. ////
  3706. const int cgmEscape::myClass = 6;
  3707. ////
  3708. // escape element
  3709. ////
  3710. const int cgmEscapeElement::myElement = 1;
  3711. const char *cgmEscapeElement::myName = "Escape";
  3712. const int cgmEscapeElement::indexFlag = -64;
  3713. //// 
  3714. // constructor
  3715. ////
  3716. cgmEscapeElement::cgmEscapeElement(cgmContainer *inOwner, cgmInput *cgmIn,
  3717.         baseCGM *inPrev, baseCGM *inNext)
  3718. : cgmEscape(inOwner, inPrev, inNext)
  3719. {
  3720.   myId = cgmIn->getInt();
  3721.   myData = cgmIn->getString(dataSize);
  3722.   if ((myId = indexFlag) && !mfOwner()->indexed() &&
  3723.       (cgmIn->isa() != clearCGM)) { // don't trust on clear text
  3724.     mfOwner()->setIndexed(); // so as not recurse indefinitely
  3725.     filePos startPos = cgmIn->pos(); // mark our spot
  3726.     makeIndex(mfOwner(), cgmIn);
  3727.     if (cgmIn->pos() != startPos) cgmIn->goTo(startPos); // safety
  3728.   }
  3729. }
  3730. ////
  3731. // construct an index using our index blocks
  3732. ////
  3733. void cgmEscapeElement::makeIndex(cgmMetafile *inMF, cgmInput *cgmIn)
  3734. {
  3735.   // have to assume filepos is a long here in order to use sscanf
  3736.   long myAddress, nextPos, nextPtr;
  3737.   baseCGM *myCGM;
  3738.   cgmBeginPicture *myBeginPic;
  3739.   cgmPicture *myPic, *lastPic;
  3740.   cgmEscapeElement *myEscape;
  3741.   int noPages, done = 0, i, strLen;
  3742.   char *strPtr;
  3743.   // get ready for the loop
  3744.   myEscape = this;
  3745.   // get the last picture that we already know
  3746.   for (lastPic = inMF->firstPic; lastPic && lastPic->next;
  3747.        lastPic = lastPic->next);
  3748.   do {
  3749.     strPtr = myEscape->data();
  3750.     while (*strPtr == ' ') ++strPtr; // skip spaces
  3751.     if (sscanf(strPtr, "%d", &noPages) != 1) { // how many pages ?
  3752.       myError("couldn't read noPages");
  3753.       return;
  3754.     }
  3755.     while (haveNumber(*strPtr)) ++strPtr; // skip number
  3756.     ////
  3757.     for (i=0; i<noPages; ++i) { // entry for each page
  3758.       while (*strPtr == ' ') ++strPtr; // skip spaces
  3759.       if (sscanf(strPtr, "%ld", &myAddress) != 1) { // get the address
  3760.     myError("couldn't get byte address");
  3761.     return;
  3762.       }
  3763.       while (haveNumber(*strPtr)) ++strPtr; // skip number
  3764.       while (*strPtr == ' ') ++strPtr; // skip spaces
  3765.       if (sscanf(strPtr, "%ld", &strLen) != 1) { // get the string length
  3766.     myError("couldn't get string length");
  3767.     return;
  3768.       }
  3769.       while (haveNumber(*strPtr)) ++strPtr; // skip number
  3770.       // now have the picture name
  3771.       ++strPtr;    // one-char gap
  3772.       // get new begin picture and cgm picture
  3773.       myBeginPic = new cgmBeginPicture(inMF, strPtr, strLen);
  3774.       myPic = new cgmPicture(inMF, cgmIn, myBeginPic, lastPic,
  3775.                    cgmIn->lastPos() + myAddress);
  3776.       if (!lastPic) inMF->firstPic = myPic;
  3777.       lastPic = myPic;
  3778.  
  3779.       strPtr += strLen; // skip over the string
  3780.     }
  3781.     // now need pointer to next index block
  3782.     if (sscanf(strPtr, " %d", &nextPtr) != 1) {
  3783.       myError("couldn't read pointer to next index block");
  3784.       return;
  3785.     }
  3786.     if (nextPtr) {
  3787.       nextPos = cgmIn->lastPos() + nextPtr;
  3788.       cgmIn->goTo(nextPos);
  3789.       if (!cgmIn->getCmd()) {
  3790.     myError("couldn't get next index block");
  3791.     return;
  3792.       }
  3793.       if (!(myCGM = cgmIn->doCmd(inMF, NULL))) {
  3794.     myError("couldn't parse next index block");
  3795.     return;
  3796.       }
  3797.       if ((myCGM->cgmClass() != myClass)||(myCGM->cgmElement() != myElement)) {
  3798.     myError("next index block not in an escape element",
  3799.         myCGM->cgmName());
  3800.     return;
  3801.       }
  3802.       // now know we have an escape element
  3803.       myEscape = (cgmEscapeElement *) myCGM;
  3804.       if (myEscape->myId != indexFlag) {
  3805.     myError("index block escape element has wrong id");
  3806.     return;
  3807.       }
  3808.     }
  3809.     else done = 1;
  3810.   } while (!done);
  3811. }
  3812. //// 
  3813. // output in a CGM format
  3814. //// 
  3815. int cgmEscapeElement::cgmOut(cgmOutput *inOut)
  3816. {
  3817.   // strip out escapes for now, may do more harm than good
  3818.   // inOut->startCmd(this);
  3819.   // fill out later
  3820.   // inOut->endCmd();
  3821.   return 1;
  3822. }
  3823. ////
  3824. // the External class
  3825. ////
  3826. const int cgmExternal::myClass = 7;
  3827. ////
  3828. // message element
  3829. ////
  3830. const int cgmMessage::myElement = 1;
  3831. const char *cgmMessage::myName = "Message";
  3832. //// 
  3833. // constructor
  3834. ////
  3835. cgmMessage::cgmMessage(cgmContainer *inOwner, cgmInput *cgmIn,
  3836.         baseCGM *inPrev, baseCGM *inNext)
  3837. : cgmExternal(inOwner, inPrev, inNext)
  3838. {
  3839.   // fill out later
  3840. }
  3841. //// 
  3842. // output in a CGM format
  3843. //// 
  3844. int cgmMessage::cgmOut(cgmOutput *inOut)
  3845. {
  3846.   inOut->startCmd(this);
  3847.   // fill out later
  3848.   inOut->endCmd();
  3849.   return 1;
  3850. }
  3851. ////
  3852. // application data
  3853. ////
  3854. const int cgmApplData::myElement = 2;
  3855. const char *cgmApplData::myName = "ApplData";
  3856. //// 
  3857. // constructor
  3858. ////
  3859. cgmApplData::cgmApplData(cgmContainer *inOwner, cgmInput *cgmIn,
  3860.              baseCGM *inPrev, baseCGM *inNext)
  3861. : cgmExternal(inOwner, inPrev, inNext)
  3862. {
  3863.   // fill out later
  3864. }
  3865. //// 
  3866. // output in a CGM format
  3867. //// 
  3868. int cgmApplData::cgmOut(cgmOutput *inOut)
  3869. {
  3870.   inOut->startCmd(this);
  3871.   // fill out later
  3872.   inOut->endCmd();
  3873.   return 1;
  3874. }
  3875. ////
  3876. // the containing classes
  3877. ////
  3878. ////
  3879. // container for one metafile
  3880. ////
  3881. // constructor
  3882. ////
  3883. cgmMetafile::cgmMetafile(cgmBeginMetafile *inStart, cgmInput *inInput)
  3884. {
  3885.   contents = inStart;
  3886.   myInput = inInput;
  3887.   myStart = myInput->pos();
  3888.   if (inStart) inStart->setOwner(this); // get off on the right foot
  3889.   myDefaults = NULL;
  3890.   firstPic = NULL;
  3891.   versionCmd = NULL;
  3892.   descriptionCmd = NULL;
  3893.   vdcTypeCmd = NULL;
  3894.   maxColrIndexCmd = NULL;
  3895.   colrValueExtentCmd = NULL;
  3896.   vdcExtentCmd = NULL;
  3897.   intDefVdcExtent = new vdcPts(0, 0, 32767, 32767);
  3898.   // double for macintosh
  3899.   floatDefVdcExtent = new vdcPts((double)0.0, (double)0.0,
  3900.                  (double)1.0, (double) 1.0);
  3901.   myColrTable = new colrTable(64, colrExtent());
  3902.   myIndexed = 0; // not indexed yet
  3903. }
  3904. ////
  3905. // destructor
  3906. ////
  3907. cgmMetafile::~cgmMetafile() 
  3908. {
  3909.   delete intDefVdcExtent;
  3910.   delete floatDefVdcExtent;
  3911.   for (cgmPicture *myPic = firstPic; myPic; myPic = firstPic) {
  3912.     firstPic = myPic->next;
  3913.     delete myPic;
  3914.   }
  3915. }
  3916. ////
  3917. // add one set of defaults to the metafile
  3918. ////
  3919. void cgmMetafile::addDefaults(cgmDefaults *inDefaults) 
  3920. {
  3921.   if (!myDefaults) myDefaults = inDefaults; // first set
  3922.   else {
  3923.     cgmDefaults *myPtr = myDefaults;
  3924.     while (myPtr->next()) myPtr = myPtr->next(); // find last one
  3925.     myPtr->addNext(inDefaults);
  3926.   }
  3927. }
  3928. ////
  3929. // output the whole metafile to a cgm format
  3930. ////
  3931. cgmMetafile::cgmOut(cgmOutput *inOut) 
  3932. {
  3933.   for (baseCGM *myCGM = contents; myCGM; myCGM = myCGM->next) {
  3934.     myCGM->cgmOut(inOut); // metafile specifics
  3935.   }
  3936.   // now do the pages
  3937.   for (cgmPicture *myPic = firstPic; myPic; myPic = myPic->next) {
  3938.     if (myPic->want()) { // want this one
  3939.       myPic->readIn();
  3940.       myPic->cgmOut(inOut);
  3941.       myPic->setAside();
  3942.     } else if (!indexed()) { // don't already have all of their positions
  3943.       myPic->readIn(); // just to get next picture position
  3944.       myPic->setAside();
  3945.     }
  3946.   }
  3947.   return 1;
  3948. }
  3949. ////
  3950. // display the whole file
  3951. ////
  3952. void cgmMetafile::display(baseDisplay *inDisplay)
  3953. {
  3954.   for (baseCGM *myCGM = contents; myCGM; myCGM = myCGM->next) {
  3955.     myCGM->display(inDisplay); // metafile specifics
  3956.   }
  3957. }
  3958. ////
  3959. // index the file (if we can)
  3960. ////
  3961. int cgmMetafile::makeIndex()
  3962. {
  3963.   if (!indexed() && myInput) myInput->makeIndex(this);
  3964.   myIndexed = 1; // mark as done
  3965.   return 1;
  3966. }
  3967. ////
  3968. // return the version
  3969. ////
  3970. int cgmMetafile::version() 
  3971. {
  3972.   return versionCmd ? versionCmd->versionNumber : 1;
  3973. }
  3974. ////
  3975. // return the description
  3976. ////
  3977. const char *cgmMetafile::description() 
  3978. {
  3979.   return descriptionCmd ? descriptionCmd->mfDescription : NULL;
  3980. }
  3981. ////
  3982. // return the colour value extent
  3983. ////
  3984. const colrValueExtent *cgmMetafile::colrExtent() 
  3985. {
  3986.   return colrValueExtentCmd ? &(colrValueExtentCmd->myExtent) : &defExtent;
  3987. }
  3988. ////
  3989. // now access to the picture state defaults
  3990. ////
  3991. // return the scaling mode
  3992. ////
  3993. int cgmMetafile::scalingMode() 
  3994. {
  3995.   return scalingCmd ? scalingCmd->mode : 0;
  3996. }
  3997. ////
  3998. // return the scaling factor
  3999. ////
  4000. float cgmMetafile::scalingFactor() 
  4001. {
  4002.   return scalingCmd ? scalingCmd->factor : 1.0;
  4003. }
  4004. ////
  4005. // return the colour selection mode
  4006. ////
  4007. int cgmMetafile::colrMode() 
  4008. {
  4009.   return colrModeCmd ? colrModeCmd->mode : 0;
  4010. }
  4011. ////
  4012. // return the line width specification mode
  4013. ////
  4014. int cgmMetafile::lineMode() 
  4015. {
  4016.   return lineModeCmd ? lineModeCmd->mode : 1;
  4017. }
  4018. ////
  4019. // return the marker size specification mode
  4020. ////
  4021. int cgmMetafile::markerMode() 
  4022. {
  4023.   return markerModeCmd ? markerModeCmd->mode : 1;
  4024. }
  4025. ////
  4026. // return the edge width specification mode
  4027. ////
  4028. int cgmMetafile::edgeMode() 
  4029. {
  4030.   return edgeModeCmd ? edgeModeCmd->mode : 1;
  4031. }
  4032.  
  4033.  
  4034. ////
  4035. // return the vdc extent
  4036. ////
  4037.  
  4038. const vdcPts *cgmMetafile::vdcExtent() const
  4039. {
  4040.   return vdcExtentCmd ? vdcExtentCmd->myPts : myVdcType() ?
  4041.     floatDefVdcExtent : intDefVdcExtent;
  4042. }
  4043. ////
  4044. // container for a single picture
  4045. ////
  4046. cgmPicture::cgmPicture(cgmMetafile *inMetafile, cgmInput *inInput,
  4047.                cgmBeginPicture *inPicture, cgmPicture *inPrev,
  4048.                filePos inPos)
  4049.   myColrTable = NULL; // get when we read in data
  4050.   contents = NULL;
  4051.   prev = next = NULL;
  4052.   metafile = inMetafile;
  4053.   if (!metafile) myError("no metafile for cgmPicture", "exiting", 0);
  4054.   prev = inPrev;
  4055.   if (prev) prev->next = this; // link pointers
  4056.   myInput = inInput;
  4057.   // do we already have the position ?
  4058.   myPos = (inPos) ? inPos : myInput->pos(); 
  4059.   myBeginPicture = inPicture;
  4060.   if (!myBeginPicture) myError("no beginPicture for cgmPicture", "exiting", 0);
  4061.   setWant(1); // default is to want it
  4062. }
  4063. ////
  4064. // destructor
  4065. ////
  4066. cgmPicture::~cgmPicture()
  4067. {
  4068.   delete myBeginPicture;
  4069.   for (baseCGM *myCGM = contents; myCGM; myCGM = contents) {
  4070.     contents = myCGM->next;
  4071.     delete myCGM;
  4072.   }
  4073. }
  4074. ////
  4075. // output to cgm format
  4076. ////
  4077. cgmPicture::cgmOut(cgmOutput *inOut) 
  4078. {
  4079.   myBeginPicture->cgmOut(inOut); // the begin picture element
  4080.   for (baseCGM *myCGM = contents; myCGM && myCGM->cgmOut(inOut);
  4081.        myCGM = myCGM->next);
  4082.   return !myCGM;
  4083. }
  4084. ////
  4085. // display one picture
  4086. ////
  4087. void cgmPicture::display(baseDisplay *inDisplay) 
  4088. {
  4089.   if (!inDisplay) myError("no inDisplay for cgmPicture", "exiting", 0); 
  4090.   if (!myBeginPicture) myError("no myBeginPicture for cgmPicture display",
  4091.                    "exiting", 0);
  4092.   myBeginPicture->display(inDisplay); // the begin picture body
  4093.  
  4094.   if (!contents) { 
  4095.     myError("no contents in this picture");
  4096.     return;
  4097.   }
  4098.   baseCGM *myCGM = contents;
  4099.   // go to begin picture body
  4100.   while (myCGM &&
  4101.      !((myCGM->cgmClass() == cgmDelimiter::myClass) &&
  4102.        (myCGM->cgmElement() == cgmBeginPictureBody::myElement))) {
  4103.     myCGM->display(inDisplay); // for control elements, etc.
  4104.     myCGM = myCGM->next;
  4105.   }
  4106.   ////
  4107.   // have a chance to adjust things before picture body
  4108.   ////
  4109.   if (tInfo.height() == 0) { // never set text height
  4110.     tInfo.setHeight(vdcExtent()->height() * 0.01); // default
  4111.   }
  4112.   ////
  4113.   // display everything up to the end picture
  4114.   while (myCGM &&
  4115.      !((myCGM->cgmClass() == cgmDelimiter::myClass) &&
  4116.         (myCGM->cgmElement() == cgmEndPicture::myElement))
  4117.      ) {
  4118.     myCGM->display(inDisplay); // for graphical primitives attributes, etc.
  4119.     myCGM = myCGM->next; 
  4120.   }
  4121.   if (myCGM) myCGM->display(inDisplay); // the end picture
  4122.   // done
  4123. }
  4124. ////
  4125. // read in one picture
  4126. ////
  4127. int cgmPicture::readIn()
  4128. {
  4129.   if (contents) return 1; // already read in
  4130.   baseCGM *gotCmd, *lastPtr = NULL;
  4131.   // set up defaults
  4132.   tInfo = metafile->tInfo; // bit wise copy
  4133.   myColrTable = new colrTable(64, colrExtent());
  4134.   if (myInput->goTo(myPos)) { // go to the correct position
  4135.     myError("couldn't goTo beginning of picture");
  4136.     return 0;
  4137.   }
  4138.   // loop thru commands
  4139.   while(myInput->getCmd()) { // have input
  4140.     // is this an unknown command ?
  4141.     if (!(gotCmd = myInput->doCmd(this, lastPtr))) continue;
  4142.     // is this a delimiter ?
  4143.     if (gotCmd->cgmClass() == cgmDelimiter::myClass) {
  4144.         switch(gotCmd->cgmElement()) {
  4145.         case cgmBeginPictureMyElement: // begin picture
  4146. //        case cgmBeginPicture::myElement: // begin picture
  4147.  
  4148.     if (!contents) continue; // first element, OK
  4149.     else if (!next) { // new next picture
  4150.       next = new cgmPicture(metafile, myInput,
  4151.                 (cgmBeginPicture *) gotCmd, this);
  4152.       if (lastPtr) lastPtr->next = NULL;
  4153.       return 1; // done
  4154.     } else {
  4155.       myError("unexpected begin picture"); // should never happen
  4156.       return 0;
  4157.     }
  4158.         case cgmEndPictureMyElement: // end picture
  4159.     if (next) return 1; // don't need to go any farther
  4160.     else break;
  4161.         case cgmEndMetafileMyElement:
  4162.     if (lastPtr) lastPtr->next = NULL;
  4163.     return 1; // done
  4164.       } 
  4165.     }
  4166.     if (!contents) contents = gotCmd;
  4167.     lastPtr = gotCmd;
  4168.   } 
  4169.   if (lastPtr) lastPtr->next = NULL;
  4170.   return 0; // ran out of commands
  4171. }
  4172. ////
  4173. // set it aside as we go on to another picture
  4174. ////
  4175. void cgmPicture::setAside()
  4176. {
  4177.   baseCGM *myPtr, *nextPtr; // delete the main contents (save the BP)
  4178.   for (myPtr = contents; myPtr; myPtr = nextPtr) {
  4179.     nextPtr = myPtr->next;
  4180.     delete myPtr;
  4181.   }
  4182.   contents = NULL; // nothing there
  4183. }
  4184. ////
  4185. // now access to the state variables
  4186. ////
  4187. // the colour value extent
  4188. ////
  4189. const colrValueExtent *cgmPicture::colrExtent()
  4190. {
  4191.   return metafile->colrExtent();
  4192. }
  4193. ////
  4194. // return the scaling mode
  4195. ////
  4196. int cgmPicture::scalingMode() 
  4197. {
  4198.   return scalingCmd ? scalingCmd->mode : metafile->scalingMode();
  4199. }
  4200. ////
  4201. // return the scaling factor
  4202. ////
  4203. float cgmPicture::scalingFactor() 
  4204. {
  4205.   return scalingCmd ? scalingCmd->factor : metafile->scalingFactor();
  4206. }
  4207. ////
  4208. // return the colour selection mode
  4209. ////
  4210. int cgmPicture::colrMode() 
  4211. {
  4212.   return colrModeCmd ? colrModeCmd->mode : metafile->colrMode();
  4213. }
  4214. ////
  4215. // return the line width specification mode
  4216. ////
  4217. int cgmPicture::lineMode() 
  4218. {
  4219.   return lineModeCmd ? lineModeCmd->mode : metafile->lineMode();
  4220. }
  4221. ////
  4222. // return the marker size specification mode
  4223. ////
  4224. int cgmPicture::markerMode() 
  4225. {
  4226.   return markerModeCmd ? markerModeCmd->mode : metafile->markerMode();
  4227. }
  4228. ////
  4229. // return the edge width specification mode
  4230. ////
  4231. int cgmPicture::edgeMode() 
  4232. {
  4233.   return edgeModeCmd ? edgeModeCmd->mode : metafile->edgeMode();
  4234. }
  4235. ////
  4236. // return the vdc extent
  4237. ////
  4238. const vdcPts *cgmPicture::vdcExtent() const
  4239. {
  4240.   return vdcExtentCmd ? vdcExtentCmd->myPts : metafile->vdcExtent();
  4241. }
  4242. ////
  4243. // particular classes for the cgm state
  4244. ////
  4245. // the cgm file object, refHand usd as file ref#/handle by the mac/pc
  4246. // must be in this file since it needs case label constants at compile time
  4247. ////
  4248. cgmFile::cgmFile(const char *inName, short refHand) : basicInput(inName, refHand)
  4249. {
  4250.   metafile = NULL;
  4251.   inputHandler = NULL;
  4252.   if (inName) { // got a name, store
  4253.     nameSize = strlen(inName);
  4254.     inputName = new char[nameSize + 1];
  4255.     strcpy(inputName, inName);
  4256.   } else { // no name
  4257.     inputName = NULL;
  4258.     nameSize = 0;
  4259.   }
  4260.   if (!openedFile()) return; 
  4261.   ////
  4262.   // get the input handler
  4263.   if (!(inputHandler = getCgmInput())) return;
  4264. #if __MSDOS__
  4265.   if (hGlobalBuffer)
  4266.       {
  4267.       GlobalUnlock(hGlobalBuffer);
  4268.       GlobalFree(hGlobalBuffer);
  4269.       buffer = NULL;
  4270.       hGlobalBuffer = NULL;
  4271.       }
  4272. #endif
  4273.   ////
  4274.   // get the first command and parse it
  4275.   if (!inputHandler->getCmd()) { // no commands at all
  4276.     myError("no commands in file", inputName);
  4277.     return;
  4278.   }
  4279.   baseCGM *gotCmd = inputHandler->doCmd(NULL, NULL); // parse it
  4280.   if (!gotCmd) { // couldn't parse it
  4281.     myError("couldn't parse first command in", inputName);
  4282.     return;
  4283.   }
  4284.   ////
  4285.   // make sure it's a begin metafile
  4286.   if (!((gotCmd->cgmClass() == cgmDelimiter::myClass) &&
  4287.     (gotCmd->cgmElement() == cgmBeginMetafile::myElement))) { 
  4288.     myError("illegal first command", gotCmd->cgmName());
  4289.     return;
  4290.   }
  4291.   ////
  4292.   // create the metafile
  4293.   metafile = new cgmMetafile((cgmBeginMetafile *) gotCmd, inputHandler);
  4294.   ////
  4295.   // parse to the first begin picture
  4296.   baseCGM *lastPtr = gotCmd; // for initialization
  4297.   while(inputHandler->getCmd()) { // while we have commands
  4298.     gotCmd = inputHandler->doCmd(metafile, lastPtr); // parse it
  4299.     if (gotCmd) { // successfully parsed
  4300.       if ((gotCmd->cgmClass() == cgmDelimiter::myClass) &&
  4301.       (gotCmd->cgmElement() == cgmBeginPicture::myElement)) {
  4302.     if (lastPtr) lastPtr->next = NULL;
  4303.     gotCmd->prev = NULL; // terminate chain
  4304.     break; // done
  4305.       } else {
  4306.     if ((gotCmd->cgmClass() != cgmMetafileDescriptor::myClass) &&
  4307.         (gotCmd->cgmClass() != cgmEscape::myClass) &&
  4308.         (gotCmd->cgmClass() != cgmExternal::myClass))  {
  4309.       myError("illegal command in metafile descriptor area",
  4310.           gotCmd->cgmName());
  4311.     } 
  4312.       }
  4313.       lastPtr = gotCmd;
  4314.     } // successfully parsed
  4315.   } // successfully got
  4316.   // might have got first picture from index block
  4317.   if (!metafile->firstPic) {
  4318.     ////
  4319.     // get the first picture
  4320.     if (gotCmd && (gotCmd->cgmClass() == cgmDelimiter::myClass) &&
  4321.     (gotCmd->cgmElement() == cgmBeginPicture::myElement)) { // picture
  4322.       metafile->firstPic = new cgmPicture(metafile, inputHandler,
  4323.                       (cgmBeginPicture *)gotCmd);
  4324.     } else {
  4325.       myError("no first picture", inName);
  4326.       return;
  4327.     }
  4328.   }
  4329.   metafile->firstPic->readIn(); // read in first picture
  4330. }
  4331. ////
  4332. // destructor
  4333. ////
  4334. cgmFile::~cgmFile()
  4335. {
  4336.   if (inputName) delete inputName;
  4337.   if (inputHandler) delete inputHandler;
  4338. }
  4339. ////
  4340. // function to return the correct input handler
  4341. ////
  4342. cgmInput *cgmFile::getCgmInput()
  4343. {
  4344.   // try to figure out what type of file we have
  4345.   if (!getOffBytes(4)) { // need 4 bytes to identify NCAR files
  4346.     myError("couldn't get file header");
  4347.     return NULL;
  4348.   }
  4349.   // now see if we recognize them, try binary types first
  4350.   if ((((binaryInput *)this)->bufferClass()==cgmDelimiter::myClass) &&
  4351.       (((binaryInput *)this)->bufferElement()==cgmBeginMetafile::myElement)) {
  4352.      return new binaryInput(filePtr, frefHand); // regular binary
  4353.   } else if (buffer[0] == 1) {
  4354.      return new LANLInput(filePtr, frefHand); // LANL-style
  4355.   } else if ((buffer[0] == 's') && (buffer[1] == 'r')) {
  4356.      return new MilInput(filePtr, frefHand); // military-style
  4357.   } else if ((buffer[0] < 128) && (isprint(buffer[0])||isspace(buffer[0])) &&
  4358.          (buffer[1] < 128) && (isprint(buffer[1])||isspace(buffer[1]))) {
  4359.      return new clearInput(filePtr, frefHand); // clear text
  4360.   } else if ((buffer[2] == 52) && (buffer[3] == 0)) { // 52 = 3 << 4 + 4
  4361.      return new NCARInput(filePtr, frefHand); // NCAR file
  4362.   }
  4363.   else { // unknown
  4364.     char myString[60]; // should be enough
  4365.     sprintf(myString,  "header = [%d, %d, %d, %d]\n", (int) buffer[0],
  4366.         (int) buffer[1], (int) buffer[2], (int) buffer[3]);
  4367.     myError("unknown format CGM file", myString);
  4368.     return NULL;
  4369.   }
  4370. }
  4371. ////
  4372. // interpret the command in memory and return appropriate  CGM object
  4373. // this function needs to know some cgm constants
  4374. ////
  4375. baseCGM *cgmInput::doCmd(cgmContainer *inOwner, baseCGM *inPrev)
  4376. {
  4377.   baseCGM *gotCmd;
  4378.   for (int i=0; (i<cgmNoClasses) && !sameCmd(cgmNameArray[i]);  ++i);
  4379.   if (i>=cgmNoClasses) {
  4380.     if (!padCmd()) myError("unknown command", cmdSignature());
  4381.     return NULL;
  4382.   } 
  4383.   // only the begin metafile command can have no owner
  4384.   if (!inOwner &&
  4385.       !((cgmNameArray[i].myClass == cgmDelimiter::myClass) &&
  4386.     (cgmNameArray[i].myElement  == cgmBeginMetafile::myElement))) {
  4387.     myError("illegal first command", *cgmNameArray[i].myName);
  4388.     return NULL;
  4389.   } else gotCmd = cgmNameArray[i].fp(inOwner, this, inPrev);
  4390.   //
  4391.   // may need to mark this command for use in interpretation
  4392.   if (gotCmd->cgmClass() == cgmMetafileDescriptor::myClass) {
  4393.     switch (gotCmd->cgmElement()) {
  4394.      case cgmVdcTypeMyElement:
  4395.       vdcTypeCmd = (cgmVdcType *) gotCmd;
  4396.       break;
  4397.      case cgmIntegerPrecMyElement:
  4398.       intPrecCmd = (cgmIntegerPrec *) gotCmd;
  4399.       break;
  4400.      case cgmRealPrecMyElement:
  4401.       realPrecCmd = (cgmRealPrec *) gotCmd;
  4402.       break;
  4403.      case cgmIndexPrecMyElement:
  4404.       indexPrecCmd = (cgmIndexPrec *) gotCmd;
  4405.       break;
  4406.      case cgmColrPrecMyElement:
  4407.       colrPrecCmd = (cgmColrPrec *) gotCmd;
  4408.       break;
  4409.      case cgmColrIndexPrecMyElement:
  4410.       colrIndexPrecCmd = (cgmColrIndexPrec *) gotCmd;
  4411.       break;
  4412.     }
  4413.   } else if (gotCmd->cgmClass() == cgmControl::myClass) {
  4414.     switch (gotCmd->cgmElement()) {
  4415.      case cgmVdcIntegerMyElement:
  4416.         if (inOwner->mf()) { // metafile owner, set defaults
  4417.     defVdcIntPrecCmd = (cgmVdcInteger *) gotCmd;
  4418.         } else vdcIntPrecCmd = (cgmVdcInteger *) gotCmd;
  4419.      case cgmVdcRealMyElement:
  4420.       if (inOwner->mf()) { // metafile owner, set defaults
  4421.     defVdcRealPrecCmd = (cgmVdcReal *) gotCmd;
  4422.       } else vdcRealPrecCmd = (cgmVdcReal *) gotCmd;
  4423.     }
  4424.   } else if ((gotCmd->cgmClass() == cgmDelimiter::myClass) &&
  4425.           (gotCmd->cgmElement() == cgmBeginPicture::myElement)) {
  4426.     vdcIntPrecCmd = NULL;
  4427.     vdcRealPrecCmd = NULL;
  4428.   }
  4429.   return gotCmd;
  4430. }
  4431. ////
  4432. // binary input
  4433. ////
  4434. // get a set of defaults (the whole set is in the buffer aleady)
  4435. ////
  4436. cgmDefaults *binaryInput::getDefaults(cgmMetafile *inOwner)
  4437. {
  4438.   // make some room and copy over the contained commands
  4439.   if (tempBufferIndex || tempBufferSize) {
  4440.     myError("tempBuffer already in use");
  4441.     return NULL;
  4442.   }
  4443.   tempBufferSize = bIndex - aIndex;
  4444.   tempBufferIndex = 0;
  4445.   if (tempBufferSize <= 0) { // screwed up somewhere
  4446.     myError("no contents to binary Metafile Defaults");
  4447.     tempBufferSize = 0;
  4448.     return NULL; 
  4449.   }
  4450.   // move over the data
  4451.   tempBuffer = new unsigned char[tempBufferSize];
  4452.   for (int i=0; i<tempBufferSize; ++i) tempBuffer[i] = buffer[i + aIndex];
  4453.   baseCGM *lastPtr = NULL, *firstPtr = NULL, *gotCmd;
  4454.   ////
  4455.   // loop thru commands until end of defaults
  4456.   while((tempBufferIndex < tempBufferSize) && getCmd()) {
  4457.     gotCmd = doCmd(inOwner, lastPtr); // parse it
  4458.     ////
  4459.     if (!gotCmd) continue; // go on to next command
  4460.     ////
  4461.     // legal command for defaults replacement ?
  4462.     if ((gotCmd->cgmClass() != cgmPictureDescriptor::myClass) &&
  4463.     (gotCmd->cgmClass() != cgmControl::myClass) &&
  4464.     (gotCmd->cgmClass() != cgmAttribute::myClass)) {
  4465.       myError("illegal defaults replacement", gotCmd->cgmName());
  4466.       break; // maybe lost end of command
  4467.     } else {
  4468.       // take care of first, last ptr
  4469.       if (!firstPtr) firstPtr = gotCmd;
  4470.       lastPtr = gotCmd;
  4471.     }
  4472.   }
  4473.   delete tempBuffer;
  4474.   tempBuffer = NULL;
  4475.   tempBufferIndex = 0;
  4476.   tempBufferSize = 0;
  4477.   return new cgmDefaults(firstPtr);
  4478. }
  4479. ////
  4480. // clear text input
  4481. ////
  4482. // get a set of defaults
  4483. ////
  4484. cgmDefaults *clearInput::getDefaults(cgmMetafile *inOwner)
  4485. {
  4486.   baseCGM *lastPtr = NULL, *firstPtr = NULL, *gotCmd;
  4487.   ////
  4488.   // loop thru commands until end of defaults
  4489.   while(*getCmd() && !same(cgmMetafileDefaultsReplacement::endName)) { 
  4490.     gotCmd = doCmd(inOwner, lastPtr); // parse it
  4491.     ////
  4492.     if (!gotCmd) continue; // go on to next command
  4493.     ////
  4494.     // legal command for defaults replacement ?
  4495.     if ((gotCmd->cgmClass() != cgmPictureDescriptor::myClass) &&
  4496.     (gotCmd->cgmClass() != cgmControl::myClass) &&
  4497.     (gotCmd->cgmClass() != cgmAttribute::myClass)) {
  4498.       myError("illegal defaults replacement", gotCmd->cgmName());
  4499.       break; // maybe lost end of command
  4500.     } else {
  4501.       // take care of first, last ptr
  4502.       if (!firstPtr) firstPtr = gotCmd;
  4503.       lastPtr = gotCmd;
  4504.     }
  4505.   }
  4506.   return new cgmDefaults(firstPtr);
  4507. }
  4508. ////
  4509. // parsing info
  4510. ////
  4511. // set the size of the parsing table, has to be here for the MAC
  4512. ////
  4513. const int cgmInput::cgmNoClasses = 
  4514. cgmEndPicture::myElement + cgmCharacterCodingAnnouncer::myElement +
  4515. cgmBackgroundColr::myElement + cgmClip::myElement +
  4516. cgmEllipArcClose::myElement + cgmASF::myElement +
  4517. cgmEscapeElement::myElement + cgmApplData::myElement;
  4518.  
  4519. void cgmDefaults::display(baseDisplay *inDisplay) // display the elements
  4520.      {for (baseCGM *myPtr=contents(); myPtr; myPtr=myPtr->next)
  4521.          myPtr->display(inDisplay);}
  4522.  
  4523. void cgmMetafile::displayDefaults(baseDisplay *inDisplay) const // display the defaults
  4524.      {for (cgmDefaults *myPtr=myDefaults; myPtr; myPtr=myPtr->next())
  4525.          myPtr->display(inDisplay);}
  4526.