/src/Xw/Xw_draw_line.cxx

https://github.com/hmeyer/oce · C++ · 518 lines · 375 code · 53 blank · 90 comment · 63 complexity · e7f229e6f0b12d991b119dc53d1b39c7 MD5 · raw file

  1. #define S3593 /*GG_130398
  2. OPTIMISATION MFT
  3. Activer le clipping de maniere optionnelle
  4. */
  5. #include <Xw_Extension.h>
  6. /* ifdef then trace on */
  7. #ifdef TRACE
  8. #define TRACE_DRAW_LINE
  9. #endif
  10. /*
  11. STATUS Xw_draw_line (awindow,npoint,x,y):
  12. XW_EXT_WINDOW *awindow
  13. int npoint Polyline point number
  14. float *x,*y Points Arrays
  15. Display continuous line in current QG set by set_line_attrib .
  16. Note that lines can be buffered depending of the DisplayMode context
  17. and Flush at Xw_flush time .
  18. returns ERROR if npoint > MAXPOINTS
  19. returns SUCCESS always
  20. */
  21. static int BeginLine = -1 ;
  22. static XW_EXT_LINE *plinelist ;
  23. static XW_EXT_POINT *plinedesc ;
  24. static XSegment segment;
  25. #ifdef XW_PROTOTYPE
  26. XW_STATUS Xw_draw_line (void* awindow,int npoint,float* px,float* py)
  27. #else
  28. XW_STATUS Xw_draw_line (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,nline,ldesc,bindex;
  37. int x,y,lx=0,ly=0 ;
  38. if( !Xw_isdefine_window(pwindow) ) {
  39. /*ERROR*Bad EXT_WINDOW Address*/
  40. Xw_set_error(24,"Xw_draw_line",pwindow) ;
  41. return (XW_ERROR) ;
  42. }
  43. if( npoint > MAXPOINTS ) {
  44. npoint = MAXPOINTS;
  45. /*ERROR*Too many points in LINE*/
  46. Xw_set_error(28,"Xw_draw_line",&npoint) ;
  47. return (XW_ERROR) ;
  48. }
  49. bindex = _BINDEX ;
  50. pbuffer = &_BUFFER(bindex) ;
  51. for( plinelist = pbuffer->plinelist ; plinelist ;
  52. plinelist = (XW_EXT_LINE*)plinelist->link ) {
  53. if( plinelist->nline < MAXLINES ) break ;
  54. }
  55. if( !plinelist ) {
  56. plinelist = Xw_add_polyline_structure(pbuffer) ;
  57. }
  58. if( !plinelist ) return XW_ERROR ;
  59. for( plinedesc = pbuffer->plinedesc ; plinedesc ;
  60. plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
  61. if( plinedesc->npoint + npoint <= MAXPOINTS ) break ;
  62. }
  63. if( !plinedesc ) {
  64. plinedesc = Xw_add_line_desc_structure(pbuffer) ;
  65. }
  66. if( !plinedesc ) return XW_ERROR ;
  67. nline = plinelist->nline ;
  68. ldesc = plinedesc->npoint ;
  69. plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ;
  70. for( i=0 ; i<npoint ; i++ ) {
  71. //OCC186
  72. x = PXPOINT(px[i], pwindow->xratio) ;
  73. y = PYPOINT(py[i], pwindow->attributes.height, pwindow->yratio) ;
  74. //OCC186
  75. #ifdef S3593
  76. if( pwindow->clipflag ) {
  77. #endif
  78. if( i > 0 ) {
  79. int status;
  80. status = Xw_clip_segment(pwindow,lx,ly,x,y,&segment);
  81. if( status >= 0 ) {
  82. if( (i < 2) || (status & 0xF ) ) {
  83. plinedesc->rpoints[ldesc].x = segment.x1 ;
  84. plinedesc->rpoints[ldesc].y = segment.y1 ;
  85. ldesc++;
  86. if( bindex > 0 ) {
  87. int xx = segment.x1,yy = segment.y1;
  88. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  89. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  90. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  91. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  92. }
  93. }
  94. plinedesc->rpoints[ldesc].x = segment.x2 ;
  95. plinedesc->rpoints[ldesc].y = segment.y2 ;
  96. ldesc++;
  97. if( bindex > 0 ) {
  98. int xx = segment.x2,yy = segment.y2;
  99. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  100. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  101. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  102. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  103. }
  104. }
  105. }
  106. lx = x; ly = y;
  107. #ifdef S3593
  108. } else {
  109. plinedesc->rpoints[ldesc].x = x ;
  110. plinedesc->rpoints[ldesc].y = y ;
  111. ldesc++ ;
  112. if( bindex > 0 ) {
  113. pbuffer->rxmin = min(pbuffer->rxmin,x) ;
  114. pbuffer->rymin = min(pbuffer->rymin,y) ;
  115. pbuffer->rxmax = max(pbuffer->rxmax,x) ;
  116. pbuffer->rymax = max(pbuffer->rymax,y) ;
  117. }
  118. }
  119. #endif
  120. }
  121. plinelist->lines[nline] = ldesc - plinedesc->npoint ;
  122. if( plinelist->lines[nline] > 1 ) {
  123. plinedesc->npoint = ldesc ;
  124. plinelist->nline++ ;
  125. if( bindex > 0 ) {
  126. pbuffer->isempty = False ;
  127. } else if( BeginLine < 0 ) {
  128. int index = pwindow->lineindex ;
  129. Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc);
  130. plinelist->nline = 0 ;
  131. plinedesc->npoint = 0 ;
  132. }
  133. }
  134. #ifdef TRACE_DRAW_LINE
  135. if( Xw_get_trace() > 2 ) {
  136. printf(" Xw_draw_line(%lx,%d)\n",(long ) pwindow,npoint) ;
  137. for( i=0 ; i<npoint ; i++ ) {
  138. printf(" Point(%d) = {%f,%f}\n",i,px[i],py[i]) ;
  139. }
  140. }
  141. #endif
  142. return (XW_SUCCESS);
  143. }
  144. #ifdef XW_PROTOTYPE
  145. void Xw_draw_pixel_lines (XW_EXT_WINDOW* pwindow,XW_EXT_LINE *plinelist,GC gc)
  146. #else
  147. void Xw_draw_pixel_lines (pwindow,plinelist,gc)
  148. XW_EXT_WINDOW *pwindow;
  149. XW_EXT_LINE *plinelist;
  150. GC gc ;
  151. #endif /*XW_PROTOTYPE*/
  152. {
  153. int i,npoint;
  154. XPoint *ppoint ;
  155. for( i=0 ; i<plinelist->nline ; i++ ) {
  156. npoint = plinelist->lines[i] ;
  157. ppoint = plinelist->plines[i] ;
  158. if( plinelist->isupdated ) {
  159. ppoint += MAXPOINTS ;
  160. }
  161. if( ppoint && npoint > 1 ) {
  162. XDrawLines(_DISPLAY,_DRAWABLE,gc,ppoint,npoint,CoordModeOrigin) ;
  163. }
  164. }
  165. }
  166. /*
  167. STATUS Xw_begin_line (awindow,npoint):
  168. XW_EXT_WINDOW *awindow
  169. int npoint Polyline point number
  170. Begin Polyline which must be filled by Xw_line_point and
  171. closed by Xw_close_line
  172. returns ERROR if npoint > MAXPOINTS
  173. returns SUCCESS if successful
  174. */
  175. static int Npoint = 0;
  176. static int Lx,Ly;
  177. #ifdef XW_PROTOTYPE
  178. XW_STATUS Xw_begin_line(void* awindow,int npoint)
  179. #else
  180. XW_STATUS Xw_begin_line(awindow,npoint)
  181. void *awindow ;
  182. int npoint ;
  183. #endif /*XW_PROTOTYPE*/
  184. {
  185. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  186. XW_EXT_BUFFER *pbuffer ;
  187. int nline,ldesc,bindex ;
  188. if( !Xw_isdefine_window(pwindow) ) {
  189. /*ERROR*Bad EXT_WINDOW Address*/
  190. Xw_set_error(24,"Xw_begin_line",pwindow) ;
  191. return (XW_ERROR) ;
  192. }
  193. if( npoint > MAXPOINTS ) {
  194. npoint = MAXPOINTS ;
  195. /*ERROR*Too many points in LINE*/
  196. Xw_set_error(28,"Xw_begin_line",&npoint) ;
  197. return (XW_ERROR) ;
  198. }
  199. if( BeginLine >= 0 ) Xw_close_line(pwindow);
  200. bindex = _BINDEX ;
  201. pbuffer = &_BUFFER(bindex) ;
  202. for( plinelist = pbuffer->plinelist ; plinelist ;
  203. plinelist = (XW_EXT_LINE*)plinelist->link ) {
  204. if( plinelist->nline < MAXLINES ) break ;
  205. }
  206. if( !plinelist ) {
  207. plinelist = Xw_add_polyline_structure(pbuffer) ;
  208. }
  209. if( !plinelist ) return XW_ERROR ;
  210. for( plinedesc = pbuffer->plinedesc ; plinedesc ;
  211. plinedesc = (XW_EXT_POINT*)plinedesc->link ) {
  212. if( plinedesc->npoint + npoint <= MAXPOINTS ) break ;
  213. }
  214. if( !plinedesc ) {
  215. plinedesc = Xw_add_line_desc_structure(pbuffer) ;
  216. }
  217. if( !plinedesc ) return XW_ERROR ;
  218. nline = plinelist->nline ;
  219. ldesc = plinedesc->npoint ;
  220. plinelist->lines[nline] = Npoint = 0 ;
  221. plinelist->plines[nline] = &plinedesc->rpoints[ldesc] ;
  222. BeginLine = ldesc ;
  223. #ifdef TRACE_DRAW_LINE
  224. if( Xw_get_trace() > 2 ) {
  225. printf(" Xw_begin_line(%lx,%d)\n",(long ) pwindow,npoint) ;
  226. }
  227. #endif
  228. return (XW_SUCCESS) ;
  229. }
  230. /*
  231. STATUS Xw_line_point (awindow,x,y):
  232. XW_EXT_WINDOW *awindow
  233. float x,y New point to add in polyline in user-space coordinates
  234. Fill Polyline with one point more
  235. returns ERROR if Too Many Points in polylines
  236. returns SUCCESS if successful
  237. */
  238. #ifdef XW_PROTOTYPE
  239. XW_STATUS Xw_line_point(void* awindow,float x,float y)
  240. #else
  241. XW_STATUS Xw_line_point(awindow,x,y)
  242. void *awindow ;
  243. float x,y ;
  244. #endif /*XW_PROTOTYPE*/
  245. {
  246. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  247. XW_EXT_BUFFER *pbuffer ;
  248. int bindex,xi,yi ;
  249. if( BeginLine >= 0 ) {
  250. int ldesc = plinedesc->npoint ;
  251. if( ldesc >= MAXPOINTS ) {
  252. /*ERROR*Too many points in LINE*/
  253. Xw_set_error(28,"Xw_line_point",&ldesc) ;
  254. Xw_close_line(pwindow) ;
  255. return (XW_ERROR) ;
  256. }
  257. bindex = _BINDEX ;
  258. pbuffer = &_BUFFER(bindex) ;
  259. //OCC186
  260. xi = PXPOINT(x, pwindow->xratio) ;
  261. yi = PYPOINT(y, pwindow->attributes.height, pwindow->yratio) ;
  262. //OCC186
  263. #ifdef S3593
  264. if( pwindow->clipflag ) {
  265. #endif
  266. if( Npoint > 0 ) {
  267. int status;
  268. status = Xw_clip_segment(pwindow,Lx,Ly,xi,yi,&segment);
  269. if( status >= 0 ) {
  270. if( (Npoint < 2) || (status & 0xF ) ) {
  271. plinedesc->rpoints[ldesc].x = segment.x1 ;
  272. plinedesc->rpoints[ldesc].y = segment.y1 ;
  273. ldesc++;
  274. if( bindex > 0 ) {
  275. int xx = segment.x1,yy = segment.y1;
  276. pbuffer->isempty = False ;
  277. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  278. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  279. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  280. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  281. }
  282. }
  283. plinedesc->rpoints[ldesc].x = segment.x2 ;
  284. plinedesc->rpoints[ldesc].y = segment.y2 ;
  285. ldesc++;
  286. if( bindex > 0 ) {
  287. int xx = segment.x2,yy = segment.y2;
  288. pbuffer->isempty = False ;
  289. pbuffer->rxmin = min(pbuffer->rxmin,xx) ;
  290. pbuffer->rymin = min(pbuffer->rymin,yy) ;
  291. pbuffer->rxmax = max(pbuffer->rxmax,xx) ;
  292. pbuffer->rymax = max(pbuffer->rymax,yy) ;
  293. }
  294. }
  295. }
  296. Lx = xi; Ly = yi;
  297. #ifdef S3593
  298. } else {
  299. plinedesc->rpoints[ldesc].x = xi ;
  300. plinedesc->rpoints[ldesc].y = yi ;
  301. ldesc++;
  302. if( bindex > 0 ) {
  303. pbuffer->isempty = False ;
  304. pbuffer->rxmin = min(pbuffer->rxmin,xi) ;
  305. pbuffer->rymin = min(pbuffer->rymin,yi) ;
  306. pbuffer->rxmax = max(pbuffer->rxmax,xi) ;
  307. pbuffer->rymax = max(pbuffer->rymax,yi) ;
  308. }
  309. }
  310. #endif
  311. Npoint++;
  312. plinedesc->npoint = ldesc ;
  313. }
  314. #ifdef TRACE_DRAW_LINE
  315. if( Xw_get_trace() > 3 ) {
  316. printf(" Xw_line_point(%lx,%f,%f)\n",(long ) pwindow,x,y) ;
  317. }
  318. #endif
  319. return (XW_SUCCESS) ;
  320. }
  321. /*
  322. STATUS Xw_close_line (awindow):
  323. XW_EXT_WINDOW *awindow
  324. Close the Polyline
  325. returns ERROR if Polyline is empty
  326. returns SUCCESS if successful
  327. */
  328. #ifdef XW_PROTOTYPE
  329. XW_STATUS Xw_close_line(void* awindow)
  330. #else
  331. XW_STATUS Xw_close_line(awindow)
  332. void *awindow ;
  333. #endif /*XW_PROTOTYPE*/
  334. {
  335. XW_EXT_WINDOW *pwindow = (XW_EXT_WINDOW*)awindow ;
  336. if( BeginLine >= 0 ) {
  337. int nline = plinelist->nline ;
  338. int ldesc = plinedesc->npoint ;
  339. int bindex = _BINDEX ;
  340. plinelist->lines[nline] = ldesc - BeginLine ;
  341. plinelist->nline++ ;
  342. if( !bindex ) {
  343. int index = pwindow->lineindex ;
  344. Xw_draw_pixel_lines(pwindow,plinelist,pwindow->qgline[index].gc) ;
  345. plinelist->nline = 0 ;
  346. plinedesc->npoint = 0 ;
  347. }
  348. BeginLine = -1 ;
  349. }
  350. #ifdef TRACE_DRAW_LINE
  351. if( Xw_get_trace() > 2 ) {
  352. printf(" Xw_close_line(%lx)\n",(long ) pwindow) ;
  353. }
  354. #endif
  355. return (XW_SUCCESS) ;
  356. }
  357. #ifdef XW_PROTOTYPE
  358. XW_EXT_LINE* Xw_add_polyline_structure(XW_EXT_BUFFER* pbuflist )
  359. #else
  360. XW_EXT_LINE* Xw_add_polyline_structure(pbuflist )
  361. XW_EXT_BUFFER *pbuflist ;
  362. #endif /*XW_PROTOTYPE*/
  363. /*
  364. Create and Insert at end one Extended polyline structure in the
  365. polyline List
  366. returns Extended polyline address if successful
  367. or NULL if Bad Allocation
  368. */
  369. {
  370. XW_EXT_LINE *pline ;
  371. pline = (XW_EXT_LINE*) Xw_malloc(sizeof(XW_EXT_LINE)) ;
  372. if( pline ) {
  373. pline->link = pbuflist->plinelist ;
  374. pline->isupdated = False ;
  375. pline->nline = 0 ;
  376. pbuflist->plinelist = pline ;
  377. } else {
  378. /*ERROR*EXT_LINE allocation failed*/
  379. Xw_set_error(30,"Xw_add_polyline_structure",NULL) ;
  380. }
  381. return (pline) ;
  382. }
  383. #ifdef XW_PROTOTYPE
  384. XW_STATUS Xw_del_polyline_structure(XW_EXT_BUFFER* pbuflist)
  385. #else
  386. XW_STATUS Xw_del_polyline_structure(pbuflist)
  387. XW_EXT_BUFFER *pbuflist ;
  388. #endif /*XW_PROTOTYPE*/
  389. /*
  390. Remove ALL Extended polyline structure in the
  391. polyline List
  392. SUCCESS always
  393. */
  394. {
  395. XW_EXT_LINE *pline,*qline ;
  396. for( pline = pbuflist->plinelist ; pline ; pline = qline ) {
  397. qline = (XW_EXT_LINE*)pline->link ;
  398. Xw_free(pline) ;
  399. }
  400. pbuflist->plinelist = NULL ;
  401. return (XW_SUCCESS) ;
  402. }
  403. #ifdef XW_PROTOTYPE
  404. XW_EXT_POINT* Xw_add_line_desc_structure(XW_EXT_BUFFER* pbuflist )
  405. #else
  406. XW_EXT_POINT* Xw_add_line_desc_structure(pbuflist )
  407. XW_EXT_BUFFER *pbuflist ;
  408. #endif /*XW_PROTOTYPE*/
  409. /*
  410. Create and Insert at end one Extended line_desc structure in the
  411. line_desc List
  412. returns Extended line_desc address if successful
  413. or NULL if Bad Allocation
  414. */
  415. {
  416. XW_EXT_POINT *pdesc ;
  417. pdesc = (XW_EXT_POINT*) Xw_malloc(sizeof(XW_EXT_POINT)) ;
  418. if( pdesc ) {
  419. pdesc->link = pbuflist->plinedesc ;
  420. pdesc->npoint = 0 ;
  421. pbuflist->plinedesc = pdesc ;
  422. } else {
  423. /*ERROR*EXT_POINT allocation failed*/
  424. Xw_set_error(117,"Xw_add_line_desc_structure",NULL) ;
  425. }
  426. return (pdesc) ;
  427. }
  428. #ifdef XW_PROTOTYPE
  429. XW_STATUS Xw_del_line_desc_structure(XW_EXT_BUFFER* pbuflist)
  430. #else
  431. XW_STATUS Xw_del_line_desc_structure(pbuflist)
  432. XW_EXT_BUFFER *pbuflist ;
  433. #endif /*XW_PROTOTYPE*/
  434. /*
  435. Remove ALL Extended line_desc structure in the
  436. line_desc List
  437. SUCCESS always
  438. */
  439. {
  440. XW_EXT_POINT *pdesc,*qdesc ;
  441. for( pdesc = pbuflist->plinedesc ; pdesc ; pdesc = qdesc ) {
  442. qdesc = (XW_EXT_POINT*)pdesc->link ;
  443. Xw_free(pdesc) ;
  444. }
  445. pbuflist->plinedesc = NULL ;
  446. return (XW_SUCCESS) ;
  447. }