Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1033 lines
25 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "tier0/dbg.h"
  9. #include <stdio.h>
  10. #include "drawhelper.h"
  11. // #define COLOR_BACKGROUND RGB( 120, 120, 150 )
  12. //-----------------------------------------------------------------------------
  13. // Purpose:
  14. // Input : *widget -
  15. //-----------------------------------------------------------------------------
  16. CDrawHelper::CDrawHelper( mxWindow *widget )
  17. {
  18. Init( widget, 0, 0, 0, 0, COLOR_BACKGROUND );
  19. }
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. // Input : *widget -
  23. //-----------------------------------------------------------------------------
  24. CDrawHelper::CDrawHelper( mxWindow *widget, COLORREF bgColor )
  25. {
  26. Init( widget, 0, 0, 0, 0, bgColor );
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose:
  30. // Input : *widget -
  31. // bounds -
  32. //-----------------------------------------------------------------------------
  33. CDrawHelper::CDrawHelper( mxWindow *widget, RECT& bounds )
  34. {
  35. Init( widget, bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, COLOR_BACKGROUND );
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose:
  39. // Input : *widget -
  40. // x -
  41. // y -
  42. // w -
  43. // h -
  44. //-----------------------------------------------------------------------------
  45. CDrawHelper::CDrawHelper( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor )
  46. {
  47. Init( widget, x, y, w, h, bgColor );
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Purpose:
  51. // Input : *widget -
  52. // bounds -
  53. // bgColor -
  54. //-----------------------------------------------------------------------------
  55. CDrawHelper::CDrawHelper( mxWindow *widget, RECT& bounds, COLORREF bgColor )
  56. {
  57. Init( widget, bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, bgColor );
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose:
  61. // Input : *widget -
  62. // x -
  63. // y -
  64. // w -
  65. // h -
  66. //-----------------------------------------------------------------------------
  67. void CDrawHelper::Init( mxWindow *widget, int x, int y, int w, int h, COLORREF bgColor )
  68. {
  69. m_x = x;
  70. m_y = y;
  71. m_w = w ? w : widget->w2();
  72. m_h = h ? h : widget->h2();
  73. m_hWnd = (HWND)widget->getHandle();
  74. Assert( m_hWnd );
  75. m_dcReal = GetDC( m_hWnd );
  76. m_rcClient.left = m_x;
  77. m_rcClient.top = m_y;
  78. m_rcClient.right = m_x + m_w;
  79. m_rcClient.bottom = m_y + m_h;
  80. m_dcMemory = CreateCompatibleDC( m_dcReal );
  81. m_bmMemory = CreateCompatibleBitmap( m_dcReal, m_w, m_h );
  82. m_bmOld = (HBITMAP)SelectObject( m_dcMemory, m_bmMemory );
  83. m_clrOld = SetBkColor( m_dcMemory, bgColor );
  84. HBRUSH br = CreateSolidBrush( bgColor );
  85. RECT rcFill = m_rcClient;
  86. OffsetRect( &rcFill, -m_rcClient.left, -m_rcClient.top );
  87. FillRect( m_dcMemory, &rcFill, br );
  88. DeleteObject( br );
  89. m_ClipRegion = (HRGN)0;
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: Finish up
  93. //-----------------------------------------------------------------------------
  94. CDrawHelper::~CDrawHelper( void )
  95. {
  96. SelectClipRgn( m_dcMemory, NULL );
  97. while ( m_ClipRects.Size() > 0 )
  98. {
  99. StopClipping();
  100. }
  101. BitBlt( m_dcReal, m_x, m_y, m_w, m_h, m_dcMemory, 0, 0, SRCCOPY );
  102. SetBkColor( m_dcMemory, m_clrOld );
  103. SelectObject( m_dcMemory, m_bmOld );
  104. DeleteObject( m_bmMemory );
  105. DeleteObject( m_dcMemory );
  106. ReleaseDC( m_hWnd, m_dcReal );
  107. ValidateRect( m_hWnd, &m_rcClient );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose:
  111. // Output : int
  112. //-----------------------------------------------------------------------------
  113. int CDrawHelper::GetWidth( void )
  114. {
  115. return m_w;
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Purpose:
  119. // Output : int
  120. //-----------------------------------------------------------------------------
  121. int CDrawHelper::GetHeight( void )
  122. {
  123. return m_h;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose:
  127. // Input : rc -
  128. //-----------------------------------------------------------------------------
  129. void CDrawHelper::GetClientRect( RECT& rc )
  130. {
  131. rc.left = rc.top = 0;
  132. rc.right = m_w;
  133. rc.bottom = m_h;
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose:
  137. // Output : HDC
  138. //-----------------------------------------------------------------------------
  139. HDC CDrawHelper::GrabDC( void )
  140. {
  141. return m_dcMemory;
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose:
  145. // Input : *font -
  146. // pointsize -
  147. // weight -
  148. // maxwidth -
  149. // rcText -
  150. // *fmt -
  151. // ... -
  152. //-----------------------------------------------------------------------------
  153. void CDrawHelper::CalcTextRect( const char *font, int pointsize, int weight, int maxwidth, RECT& rcText, const char *fmt, ... )
  154. {
  155. va_list args;
  156. static char output[1024];
  157. va_start( args, fmt );
  158. vprintf( fmt, args );
  159. vsprintf( output, fmt, args );
  160. HFONT fnt = CreateFont(
  161. -pointsize,
  162. 0,
  163. 0,
  164. 0,
  165. weight,
  166. FALSE,
  167. FALSE,
  168. FALSE,
  169. ANSI_CHARSET,
  170. OUT_TT_PRECIS,
  171. CLIP_DEFAULT_PRECIS,
  172. ANTIALIASED_QUALITY,
  173. DEFAULT_PITCH,
  174. font );
  175. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  176. DrawText( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_WORDBREAK | DT_CALCRECT );
  177. SelectObject( m_dcMemory, oldFont );
  178. DeleteObject( fnt );
  179. }
  180. //-----------------------------------------------------------------------------
  181. // Purpose:
  182. // Input : *font -
  183. // pointsize -
  184. // weight -
  185. // *fmt -
  186. // ... -
  187. // Output : int
  188. //-----------------------------------------------------------------------------
  189. int CDrawHelper::CalcTextWidth( const char *font, int pointsize, int weight, const char *fmt, ... )
  190. {
  191. va_list args;
  192. static char output[1024];
  193. va_start( args, fmt );
  194. vprintf( fmt, args );
  195. vsprintf( output, fmt, args );
  196. HFONT fnt = CreateFont(
  197. -pointsize,
  198. 0,
  199. 0,
  200. 0,
  201. weight,
  202. FALSE,
  203. FALSE,
  204. FALSE,
  205. ANSI_CHARSET,
  206. OUT_TT_PRECIS,
  207. CLIP_DEFAULT_PRECIS,
  208. ANTIALIASED_QUALITY,
  209. DEFAULT_PITCH,
  210. font );
  211. HDC screen = GetDC( NULL );
  212. HFONT oldFont = (HFONT)SelectObject( screen, fnt );
  213. RECT rcText;
  214. rcText.left = rcText.top = 0;
  215. rcText.bottom = pointsize + 5;
  216. rcText.right = rcText.left + 2048;
  217. DrawText( screen, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT );
  218. SelectObject( screen, oldFont );
  219. DeleteObject( fnt );
  220. ReleaseDC( NULL, screen );
  221. return rcText.right;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. // Input : *font -
  226. // pointsize -
  227. // weight -
  228. // *fmt -
  229. // ... -
  230. // Output : int
  231. //-----------------------------------------------------------------------------
  232. int CDrawHelper::CalcTextWidthW( const char *font, int pointsize, int weight, const wchar_t *fmt, ... )
  233. {
  234. va_list args;
  235. static wchar_t output[1024];
  236. va_start( args, fmt );
  237. vwprintf( fmt, args );
  238. vswprintf( output, fmt, args );
  239. HFONT fnt = CreateFont(
  240. -pointsize,
  241. 0,
  242. 0,
  243. 0,
  244. weight,
  245. FALSE,
  246. FALSE,
  247. FALSE,
  248. ANSI_CHARSET,
  249. OUT_TT_PRECIS,
  250. CLIP_DEFAULT_PRECIS,
  251. ANTIALIASED_QUALITY,
  252. DEFAULT_PITCH,
  253. font );
  254. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  255. RECT rcText;
  256. rcText.left = rcText.top = 0;
  257. rcText.bottom = pointsize + 5;
  258. rcText.right = rcText.left + 2048;
  259. DrawTextW( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT );
  260. SelectObject( m_dcMemory, oldFont );
  261. DeleteObject( fnt );
  262. return rcText.right;
  263. }
  264. //-----------------------------------------------------------------------------
  265. // Purpose:
  266. // Input : fnt -
  267. // *fmt -
  268. // ... -
  269. // Output : int
  270. //-----------------------------------------------------------------------------
  271. int CDrawHelper::CalcTextWidth( HFONT fnt, const char *fmt, ... )
  272. {
  273. va_list args;
  274. static char output[1024];
  275. va_start( args, fmt );
  276. vprintf( fmt, args );
  277. vsprintf( output, fmt, args );
  278. HDC screen = GetDC( NULL );
  279. HFONT oldFont = (HFONT)SelectObject( screen, fnt );
  280. RECT rcText;
  281. rcText.left = rcText.top = 0;
  282. rcText.bottom = 1000;
  283. rcText.right = rcText.left + 2048;
  284. DrawText( screen, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT );
  285. SelectObject( screen, oldFont );
  286. ReleaseDC( NULL, screen );
  287. return rcText.right;
  288. }
  289. int CDrawHelper::CalcTextWidthW( HFONT fnt, const wchar_t *fmt, ... )
  290. {
  291. va_list args;
  292. static wchar_t output[1024];
  293. va_start( args, fmt );
  294. vwprintf( fmt, args );
  295. vswprintf( output, fmt, args );
  296. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  297. RECT rcText;
  298. rcText.left = rcText.top = 0;
  299. rcText.bottom = 1000;
  300. rcText.right = rcText.left + 2048;
  301. DrawTextW( m_dcMemory, output, -1, &rcText, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT );
  302. SelectObject( m_dcMemory, oldFont );
  303. return rcText.right;
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Purpose:
  307. // Input : *font -
  308. // pointsize -
  309. // weight -
  310. // clr -
  311. // rcText -
  312. // *fmt -
  313. // ... -
  314. //-----------------------------------------------------------------------------
  315. void CDrawHelper::DrawColoredText( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const char *fmt, ... )
  316. {
  317. va_list args;
  318. static char output[1024];
  319. va_start( args, fmt );
  320. vsprintf( output, fmt, args );
  321. va_end( args );
  322. DrawColoredTextCharset( font, pointsize, weight, ANSI_CHARSET, clr, rcText, output );
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose:
  326. // Input : *font -
  327. // pointsize -
  328. // weight -
  329. // clr -
  330. // rcText -
  331. // *fmt -
  332. // ... -
  333. //-----------------------------------------------------------------------------
  334. void CDrawHelper::DrawColoredTextW( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... )
  335. {
  336. va_list args;
  337. static wchar_t output[1024];
  338. va_start( args, fmt );
  339. vswprintf( output, fmt, args );
  340. va_end( args );
  341. DrawColoredTextCharsetW( font, pointsize, weight, ANSI_CHARSET, clr, rcText, output );
  342. }
  343. //-----------------------------------------------------------------------------
  344. // Purpose:
  345. // Input : font -
  346. // clr -
  347. // rcText -
  348. // *fmt -
  349. // ... -
  350. //-----------------------------------------------------------------------------
  351. void CDrawHelper::DrawColoredText( HFONT font, COLORREF clr, RECT& rcText, const char *fmt, ... )
  352. {
  353. va_list args;
  354. static char output[1024];
  355. va_start( args, fmt );
  356. vsprintf( output, fmt, args );
  357. va_end( args );
  358. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, font );
  359. COLORREF oldColor = SetTextColor( m_dcMemory, clr );
  360. int oldMode = SetBkMode( m_dcMemory, TRANSPARENT );
  361. RECT rcTextOffset = rcText;
  362. OffsetSubRect( rcTextOffset );
  363. DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS );
  364. SetBkMode( m_dcMemory, oldMode );
  365. SetTextColor( m_dcMemory, oldColor );
  366. SelectObject( m_dcMemory, oldFont );
  367. }
  368. //-----------------------------------------------------------------------------
  369. // Purpose:
  370. // Input : font -
  371. // clr -
  372. // rcText -
  373. // *fmt -
  374. // ... -
  375. //-----------------------------------------------------------------------------
  376. void CDrawHelper::DrawColoredTextW( HFONT font, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... )
  377. {
  378. va_list args;
  379. static wchar_t output[1024];
  380. va_start( args, fmt );
  381. vswprintf( output, fmt, args );
  382. va_end( args );
  383. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, font );
  384. COLORREF oldColor = SetTextColor( m_dcMemory, clr );
  385. int oldMode = SetBkMode( m_dcMemory, TRANSPARENT );
  386. RECT rcTextOffset = rcText;
  387. OffsetSubRect( rcTextOffset );
  388. DrawTextW( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS );
  389. SetBkMode( m_dcMemory, oldMode );
  390. SetTextColor( m_dcMemory, oldColor );
  391. SelectObject( m_dcMemory, oldFont );
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Purpose:
  395. // Input : *font -
  396. // pointsize -
  397. // weight -
  398. // clr -
  399. // rcText -
  400. // *fmt -
  401. // ... -
  402. //-----------------------------------------------------------------------------
  403. void CDrawHelper::DrawColoredTextCharset( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, const char *fmt, ... )
  404. {
  405. va_list args;
  406. static char output[1024];
  407. va_start( args, fmt );
  408. vsprintf( output, fmt, args );
  409. va_end( args );
  410. HFONT fnt = CreateFont(
  411. -pointsize,
  412. 0,
  413. 0,
  414. 0,
  415. weight,
  416. FALSE,
  417. FALSE,
  418. FALSE,
  419. charset,
  420. OUT_TT_PRECIS,
  421. CLIP_DEFAULT_PRECIS,
  422. ANTIALIASED_QUALITY,
  423. DEFAULT_PITCH,
  424. font );
  425. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  426. COLORREF oldColor = SetTextColor( m_dcMemory, clr );
  427. int oldMode = SetBkMode( m_dcMemory, TRANSPARENT );
  428. RECT rcTextOffset = rcText;
  429. OffsetSubRect( rcTextOffset );
  430. DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS );
  431. SetBkMode( m_dcMemory, oldMode );
  432. SetTextColor( m_dcMemory, oldColor );
  433. SelectObject( m_dcMemory, oldFont );
  434. DeleteObject( fnt );
  435. }
  436. void CDrawHelper::DrawColoredTextCharsetW( const char *font, int pointsize, int weight, DWORD charset, COLORREF clr, RECT& rcText, const wchar_t *fmt, ... )
  437. {
  438. va_list args;
  439. static wchar_t output[1024];
  440. va_start( args, fmt );
  441. vswprintf( output, fmt, args );
  442. va_end( args );
  443. HFONT fnt = CreateFont(
  444. -pointsize,
  445. 0,
  446. 0,
  447. 0,
  448. weight,
  449. FALSE,
  450. FALSE,
  451. FALSE,
  452. charset,
  453. OUT_TT_PRECIS,
  454. CLIP_DEFAULT_PRECIS,
  455. ANTIALIASED_QUALITY,
  456. DEFAULT_PITCH,
  457. font );
  458. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  459. COLORREF oldColor = SetTextColor( m_dcMemory, clr );
  460. int oldMode = SetBkMode( m_dcMemory, TRANSPARENT );
  461. RECT rcTextOffset = rcText;
  462. OffsetSubRect( rcTextOffset );
  463. DrawTextW( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS );
  464. SetBkMode( m_dcMemory, oldMode );
  465. SetTextColor( m_dcMemory, oldColor );
  466. SelectObject( m_dcMemory, oldFont );
  467. DeleteObject( fnt );
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Purpose:
  471. // Input : *font -
  472. // pointsize -
  473. // weight -
  474. // clr -
  475. // rcText -
  476. // *fmt -
  477. // ... -
  478. //-----------------------------------------------------------------------------
  479. void CDrawHelper::DrawColoredTextMultiline( const char *font, int pointsize, int weight, COLORREF clr, RECT& rcText, const char *fmt, ... )
  480. {
  481. va_list args;
  482. static char output[1024];
  483. va_start( args, fmt );
  484. vprintf( fmt, args );
  485. vsprintf( output, fmt, args );
  486. HFONT fnt = CreateFont(
  487. -pointsize,
  488. 0,
  489. 0,
  490. 0,
  491. weight,
  492. FALSE,
  493. FALSE,
  494. FALSE,
  495. ANSI_CHARSET,
  496. OUT_TT_PRECIS,
  497. CLIP_DEFAULT_PRECIS,
  498. ANTIALIASED_QUALITY,
  499. DEFAULT_PITCH,
  500. font );
  501. HFONT oldFont = (HFONT)SelectObject( m_dcMemory, fnt );
  502. COLORREF oldColor = SetTextColor( m_dcMemory, clr );
  503. int oldMode = SetBkMode( m_dcMemory, TRANSPARENT );
  504. RECT rcTextOffset = rcText;
  505. OffsetSubRect( rcTextOffset );
  506. DrawText( m_dcMemory, output, -1, &rcTextOffset, DT_LEFT | DT_NOPREFIX | DT_VCENTER | DT_WORDBREAK | DT_WORD_ELLIPSIS );
  507. SetBkMode( m_dcMemory, oldMode );
  508. SetTextColor( m_dcMemory, oldColor );
  509. SelectObject( m_dcMemory, oldFont );
  510. DeleteObject( fnt );
  511. }
  512. //-----------------------------------------------------------------------------
  513. // Purpose:
  514. // Input : r -
  515. // g -
  516. // b -
  517. // style -
  518. // width -
  519. // x1 -
  520. // y1 -
  521. // x2 -
  522. // y2 -
  523. //-----------------------------------------------------------------------------
  524. void CDrawHelper::DrawColoredLine( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 )
  525. {
  526. HPEN pen = CreatePen( style, width, clr );
  527. HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen );
  528. MoveToEx( m_dcMemory, x1-m_x, y1-m_y, NULL );
  529. LineTo( m_dcMemory, x2-m_x, y2-m_y );
  530. SelectObject( m_dcMemory, oldPen );
  531. DeleteObject( pen );
  532. };
  533. //-----------------------------------------------------------------------------
  534. // Purpose:
  535. // Input : clr -
  536. // style -
  537. // width -
  538. // count -
  539. // *pts -
  540. //-----------------------------------------------------------------------------
  541. void CDrawHelper::DrawColoredPolyLine( COLORREF clr, int style, int width, CUtlVector< POINT >& points )
  542. {
  543. int c = points.Count();
  544. if ( c < 2 )
  545. return;
  546. HPEN pen = CreatePen( style, width, clr );
  547. HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen );
  548. POINT *temp = (POINT *)_alloca( c * sizeof( POINT ) );
  549. Assert( temp );
  550. int i;
  551. for ( i = 0; i < c; i++ )
  552. {
  553. POINT *pt = &points[ i ];
  554. temp[ i ].x = pt->x - m_x;
  555. temp[ i ].y = pt->y - m_y;
  556. }
  557. Polyline( m_dcMemory, temp, c );
  558. SelectObject( m_dcMemory, oldPen );
  559. DeleteObject( pen );
  560. }
  561. //-----------------------------------------------------------------------------
  562. // Purpose:
  563. // Input : r -
  564. // g -
  565. // b -
  566. // style -
  567. // width -
  568. // x1 -
  569. // y1 -
  570. // x2 -
  571. // y2 -
  572. //-----------------------------------------------------------------------------
  573. POINTL CDrawHelper::DrawColoredRamp( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2, float rate, float sustain )
  574. {
  575. HPEN pen = CreatePen( style, width, clr );
  576. HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen );
  577. MoveToEx( m_dcMemory, x1-m_x, y1-m_y, NULL );
  578. int dx = x2 - x1;
  579. int dy = y2 - y1;
  580. POINTL p;
  581. p.x = 0L;
  582. p.y = 0L;
  583. for (float i = 0.1f; i <= 1.09f; i += 0.1f)
  584. {
  585. float j = 3.0f * i * i - 2.0f * i * i * i;
  586. p.x = x1+(int)(dx*i*(1.0f-rate))-m_x;
  587. p.y = y1+(int)(dy*sustain*j)-m_y;
  588. LineTo( m_dcMemory, p.x, p.y );
  589. }
  590. SelectObject( m_dcMemory, oldPen );
  591. DeleteObject( pen );
  592. return p;
  593. };
  594. //-----------------------------------------------------------------------------
  595. // Purpose: Draw a filled rect
  596. // Input : clr -
  597. // x1 -
  598. // y1 -
  599. // x2 -
  600. // y2 -
  601. //-----------------------------------------------------------------------------
  602. void CDrawHelper::DrawFilledRect( COLORREF clr, RECT& rc )
  603. {
  604. RECT rcCopy = rc;
  605. HBRUSH br = CreateSolidBrush( clr );
  606. OffsetSubRect( rcCopy );
  607. FillRect( m_dcMemory, &rcCopy, br );
  608. DeleteObject( br );
  609. }
  610. //-----------------------------------------------------------------------------
  611. // Purpose: Draw a filled rect
  612. // Input : clr -
  613. // x1 -
  614. // y1 -
  615. // x2 -
  616. // y2 -
  617. //-----------------------------------------------------------------------------
  618. void CDrawHelper::DrawFilledRect( COLORREF clr, int x1, int y1, int x2, int y2 )
  619. {
  620. HBRUSH br = CreateSolidBrush( clr );
  621. RECT rc;
  622. rc.left = x1;
  623. rc.right = x2;
  624. rc.top = y1;
  625. rc.bottom = y2;
  626. OffsetSubRect( rc );
  627. FillRect( m_dcMemory, &rc, br );
  628. DeleteObject( br );
  629. }
  630. //-----------------------------------------------------------------------------
  631. // Purpose:
  632. // Input : clr -
  633. // style -
  634. // width -
  635. // rc -
  636. //-----------------------------------------------------------------------------
  637. void CDrawHelper::DrawOutlinedRect( COLORREF clr, int style, int width, RECT& rc )
  638. {
  639. DrawOutlinedRect( clr, style, width, rc.left, rc.top, rc.right, rc.bottom );
  640. }
  641. //-----------------------------------------------------------------------------
  642. // Purpose: Draw an outlined rect
  643. // Input : clr -
  644. // style -
  645. // width -
  646. // x1 -
  647. // y1 -
  648. // x2 -
  649. // y2 -
  650. //-----------------------------------------------------------------------------
  651. void CDrawHelper::DrawOutlinedRect( COLORREF clr, int style, int width, int x1, int y1, int x2, int y2 )
  652. {
  653. HPEN oldpen, pen;
  654. HBRUSH oldbrush, brush;
  655. pen = CreatePen( PS_SOLID, width, clr );
  656. oldpen = (HPEN)SelectObject( m_dcMemory, pen );
  657. brush = (HBRUSH)GetStockObject( NULL_BRUSH );
  658. oldbrush = (HBRUSH)SelectObject( m_dcMemory, brush );
  659. RECT rc;
  660. rc.left = x1;
  661. rc.right = x2;
  662. rc.top = y1;
  663. rc.bottom = y2;
  664. OffsetSubRect( rc);
  665. Rectangle( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom );
  666. SelectObject( m_dcMemory, oldbrush );
  667. DeleteObject( brush );
  668. SelectObject( m_dcMemory, oldpen );
  669. DeleteObject( pen );
  670. }
  671. //-----------------------------------------------------------------------------
  672. // Purpose:
  673. // Input : x1 -
  674. // y1 -
  675. // x2 -
  676. // y2 -
  677. // clr -
  678. // thickness -
  679. //-----------------------------------------------------------------------------
  680. void CDrawHelper::DrawLine( int x1, int y1, int x2, int y2, COLORREF clr, int thickness )
  681. {
  682. HPEN oldpen, pen;
  683. HBRUSH oldbrush, brush;
  684. pen = CreatePen( PS_SOLID, thickness, clr );
  685. oldpen = (HPEN)SelectObject( m_dcMemory, pen );
  686. brush = (HBRUSH)GetStockObject( NULL_BRUSH );
  687. oldbrush = (HBRUSH)SelectObject( m_dcMemory, brush );
  688. // Offset
  689. x1 -= m_x;
  690. x2 -= m_x;
  691. y1 -= m_y;
  692. y2 -= m_y;
  693. MoveToEx( m_dcMemory, x1, y1, NULL );
  694. LineTo( m_dcMemory, x2, y2 );
  695. SelectObject( m_dcMemory, oldbrush );
  696. DeleteObject( brush );
  697. SelectObject( m_dcMemory, oldpen );
  698. DeleteObject( pen );
  699. }
  700. //-----------------------------------------------------------------------------
  701. // Purpose:
  702. // Input : rc -
  703. // fillr -
  704. // fillg -
  705. // fillb -
  706. //-----------------------------------------------------------------------------
  707. void CDrawHelper::DrawTriangleMarker( RECT& rc, COLORREF fill, bool inverted /*= false*/ )
  708. {
  709. POINT region[3];
  710. int cPoints = 3;
  711. if ( !inverted )
  712. {
  713. region[ 0 ].x = rc.left - m_x;
  714. region[ 0 ].y = rc.top - m_y;
  715. region[ 1 ].x = rc.right - m_x;
  716. region[ 1 ].y = rc.top - m_y;
  717. region[ 2 ].x = ( ( rc.left + rc.right ) / 2 ) - m_x;
  718. region[ 2 ].y = rc.bottom - m_y;
  719. }
  720. else
  721. {
  722. region[ 0 ].x = rc.left - m_x;
  723. region[ 0 ].y = rc.bottom - m_y;
  724. region[ 1 ].x = rc.right - m_x;
  725. region[ 1 ].y = rc.bottom - m_y;
  726. region[ 2 ].x = ( ( rc.left + rc.right ) / 2 ) - m_x;
  727. region[ 2 ].y = rc.top - m_y;
  728. }
  729. HRGN rgn = CreatePolygonRgn( region, cPoints, ALTERNATE );
  730. int oldPF = SetPolyFillMode( m_dcMemory, ALTERNATE );
  731. HBRUSH brFace = CreateSolidBrush( fill );
  732. FillRgn( m_dcMemory, rgn, brFace );
  733. DeleteObject( brFace );
  734. SetPolyFillMode( m_dcMemory, oldPF );
  735. DeleteObject( rgn );
  736. }
  737. void CDrawHelper::StartClipping( RECT& clipRect )
  738. {
  739. RECT fixed = clipRect;
  740. OffsetSubRect( fixed );
  741. m_ClipRects.AddToTail( fixed );
  742. ClipToRects();
  743. }
  744. void CDrawHelper::StopClipping( void )
  745. {
  746. Assert( m_ClipRects.Size() > 0 );
  747. if ( m_ClipRects.Size() <= 0 )
  748. return;
  749. m_ClipRects.Remove( m_ClipRects.Size() - 1 );
  750. ClipToRects();
  751. }
  752. void CDrawHelper::ClipToRects( void )
  753. {
  754. SelectClipRgn( m_dcMemory, NULL );
  755. if ( m_ClipRegion )
  756. {
  757. DeleteObject( m_ClipRegion );
  758. m_ClipRegion = HRGN( 0 );
  759. }
  760. if ( m_ClipRects.Size() > 0 )
  761. {
  762. RECT rc = m_ClipRects[ 0 ];
  763. m_ClipRegion = CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom );
  764. for ( int i = 1; i < m_ClipRects.Size(); i++ )
  765. {
  766. RECT add = m_ClipRects[ i ];
  767. HRGN addIn = CreateRectRgn( add.left, add.top, add.right, add.bottom );
  768. HRGN result = CreateRectRgn( 0, 0, 100, 100 );
  769. CombineRgn( result, m_ClipRegion, addIn, RGN_AND );
  770. DeleteObject( m_ClipRegion );
  771. DeleteObject( addIn );
  772. m_ClipRegion = result;
  773. }
  774. }
  775. SelectClipRgn( m_dcMemory, m_ClipRegion );
  776. }
  777. //-----------------------------------------------------------------------------
  778. // Purpose:
  779. // Input : rc -
  780. //-----------------------------------------------------------------------------
  781. void CDrawHelper::OffsetSubRect( RECT& rc )
  782. {
  783. OffsetRect( &rc, -m_x, -m_y );
  784. }
  785. //-----------------------------------------------------------------------------
  786. // Purpose:
  787. // Input : br -
  788. // rc -
  789. //-----------------------------------------------------------------------------
  790. void CDrawHelper::DrawFilledRect( HBRUSH br, RECT& rc )
  791. {
  792. RECT rcFill = rc;
  793. OffsetSubRect( rcFill );
  794. FillRect( m_dcMemory, &rcFill, br );
  795. }
  796. void CDrawHelper::DrawCircle( COLORREF clr, int x, int y, int radius, bool filled /*= true*/ )
  797. {
  798. RECT rc;
  799. rc.left = x - radius / 2;
  800. rc.right = rc.left + radius;
  801. rc.top = y - radius / 2;
  802. rc.bottom = y + radius;
  803. OffsetSubRect( rc );
  804. HPEN pen = CreatePen( PS_SOLID, 1, clr );
  805. HBRUSH br = CreateSolidBrush( clr );
  806. HPEN oldPen = (HPEN)SelectObject( m_dcMemory, pen );
  807. HBRUSH oldBr = (HBRUSH)SelectObject( m_dcMemory, br );
  808. if ( filled )
  809. {
  810. Ellipse( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom );
  811. }
  812. else
  813. {
  814. Arc( m_dcMemory, rc.left, rc.top, rc.right, rc.bottom,
  815. rc.left, rc.top, rc.left, rc.top );
  816. }
  817. SelectObject( m_dcMemory, oldPen );
  818. SelectObject( m_dcMemory, oldBr );
  819. DeleteObject( pen );
  820. DeleteObject( br );
  821. }
  822. //-----------------------------------------------------------------------------
  823. // Purpose:
  824. // Input : rc -
  825. // clr1 -
  826. // clr2 -
  827. // vertical -
  828. //-----------------------------------------------------------------------------
  829. void CDrawHelper::DrawGradientFilledRect( RECT& rc, COLORREF clr1, COLORREF clr2, bool vertical )
  830. {
  831. RECT rcDraw = rc;
  832. OffsetRect( &rcDraw, -m_x, -m_y );
  833. TRIVERTEX vert[2] ;
  834. GRADIENT_RECT gradient_rect;
  835. vert[0].x = rcDraw.left;
  836. vert[0].y = rcDraw.top;
  837. vert[0].Red = GetRValue( clr1 ) << 8;
  838. vert[0].Green = GetGValue( clr1 ) << 8;
  839. vert[0].Blue = GetBValue( clr1 ) << 8;
  840. vert[0].Alpha = 0x0000;
  841. vert[1].x = rcDraw.right;
  842. vert[1].y = rcDraw.bottom;
  843. vert[1].Red = GetRValue( clr2 ) << 8;
  844. vert[1].Green = GetGValue( clr2 ) << 8;
  845. vert[1].Blue = GetBValue( clr2 ) << 8;
  846. vert[1].Alpha = 0x0000;
  847. gradient_rect.UpperLeft = 0;
  848. gradient_rect.LowerRight = 1;
  849. GradientFill(
  850. m_dcMemory,
  851. vert, 2,
  852. &gradient_rect, 1,
  853. vertical ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H );
  854. }