PageRenderTime 491ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Xw/Xw_draw_poly.cxx

https://github.com/hmeyer/oce
C++ | 583 lines | 436 code | 58 blank | 89 comment | 83 complexity | b1c26d9c8c57ded50fb5e2d70f67de5c MD5 | raw file
  1. #define BUC40223 /*GG_070797
  2. Protection contre zoom trop grand*/
  3. #include <Xw_Extension.h>
  4. /* ifdef then trace on */
  5. #ifdef TRACE
  6. #define TRACE_DRAW_POLY
  7. #endif
  8. /*
  9. STATUS Xw_draw_poly (awindow,npoint,px,py):
  10. XW_EXT_WINDOW *awindow
  11. int npoint Polygone point number
  12. float *px,*py Polygone points
  13. Display continuous poly in current QG set by set_poly_attrib .
  14. Note that polys can be buffered depending of the DisplayMode context
  15. and Flush at Xw_flush time .
  16. returns ERROR if npoint > MAXPOINTS
  17. returns SUCCESS if successful
  18. */
  19. static int FirstPolyPoint = -1 ;
  20. static int FirstPolyLine = -1 ;
  21. static int FirstPathPoint = -1 ;
  22. static XW_EXT_POLY *ppolylist ;
  23. static XW_EXT_POINT *plinedesc ;
  24. static XSegment segment;
  25. #ifdef XW_PROTOTYPE
  26. XW_STATUS Xw_draw_poly (void* awindow,int npoint,float* px,float* py)
  27. #else
  28. XW_STATUS Xw_draw_poly (awindow,npoint,px,py)
  29. void *awindow;
  30. int npoint ;
  31. float *px,*py ;
  32. #endif /*XW_PROTOTYPE*/
  33. {
  34. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow;
  35. XW_EXT_BUFFER *pbuffer ;
  36. int i,npoly,ldesc,bindex;
  37. int x=0,y=0,lx=0,ly=0 ;
  38. XPoint *ppoint ;
  39. if( !Xw_isdefine_window(pwindow) ) {
  40. /*ERROR*Bad EXT_WINDOW Address*/
  41. Xw_set_error(24,"Xw_draw_poly",pwindow) ;
  42. return (XW_ERROR) ;
  43. }
  44. if( npoint >= MAXPOINTS ) {
  45. npoint = MAXPOINTS-1 ;
  46. /*ERROR*Too many points in POLYGONE*/
  47. Xw_set_error(28,"Xw_draw_poly",&npoint) ;
  48. return (XW_ERROR) ;
  49. }
  50. if( npoint < 3 ) {
  51. /*WARNING*POLYGONE is Empty !!!*/
  52. Xw_set_error(33,"Xw_draw_poly",&npoint) ;
  53. return (XW_ERROR) ;
  54. }
  55. bindex = _BINDEX ;
  56. pbuffer = &_BUFFER(bindex) ;
  57. for( ppolylist = pbuffer->ppolylist ; ppolylist ;
  58. ppolylist = (XW_EXT_POLY*)ppolylist->link ) {
  59. if( ppolylist->npoly < MAXPOLYS ) break ;
  60. }
  61. if( !ppolylist ) {
  62. ppolylist = Xw_add_polygone_structure(pbuffer) ;
  63. }
  64. if( !ppolylist ) return XW_ERROR ;
  65. for( plinedesc = pbuffer->plinedesc ; plinedesc ;
  66. plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
  67. if( plinedesc->npoint + npoint < MAXPOINTS ) break ;
  68. }
  69. if( !plinedesc ) {
  70. plinedesc = Xw_add_line_desc_structure(pbuffer) ;
  71. }
  72. if( !plinedesc ) return XW_ERROR ;
  73. npoly = ppolylist->npoly ;
  74. ldesc = plinedesc->npoint ;
  75. ppolylist->ppolys[npoly] = ppoint = &plinedesc->rpoints[ldesc] ;
  76. for( i=0 ; i<npoint ; i++ ) {
  77. //OCC186
  78. x = PXPOINT(px[i], pwindow->xratio) ;
  79. y = PYPOINT(py[i], pwindow->attributes.height, pwindow->yratio) ;
  80. //OCC186
  81. #ifdef BUC40223
  82. if( i > 0 ) {
  83. int status;
  84. status = Xw_clip_segment(pwindow,lx,ly,x,y,&segment);
  85. if( status >= 0 ) {
  86. if( (i < 2) || (status & 0xF ) ) {
  87. plinedesc->rpoints[ldesc].x = segment.x1 ;
  88. plinedesc->rpoints[ldesc].y = segment.y1 ;
  89. ldesc++;
  90. if( bindex > 0 ) {
  91. int xx = segment.x1,yy = segment.y1;
  92. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  93. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  94. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  95. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  96. }
  97. }
  98. plinedesc->rpoints[ldesc].x = segment.x2 ;
  99. plinedesc->rpoints[ldesc].y = segment.y2 ;
  100. ldesc++;
  101. if( bindex > 0 ) {
  102. int xx = segment.x2,yy = segment.y2;
  103. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  104. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  105. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  106. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  107. }
  108. }
  109. }
  110. lx = x; ly = y;
  111. #else
  112. plinedesc->rpoints[ldesc].x = x ;
  113. plinedesc->rpoints[ldesc].y = y ;
  114. ldesc++ ;
  115. if( bindex > 0 ) {
  116. pbuffer->rxmin = min(pbuffer->rxmin,x) ;
  117. pbuffer->rymin = min(pbuffer->rymin,y) ;
  118. pbuffer->rxmax = max(pbuffer->rxmax,x) ;
  119. pbuffer->rymax = max(pbuffer->rymax,y) ;
  120. }
  121. #endif
  122. }
  123. if( ppoint->x != x || ppoint->y != y ) {
  124. plinedesc->rpoints[ldesc].x = ppoint->x ;
  125. plinedesc->rpoints[ldesc].y = ppoint->y ;
  126. ldesc++ ;
  127. }
  128. ppolylist->polys[npoly] = ldesc - plinedesc->npoint ;
  129. ppolylist->paths[npoly] = ppolylist->polys[npoly] ;
  130. if( ppolylist->polys[npoly] > 3 ) {
  131. ppolylist->npoly++ ;
  132. plinedesc->npoint = ldesc ;
  133. if( bindex > 0 ) {
  134. pbuffer->isempty = False ;
  135. } else if( FirstPolyPoint < 0 ) {
  136. int polyindex = pwindow->polyindex ;
  137. int lineindex = pwindow->lineindex ;
  138. GC gcpoly = (QGTILE(pwindow->qgpoly[polyindex].code)) ?
  139. pwindow->qgpoly[polyindex].gc : NULL ;
  140. GC gcline = (QGTYPE(pwindow->qgpoly[polyindex].code)) ?
  141. pwindow->qgline[lineindex].gc : NULL ;
  142. Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline);
  143. ppolylist->npoly = 0 ;
  144. plinedesc->npoint = 0 ;
  145. }
  146. }
  147. #ifdef TRACE_DRAW_POLY
  148. if( Xw_get_trace() > 2 ) {
  149. printf(" Xw_draw_poly(%lx,%d)\n",(long ) pwindow,npoint) ;
  150. for( i=0 ; i<npoint ; i++ ) {
  151. printf(" Point(%d) = {%f,%f}\n",i,px[i],py[i]) ;
  152. }
  153. }
  154. #endif
  155. return (XW_SUCCESS);
  156. }
  157. #ifdef XW_PROTOTYPE
  158. void Xw_draw_pixel_polys(XW_EXT_WINDOW* pwindow,XW_EXT_POLY* ppolylist,
  159. GC gcpoly,GC gcline)
  160. #else
  161. void Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline)
  162. XW_EXT_WINDOW *pwindow ;
  163. XW_EXT_POLY *ppolylist ;
  164. GC gcpoly,gcline ;
  165. #endif
  166. {
  167. int i,npolypoint,npathpoint,shape,npoint=0,count=0;
  168. Region chr_region=NULL;
  169. XPoint *ppoint ;
  170. for( i=0 ; i<ppolylist->npoly ; i++ ) {
  171. npolypoint = ppolylist->polys[i] ;
  172. npathpoint = ppolylist->paths[i] ;
  173. ppoint = ppolylist->ppolys[i] ;
  174. if( ppolylist->isupdated ) {
  175. ppoint += MAXPOINTS ;
  176. }
  177. if( gcpoly ) {
  178. if( npolypoint > 0 ) {
  179. npoint = npolypoint; count = 0;
  180. chr_region = 0;
  181. }
  182. if( npoint > npathpoint ) {
  183. if( npathpoint > 3 ) {
  184. if( chr_region == 0 ) {
  185. chr_region =
  186. XPolygonRegion(ppoint,npathpoint-1,EvenOddRule);
  187. } else {
  188. Region chr_pathreg =
  189. XPolygonRegion(ppoint,npathpoint-1,EvenOddRule);
  190. Region chr_xorreg = XCreateRegion ();
  191. XXorRegion (chr_region, chr_pathreg, chr_xorreg);
  192. XDestroyRegion (chr_region);
  193. chr_region = chr_xorreg;
  194. }
  195. }
  196. count += npathpoint;
  197. if( count >= npoint && chr_region ) {
  198. XRectangle rect;
  199. XSetRegion(_DISPLAY,gcpoly,chr_region);
  200. XClipBox(chr_region,&rect);
  201. XFillRectangles(_DISPLAY,_DRAWABLE,gcpoly,&rect,1);
  202. XDestroyRegion(chr_region);
  203. XSetClipMask(_DISPLAY,gcpoly,None);
  204. }
  205. } else if( npoint > 3 ) {
  206. shape = (npoint > 4) ? Nonconvex : Convex;
  207. XFillPolygon(_DISPLAY,_DRAWABLE,gcpoly,ppoint,npoint-1,
  208. shape,CoordModeOrigin) ;
  209. }
  210. }
  211. if( gcline && (gcpoly != gcline) && (npathpoint > 3) ) {
  212. XDrawLines(_DISPLAY,_DRAWABLE,gcline,
  213. ppoint,npathpoint,CoordModeOrigin) ;
  214. }
  215. }
  216. }
  217. /*
  218. STATUS Xw_begin_poly (awindow,npoint,npath):
  219. XW_EXT_WINDOW *awindow
  220. int npoint Estimated polygone point number
  221. int npath Estimated polygone path number
  222. Begin Polygone which must be filled by Xw_poly_point and
  223. closed by Xw_close_poly
  224. returns ERROR if npoint > MAXPOINTS
  225. or npath > MAXPOLYS
  226. returns SUCCESS if successful
  227. */
  228. static int Npoint = 0;
  229. static int Lx,Ly;
  230. #ifdef XW_PROTOTYPE
  231. XW_STATUS Xw_begin_poly(void* awindow,int npoint,int npath)
  232. #else
  233. XW_STATUS Xw_begin_poly(awindow,npoint,npath)
  234. void *awindow ;
  235. int npoint,npath ;
  236. #endif /*XW_PROTOTYPE*/
  237. {
  238. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  239. int npoly,ldesc,bindex ;
  240. if( !Xw_isdefine_window(pwindow) ) {
  241. /*ERROR*Bad EXT_WINDOW Address*/
  242. Xw_set_error(24,"Xw_begin_poly",pwindow) ;
  243. return (XW_ERROR) ;
  244. }
  245. if( npoint >= MAXPOINTS ) {
  246. npoint = MAXPOINTS-1 ;
  247. /*ERROR*Too many points in POLYGONE*/
  248. Xw_set_error(32,"Xw_begin_poly",&npoint) ;
  249. return (XW_ERROR) ;
  250. }
  251. if( npath >= MAXPOLYS ) {
  252. npath = MAXPOLYS-1 ;
  253. /*ERROR*Too many paths in POLYGONE*/
  254. Xw_set_error(32,"Xw_begin_poly",&npath) ;
  255. return (XW_ERROR) ;
  256. }
  257. if( FirstPolyPoint >= 0 ) Xw_close_poly(pwindow) ;
  258. bindex = _BINDEX ;
  259. for( ppolylist = _BUFFER(bindex).ppolylist ; ppolylist ;
  260. ppolylist = (XW_EXT_POLY*)ppolylist->link ) {
  261. if( (ppolylist->npoly + npath) < MAXPOLYS ) break ;
  262. }
  263. if( !ppolylist ) {
  264. ppolylist = Xw_add_polygone_structure(&_BUFFER(bindex)) ;
  265. }
  266. if( !ppolylist ) return XW_ERROR ;
  267. for( plinedesc = _BUFFER(bindex).plinedesc ; plinedesc ;
  268. plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
  269. if( (plinedesc->npoint + npoint) < MAXPOINTS ) break ;
  270. }
  271. if( !plinedesc ) {
  272. plinedesc = Xw_add_line_desc_structure(&_BUFFER(bindex)) ;
  273. }
  274. if( !plinedesc ) return XW_ERROR ;
  275. npoly = ppolylist->npoly ;
  276. ldesc = plinedesc->npoint ;
  277. ppolylist->polys[npoly] = 0 ;
  278. ppolylist->paths[npoly] = Npoint = 0 ;
  279. ppolylist->ppolys[npoly] = &plinedesc->rpoints[ldesc] ;
  280. FirstPolyPoint = FirstPathPoint = ldesc ;
  281. FirstPolyLine = npoly;
  282. #ifdef TRACE_DRAW_POLY
  283. if( Xw_get_trace() > 2 ) {
  284. printf(" Xw_begin_poly(%lx,%d,%d)\n",(long ) pwindow,npoint,npath) ;
  285. }
  286. #endif
  287. return (XW_SUCCESS) ;
  288. }
  289. /*
  290. STATUS Xw_poly_point (awindow,x,y):
  291. XW_EXT_WINDOW *awindow
  292. float x,y New point to add in polygone in user-space coordinates
  293. Fill Polygone with one point more
  294. returns ERROR if Too Many Points in polygones
  295. returns SUCCESS if successful
  296. */
  297. #ifdef XW_PROTOTYPE
  298. XW_STATUS Xw_poly_point(void* awindow,float x,float y)
  299. #else
  300. XW_STATUS Xw_poly_point(awindow,x,y)
  301. void *awindow ;
  302. float x,y ;
  303. #endif /*XW_PROTOTYPE*/
  304. {
  305. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  306. XW_EXT_BUFFER *pbuffer ;
  307. int bindex,xi,yi ;
  308. if( FirstPolyPoint >= 0 ) {
  309. int ldesc = plinedesc->npoint ;
  310. if( ldesc >= MAXPOINTS ) {
  311. /*ERROR*Too many points in POLYGONE*/
  312. Xw_set_error(32,"Xw_poly_point",&ldesc) ;
  313. Xw_close_poly(pwindow) ;
  314. return (XW_ERROR) ;
  315. }
  316. bindex = _BINDEX ;
  317. //OCC186
  318. xi = PXPOINT(x, pwindow->xratio) ;
  319. yi = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
  320. //OCC186
  321. #ifdef BUC40223
  322. if( Npoint > 0 ) {
  323. int status;
  324. status = Xw_clip_segment(pwindow,Lx,Ly,xi,yi,&segment);
  325. if( status >= 0 ) {
  326. if( (Npoint < 2) || (status & 0xF ) ) {
  327. plinedesc->rpoints[ldesc].x = segment.x1 ;
  328. plinedesc->rpoints[ldesc].y = segment.y1 ;
  329. ldesc++; plinedesc->npoint++ ;
  330. if( bindex > 0 ) {
  331. int xx = segment.x1,yy = segment.y1;
  332. pbuffer = &_BUFFER(bindex) ;
  333. pbuffer->isempty = False ;
  334. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  335. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  336. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  337. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  338. }
  339. }
  340. plinedesc->rpoints[ldesc].x = segment.x2 ;
  341. plinedesc->rpoints[ldesc].y = segment.y2 ;
  342. plinedesc->npoint++ ;
  343. if( bindex > 0 ) {
  344. int xx = segment.x2,yy = segment.y2;
  345. pbuffer = &_BUFFER(bindex) ;
  346. pbuffer->isempty = False ;
  347. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  348. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  349. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  350. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  351. }
  352. }
  353. }
  354. Lx = xi; Ly = yi;
  355. Npoint++;
  356. #else
  357. plinedesc->rpoints[ldesc].x = xi ;
  358. plinedesc->rpoints[ldesc].y = yi ;
  359. plinedesc->npoint++ ;
  360. if( bindex > 0 ) {
  361. pbuffer = &_BUFFER(bindex) ;
  362. pbuffer->isempty = False ;
  363. pbuffer->rxmin = min(pbuffer->rxmin,xi) ;
  364. pbuffer->rymin = min(pbuffer->rymin,yi) ;
  365. pbuffer->rxmax = max(pbuffer->rxmax,xi) ;
  366. pbuffer->rymax = max(pbuffer->rymax,yi) ;
  367. }
  368. #endif
  369. }
  370. #ifdef TRACE_DRAW_POLY
  371. if( Xw_get_trace() > 3 ) {
  372. printf(" Xw_poly_point(%lx,%f,%f)\n",(long ) pwindow,x,y) ;
  373. }
  374. #endif
  375. return (XW_SUCCESS) ;
  376. }
  377. /*
  378. STATUS Xw_close_path (awindow):
  379. XW_EXT_WINDOW *awindow
  380. Close the Polygone path
  381. returns ERROR if TOO many path
  382. returns SUCCESS if successful
  383. */
  384. #ifdef XW_PROTOTYPE
  385. XW_STATUS Xw_close_path(void* awindow)
  386. #else
  387. XW_STATUS Xw_close_path(awindow)
  388. void *awindow ;
  389. #endif /*XW_PROTOTYPE*/
  390. {
  391. #ifdef TRACE_DRAW_POLY
  392. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  393. #endif
  394. if( FirstPolyPoint >= 0 ) {
  395. int npoly = ppolylist->npoly ;
  396. int ldesc = plinedesc->npoint ;
  397. if( plinedesc->rpoints[FirstPathPoint].x != plinedesc->rpoints[ldesc-1].x ||
  398. plinedesc->rpoints[FirstPathPoint].y != plinedesc->rpoints[ldesc-1].y ) {
  399. plinedesc->rpoints[ldesc].x = plinedesc->rpoints[FirstPathPoint].x ;
  400. plinedesc->rpoints[ldesc].y = plinedesc->rpoints[FirstPathPoint].y ;
  401. plinedesc->npoint++ ; ldesc++ ;
  402. }
  403. ppolylist->polys[FirstPolyLine] = ldesc - FirstPolyPoint ;
  404. ppolylist->paths[npoly] = ldesc - FirstPathPoint ;
  405. FirstPathPoint = ldesc;
  406. if( ppolylist->npoly < MAXPOLYS ) {
  407. ppolylist->npoly = ++npoly ;
  408. ppolylist->polys[npoly] = 0 ;
  409. ppolylist->paths[npoly] = Npoint = 0 ;
  410. ppolylist->ppolys[npoly] = &plinedesc->rpoints[ldesc] ;
  411. } else {
  412. /*ERROR*Too many paths in POLYGONE*/
  413. Xw_set_error(32,"Xw_close_path",&ppolylist->npoly) ;
  414. return (XW_ERROR) ;
  415. }
  416. }
  417. #ifdef TRACE_DRAW_POLY
  418. if( Xw_get_trace() > 2 ) {
  419. printf(" Xw_close_path(%lx)\n",(long ) pwindow) ;
  420. }
  421. #endif
  422. return (XW_SUCCESS) ;
  423. }
  424. /*
  425. STATUS Xw_close_poly (awindow):
  426. XW_EXT_WINDOW *awindow
  427. Close the Polygone
  428. returns ERROR if Polygone is empty
  429. returns SUCCESS if successful
  430. */
  431. #ifdef XW_PROTOTYPE
  432. XW_STATUS Xw_close_poly(void* awindow)
  433. #else
  434. XW_STATUS Xw_close_poly(awindow)
  435. void *awindow ;
  436. #endif /*XW_PROTOTYPE*/
  437. {
  438. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  439. if( FirstPolyPoint >= 0 ) {
  440. if( plinedesc->npoint > FirstPathPoint ) Xw_close_path(pwindow);
  441. if( !_BINDEX ) {
  442. int polyindex = pwindow->polyindex ;
  443. int lineindex = pwindow->lineindex ;
  444. GC gcpoly = (QGTILE(pwindow->qgpoly[polyindex].code)) ?
  445. pwindow->qgpoly[polyindex].gc : NULL ;
  446. GC gcline = (QGTYPE(pwindow->qgpoly[polyindex].code)) ?
  447. pwindow->qgline[lineindex].gc : NULL ;
  448. Xw_draw_pixel_polys(pwindow,ppolylist,gcpoly,gcline);
  449. ppolylist->npoly = 0 ;
  450. plinedesc->npoint = 0 ;
  451. }
  452. FirstPolyPoint = -1 ;
  453. }
  454. #ifdef TRACE_DRAW_POLY
  455. if( Xw_get_trace() > 2 ) {
  456. printf(" Xw_close_poly(%lx)\n",(long ) pwindow) ;
  457. }
  458. #endif
  459. return (XW_SUCCESS) ;
  460. }
  461. #ifdef XW_PROTOTYPE
  462. XW_EXT_POLY* Xw_add_polygone_structure(XW_EXT_BUFFER* pbuflist )
  463. #else
  464. XW_EXT_POLY* Xw_add_polygone_structure(pbuflist )
  465. XW_EXT_BUFFER *pbuflist ;
  466. #endif /*XW_PROTOTYPE*/
  467. /*
  468. Create and Insert at end one Extended polygone structure in the
  469. polygone List
  470. returns Extended polygone address if successful
  471. or NULL if Bad Allocation
  472. */
  473. {
  474. XW_EXT_POLY *ppoly ;
  475. ppoly = (XW_EXT_POLY*) Xw_malloc(sizeof(XW_EXT_POLY)) ;
  476. if( ppoly ) {
  477. ppoly->link = pbuflist->ppolylist ;
  478. ppoly->isupdated = False ;
  479. ppoly->npoly = 0 ;
  480. pbuflist->ppolylist = ppoly ;
  481. } else {
  482. /*ERROR*EXT_POLYGONE allocation failed*/
  483. Xw_set_error(34,"Xw_add_polygone_structure",NULL) ;
  484. }
  485. return (ppoly) ;
  486. }
  487. #ifdef XW_PROTOTYPE
  488. XW_STATUS Xw_del_polygone_structure(XW_EXT_BUFFER* pbuflist)
  489. #else
  490. XW_STATUS Xw_del_polygone_structure(pbuflist)
  491. XW_EXT_BUFFER *pbuflist ;
  492. #endif /*XW_PROTOTYPE*/
  493. /*
  494. Remove ALL Extended polygone structure in the
  495. polygone List
  496. SUCCESS always
  497. */
  498. {
  499. XW_EXT_POLY *ppoly,*qpoly ;
  500. for( ppoly = pbuflist->ppolylist ; ppoly ; ppoly = qpoly ) {
  501. qpoly = (XW_EXT_POLY*)ppoly->link ;
  502. Xw_free(ppoly) ;
  503. }
  504. pbuflist->ppolylist = NULL ;
  505. return (XW_SUCCESS) ;
  506. }