• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* drawf  DrawFile functions */
2 
3 #include "oslib/os.h"
4 #include "oslib/osfile.h"
5 #include "oslib/drawfile.h"
6 #include "Python.h"
7 
8 #include <limits.h>
9 
10 #define PyDrawF_Check(op) ((op)->ob_type == &PyDrawFType)
11 #define HDRSIZE 40
12 #define GRPHDRSIZE 36
13 #define DRAWTYPE 0xaff
14 #define NEXT(d) ((drawfile_object*)((char*)(d)+(d)->size))
15 
16 typedef struct
17 { PyObject_HEAD
18   drawfile_diagram *drawf;
19   int size; /*length in bytes*/
20   int nobjs;  /* no of objects */
21 } PyDrawFObject;
22 
23 typedef struct dheader
24 {  char tag [4];
25    int major_version;
26    int minor_version;
27    char source [12];
28    os_box bbox;
29 } dheader;
30 
31 static PyObject *DrawFError; /* Exception drawf.error */
32 static os_error *e;
33 static PyTypeObject PyDrawFType;
34 
35 static dheader header=
36 { {'D','r','a','w'},
37   201,0,
38   {'P','y','t','h','o','n',' ',' ',' ',' ',' ',' '},
39   {INT_MAX,INT_MAX,INT_MIN,INT_MIN}
40 };
41 
drawf_oserror(void)42 static PyObject *drawf_oserror(void)
43 { PyErr_SetString(DrawFError,e->errmess);
44   return 0;
45 }
46 
drawf_error(char * s)47 static PyObject *drawf_error(char *s)
48 { PyErr_SetString(DrawFError,s);
49   return 0;
50 }
51 
52 /* DrawFile commands */
53 
countobjs(PyDrawFObject * pd)54 static void countobjs(PyDrawFObject *pd)
55 { int k=0,q;
56   drawfile_diagram *dd=pd->drawf;
57   drawfile_object *d=dd->objects;
58   char *end=(char*)dd+pd->size;
59   pd->nobjs=-1;
60   while((char*)d<end)
61   { k++;
62     q=d->size;
63     if(q<=0||q&3) return ;
64     d=NEXT(d);
65   }
66   if ((char*)d==end) pd->nobjs=k;
67 }
68 
findobj(PyDrawFObject * pd,Py_ssize_t n)69 static drawfile_object *findobj(PyDrawFObject *pd,Py_ssize_t n)
70 { drawfile_diagram *dd=pd->drawf;
71   drawfile_object *d=dd->objects;
72   for(;n>0;n--) d=NEXT(d);
73   return d;
74 }
75 
new(int size)76 static PyDrawFObject* new(int size)
77 { PyDrawFObject *b=PyObject_NEW(PyDrawFObject,&PyDrawFType);
78   if(!b) return NULL;
79   size+=HDRSIZE;
80   b->drawf=malloc(size);
81   if(!b->drawf)
82   { Py_DECREF(b);
83     return (PyDrawFObject*)PyErr_NoMemory();
84   }
85   b->size=size;
86   return b;
87 }
88 
extend(os_box * b,os_box * c)89 static void extend(os_box *b,os_box *c)
90 { if(b->x0>c->x0) b->x0=c->x0;
91   if(b->y0>c->y0) b->y0=c->y0;
92   if(b->x1<c->x1) b->x1=c->x1;
93   if(b->y1<c->y1) b->y1=c->y1;
94 }
95 
DrawF_New(PyObject * self,PyObject * args)96 static PyObject *DrawF_New(PyObject *self,PyObject *args)
97 { PyDrawFObject *b;
98   if(!PyArg_ParseTuple(args,"")) return NULL;
99   b=new(0);
100   if(!b) return NULL;
101   *((dheader*)b->drawf)=header;
102   b->nobjs=0;
103   return (PyObject *)b;
104 }
105 
DrawF_Load(PyObject * self,PyObject * args)106 static PyObject *DrawF_Load(PyObject *self,PyObject *args)
107 { int size;
108   char *fname;
109   PyDrawFObject *b;
110   fileswitch_object_type ot;
111   if(!PyArg_ParseTuple(args,"s",&fname)) return NULL;
112   e=xosfile_read_no_path(fname,&ot,0,0,&size,0);
113   if(e) return drawf_oserror();
114   size-=HDRSIZE;
115   if(ot!=osfile_IS_FILE||size<0||size&3) return drawf_error("Bad draw file");
116   b=new(size);
117   if(!b) return NULL;
118   e=xosfile_load_stamped_no_path(fname,(byte*)(b->drawf),0,0,0,0,0);
119   if(e)
120   { Py_DECREF(b);
121     return drawf_oserror();
122   }
123   countobjs(b);
124   if(b->nobjs>=0) return (PyObject *)b;
125   Py_DECREF(b);
126   return drawf_error("Corrupt draw file");
127 }
128 
129 
DrawF_Save(PyDrawFObject * self,PyObject * arg)130 static PyObject *DrawF_Save(PyDrawFObject *self,PyObject *arg)
131 { char *fname;
132   if(!PyArg_ParseTuple(arg,"s",&fname)) return NULL;
133   e=xosfile_save_stamped(fname,DRAWTYPE,
134   (byte*)(self->drawf),(byte*)(self->drawf)+self->size);
135   if (e) return drawf_oserror();
136   Py_INCREF(Py_None);return Py_None;
137 }
138 
DrawF_Render(PyDrawFObject * self,PyObject * arg)139 static PyObject *DrawF_Render(PyDrawFObject *self,PyObject *arg)
140 { int flags,trans,clip,flat;
141   if(!PyArg_ParseTuple(arg,"iiii",&flags,&trans,&clip,&flat)) return NULL;
142   e=xdrawfile_render((drawfile_render_flags)flags,self->drawf,self->size,
143   (os_trfm*)trans,(os_box*)clip,flat);
144   if(e) return drawf_oserror();
145   Py_INCREF(Py_None);return Py_None;
146 }
147 
DrawF_Path(PyDrawFObject * self,PyObject * arg)148 static PyObject *DrawF_Path(PyDrawFObject *self,PyObject *arg)
149 { PyObject *pl;
150   PyObject *dp=0;
151   os_colour fill;
152   os_colour outline;
153   int width,start=0;
154   drawfile_path_style style;
155   int size=40;
156   int n,i,element_count;
157   drawfile_diagram *diag;
158   drawfile_object *dobj;
159   drawfile_path *dpath;
160   draw_path *thepath;
161   draw_line_style line_style;
162   draw_dash_pattern *dash_pattern=0;
163   os_box *box;
164   long *pe;
165   if(!PyArg_ParseTuple(arg,"O!(iiii)|O!i",&PyList_Type,&pl,(int*)&fill,
166      (int*)&outline,&width,(int*)&style,&PyTuple_Type,&dp,&start)) return NULL;
167   if(dp)
168   { element_count=PyTuple_Size(dp);
169     size+=4*element_count+8;
170     style.flags|=drawfile_PATH_DASHED;
171   }
172   else style.flags&=~drawfile_PATH_DASHED;
173   n=PyList_Size(pl);
174   size+=4*n+8;
175   for(i=0;i<n;i++) if(!PyInt_Check(PyList_GetItem(pl,i))) size+=4;
176   diag=realloc(self->drawf,self->size+size);
177   if(!diag) return PyErr_NoMemory();
178   self->drawf=diag;
179   dobj=(drawfile_object*)((char*)diag+self->size);
180   dobj->type=drawfile_TYPE_PATH;
181   dobj->size=size;
182   dpath=&dobj->data.path;
183   self->size+=size;
184   self->nobjs++;
185   box=&dpath->bbox;
186   dpath->fill=fill;dpath->outline=outline;
187   dpath->width=width;dpath->style=style;
188   pe=(long*)&(dpath->path);
189   if(dp)
190   { dash_pattern=&(((drawfile_path_with_pattern*)dpath)->pattern);
191     dash_pattern->start=start;
192     dash_pattern->element_count=element_count;
193     for(i=0;i<element_count;i++)
194     { dash_pattern->elements[i]=(int)PyInt_AsLong(PyTuple_GetItem(dp,i));
195     }
196     pe+=element_count+2;
197   }
198   thepath=(draw_path*)pe;
199   *pe++=draw_MOVE_TO;
200   for(i=0;i<n;i++)
201   { PyObject *p=PyList_GetItem(pl,i);
202     if(PyInt_Check(p))
203       *pe++=PyInt_AsLong(p);
204     else
205     {
206       *pe++=PyInt_AsLong(PyTuple_GetItem(p,0));
207       *pe++=PyInt_AsLong(PyTuple_GetItem(p,1));
208     }
209   }
210   *pe=draw_END_PATH;
211   line_style.join_style=style.flags&3;
212   line_style.end_cap_style=(style.flags&3)>>2;
213   line_style.start_cap_style=(style.flags&3)>>4;
214   line_style.reserved=0;
215   line_style.mitre_limit=10;
216   line_style.start_cap_width=style.cap_width;
217   line_style.end_cap_width=style.cap_width;
218   line_style.start_cap_length=style.cap_length;
219   line_style.end_cap_length=style.cap_length;
220   e=xdraw_process_path(thepath,0x70000000,0,0,width,&line_style,dash_pattern,
221   (draw_output_path)((char*)box+0x80000000),0);
222   if(e) return drawf_oserror();
223 
224   /* draw_process_path seems to have a bug:
225      If the bounding box size is zero, it returns 0x7FFFFFFF, ..., 0x80000000 instead of the
226      correct size. */
227   if (box->x0==0x7FFFFFFF)
228   {
229       /* path has zero extension, so forget it; it would be invisible anyway */
230       self->size-=size;
231       self->nobjs--;
232       diag=realloc(self->drawf,self->size);
233       if(!diag) return PyErr_NoMemory();
234       self->drawf=diag;
235   }
236   else
237       extend(&(diag->bbox),box);
238   Py_INCREF(Py_None);return Py_None;
239 }
240 
DrawF_Text(PyDrawFObject * self,PyObject * arg)241 static PyObject *DrawF_Text(PyDrawFObject *self,PyObject *arg)
242 { os_colour fill,bg_hint;
243   drawfile_text_style style;
244   int xsize,ysize,x,y;
245   int size,len;
246   char *text;
247   drawfile_diagram *diag;
248   drawfile_object *dobj;
249   drawfile_text *dtext;
250   os_box *box;
251   if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)",&x,&y,&text,
252      (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize)) return NULL;
253   len=strlen(text);
254   size=((len+4)&(~3))+52;
255   diag=realloc(self->drawf,self->size+size);
256   if(!diag) return PyErr_NoMemory();
257   self->drawf=diag;
258   dobj=(drawfile_object*)((char*)diag+self->size);
259   dobj->type=drawfile_TYPE_TEXT;
260   dobj->size=size;
261   dtext=&dobj->data.text;
262   self->size+=size;
263   self->nobjs++;
264   dtext->fill=fill;
265   dtext->bg_hint=bg_hint;
266   dtext->style=style;
267   dtext->xsize=xsize;
268   dtext->ysize=ysize;
269   dtext->base.x=x;
270   dtext->base.y=y;
271   memset(dtext->text,0,(len+4)&(~3));
272   sprintf(dtext->text,"%s",text);
273   box=&(dtext->bbox);
274   box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
275   extend(&(diag->bbox),box);
276   Py_INCREF(Py_None);return Py_None;
277 }
278 
DrawF_TText(PyDrawFObject * self,PyObject * arg)279 static PyObject *DrawF_TText(PyDrawFObject *self,PyObject *arg)
280 { os_colour fill,bg_hint;
281   drawfile_text_style style;
282   int xsize,ysize,x,y;
283   int t1,t2,t3,t4,t5,t6;
284   int size,len;
285   char *text;
286   drawfile_diagram *diag;
287   drawfile_object *dobj;
288   drawfile_trfm_text *dtext;
289   os_box *box;
290   t1=1<<16;t2=0;
291   t3=0;t4=1<<16;
292   t5=t6=0;
293   if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)|(iiiiii)",&x,&y,&text,
294      (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize,&t1,&t2,&t3,&t4,&t5,&t6)) return NULL;
295   len=strlen(text);
296   size=((len+4)&(~3))+52+28;
297   diag=realloc(self->drawf,self->size+size);
298   if(!diag) return PyErr_NoMemory();
299   self->drawf=diag;
300   dobj=(drawfile_object*)((char*)diag+self->size);
301   dobj->type=drawfile_TYPE_TRFM_TEXT;
302   dobj->size=size;
303   dtext=&dobj->data.trfm_text;
304   self->size+=size;
305   self->nobjs++;
306   dtext->trfm.entries[0][0]=t1;
307   dtext->trfm.entries[0][1]=t2;
308   dtext->trfm.entries[1][0]=t3;
309   dtext->trfm.entries[1][1]=t4;
310   dtext->trfm.entries[2][0]=t5;
311   dtext->trfm.entries[2][1]=t6;
312   dtext->flags=0;
313   dtext->fill=fill;
314   dtext->bg_hint=bg_hint;
315   dtext->style=style;
316   dtext->xsize=xsize;
317   dtext->ysize=ysize;
318   dtext->base.x=x;
319   dtext->base.y=y;
320   memset(dtext->text,0,(len+4)&(~3));
321   sprintf(dtext->text,"%s",text);
322   box=&(dtext->bbox);
323   box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
324   extend(&(diag->bbox),box);
325   Py_INCREF(Py_None);return Py_None;
326 }
327 
DrawF_FontTable(PyDrawFObject * self,PyObject * arg)328 static PyObject *DrawF_FontTable(PyDrawFObject *self,PyObject *arg)
329 { int size=8,n=0;
330   PyObject *d,*key,*value;
331   drawfile_diagram *diag;
332   drawfile_object *dobj;
333   char *dtable;
334   if(!PyArg_ParseTuple(arg,"O!",&PyDict_Type,&d)) return NULL;
335   while(PyDict_Next(d,&n,&key,&value))
336   { int m=PyString_Size(value);
337     if(m<0||!PyInt_Check(key)) return NULL;
338     size+=m+2;
339   }
340   size=(size+3)&(~3);
341   diag=realloc(self->drawf,self->size+size);
342   if(!diag) return PyErr_NoMemory();
343   self->drawf=diag;
344   dobj=(drawfile_object*)((char*)diag+self->size);
345   dobj->type=drawfile_TYPE_FONT_TABLE;
346   dobj->size=size;
347   dtable=(char*)(&dobj->data.font_table);
348   self->size+=size;
349   self->nobjs++;
350   memset(dtable,0,size-8);
351   n=0;
352   while(PyDict_Next(d,&n,&key,&value))
353   { int m=PyString_Size(value);
354     *dtable=(char)PyInt_AsLong(key);
355     strcpy(dtable+1,PyString_AsString(value));
356     dtable+=m+2;
357   }
358   Py_INCREF(Py_None);return Py_None;
359 }
360 
DrawF_Group(PyDrawFObject * self,PyObject * arg)361 static PyObject *DrawF_Group(PyDrawFObject *self,PyObject *arg)
362 { int size,n;
363   PyDrawFObject *g;
364   char *name="";
365   drawfile_diagram *diag;
366   drawfile_object *dobj;
367   drawfile_group *dgroup;
368   if(!PyArg_ParseTuple(arg,"O!|s",&PyDrawFType,(PyObject*)&g,&name))
369        return NULL;
370   size=g->size-4;
371   diag=realloc(self->drawf,self->size+size);
372   if(!diag) return PyErr_NoMemory();
373   self->drawf=diag;
374   self->nobjs++;
375   dobj=(drawfile_object*)((char*)diag+self->size);
376   self->size+=size;
377   dobj->type=drawfile_TYPE_GROUP;
378   dobj->size=g->size-4;
379   dgroup=&dobj->data.group;
380   dgroup->bbox=g->drawf->bbox;
381   memset(dgroup->name,' ',12);
382   n=strlen(name);
383   if(n>12) n=12;
384   memcpy(dgroup->name,name,n);
385   memcpy((char*)dgroup->objects,(char*)g->drawf+40,g->size-40);
386   extend(&(diag->bbox),&(dgroup->bbox));
387   Py_INCREF(Py_None);return Py_None;
388 }
389 
DrawF_Find(PyDrawFObject * self,PyObject * arg)390 static PyObject *DrawF_Find(PyDrawFObject *self,PyObject *arg)
391 { int x,y,n=0;
392   int r=-1;
393   drawfile_object *d;
394   if(!PyArg_ParseTuple(arg,"ii|i",&x,&y,&n)) return NULL;
395   if(n<self->nobjs&&n>=0)
396   { d=findobj(self,n);
397     while(n<self->nobjs)
398     { if(x>=d->data.text.bbox.x0&&x<=d->data.text.bbox.x1&&
399          y>=d->data.text.bbox.y0&&y<=d->data.text.bbox.y1) { r=n;break;}
400       n++;
401       d=NEXT(d);
402     }
403   }
404   return PyInt_FromLong(r);
405 }
406 
407 
DrawF_Box(PyDrawFObject * self,PyObject * arg)408 static PyObject *DrawF_Box(PyDrawFObject *self,PyObject *arg)
409 { int n=-1;
410   os_box *box;
411   if(!PyArg_ParseTuple(arg,"|i",&n)) return NULL;
412   if(n>=self->nobjs|n<0) box=&(self->drawf->bbox);
413   else box=&(findobj(self,n)->data.text.bbox);
414   return Py_BuildValue("iiii",box->x0,box->y0,box->x1,box->y1);
415 }
416 
SetBlock(drawfile_object * d,int size,int type,int offset,int value)417 static void SetBlock(drawfile_object *d,int size,int type,int offset,int value)
418 { char *end=(char*)d+size;
419   printf("s%d t%d o%d v%d\n",size,type,offset,value);
420   for(;(char*)d<end;d=NEXT(d))
421     if(d->type==type) ((int*)(d))[offset]=value;
422     else if(d->type==drawfile_TYPE_GROUP)
423            SetBlock((drawfile_object*)&d->data.group.objects,
424                     d->size,type,offset,value);
425   printf("SetBlock Done\n");
426 }
427 
SetWord(PyDrawFObject * self,PyObject * arg,int type,int offset)428 static PyObject *SetWord(PyDrawFObject *self,PyObject *arg,int type,int offset)
429 { int n=PyTuple_Size(arg);
430   int m,value,q;
431   PyObject *par;
432   drawfile_object *e,*d=self->drawf->objects;
433   if(n==0) return  drawf_error("Value Required");
434   par=PyTuple_GetItem(arg,0);
435   if(!PyInt_Check(par))
436   { PyErr_SetString(PyExc_TypeError,"Int Required");
437     return 0;
438   }
439   value=(int)PyInt_AsLong(par);
440   if(n==1) SetBlock(d,self->size-HDRSIZE,type,offset,value);
441   else
442   { for(m=1;m<n;m++)
443     { par=PyTuple_GetItem(arg,m);
444       if(!PyInt_Check(par))
445       { PyErr_SetString(PyExc_TypeError,"Int Required");
446         return 0;
447       }
448       q=(int)PyInt_AsLong(par);
449       if(q<0||q>=self->nobjs)
450       { PyErr_SetString(PyExc_ValueError,"Object out of range");
451         return 0;
452       }
453       e=d;
454       for(;q>0;q--) e=NEXT(e);
455       if(e->type==type)
456       { ((int*)(e))[offset]=value;
457       }
458       else if(e->type==drawfile_TYPE_GROUP)
459              SetBlock((drawfile_object*)&e->data.group.objects,
460                       e->size-GRPHDRSIZE,type,offset,value);
461     }
462   }
463   Py_INCREF(Py_None);return Py_None;
464 }
465 
DrawF_PathFill(PyDrawFObject * self,PyObject * arg)466 static PyObject *DrawF_PathFill(PyDrawFObject *self,PyObject *arg)
467 { return SetWord(self,arg,drawfile_TYPE_PATH,6);
468 }
469 
DrawF_PathColour(PyDrawFObject * self,PyObject * arg)470 static PyObject *DrawF_PathColour(PyDrawFObject *self,PyObject *arg)
471 { return SetWord(self,arg,drawfile_TYPE_PATH,7);
472 }
473 
DrawF_TextColour(PyDrawFObject * self,PyObject * arg)474 static PyObject *DrawF_TextColour(PyDrawFObject *self,PyObject *arg)
475 { return SetWord(self,arg,drawfile_TYPE_TEXT,6);
476 }
477 
DrawF_TextBackground(PyDrawFObject * self,PyObject * arg)478 static PyObject *DrawF_TextBackground(PyDrawFObject *self,PyObject *arg)
479 { return SetWord(self,arg,drawfile_TYPE_TEXT,7);
480 }
481 
482 static struct PyMethodDef PyDrawF_Methods[]=
483 {
484   { "render",(PyCFunction)DrawF_Render,1},
485   { "save",(PyCFunction)DrawF_Save,1},
486   { "path",(PyCFunction)DrawF_Path,1},
487   { "text",(PyCFunction)DrawF_Text,1},
488   { "ttext",(PyCFunction)DrawF_TText,1},
489   { "fonttable",(PyCFunction)DrawF_FontTable,1},
490   { "group",(PyCFunction)DrawF_Group,1},
491   { "find",(PyCFunction)DrawF_Find,1},
492   { "box",(PyCFunction)DrawF_Box,1},
493   { "pathfill",(PyCFunction)DrawF_PathFill,1},
494   { "pathcolour",(PyCFunction)DrawF_PathColour,1},
495   { "textcolour",(PyCFunction)DrawF_TextColour,1},
496   { "textbackground",(PyCFunction)DrawF_TextBackground,1},
497   { NULL,NULL}		/* sentinel */
498 };
499 
drawf_len(PyDrawFObject * b)500 static int drawf_len(PyDrawFObject *b)
501 { return b->nobjs;
502 }
503 
drawf_concat(PyDrawFObject * b,PyDrawFObject * c)504 static PyObject *drawf_concat(PyDrawFObject *b,PyDrawFObject *c)
505 { int size=b->size+c->size-2*HDRSIZE;
506   PyDrawFObject *p=new(size);
507   drawfile_diagram *dd;
508   drawfile_object *d;
509   int n;
510   if(!p) return NULL;
511   dd=p->drawf;
512   d=(drawfile_object*)((char*)dd+b->size);
513   memcpy((char*)dd,(char*)(b->drawf),b->size);
514   memcpy(d,(char*)(c->drawf)+HDRSIZE,c->size-HDRSIZE);
515   p->nobjs=b->nobjs+c->nobjs;
516   for(n=c->nobjs;n>0;n--)
517   { extend(&(dd->bbox),&(d->data.path.bbox));
518     d=NEXT(d);
519   }
520   return (PyObject*)p;
521 }
522 
drawf_repeat(PyDrawFObject * b,Py_ssize_t i)523 static PyObject *drawf_repeat(PyDrawFObject *b,Py_ssize_t i)
524 { PyErr_SetString(PyExc_IndexError,"drawf repetition not implemented");
525   return NULL;
526 }
527 
drawf_item(PyDrawFObject * b,Py_ssize_t i)528 static PyObject *drawf_item(PyDrawFObject *b,Py_ssize_t i)
529 { PyDrawFObject *c;
530   Py_ssize_t size;
531   drawfile_diagram *dd;
532   drawfile_object *d;
533   if(i<0||i>=b->nobjs)
534   { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
535     return NULL;
536   }
537   d=findobj(b,i);
538   size=(char*)findobj(b,i+1)-(char*)d;
539   c=new(size);
540   if(!c) return NULL;
541   dd=c->drawf;
542   *((dheader*)dd)=header;
543   memcpy(dd->objects,d,size);
544   c->nobjs=1;
545   extend(&(dd->bbox),&(d->data.path.bbox));
546   return (PyObject*)c;
547 }
548 
drawf_slice(PyDrawFObject * b,Py_ssize_t i,Py_ssize_t j)549 static PyObject *drawf_slice(PyDrawFObject *b,Py_ssize_t i,Py_ssize_t j)
550 { PyDrawFObject *c;
551   Py_ssize_t size,n;
552   drawfile_diagram *dd;
553   drawfile_object *d;
554   if(i<0||j>b->nobjs)
555   { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
556     return NULL;
557   }
558   d=findobj(b,i);
559   size=(char*)findobj(b,j)-(char*)d;
560   c=new(size);
561   if(!c) return NULL;
562   dd=c->drawf;
563   *((dheader*)dd)=header;
564   memcpy(dd->objects,d,size);
565   c->nobjs=j-i;
566   for(n=j-i;n>0;n--)
567   { extend(&(dd->bbox),&(d->data.path.bbox));
568     d=NEXT(d);
569   }
570   return (PyObject*)c;
571 }
572 
drawf_ass_item(PyDrawFObject * b,Py_ssize_t i,PyObject * v)573 static int drawf_ass_item(PyDrawFObject *b,Py_ssize_t i,PyObject *v)
574 { PyErr_SetString(PyExc_IndexError,"drawf ass not implemented");
575   return NULL;
576 }
577 /*{ if(i<0||4*i>=b->length)
578   { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
579     return -1;
580   }
581   if(!PyInt_Check(v))
582   { PyErr_SetString(PyExc_TypeError,"drawf item must be integer");
583     return -1;
584   }
585   ((long*)(b->drawf))[i]=PyInt_AsLong(v);
586   return 0;
587 }
588 */
589 
drawf_ass_slice(PyDrawFObject * b,Py_ssize_t i,Py_ssize_t j,PyObject * v)590 static int drawf_ass_slice(PyDrawFObject *b,Py_ssize_t i,Py_ssize_t j,PyObject *v)
591 { PyErr_SetString(PyExc_IndexError,"drawf ass_slice not implemented");
592   return NULL;
593 }
594 
595 static PySequenceMethods drawf_as_sequence=
596 { (inquiry)drawf_len,
597   (binaryfunc)drawf_concat,
598   (ssizeargfunc)drawf_repeat,
599   (ssizeargfunc)drawf_item,
600   (ssizessizeargfunc)drawf_slice,
601   (ssizeobjargproc)drawf_ass_item,
602   (ssizessizeobjargproc)drawf_ass_slice,
603 };
604 
PyDrawF_GetAttr(PyDrawFObject * s,char * name)605 static PyObject *PyDrawF_GetAttr(PyDrawFObject *s,char *name)
606 {
607   if (!strcmp(name, "size")) return PyInt_FromLong((long)s->size);
608   if (!strcmp(name, "start")) return PyInt_FromLong((long)s->drawf);
609   if (!strcmp(name, "__members__"))
610   { PyObject *list = PyList_New(2);
611     if (list)
612     { PyList_SetItem(list, 0, PyString_FromString("size"));
613       PyList_SetItem(list, 1, PyString_FromString("start"));
614       if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
615     }
616     return list;
617   }
618   return Py_FindMethod(PyDrawF_Methods, (PyObject*) s,name);
619 }
620 
PyDrawF_Dealloc(PyDrawFObject * b)621 static void PyDrawF_Dealloc(PyDrawFObject *b)
622 {
623     if (b->drawf)
624         ;
625     else
626         PyMem_DEL(b->drawf);
627   PyMem_DEL(b);
628 }
629 
630 static PyTypeObject PyDrawFType=
631 { PyObject_HEAD_INIT(&PyType_Type)
632   0,				/*ob_size*/
633   "drawf",			/*tp_name*/
634   sizeof(PyDrawFObject),	/*tp_size*/
635   0,				/*tp_itemsize*/
636 	/* methods */
637   (destructor)PyDrawF_Dealloc,	/*tp_dealloc*/
638   0,				/*tp_print*/
639   (getattrfunc)PyDrawF_GetAttr,	/*tp_getattr*/
640   0,				/*tp_setattr*/
641   0,				/*tp_compare*/
642   0,				/*tp_repr*/
643   0,				/*tp_as_number*/
644   &drawf_as_sequence,		/*tp_as_sequence*/
645   0,				/*tp_as_mapping*/
646   0,                            /*tp_hash*/
647 };
648 
649 
650 
651 static PyMethodDef DrawFMethods[]=
652 {
653   { "load",DrawF_Load,1},
654   { "new",DrawF_New,1},
655   { NULL,NULL}		 /* Sentinel */
656 };
657 
initdrawf()658 void initdrawf()
659 { PyObject *m, *d;
660   m = Py_InitModule("drawf", DrawFMethods);
661   d = PyModule_GetDict(m);
662   DrawFError=PyString_FromString("drawf.error");
663   PyDict_SetItemString(d,"error",DrawFError);
664 }
665