libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmGrDevCtx.c 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. #include "cmGlobal.h"
  2. #include "cmFloatTypes.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmGr.h"
  9. #include "cmGrDevCtx.h"
  10. #define _cmGrDcOffsX(p,xx) (xx) // ((p)->pext.loc.x + (xx))
  11. #define _cmGrDcOffsY(p,yy) (yy) // ((p)->pext.loc.y + (yy))
  12. cmGrDcH_t cmGrDcNullHandle = cmSTATIC_NULL_HANDLE;
  13. // cmGrDcRecd is used to store the state of the
  14. // device context on the cmGrDC_t stack.
  15. typedef struct cmGrDcRecd_str
  16. {
  17. cmGrColor_t color;
  18. unsigned fontId;
  19. unsigned fontStyle;
  20. unsigned fontSize;
  21. unsigned penWidth;
  22. unsigned penStyle;
  23. struct cmGrDcRecd_str* next;
  24. struct cmGrDcRecd_str* prev;
  25. } cmGrDcRecd_t;
  26. typedef struct cmGrDc_str
  27. {
  28. cmErr_t err;
  29. cmGrDev_t* dd; // device driver used by this context
  30. void* ddArg; // user assigned device driver callback arg
  31. cmGrDcRecd_t* list; // First recd on the stack (not the top).
  32. cmGrDcRecd_t* cur; // Top recd on the stack.
  33. cmGrPExt_t pext; // x,y is offset added to all drawing coordinates
  34. // w,h is size of drawing area
  35. } cmGrDc_t;
  36. // Note: recd's prior to p->cur are available.
  37. // Recd's after p->cur are on the stack.
  38. cmGrDc_t* _cmGrDcHandleToPtr( cmGrDcH_t h )
  39. {
  40. cmGrDc_t* p = (cmGrDc_t*)h.h;
  41. assert( p != NULL );
  42. return p;
  43. }
  44. void _cmGrDcRecdPrint( const cmChar_t* label, const cmGrDcRecd_t* r )
  45. {
  46. printf("%s r:%i g:%i b:%i fid:%i fs:0x%x fsz:%i pw:%i ps:0x%x\n",
  47. cmStringNullGuard(label),
  48. cmGrColorToR(r->color),cmGrColorToG(r->color),cmGrColorToB(r->color),
  49. r->fontId,r->fontStyle,r->fontSize,r->penWidth,r->penStyle);
  50. }
  51. // Make a duplicate of the current record (if it exists)
  52. // and insert it prior to the current record.
  53. // make the new record current.
  54. void _cmGrDcPush( cmGrDc_t* p )
  55. {
  56. if( p->cur == NULL )
  57. {
  58. assert( p->list == NULL );
  59. cmGrDcRecd_t* r = cmMemAllocZ( cmGrDcRecd_t, 1);
  60. p->dd->get_color( p->ddArg, &r->color );
  61. r->fontId = p->dd->get_font_family(p->ddArg );
  62. r->fontSize = p->dd->get_font_size( p->ddArg );
  63. r->fontStyle = p->dd->get_font_style( p->ddArg );
  64. r->penWidth = p->dd->get_pen_width( p->ddArg );
  65. r->penStyle = p->dd->get_pen_style( p->ddArg );
  66. p->list = r;
  67. p->cur = r;
  68. }
  69. else
  70. {
  71. cmGrDcRecd_t* r = p->cur->prev;
  72. // if no prev recd exists ...
  73. if( r == NULL )
  74. {
  75. // .... then allocate one
  76. r = cmMemAllocZ( cmGrDcRecd_t, 1 );
  77. *r = *p->cur;
  78. p->cur->prev = r;
  79. r->next = p->cur;
  80. }
  81. else
  82. {
  83. // ... otherwise use the prev one
  84. cmGrDcRecd_t* nrp = r->next;
  85. cmGrDcRecd_t* prp = r->prev;
  86. *r = *p->cur;
  87. r->next = nrp;
  88. r->prev = prp;
  89. }
  90. // make the new recd the cur recd
  91. p->cur = r;
  92. // if the new recd is the first on the list
  93. // then update the list begin pointer
  94. if( p->cur->prev == NULL )
  95. p->list = p->cur;
  96. }
  97. //_cmGrDcRecdPrint("push:", p->cur );
  98. }
  99. cmGrDcRC_t _cmGrDcPop(cmGrDc_t* p )
  100. {
  101. if( p->cur==NULL || p->cur->next == NULL )
  102. return cmErrMsg(&p->err,kStackFaultGrDcRC,"Cannot pop the last context record off the stack.");
  103. p->cur = p->cur->next;
  104. p->dd->set_color( p->ddArg, p->cur->color );
  105. p->dd->set_font_family( p->ddArg, p->cur->fontId );
  106. p->dd->set_font_size( p->ddArg, p->cur->fontSize );
  107. p->dd->set_font_style( p->ddArg, p->cur->fontStyle );
  108. p->dd->set_pen_width( p->ddArg, p->cur->penWidth );
  109. p->dd->set_pen_style( p->ddArg, p->cur->penStyle );
  110. //_cmGrDcRecdPrint("pop:", p->cur );
  111. return kOkGrDcRC;
  112. }
  113. cmGrDcRC_t _cmGrDcDestroy( cmGrDc_t* p )
  114. {
  115. cmGrDcRecd_t* rp = p->list;
  116. while( rp!=NULL )
  117. {
  118. cmGrDcRecd_t* tp = rp->next;
  119. cmMemFree( rp );
  120. rp = tp;
  121. }
  122. p->dd->destroy(p->ddArg);
  123. cmMemFree(p);
  124. return kOkGrDcRC;
  125. }
  126. cmGrDcRC_t cmGrDevCtxCreate( cmCtx_t* ctx, cmGrDcH_t* hp, cmGrDev_t* dd, void* ddArg, int x, int y, int w, int h )
  127. {
  128. cmGrDcRC_t rc;
  129. if((rc = cmGrDevCtxDestroy(hp)) != kOkGrDcRC )
  130. return rc;
  131. cmGrDc_t* p = cmMemAllocZ(cmGrDc_t,1);
  132. cmErrSetup(&p->err,&ctx->rpt,"cmGrDevCtx");
  133. p->dd = dd;
  134. p->ddArg = ddArg;
  135. cmGrPExtSet(&p->pext,x,y,w,h);
  136. if( dd->create(ddArg,w,h) == false )
  137. {
  138. cmErrMsg(&p->err,kDevDrvFailGrDcRC,"Device driver create failed.");
  139. goto errLabel;
  140. }
  141. _cmGrDcPush(p); // create the default context
  142. hp->h = p;
  143. errLabel:
  144. if(rc != kOkGrDcRC )
  145. _cmGrDcDestroy(p);
  146. return rc;
  147. }
  148. cmGrDcRC_t cmGrDevCtxDestroy( cmGrDcH_t* hp )
  149. {
  150. cmGrDcRC_t rc;
  151. if( hp==NULL || cmGrDevCtxIsValid(*hp)==false )
  152. return kOkGrDcRC;
  153. cmGrDc_t* p = _cmGrDcHandleToPtr(*hp);
  154. if((rc = _cmGrDcDestroy(p)) != kOkGrDcRC )
  155. return rc;
  156. hp->h = NULL;
  157. return rc;
  158. }
  159. bool cmGrDevCtxIsValid( cmGrDcH_t h )
  160. { return h.h != NULL; }
  161. cmGrDcRC_t cmGrDevCtxResize( cmGrDcH_t h, int x, int y, int ww, int hh )
  162. {
  163. cmGrDcRC_t rc = kOkGrDcRC;
  164. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  165. // store the current drawing context state
  166. _cmGrDcPush(p);
  167. if( p->dd->create(p->ddArg,ww,hh) == false )
  168. {
  169. cmErrMsg(&p->err,kDevDrvFailGrDcRC,"Device driver create failed on resize.");
  170. goto errLabel;
  171. }
  172. cmGrPExtSet(&p->pext,x,y,ww,hh);
  173. errLabel:
  174. // force the current state to be reapplied to the new drawing context
  175. _cmGrDcPop(p);
  176. return rc;
  177. }
  178. void cmGrDevCtxSize( cmGrDcH_t h, cmGrPExt_t* pext )
  179. {
  180. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  181. *pext = p->pext;
  182. pext->loc.x *= -1;
  183. pext->loc.y *= -1;
  184. }
  185. void cmGrDevCtxBeginDraw( cmGrDcH_t h )
  186. {
  187. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  188. p->dd->begin_draw( p->ddArg );
  189. }
  190. void cmGrDevCtxEndDraw( cmGrDcH_t h )
  191. {
  192. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  193. p->dd->end_draw( p->ddArg );
  194. }
  195. void cmGrDevCtxDraw( cmGrDcH_t h )
  196. {
  197. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  198. p->dd->draw( p->ddArg, -p->pext.loc.x, -p->pext.loc.y );
  199. }
  200. void cmGrDcPushCtx( cmGrDcH_t h )
  201. {
  202. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  203. _cmGrDcPush(p);
  204. }
  205. void cmGrDcPopCtx( cmGrDcH_t h )
  206. {
  207. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  208. _cmGrDcPop(p);
  209. }
  210. unsigned cmGrDcColor( cmGrDcH_t h )
  211. {
  212. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  213. return p->cur->color;
  214. }
  215. void cmGrDcSetColorRgb( cmGrDcH_t h, unsigned char r, unsigned char g, unsigned char b )
  216. {
  217. cmGrDcSetColor(h,cmGrRgbToColor(r,g,b));
  218. }
  219. void cmGrDcSetColor( cmGrDcH_t h, cmGrColor_t color )
  220. {
  221. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  222. p->dd->set_color( p->ddArg, color );
  223. }
  224. unsigned cmGrDcFontFamily( cmGrDcH_t h )
  225. {
  226. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  227. return p->cur->fontId;
  228. }
  229. void cmGrDcSetFontFamily( cmGrDcH_t h, unsigned fontId )
  230. {
  231. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  232. p->cur->fontId = fontId;
  233. p->dd->set_font_family( p->ddArg, fontId );
  234. }
  235. unsigned cmGrDcFontStyle( cmGrDcH_t h )
  236. {
  237. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  238. return p->cur->fontStyle;
  239. }
  240. void cmGrDcSetFontStyle( cmGrDcH_t h, unsigned style )
  241. {
  242. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  243. p->cur->fontStyle = style;
  244. p->dd->set_font_style( p->ddArg, style );
  245. }
  246. unsigned cmGrDcFontSize( cmGrDcH_t h )
  247. {
  248. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  249. return p->cur->fontSize;
  250. }
  251. void cmGrDcSetFontSize( cmGrDcH_t h, unsigned size )
  252. {
  253. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  254. p->cur->fontSize = size;
  255. p->dd->set_font_size( p->ddArg, size );
  256. }
  257. unsigned cmGrDcPenWidth( cmGrDcH_t h )
  258. {
  259. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  260. return p->cur->penWidth;
  261. }
  262. void cmGrDcSetPenWidth( cmGrDcH_t h, unsigned width )
  263. {
  264. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  265. p->cur->penWidth = width;
  266. p->dd->set_pen_width( p->ddArg, width );
  267. }
  268. unsigned cmGrDcPenStyle( cmGrDcH_t h )
  269. {
  270. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  271. return p->cur->penStyle;
  272. }
  273. void cmGrDcSetPenStyle( cmGrDcH_t h, unsigned style )
  274. {
  275. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  276. p->cur->penStyle = style;
  277. p->dd->set_pen_style( p->ddArg, style );
  278. }
  279. void cmGrDcDrawLine( cmGrDcH_t h, int x0, int y0, int x1, int y1 )
  280. {
  281. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  282. p->dd->draw_line( p->ddArg, _cmGrDcOffsX(p,x0), _cmGrDcOffsY(p,y0), _cmGrDcOffsX(p,x1), _cmGrDcOffsY(p,y1) );
  283. }
  284. void cmGrDcDrawRect( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  285. {
  286. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  287. p->dd->draw_rect( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  288. }
  289. void cmGrDcDrawRectPExt( cmGrDcH_t h, const cmGrPExt_t* pext )
  290. { cmGrDcDrawRect( h, cmGrPExtL(pext), cmGrPExtT(pext), cmGrPExtW(pext), cmGrPExtH(pext) ); }
  291. void cmGrDcFillRect( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  292. {
  293. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  294. p->dd->fill_rect( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  295. }
  296. void cmGrDcDrawEllipse( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  297. {
  298. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  299. p->dd->draw_ellipse( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  300. }
  301. void cmGrDcFillEllipse( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  302. {
  303. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  304. p->dd->fill_ellipse( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  305. }
  306. void cmGrDcDrawDiamond( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  307. {
  308. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  309. p->dd->draw_diamond( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  310. }
  311. void cmGrDcFillDiamond( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
  312. {
  313. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  314. p->dd->fill_diamond( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
  315. }
  316. void cmGrDcDrawTriangle( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh, unsigned dirFlag )
  317. {
  318. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  319. p->dd->draw_triangle( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh, dirFlag );
  320. }
  321. void cmGrDcFillTriangle( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh, unsigned dirFlag )
  322. {
  323. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  324. p->dd->fill_triangle( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh, dirFlag );
  325. }
  326. void cmGrDcMeasure( cmGrDcH_t h, const cmChar_t* text, cmGrPSz_t* sz )
  327. {
  328. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  329. if( text == NULL )
  330. cmGrPSzSet(sz,0,0);
  331. else
  332. {
  333. unsigned ww,hh;
  334. p->dd->measure_text( p->ddArg, text, &ww, &hh );
  335. sz->w = ww;
  336. sz->h = hh;
  337. }
  338. }
  339. void cmGrDcDrawText( cmGrDcH_t h, const cmChar_t* text, int x, int y )
  340. {
  341. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  342. p->dd->draw_text( p->ddArg, text, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y) );
  343. }
  344. void cmGrDcDrawTextRot( cmGrDcH_t h, const cmChar_t* text, int x, int y, int angle )
  345. {
  346. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  347. p->dd->draw_text_rot( p->ddArg, text, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), angle );
  348. }
  349. void cmGrDcReadImage( cmGrDcH_t h, unsigned char* a, const cmGrPExt_t* pext )
  350. {
  351. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  352. p->dd->read_image( p->ddArg, a, _cmGrDcOffsX(p,pext->loc.x), _cmGrDcOffsY(p,pext->loc.y), pext->sz.w, pext->sz.h );
  353. }
  354. void cmGrDcDrawImage( cmGrDcH_t h, const unsigned char* a, const cmGrPExt_t* pext )
  355. {
  356. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  357. p->dd->draw_image( p->ddArg, a, _cmGrDcOffsX(p,pext->loc.x), _cmGrDcOffsY(p,pext->loc.y), pext->sz.w, pext->sz.h );
  358. }
  359. void cmGrDcSetFont( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style )
  360. {
  361. cmGrDcSetFontFamily(h,fontId);
  362. cmGrDcSetFontSize( h,size);
  363. cmGrDcSetFontStyle( h,style);
  364. }
  365. void cmGrDcFontSetAndMeasure(cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, cmGrPSz_t* sz )
  366. {
  367. cmGrDcSetFont(h,fontId,size,style);
  368. cmGrDcMeasure(h,text,sz);
  369. }
  370. void cmGrDcDrawTextJustify( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, const cmGrPExt_t* pext, unsigned flags )
  371. {
  372. int x = cmGrPExtCtrX(pext);
  373. int y = cmGrPExtCtrY(pext);
  374. if( cmIsFlag(flags,kNorthJsGrFl) )
  375. y = cmGrPExtT(pext);
  376. else
  377. if( cmIsFlag(flags,kSouthJsGrFl) )
  378. y = cmGrPExtB(pext);
  379. if( cmIsFlag(flags,kEastJsGrFl) )
  380. x = cmGrPExtR(pext);
  381. else
  382. if( cmIsFlag(flags,kWestJsGrFl) )
  383. x = cmGrPExtL(pext);
  384. cmGrDcDrawTextJustifyPt(h,fontId,size,style,text,flags,x,y);
  385. }
  386. void cmGrDcDrawTextJustifyPt( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, unsigned flags, int xx, int yy )
  387. {
  388. cmGrPSz_t sz;
  389. cmGrDcFontSetAndMeasure(h, fontId, size, style, text, &sz );
  390. int x,y;
  391. if( cmIsFlag(flags,kRightJsGrFl) )
  392. x = xx;
  393. else
  394. if( cmIsFlag(flags,kLeftJsGrFl) )
  395. x = xx - sz.w;
  396. else
  397. x = xx - sz.w/2;
  398. if( cmIsFlag(flags,kBottomJsGrFl) )
  399. y = yy;
  400. else
  401. if( cmIsFlag(flags,kTopJsGrFl) )
  402. y = yy + sz.h;
  403. else
  404. y = yy + sz.h/2;
  405. cmGrPExt_t r;
  406. cmGrPExtSet(&r,x,y,sz.w,sz.h);
  407. // Note: Checking for visibility should not be necessary however
  408. // there appears to be a problem with the FLTK text output whereby
  409. // text coordinates over 0xffff wrap around and may appear in the
  410. // visible region.
  411. if( cmGrDcRectIsVisible(h,&r) )
  412. {
  413. /*
  414. if( text!=NULL && (strncmp(text,"loc:138",7)==0 || strcmp(text,"loc:8 ")==0))
  415. {
  416. printf("%s %i %i %i %i\n",text,x,y,sz.w,xx);
  417. cmGrPExtPrint(text,&r);
  418. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  419. cmGrPExt_t res;
  420. cmGrPExtIntersect(&res,&p->pext,&r );
  421. cmGrPExtPrint(text,&p->pext);
  422. cmGrPExtPrint("isect:",&res);
  423. printf("%i\n",cmGrPExtIsNotNullOrEmpty(&res));
  424. }
  425. */
  426. cmGrDcDrawText(h, text, x+.5, y+.5 );
  427. }
  428. //cmGrPExt_t pext;
  429. //cmGrDcDrawTextJustifyRect(h, fontId, size, style, text, flags, xx, yy, &pext );
  430. //cmGrDcDrawRectPExt(h,&pext);
  431. }
  432. void cmGrDcDrawTextJustifyRect( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, unsigned flags, int xx, int yy, cmGrPExt_t* pext )
  433. {
  434. cmGrPSz_t sz;
  435. cmGrDcFontSetAndMeasure(h, fontId, size, style, text, &sz );
  436. int x,y;
  437. if( cmIsFlag(flags,kRightJsGrFl) )
  438. x = xx;
  439. else
  440. if( cmIsFlag(flags,kLeftJsGrFl) )
  441. x = xx - sz.w;
  442. else
  443. x = xx - sz.w/2;
  444. if( cmIsFlag(flags,kBottomJsGrFl) )
  445. y = yy;
  446. else
  447. if( cmIsFlag(flags,kTopJsGrFl) )
  448. y = yy + sz.h;
  449. else
  450. y = yy + sz.h/2;
  451. cmGrPExtSet( pext, x, y-sz.h, sz.w+1, sz.h );
  452. }
  453. bool cmGrDcPointIsVisible( cmGrDcH_t h, int x, int y )
  454. {
  455. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  456. return cmGrVExtIsXyInside(&p->pext,x,y);
  457. }
  458. bool cmGrDcRectIsVisible( cmGrDcH_t h, const cmGrPExt_t* r )
  459. {
  460. cmGrPExt_t res;
  461. cmGrDc_t* p = _cmGrDcHandleToPtr(h);
  462. cmGrPExtIntersect(&res,&p->pext,r );
  463. return cmGrPExtIsNotNullOrEmpty(&res);
  464. }