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);
}
static void 
set_ext(element_t *pe, mxArray *val)
{
   mxArray *pa;    /* pointer to array */
   double *pd;     /* pointer to data */

   if ( pe->kind != GDS_PATH )
      mexErrMsgTxt("set_element_data :  element has no path extension properties.");
   if ( get_field_ptr(val, "beg", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->bgnextn = (float)pd[0];
      if ( (int)pe->bgnextn )
	 pe->has |= HAS_BGNEXTN;
      else
	 pe->has &= ~HAS_BGNEXTN;
   }
   else
      mexErrMsgTxt("set_element_data :  beg field missing in ext structure.");
   if ( get_field_ptr(val, "end", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->endextn = (float)pd[0];
      if ( (int)pe->endextn )
	 pe->has |= HAS_ENDEXTN;
      else
	 pe->has &= ~HAS_ENDEXTN;
   }
   else
      mexErrMsgTxt("set_element_data :  end field missing in ext structure.");
}
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);
}
static void 
set_adim(element_t *pe, mxArray *val)
{
   mxArray *pa;    /* pointer to array */
   double *pd;     /* pointer to data */
   
   if ( pe->kind != GDS_AREF )
      mexErrMsgTxt("set_element_data :  element has no adim property.");
   if ( get_field_ptr(val, "col", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->ncol = (uint16_t)pd[0];
   }
   else
      mexErrMsgTxt("set_element_data :  col field missing in adim structure.");
   
   if ( get_field_ptr(val, "row", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->nrow = (uint16_t)pd[0];
   }
   else
      mexErrMsgTxt("set_element_data :  row field missing in adim structure.");
}
Exemple #5
0
int flatcc_verify_struct_as_nested_root(flatcc_table_verifier_descriptor_t *td,
        voffset_t id, int required, const char *fid, uint16_t align, size_t size)
{
    const uoffset_t *buf;
    uoffset_t bufsiz;

    check_result(flatcc_verify_vector_field(td, id, required, align, 1, FLATBUFFERS_COUNT_MAX(1)));
    if (0 == (buf = get_field_ptr(td, id))) {
        return flatcc_verify_ok;
    }
    buf = (const uoffset_t *)((size_t)buf + read_uoffset(buf, 0));
    bufsiz = read_uoffset(buf, 0);
    ++buf;
    return flatcc_verify_struct_as_root(buf, bufsiz, fid, align, size);
}
Exemple #6
0
int flatcc_verify_table_as_nested_root(flatcc_table_verifier_descriptor_t *td,
        voffset_t id, int required, const char *fid,
        uint16_t align, flatcc_table_verifier_f tvf)
{
    const uoffset_t *buf;
    uoffset_t bufsiz;

    check_result(flatcc_verify_vector_field(td, id, required, align, 1, FLATBUFFERS_COUNT_MAX(1)));
    if (0 == (buf = get_field_ptr(td, id))) {
        return flatcc_verify_ok;
    }
    buf = (const uoffset_t *)((size_t)buf + read_uoffset(buf, 0));
    bufsiz = read_uoffset(buf, 0);
    ++buf;
    /*
     * Don't verify nested buffers identifier - information is difficult to get and
     * might not be what is desired anyway. User can do it later.
     */
    check_result(flatcc_verify_buffer_header(buf, bufsiz, fid));
    return verify_table(buf, bufsiz, 0, read_uoffset(buf, 0), td->ttl, tvf);
}
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);
}
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);
} 
void
mexFunction(int nlhs, mxArray *plhs[],
            int nrhs, const mxArray *prhs[])
{
   FILE *fob;
   mxArray *internal;
   element_t *pe;
   double *pd;
   int compound;
   double uu_to_dbu;

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

   /* get unit conversion factor user units --> database units */
   pd = (double *)mxGetData(prhs[2]);
   uu_to_dbu = pd[0];

   /* decide what to do */
   if ( !get_field_ptr((mxArray *)prhs[1], "internal", &internal) )
      mexErrMsgTxt("gds_write_element :  missing internal data field.");
   pe = (element_t *)mxGetData(internal);

   switch (pe->kind) {
     
      case GDS_BOUNDARY:
	 pd = (double *)mxGetData(prhs[3]); /* compound */
	 compound = (int)pd[0];
	 if ( compound )
	    write_compound_boundary(fob, (mxArray *)prhs[1], uu_to_dbu);
	 else
	    write_boundary(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_PATH:
	 pd = (double *)mxGetData(prhs[3]); /* compound */
	 compound = (int)pd[0];
	 if ( compound )
	    write_compound_path(fob, (mxArray *)prhs[1], uu_to_dbu);
	 else
	    write_path(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_SREF:
	 pd = (double *)mxGetData(prhs[3]); /* compound */
	 compound = (int)pd[0];
	 if ( compound )
	    write_compound_sref(fob, (mxArray *)prhs[1], uu_to_dbu);
	 else
	    write_sref(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_AREF:
	 write_aref(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_TEXT:
	 write_text(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_NODE:
	 write_node(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      case GDS_BOX:
	 write_box(fob, (mxArray *)prhs[1], uu_to_dbu);
	 break;

      default:
	 mexErrMsgTxt("gds_write_element :  unknown element type.");
   }
}
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);
} 
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);
   }
} 
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);
}
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);
}
static void 
set_strans(element_t *pe, mxArray *val)
{
   mxArray *pa;    /* pointer to array */
   double *pd;     /* pointer to data */

   if (pe->kind != GDS_SREF && pe->kind != GDS_AREF && pe->kind != GDS_TEXT)
      mexErrMsgTxt("set_element_data :  element has no strans property.");

   if ( get_field_ptr(val, "reflect", &pa) ) {
      pd = (double *)mxGetData(pa);
      if ( (mxLogical)pd[0] ) {
	 pe->strans.flags |= 1 << 15;
	 pe->has |= HAS_STRANS;
      }
      else {
	 pe->strans.flags &= ~(1 << 15);
	 if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE))
	    pe->has &= ~HAS_STRANS;
      }
   }

   if ( get_field_ptr(val, "absmag", &pa) ) {
      pd = (double *)mxGetData(pa);
      if ( (mxLogical)pd[0] ) {
	 pe->strans.flags |= 1 << 2;
	 pe->has |= HAS_STRANS;
      }
      else {
	 pe->strans.flags &= ~(1 << 2);
	 if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE))
	    pe->has &= ~HAS_STRANS;
      }
   }

   if ( get_field_ptr(val, "absang", &pa) ) {
      pd = (double *)mxGetData(pa);
      if ( (mxLogical)pd[0] ) {
	 pe->strans.flags |= 1 << 1;
	 pe->has |= HAS_STRANS;
      }
      else {
	 pe->strans.flags &= ~(1 << 1);
	 if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE))
	    pe->has &= ~HAS_STRANS;
      }
   }

   if ( get_field_ptr(val, "mag", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->strans.mag = pd[0];
      if (pe->strans.mag != 1.0) {
	 pe->has |= HAS_MAG;
	 pe->has |= HAS_STRANS;
      }
      else {
	 pe->has &= ~HAS_MAG;
	 if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE))
	    pe->has &= ~HAS_STRANS;
      }
   }

   if ( get_field_ptr(val, "angle", &pa) ) {
      pd = (double *)mxGetData(pa);
      pe->strans.angle = pd[0];
      if (pe->strans.angle != 0.0) {
	 pe->has |= HAS_ANGLE;
	 pe->has |= HAS_STRANS;
      }
      else {
	 pe->has &= ~HAS_ANGLE;
	 if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE))
	    pe->has &= ~HAS_STRANS;
      }
   }

      /* check if HAS_STRANS can be cleared */
   if ( !pe->strans.flags && !(pe->has & HAS_MAG) && !(pe->has & HAS_ANGLE) )
      pe->has &= ~HAS_STRANS;
}