Esempio n. 1
0
static void 
write_property(FILE *fob, mxArray *prop)
{
   mxArray *pa;
   double *pd;
   int k,len,np;
   int16_t attr;
   char value[VLEN];


   /* get number of attribute / value pairs */
   np = mxGetM(prop) * mxGetN(prop);

   for (k=0; k<np; k++) {
      pa = mxGetField(prop, k, "attr");
      pd = (double *)mxGetData(pa);
      attr = (int16_t)pd[0];
      write_record_hdr(fob, PROPATTR, sizeof(int16_t));
      write_word(fob, attr);

      pa = mxGetField(prop, k, "name");
      mxGetString(pa, value, VLEN);
      len = strlen(value);
      if (len%2)
	 len += 1;
      write_record_hdr(fob, PROPVALUE, len);
      write_string(fob, value, len);
   }
}
Esempio n. 2
0
void 
mexFunction(int nlhs, mxArray *plhs[], 
	    int nrhs, const mxArray *prhs[])
{
   FILE *fob;          /* file object pointer */
   date_t cdate;       /* creation date */
   date_t mdate;       /* modification date */
   char sname[NLEN];   /* structure name */
   int slen;           /* string length */

   /* check argument number */
   if (nrhs != 3) {
      mexErrMsgTxt("3 input arguments expected.");
   }
   
   /* get file handle argument */
   fob = get_file_ptr((mxArray *)prhs[0]);

   /* BGNSTR record */
   if ( write_record_hdr(fob, BGNSTR, 2*sizeof(date_t)) )
      mexErrMsgTxt("failed to write BGNSTR record.");

   /* BGNSTR creation date */
   now(cdate);
   if ( write_word_n(fob, cdate, 6) ) /* NOTE: changes byte order in cdate */
      mexErrMsgTxt("failed to write BGNSTR record (cdate).");

   /* BGNSTR modification date */
   now(mdate);
   if ( write_word_n(fob, mdate, 6) ) /* same as cdate */
      mexErrMsgTxt("failed to write BGNSTR record (mdate).");
   
   /* STRNAME record */
   mxGetString(prhs[1], sname, NLEN-2);
   slen = mxGetN(prhs[1]);  /* string length */
   if (slen > 32) {
      mexPrintf("\nStructure name %s exceeds 32 characters\n\n", sname);
      mexErrMsgTxt("structure name too long.");     
   }
   if (slen % 2)          /* string length is odd */
      slen += 1;
   if ( write_record_hdr(fob, STRNAME, slen) )
      mexErrMsgTxt("failed to write STRNAME record.");
   if ( write_string(fob, sname, slen) )
      mexErrMsgTxt("failed to write STRNAME record (sname).");
}
Esempio n. 3
0
static void 
write_box(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *field, *propfield, *internal;
   double *pd;
   int32_t xy[10];
   int m;
   element_t box;

   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (box) :  missing internal data field.");
   memcpy(&box, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* BOX */
   write_record_hdr(fob, BOX, 0);

   /* ELFLAGS */
   if ( box.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, box.elflags);
   }

   /* PLEX */
   if ( box.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, box.plex);
   }

   /* LAYER */
   write_record_hdr(fob, LAYER, sizeof(uint16_t));
   write_word(fob, box.layer);
 
   /* BOXTYPE */
   write_record_hdr(fob, BOXTYPE, sizeof(uint16_t));
   write_word(fob, box.dtype);
   
   /* XY */
   if ( get_field_ptr(data, "xy", &field) ) {
      pd = (double *)mxGetData(field);
      m = mxGetM(field); 
      if (m < 4 || m > 5)
	 mexErrMsgTxt("gds_write_element (box) :  must supply 4 or 5 vertices.");
      scale_trans(pd, xy, m, uu_to_dbu);
      if (m == 4) { /* polygon is not closed */
	 xy[8] = xy[0]; xy[9] = xy[1];
      }
      write_record_hdr(fob, XY, 10*sizeof(int32_t));
      write_int_n(fob, xy, 10);
   }
   else   
      mexErrMsgTxt("gds_write_element (box) :  missing or empty xy field.");
   
   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
}
Esempio n. 4
0
static void 
write_node(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *field, *propfield, *internal;
   double *pd;
   int m,n;
   element_t node;

   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (node) :  missing internal data field.");
   memcpy(&node, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* NODE */
   write_record_hdr(fob, NODE, 0);

   /* ELFLAGS */
   if ( node.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, node.elflags);
   }

   /* PLEX */
   if ( node.has & HAS_PLEX ) {
      write_record_hdr(fob, ELFLAGS, sizeof(int32_t));
      write_int(fob, node.plex);
   }

   /* LAYER */
   write_record_hdr(fob, LAYER, sizeof(uint16_t));
   write_word(fob, node.layer);

   /* NODETYPE */
   write_record_hdr(fob, NODETYPE, sizeof(uint16_t));
   write_word(fob, node.dtype);
   
   /* XY */
   if ( get_field_ptr(data, "xy", &field) ) {
      pd = (double *)mxGetData(field);
      m = mxGetM(field);
      if (m > 1024)
	 mexErrMsgTxt("more than 1024 vertices in node");
      n = mxGetN(field);
      scale_trans(pd, xybuf, m, uu_to_dbu);
      write_record_hdr(fob, XY, m*n*sizeof(int32_t));
      write_int_n(fob, xybuf, m*n);
   }
   else   
      mexErrMsgTxt("gds_write_element (node) :  missing xy field.");
   
   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
}
Esempio n. 5
0
static void 
write_property(FILE *fob, mxArray *prop)
{
   mxArray *pa;
   double *pd;
   int k,len,np;
   int16_t attr;
   char value[VLEN];


   /* get number of attribute / value pairs */
   np = mxGetM(prop) * mxGetN(prop);

   for (k=0; k<np; k++) {
      pa = mxGetField(prop, k, "attr");
      if (pa == NULL) {
	 mexErrMsgTxt("Element property has no field named \"attr\".");
      }
      if ( !mxIsNumeric(pa) ) {
	  mexErrMsgTxt("Element property attribute must be a real number.");
      }
      pd = (double *)mxGetData(pa);
      attr = (int16_t)pd[0];
      write_record_hdr(fob, PROPATTR, sizeof(int16_t));
      write_word(fob, attr);

      pa = mxGetField(prop, k, "name");
      if (pa == NULL) {
	 mexErrMsgTxt("Element property has no field named \"name\".");
      }
      if ( !mxIsChar(pa) ) {
	 mexErrMsgTxt("Element property name (value) must be a string.");
      }
      mxGetString(pa, value, VLEN);
      len = strlen(value);
      if (len%2)
	 len += 1;
      write_record_hdr(fob, PROPVALUE, len);
      write_string(fob, value, len);
   }
}
Esempio n. 6
0
static void 
write_text(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *field, *propfield, *internal;
   double *pd;
   int32_t xy[2];
   int tlen;
   char txt[TXTLEN];
   element_t text;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (text) :  missing internal data field.");
   memcpy(&text, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* TEXT */
   write_record_hdr(fob, TEXT, 0);

   /* ELFLAGS */
   if ( text.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, text.elflags);
   }

   /* PLEX */
   if ( text.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, text.plex);
   }

   /* LAYER */
   write_record_hdr(fob, LAYER, sizeof(uint16_t));
   write_word(fob, text.layer);

   /* TEXTTYPE */
   write_record_hdr(fob, TEXTTYPE, sizeof(uint16_t));
   write_word(fob, text.dtype);

   /* PRESENTATION */
   if ( text.has & HAS_PRESTN ) {
      write_record_hdr(fob, PRESENTATION, sizeof(uint16_t));
      write_word(fob, text.present);
   }	

   /* PATHTYPE */
   if ( text.has & HAS_PTYPE ) {
      write_record_hdr(fob, PATHTYPE, sizeof(uint16_t));
      write_word(fob, text.ptype);
   }
   
   /* WIDTH */
   if ( text.has & HAS_WIDTH ) {
      write_record_hdr(fob, WIDTH, sizeof(int32_t));
      write_int(fob, text.width);
   }

   /* STRANS */
   if ( text.has & HAS_STRANS ) {
      write_record_hdr(fob, STRANS, sizeof(uint16_t));
      write_word(fob, text.strans.flags);
      if ( text.has & HAS_MAG && text.strans.mag != 1.0) {
	 write_record_hdr(fob, MAG, 8);
	 write_real8(fob, text.strans.mag);
      }
      if ( text.has & HAS_ANGLE && text.strans.angle != 0.0) {
	 write_record_hdr(fob, ANGLE, 8);
	 write_real8(fob, text.strans.angle);
      }
   }

   /* XY */
   if ( get_field_ptr(data, "xy", &field) ) {
      pd = (double *)mxGetData(field);
      scale_trans(pd, xy, 1, uu_to_dbu);
      write_record_hdr(fob, XY, 2*sizeof(int32_t));
      write_int_n(fob, xy, 2);
   }
   else   
      mexErrMsgTxt("gds_write_element (text) :  missing or empty xy field.");

   /* STRING */   
   if ( get_field_ptr(data, "text", &field) ) {
      mxGetString(field, txt, TXTLEN);
      tlen = strlen(txt);
      if (tlen % 2)
	 tlen += 1;
      if (tlen > 512)
	 mexErrMsgTxt("gds_write_element (text) :  text must have <= 512 chars.");
      write_record_hdr(fob, STRING, tlen);
      write_string(fob, txt, tlen);
   }
   else   
      mexErrMsgTxt("gds_write_element (text) :  missing text field.");

   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
}
Esempio n. 7
0
static void 
write_aref(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *field, *propfield, *internal;
   double *pd;
   int32_t xy[6];
   int mxy,nxy=0,nlen;
   element_t aref;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (aref) :  missing internal data field.");
   memcpy(&aref, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* AREF */
   write_record_hdr(fob, AREF, 0);

   /* ELFLAGS */
   if ( aref.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, aref.elflags);
   }

   /* PLEX */
   if ( aref.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, aref.plex);
   }

   /* SNAME */   
   nlen = strlen(aref.sname);
   if ( !nlen )
      mexErrMsgTxt("gds_write_element (aref) :  name of referenced structure missing.");
   if (nlen % 2)
      nlen += 1;
   if (nlen > 32)
      mexErrMsgTxt("gds_write_element (aref) :  structure name must have <= 32 chars.");
   write_record_hdr(fob, SNAME, nlen);
   write_string(fob, aref.sname, nlen);

   /* STRANS */
   if ( aref.has & HAS_STRANS ) {
      write_record_hdr(fob, STRANS, sizeof(uint16_t));
      write_word(fob, aref.strans.flags);
      if ( aref.has & HAS_MAG && aref.strans.mag != 1.0) {
	 write_record_hdr(fob, MAG, 8);
	 write_real8(fob, aref.strans.mag);
      }
      if ( aref.has & HAS_ANGLE && aref.strans.angle != 0.0) {
	 write_record_hdr(fob, ANGLE, 8);
	 write_real8(fob, aref.strans.angle);
      }
   }

   /* COLROW */
   if ( !aref.nrow )
      mexErrMsgTxt("gds_write_element (aref) :  number of rows is 0; must be > 0.");
   if ( !aref.ncol )
      mexErrMsgTxt("gds_write_element (aref) :  number of columns is 0; must be > 0.");
   write_record_hdr(fob, COLROW, 2*sizeof(uint16_t));
   write_word(fob, aref.ncol);
   write_word(fob, aref.nrow);
   
   /* XY */
   if ( get_field_ptr(data, "xy", &field) ) {
      pd = (double *)mxGetData(field);
      mxy = mxGetM(field);
      nxy = mxGetN(field);
      if ( (mxy != 3) || (nxy != 2) )
	 mexErrMsgTxt("gds_write_element (aref) :  xy must be 3x2 matrix.");
      scale_trans(pd, xy, mxy, uu_to_dbu);
      write_record_hdr(fob, XY, mxy*nxy*sizeof(int32_t));
      write_int_n(fob, xy, 6);
   }
   else   
      mexErrMsgTxt("gds_write_element (aref) :  missing or empty xy field.");

   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
} 
Esempio n. 8
0
static void 
write_compound_sref(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *internal, *propfield, *pxy;
   double *pdxy=NULL;
   int ncxy;      /* number of compound xy records */
   int mrem;      /* remainder in last record */
   int mxy=0;
   int k,nlen;
   element_t sref;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (sref) :  missing internal data field.");
   memcpy(&sref, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* number of sref locations contained in compound element */
   if ( get_field_ptr(data, "xy", &pxy) ) {
      mxy = mxGetM(pxy);
      pdxy = (double *)mxGetData(pxy);
   }
   else   
      mexErrMsgTxt("gds_write_element (sref) :  missing or empty xy field.");

   /* 
    * write sref elements as non-standard compound element
    */
   /* SREF */
   write_record_hdr(fob, SREF, 0);

   /* ELFLAGS */
   if ( sref.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, sref.elflags);
   }

   /* PLEX */
   if ( sref.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, sref.plex);
   }

   /* SNAME */
   nlen = strlen(sref.sname);
   if ( !nlen )
      mexErrMsgTxt("gds_write_element (sref) :  name of referenced structure missing.");
   if (nlen % 2)
      nlen += 1;
   if (nlen > 32)
      mexErrMsgTxt("gds_write_element (sref) :  structure name must have <= 32 chars.");
   write_record_hdr(fob, SNAME, nlen);
   write_string(fob, sref.sname, nlen);

   /* STRANS */
   if ( sref.has & HAS_STRANS ) {
      write_record_hdr(fob, STRANS, sizeof(uint16_t));
      write_word(fob, sref.strans.flags);
      if ( sref.has & HAS_MAG && sref.strans.mag != 1.0) {
	 write_record_hdr(fob, MAG, 8);
	 write_real8(fob, sref.strans.mag);
      }
      if ( sref.has & HAS_ANGLE && sref.strans.angle != 0.0) {
	 write_record_hdr(fob, ANGLE, 8);
	 write_real8(fob, sref.strans.angle);
      }
   }

   /* multiple large XY records */
   ncxy = mxy / MAXVERTEXNUM;
   mrem = mxy % MAXVERTEXNUM;
   for (k=0; k<ncxy; k++) {
      scale_trans(pdxy+2*k*MAXVERTEXNUM, xybuf, MAXVERTEXNUM, uu_to_dbu);
      write_record_hdr(fob, XY, (uint16_t)(MAXVERTEXNUM*2*sizeof(int32_t)));
      write_int_n(fob, xybuf, 2*MAXVERTEXNUM);
   }
   if (mrem) {
      scale_trans(pdxy+2*ncxy*MAXVERTEXNUM, xybuf, mrem, uu_to_dbu);
      write_record_hdr(fob, XY, 2*mrem*sizeof(int32_t));
      write_int_n(fob, xybuf, 2*mrem);
   }

   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
} 
Esempio n. 9
0
static void 
write_sref(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *internal, *propfield, *pxy;
   double *pdxy=NULL;
   int32_t xy[2];
   int mxy=0;
   int k,nlen;
   element_t sref;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (sref) :  missing internal data field.");
   memcpy(&sref, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* number of sref locations contained in compound element */
   if ( get_field_ptr(data, "xy", &pxy) ) {
      mxy = mxGetM(pxy);
      pdxy = (double *)mxGetData(pxy);
   }
   else   
      mexErrMsgTxt("gds_write_element (sref) :  missing or empty xy field.");

   /* 
    * write out the individual sref elements 
    */
   for (k=0; k<mxy; k++) {

      /* SREF */
      write_record_hdr(fob, SREF, 0);

      /* ELFLAGS */
      if ( sref.has & HAS_ELFLAGS ) {
	 write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
	 write_word(fob, sref.elflags);
      }

      /* PLEX */
      if ( sref.has & HAS_PLEX ) {
	 write_record_hdr(fob, PLEX, sizeof(int32_t));
	 write_int(fob, sref.plex);
      }

      /* SNAME */
      nlen = strlen(sref.sname);
      if ( !nlen )
	 mexErrMsgTxt("gds_write_element (sref) :  name of referenced structure missing.");
      if (nlen % 2)
	 nlen += 1;
      if (nlen > 32)
	 mexErrMsgTxt("gds_write_element (sref) :  structure name must have <= 32 chars.");
      write_record_hdr(fob, SNAME, nlen);
      write_string(fob, sref.sname, nlen);

      /* STRANS */
      if ( sref.has & HAS_STRANS ) {
	 write_record_hdr(fob, STRANS, sizeof(uint16_t));
	 write_word(fob, sref.strans.flags);
	 if ( sref.has & HAS_MAG && sref.strans.mag != 1.0) {
	    write_record_hdr(fob, MAG, 8);
	    write_real8(fob, sref.strans.mag);
	 }
	 if ( sref.has & HAS_ANGLE && sref.strans.angle != 0.0) {
	    write_record_hdr(fob, ANGLE, 8);
	    write_real8(fob, sref.strans.angle);
	 }
      }

      /* XY */
      xy[0] = floor(0.5 + pdxy[k]     * uu_to_dbu);
      xy[1] = floor(0.5 + pdxy[k+mxy] * uu_to_dbu);
      write_record_hdr(fob, XY, 2*sizeof(int32_t));
      write_int_n(fob, xy, 2);
   
      /* Property */
      if ( get_field_ptr(data, "prop", &propfield) )
	 write_property(fob, propfield);

      /* ENDEL */
      write_record_hdr(fob, ENDEL, 0);
   }
} 
Esempio n. 10
0
static void 
write_compound_path(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *propfield, *caxy, *pa, *internal;
   double *pd;
   int m,n,nxy=0,kxy;
   element_t path;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (path) :  missing internal data field.");
   memcpy(&path, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* number of paths contained in compound element */
   if ( get_field_ptr(data, "xy", &caxy) ) {
      nxy = mxGetNumberOfElements(caxy);
   }
   else   
      mexErrMsgTxt("gds_write_element (path) :  missing or empty xy field.");

   /* 
    * write out one path element with multiple XY records 
    */
   /* PATH */
   write_record_hdr(fob, PATH, 0);

   /* ELFLAGS */
   if ( path.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, path.elflags);
   }
      
   /* PLEX */
   if ( path.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, path.plex);
   }

   /* LAYER */
   write_record_hdr(fob, LAYER, sizeof(uint16_t));
   write_word(fob, path.layer);

   /* DATATYPE */
   write_record_hdr(fob, DATATYPE, sizeof(uint16_t));
   write_word(fob, path.dtype);
   
   /* PATHTYPE */
   if ( path.has & HAS_PTYPE ) {
      write_record_hdr(fob, PATHTYPE, sizeof(uint16_t));
      write_word(fob, path.ptype);
   }
   
   /* WIDTH */
   if ( path.has & HAS_WIDTH ) {
      write_record_hdr(fob, WIDTH, sizeof(int32_t));
      write_int(fob, (int32_t)floor(path.width * uu_to_dbu + 0.5));
   }
      
      /* Path extensions */
   if (path.has & HAS_PTYPE && path.ptype == 4) {
      if ( path.has & HAS_BGNEXTN ) {
	 write_record_hdr(fob, BGNEXTN, sizeof(int32_t));
	 write_int(fob, (int32_t)floor(path.bgnextn * uu_to_dbu + 0.5));
      }
      if ( path.has & HAS_ENDEXTN ) {
	 write_record_hdr(fob, ENDEXTN, sizeof(int32_t));
	 write_int(fob, (int32_t)floor(path.endextn * uu_to_dbu + 0.5));
      }
   }
   
   /* XY */
   for (kxy=0; kxy<nxy; kxy++) {
      pa = mxGetCell(caxy, kxy);
      m = mxGetM(pa);
      if (m > 8192)
	 mexErrMsgTxt("more than 8192 vertices in path");
      n = mxGetN(pa);
      pd = (double *)mxGetData(pa);
      scale_trans(pd, xybuf, m, uu_to_dbu);
      write_record_hdr(fob, XY, n*m*sizeof(int32_t));
      write_int_n(fob, xybuf, n*m);
   }

   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
}
Esempio n. 11
0
static void 
write_compound_boundary(FILE *fob, mxArray *data, double uu_to_dbu)
{
   mxArray *propfield, *caxy, *pa, *internal;
   double *pd;
   int m,n,nxy=0,kxy;
   element_t bnd;


   /* internal structure */
   if ( !get_field_ptr(data, "internal", &internal) )
      mexErrMsgTxt("gds_write_element (boundary) :  missing internal data field.");
   memcpy(&bnd, (int32_t *)mxGetData(internal), sizeof(element_t));

   /* number of boundaries contained in compound element */
   if ( get_field_ptr(data, "xy", &caxy) ) {
      nxy = mxGetNumberOfElements(caxy);
   }
   else   
      mexErrMsgTxt("gds_write_element (boundary) :  missing or empty xy field.");

   /* 
    * write one compound boundary element with multiple XY records 
    */
   /* BOUNDARY */
   write_record_hdr(fob, BOUNDARY, 0);

   /* ELFLAGS */
   if ( bnd.has & HAS_ELFLAGS ) {
      write_record_hdr(fob, ELFLAGS, sizeof(uint16_t));
      write_word(fob, bnd.elflags);
   }

   /* PLEX */
   if ( bnd.has & HAS_PLEX ) {
      write_record_hdr(fob, PLEX, sizeof(int32_t));
      write_int(fob, bnd.plex);
   }

   /* LAYER */
   write_record_hdr(fob, LAYER, sizeof(uint16_t));
   write_word(fob, bnd.layer);

   /* DATATYPE */
   write_record_hdr(fob, DATATYPE, sizeof(uint16_t));
   write_word(fob, bnd.dtype);
   
   /* XY */
   for (kxy=0; kxy<nxy; kxy++) {
      pa = mxGetCell(caxy, kxy);
      m = mxGetM(pa);
      if (m > 8191)
	 mexErrMsgTxt("more than 8191 vertices in boundary");
      n = mxGetN(pa);
      pd = (double *)mxGetData(pa);
      scale_trans(pd, xybuf, m, uu_to_dbu);
      if ( (xybuf[0]!=xybuf[m*n-2]) || (xybuf[1]!=xybuf[m*n-1]) ) {
	 if (m+1 > 8191)
	    mexErrMsgTxt("more than 8191 vertices in boundary");
 	 xybuf[m*n]   = xybuf[0];  /* close polygon */
	 xybuf[m*n+1] = xybuf[1];
	 m+=1;
      }
      write_record_hdr(fob, XY, m*n*sizeof(int32_t));
      write_int_n(fob, xybuf, m*n);
   }
   
   /* Property */
   if ( get_field_ptr(data, "prop", &propfield) )
      write_property(fob, propfield);

   /* ENDEL */
   write_record_hdr(fob, ENDEL, 0);
}