Source code of Windows XP (NT5)
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.

404 lines
14 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998, 1999, 2000
  4. *
  5. * TITLE: PAINTERS.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 1/13/1999
  12. *
  13. * DESCRIPTION: Image transition base class and derived classes
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include "painters.h"
  19. #include <windowsx.h>
  20. #include "ssutil.h"
  21. #include "isdbg.h"
  22. CImagePainter::CImagePainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  23. : m_pBitmapImage(pBitmapImage),
  24. m_dwInitialTickCount(0),
  25. m_rcScreen(rcScreen),
  26. m_rcImageArea(rcImageArea),
  27. m_bFirstFrame(true),
  28. m_dwDuration(0),
  29. m_bAlreadyPaintedLastFrame(false)
  30. {
  31. if (m_pBitmapImage)
  32. {
  33. m_rcFinal = m_RandomNumberGen.Generate( m_pBitmapImage->ImageSize().cx, m_pBitmapImage->ImageSize().cy, rcImageArea );
  34. WIA_TRACE((TEXT("Image size: (%d, %d)"), m_pBitmapImage->ImageSize().cx, m_pBitmapImage->ImageSize().cy ));
  35. WIA_TRACE((TEXT("Chosen Final Rect = (%d,%d), (%d,%d)"), m_rcFinal.left, m_rcFinal.top, m_rcFinal.right, m_rcFinal.bottom ));
  36. }
  37. }
  38. CImagePainter::~CImagePainter(void)
  39. {
  40. if (m_pBitmapImage)
  41. {
  42. delete m_pBitmapImage;
  43. }
  44. m_pBitmapImage = NULL;
  45. }
  46. DWORD CImagePainter::ElapsedTime(void) const
  47. {
  48. DWORD dwElapsed = GetTickCount() - m_dwInitialTickCount;
  49. if (dwElapsed > m_dwDuration)
  50. dwElapsed = m_dwDuration;
  51. return(dwElapsed);
  52. }
  53. CBitmapImage *CImagePainter::BitmapImage(void)
  54. {
  55. return(m_pBitmapImage);
  56. }
  57. void CImagePainter::Paint( CSimpleDC &PaintDC )
  58. {
  59. if (PaintDC.IsValid() && m_pBitmapImage)
  60. {
  61. ScreenSaverUtil::SelectPalette( PaintDC, m_pBitmapImage->Palette(), FALSE );
  62. CSimpleDC MemoryDC;
  63. if (MemoryDC.CreateCompatibleDC(PaintDC))
  64. {
  65. ScreenSaverUtil::SelectPalette( MemoryDC, m_pBitmapImage->Palette(), FALSE );
  66. Paint( PaintDC, MemoryDC );
  67. }
  68. }
  69. }
  70. void CImagePainter::Paint( CSimpleDC &PaintDC, CSimpleDC &MemoryDC )
  71. {
  72. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  73. BitBlt( PaintDC, m_rcFinal.left, m_rcFinal.top, RECT_WIDTH(m_rcFinal), RECT_HEIGHT(m_rcFinal), MemoryDC, 0, 0, SRCCOPY );
  74. }
  75. bool CImagePainter::TimerTick( CSimpleDC &ClientDC )
  76. {
  77. bool bStopPainting = false;
  78. if (m_bFirstFrame)
  79. {
  80. m_dwInitialTickCount = GetTickCount();
  81. Erase( ClientDC, m_rcScreen );
  82. }
  83. //
  84. if (m_bFirstFrame || NeedPainting())
  85. {
  86. if (m_pBitmapImage && ClientDC.IsValid())
  87. {
  88. ScreenSaverUtil::SelectPalette( ClientDC, m_pBitmapImage->Palette(), FALSE );
  89. CSimpleDC MemoryDC;
  90. if (MemoryDC.CreateCompatibleDC(ClientDC))
  91. {
  92. ScreenSaverUtil::SelectPalette( MemoryDC, m_pBitmapImage->Palette(), FALSE );
  93. PaintFrame( ClientDC, MemoryDC );
  94. }
  95. }
  96. if (m_bFirstFrame)
  97. m_bFirstFrame = false;
  98. }
  99. else bStopPainting = true;
  100. return bStopPainting;
  101. }
  102. void CImagePainter::Erase( CSimpleDC &ClientDC, RECT &rc )
  103. {
  104. FillRect( ClientDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH) );
  105. }
  106. bool CImagePainter::NeedPainting(void)
  107. {
  108. return(false);
  109. }
  110. bool CImagePainter::IsValid(void)
  111. {
  112. return(m_pBitmapImage && m_pBitmapImage->GetBitmap());
  113. }
  114. /****************************************************************************
  115. CSimpleTransitionPainter
  116. *****************************************************************************/
  117. CSimpleTransitionPainter::CSimpleTransitionPainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  118. : CImagePainter( pBitmapImage, ClientDC, rcImageArea, rcScreen )
  119. {
  120. }
  121. CSimpleTransitionPainter::~CSimpleTransitionPainter(void)
  122. {
  123. }
  124. void CSimpleTransitionPainter::PaintFrame( CSimpleDC &ClientDC, CSimpleDC &MemoryDC )
  125. {
  126. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  127. SIZE sizeImage = BitmapImage()->ImageSize();
  128. BitBlt( ClientDC, m_rcFinal.left, m_rcFinal.top, sizeImage.cx, sizeImage.cy, MemoryDC, 0, 0, SRCCOPY );
  129. }
  130. /****************************************************************************
  131. CSlidingTransitionPainter
  132. *****************************************************************************/
  133. CSlidingTransitionPainter::CSlidingTransitionPainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  134. : CImagePainter( pBitmapImage, ClientDC, rcImageArea, rcScreen )
  135. {
  136. m_dwDuration = 5000;
  137. ZeroMemory(&m_rcPrevious,sizeof(m_rcPrevious));
  138. switch (CRandomNumberGen().Generate(8))
  139. {
  140. case 0:
  141. // left, top
  142. m_rcOriginal.left = rcScreen.left - BitmapImage()->ImageSize().cx;
  143. m_rcOriginal.top = rcScreen.top - BitmapImage()->ImageSize().cy;
  144. m_rcOriginal.right = rcScreen.left;
  145. m_rcOriginal.bottom = rcScreen.top;
  146. break;
  147. case 1:
  148. // top
  149. m_rcOriginal.left = m_rcFinal.left;
  150. m_rcOriginal.top = rcScreen.top - BitmapImage()->ImageSize().cy;
  151. m_rcOriginal.right = m_rcFinal.right;
  152. m_rcOriginal.bottom = rcScreen.top;
  153. break;
  154. case 2:
  155. // right, top
  156. m_rcOriginal.left = rcScreen.right;
  157. m_rcOriginal.top = rcScreen.top - BitmapImage()->ImageSize().cy;
  158. m_rcOriginal.right = rcScreen.right + BitmapImage()->ImageSize().cx;
  159. m_rcOriginal.bottom = rcScreen.top;
  160. break;
  161. case 3:
  162. // right
  163. m_rcOriginal.left = rcScreen.right;
  164. m_rcOriginal.top = m_rcFinal.top;
  165. m_rcOriginal.right = rcScreen.right + BitmapImage()->ImageSize().cx;
  166. m_rcOriginal.bottom = m_rcFinal.bottom;
  167. break;
  168. case 4:
  169. // right, bottom
  170. m_rcOriginal.left = rcScreen.right;
  171. m_rcOriginal.top = rcScreen.bottom;
  172. m_rcOriginal.right = rcScreen.right + BitmapImage()->ImageSize().cx;
  173. m_rcOriginal.bottom = rcScreen.bottom + BitmapImage()->ImageSize().cy;
  174. break;
  175. case 5:
  176. // bottom
  177. m_rcOriginal.left = m_rcFinal.left;
  178. m_rcOriginal.top = rcScreen.bottom;
  179. m_rcOriginal.right = m_rcFinal.right;
  180. m_rcOriginal.bottom = rcScreen.bottom + BitmapImage()->ImageSize().cy;
  181. break;
  182. case 6:
  183. // left,bottom
  184. m_rcOriginal.left = rcScreen.left - BitmapImage()->ImageSize().cx;
  185. m_rcOriginal.top = rcScreen.bottom;
  186. m_rcOriginal.right = rcScreen.left;
  187. m_rcOriginal.bottom = rcScreen.bottom + BitmapImage()->ImageSize().cy;
  188. break;
  189. case 7:
  190. // left
  191. m_rcOriginal.left = rcScreen.left - BitmapImage()->ImageSize().cx;
  192. m_rcOriginal.top = m_rcFinal.top;
  193. m_rcOriginal.right = rcScreen.left;
  194. m_rcOriginal.bottom = m_rcFinal.bottom;
  195. break;
  196. }
  197. }
  198. CSlidingTransitionPainter::~CSlidingTransitionPainter(void)
  199. {
  200. }
  201. bool CSlidingTransitionPainter::NeedPainting(void)
  202. {
  203. if (!memcmp( &m_rcPrevious, &m_rcFinal, sizeof(RECT)))
  204. return false;
  205. return true;
  206. }
  207. void CSlidingTransitionPainter::PaintFrame( CSimpleDC &ClientDC, CSimpleDC &MemoryDC )
  208. {
  209. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  210. SIZE sizeImage = BitmapImage()->ImageSize();
  211. DWORD dwElapsedTime = ElapsedTime();
  212. SIZE sizeDelta;
  213. sizeDelta.cx = m_rcFinal.left - m_rcOriginal.left;
  214. sizeDelta.cy = m_rcFinal.top - m_rcOriginal.top;
  215. SIZE sizeOffset;
  216. sizeOffset.cx = MulDiv(sizeDelta.cx,dwElapsedTime,m_dwDuration);
  217. sizeOffset.cy = MulDiv(sizeDelta.cy,dwElapsedTime,m_dwDuration);
  218. // Make sure we don't overshoot the final rect
  219. if (WiaUiUtil::Absolute(sizeOffset.cx) > WiaUiUtil::Absolute(m_rcFinal.left - m_rcOriginal.left))
  220. sizeOffset.cx = m_rcFinal.left - m_rcOriginal.left;
  221. if (WiaUiUtil::Absolute(sizeOffset.cy) > WiaUiUtil::Absolute(m_rcFinal.top - m_rcOriginal.top))
  222. sizeOffset.cy = m_rcFinal.top - m_rcOriginal.top;
  223. RECT rcCurr = m_rcOriginal;
  224. ScreenSaverUtil::NormalizeRect(rcCurr);
  225. OffsetRect( &rcCurr, sizeOffset.cx, sizeOffset.cy );
  226. ScreenSaverUtil::EraseDiffRect( ClientDC, m_rcPrevious, rcCurr, (HBRUSH)GetStockObject(BLACK_BRUSH) );
  227. BitBlt( ClientDC, rcCurr.left, rcCurr.top, sizeImage.cx, sizeImage.cy, MemoryDC, 0, 0, SRCCOPY );
  228. m_rcPrevious = rcCurr;
  229. }
  230. /****************************************************************************
  231. CRandomBlockPainter
  232. *****************************************************************************/
  233. CRandomBlockPainter::CRandomBlockPainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  234. : CImagePainter( pBitmapImage, ClientDC, rcImageArea, rcScreen ),m_pBlockAddresses(NULL),m_nBlockSize(10),m_nStartIndex(0)
  235. {
  236. m_dwDuration = 2000;
  237. SIZE sizeImage = BitmapImage()->ImageSize();
  238. m_sizeBlockCount.cx = WiaUiUtil::Align( sizeImage.cx, m_nBlockSize ) / m_nBlockSize;
  239. m_sizeBlockCount.cy = WiaUiUtil::Align( sizeImage.cy, m_nBlockSize ) / m_nBlockSize;
  240. m_pBlockAddresses = new int[m_sizeBlockCount.cx * m_sizeBlockCount.cy];
  241. if (m_pBlockAddresses)
  242. {
  243. int i;
  244. for (i=0;i<m_sizeBlockCount.cx * m_sizeBlockCount.cy;i++)
  245. {
  246. m_pBlockAddresses[i] = i;
  247. }
  248. for (i=0;i<m_sizeBlockCount.cx * m_sizeBlockCount.cy;i++)
  249. {
  250. ScreenSaverUtil::Swap( m_pBlockAddresses[i], m_pBlockAddresses[m_RandomNumberGen.Generate(i,m_sizeBlockCount.cx * m_sizeBlockCount.cy)]);
  251. }
  252. }
  253. }
  254. CRandomBlockPainter::~CRandomBlockPainter(void)
  255. {
  256. if (m_pBlockAddresses)
  257. delete[] m_pBlockAddresses;
  258. m_pBlockAddresses = NULL;
  259. }
  260. bool CRandomBlockPainter::NeedPainting(void)
  261. {
  262. return(m_nStartIndex < m_sizeBlockCount.cx * m_sizeBlockCount.cy);
  263. }
  264. bool CRandomBlockPainter::IsValid(void)
  265. {
  266. return (CImagePainter::IsValid() && m_pBlockAddresses != NULL);
  267. }
  268. void CRandomBlockPainter::PaintFrame( CSimpleDC &ClientDC, CSimpleDC &MemoryDC )
  269. {
  270. if (m_pBlockAddresses)
  271. {
  272. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  273. int nDoUntilIndex = ((m_sizeBlockCount.cx * m_sizeBlockCount.cy) * ElapsedTime()) / m_dwDuration;
  274. for (int i=m_nStartIndex;i<nDoUntilIndex && i<m_sizeBlockCount.cx * m_sizeBlockCount.cy;i++)
  275. {
  276. int nRow = (m_pBlockAddresses[i] / m_sizeBlockCount.cx) * m_nBlockSize;
  277. int nCol = (m_pBlockAddresses[i] % m_sizeBlockCount.cx) * m_nBlockSize;
  278. BitBlt( ClientDC, m_rcFinal.left+nCol, m_rcFinal.top+nRow, m_nBlockSize, m_nBlockSize, MemoryDC, nCol, nRow, SRCCOPY );
  279. }
  280. m_nStartIndex = nDoUntilIndex;
  281. }
  282. }
  283. /****************************************************************************
  284. CAlphaFadePainter
  285. *****************************************************************************/
  286. CAlphaFadePainter::CAlphaFadePainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  287. : CImagePainter( pBitmapImage, ClientDC, rcImageArea, rcScreen )
  288. {
  289. m_dwDuration = 6000;
  290. if (BitmapImage())
  291. {
  292. ZeroMemory(&m_bfBlendFunction,sizeof(m_bfBlendFunction));
  293. m_bfBlendFunction.BlendOp = AC_SRC_OVER;
  294. m_bfBlendFunction.SourceConstantAlpha = 0;
  295. m_hbmpBuffer = CreateCompatibleBitmap( ClientDC, BitmapImage()->ImageSize().cx, BitmapImage()->ImageSize().cy );
  296. CompatDC.CreateCompatibleDC( ClientDC );
  297. }
  298. }
  299. bool CAlphaFadePainter::IsValid(void)
  300. {
  301. return (CImagePainter::IsValid() && m_hbmpBuffer != NULL && CompatDC.IsValid());
  302. }
  303. CAlphaFadePainter::~CAlphaFadePainter(void)
  304. {
  305. if (m_hbmpBuffer)
  306. DeleteObject(m_hbmpBuffer);
  307. }
  308. bool CAlphaFadePainter::NeedPainting(void)
  309. {
  310. return(m_bfBlendFunction.SourceConstantAlpha < 0xFF);
  311. }
  312. void CAlphaFadePainter::PaintFrame( CSimpleDC &ClientDC, CSimpleDC &MemoryDC )
  313. {
  314. ScreenSaverUtil::SelectPalette( CompatDC, BitmapImage()->Palette(), FALSE );
  315. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  316. HBITMAP hOldBufferBitmap = SelectBitmap( CompatDC, m_hbmpBuffer );
  317. DWORD dwCurrentIndex = (ElapsedTime() * 0xFF) / m_dwDuration;
  318. m_bfBlendFunction.SourceConstantAlpha = (BYTE)(dwCurrentIndex > 255 ? 255 : dwCurrentIndex);
  319. RECT rcImage;
  320. rcImage.left = rcImage.top = 0;
  321. rcImage.right = BitmapImage()->ImageSize().cx;
  322. rcImage.bottom = BitmapImage()->ImageSize().cy;
  323. FillRect( CompatDC, &rcImage, (HBRUSH)GetStockObject(BLACK_BRUSH) );
  324. AlphaBlend( CompatDC, 0, 0, RECT_WIDTH(m_rcFinal), RECT_HEIGHT(m_rcFinal), MemoryDC, 0, 0, RECT_WIDTH(m_rcFinal), RECT_HEIGHT(m_rcFinal), m_bfBlendFunction );
  325. BitBlt( ClientDC, m_rcFinal.left, m_rcFinal.top, RECT_WIDTH(m_rcFinal), RECT_HEIGHT(m_rcFinal), CompatDC, 0, 0, SRCCOPY );
  326. SelectBitmap( CompatDC, hOldBufferBitmap );
  327. }
  328. /****************************************************************************
  329. COpenCurtainPainter
  330. *****************************************************************************/
  331. COpenCurtainPainter::COpenCurtainPainter( CBitmapImage *pBitmapImage, CSimpleDC &ClientDC, const RECT &rcImageArea, const RECT &rcScreen )
  332. : CImagePainter( pBitmapImage, ClientDC, rcImageArea, rcScreen ), m_nCurrentWidth(0)
  333. {
  334. m_dwDuration = 3000;
  335. m_nFinalWidth = WiaUiUtil::Align(BitmapImage()->ImageSize().cx,2)/2;
  336. }
  337. COpenCurtainPainter::~COpenCurtainPainter(void)
  338. {
  339. }
  340. bool COpenCurtainPainter::NeedPainting(void)
  341. {
  342. return (m_nCurrentWidth < m_nFinalWidth);
  343. }
  344. void COpenCurtainPainter::PaintFrame( CSimpleDC &ClientDC, CSimpleDC &MemoryDC )
  345. {
  346. m_nCurrentWidth = WiaUiUtil::MulDivNoRound( m_nFinalWidth, ElapsedTime(), m_dwDuration );
  347. SelectBitmap( MemoryDC, BitmapImage()->GetBitmap() );
  348. BitBlt( ClientDC, m_rcFinal.left, m_rcFinal.top, m_nCurrentWidth, m_rcFinal.bottom-m_rcFinal.top, MemoryDC, 0, 0, SRCCOPY );
  349. BitBlt( ClientDC, m_rcFinal.right-m_nCurrentWidth, m_rcFinal.top, m_nCurrentWidth, RECT_HEIGHT(m_rcFinal), MemoryDC, RECT_WIDTH(m_rcFinal)-m_nCurrentWidth, 0, SRCCOPY );
  350. }