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

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