Leaked source code of windows server 2003
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.

379 lines
12 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998, 1999, 2000
  4. *
  5. * TITLE: IMGS.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 1/13/1999
  12. *
  13. * DESCRIPTION: Image class
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include "imgs.h"
  19. #include <windowsx.h>
  20. #include <atlbase.h>
  21. #include "ssutil.h"
  22. #include "gphelper.h"
  23. CBitmapImage::CBitmapImage(void)
  24. : m_hBitmap(NULL),
  25. m_hPalette(NULL)
  26. {
  27. WIA_PUSHFUNCTION(TEXT("CBitmapImage::CBitmapImage"));
  28. }
  29. CBitmapImage::~CBitmapImage(void)
  30. {
  31. WIA_PUSHFUNCTION(TEXT("CBitmapImage::~CBitmapImage"));
  32. Destroy();
  33. }
  34. void CBitmapImage::Destroy(void)
  35. {
  36. WIA_PUSHFUNCTION(TEXT("CBitmapImage::Destroy"));
  37. if (m_hBitmap)
  38. DeleteObject(m_hBitmap);
  39. m_hBitmap = NULL;
  40. if (m_hPalette)
  41. DeleteObject(m_hPalette);
  42. m_hPalette = NULL;
  43. }
  44. bool CBitmapImage::IsValid(void) const
  45. {
  46. return(m_hBitmap != NULL);
  47. }
  48. HPALETTE CBitmapImage::Palette(void) const
  49. {
  50. return(m_hPalette);
  51. }
  52. HBITMAP CBitmapImage::GetBitmap(void) const
  53. {
  54. return(m_hBitmap);
  55. }
  56. // Create a palette for the image
  57. HPALETTE CBitmapImage::PreparePalette( CSimpleDC &dc, HBITMAP hBitmap )
  58. {
  59. WIA_PUSHFUNCTION(TEXT("CBitmapImage::PreparePalette"));
  60. HPALETTE hPalette = NULL;
  61. if (GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE)
  62. {
  63. if (hBitmap)
  64. {
  65. DIBSECTION ds = {0};
  66. GetObject(hBitmap, sizeof (DIBSECTION), &ds);
  67. int nColors;
  68. if (ds.dsBmih.biClrUsed != 0)
  69. {
  70. nColors = ds.dsBmih.biClrUsed;
  71. }
  72. else
  73. {
  74. //
  75. // Handle the special case of an image that claims to be
  76. // a 32bit DIB as a 24bit DIB
  77. //
  78. if (ds.dsBmih.biBitCount == 32)
  79. {
  80. nColors = 1 << 24;
  81. }
  82. else
  83. {
  84. nColors = 1 << ds.dsBmih.biBitCount;
  85. }
  86. }
  87. //
  88. // Create a halftone palette if the DIB section contains more
  89. // than 256 colors
  90. //
  91. if (nColors > 256)
  92. {
  93. hPalette = CreateHalftonePalette(dc);
  94. }
  95. //
  96. // Create a custom palette from the DIB section's color table
  97. // if the number of colors is 256 or less
  98. //
  99. else
  100. {
  101. RGBQUAD* pRGB = new RGBQUAD[nColors];
  102. if (pRGB)
  103. {
  104. CSimpleDC MemDC;
  105. MemDC.CreateCompatibleDC(dc);
  106. SelectObject( MemDC, hBitmap );
  107. GetDIBColorTable( MemDC, 0, nColors, pRGB );
  108. UINT nSize = sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * (nColors - 1));
  109. LOGPALETTE* pLP = (LOGPALETTE*) new BYTE[nSize];
  110. if (pLP)
  111. {
  112. pLP->palVersion = 0x300;
  113. pLP->palNumEntries = (WORD)nColors;
  114. for (int i=0; i<nColors; i++)
  115. {
  116. pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
  117. pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
  118. pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
  119. pLP->palPalEntry[i].peFlags = 0;
  120. }
  121. hPalette = CreatePalette(pLP);
  122. delete[] pLP;
  123. }
  124. delete[] pRGB;
  125. }
  126. }
  127. }
  128. }
  129. else
  130. {
  131. hPalette = CreateHalftonePalette(dc);
  132. }
  133. WIA_TRACE((TEXT("Returning palette %08X"), hPalette ));
  134. return hPalette;
  135. }
  136. SIZE CBitmapImage::ImageSize(void) const
  137. {
  138. SIZE sizeImage = {0,0};
  139. if (IsValid())
  140. {
  141. BITMAP bm = {0};
  142. if (GetObject( m_hBitmap, sizeof(bm), &bm ))
  143. {
  144. sizeImage.cx = bm.bmWidth;
  145. sizeImage.cy = bm.bmHeight;
  146. }
  147. }
  148. return(sizeImage);
  149. }
  150. bool CBitmapImage::CreateFromText( LPCTSTR pszText, const RECT &rcScreen, int nMaxScreenPercent )
  151. {
  152. Destroy();
  153. HDC hDesktopDC = GetDC(NULL);
  154. if (hDesktopDC)
  155. {
  156. //
  157. // Calculate the maximum size of the text rectangle
  158. //
  159. RECT rcImage = { 0, 0, WiaUiUtil::MulDivNoRound(rcScreen.right - rcScreen.left,nMaxScreenPercent,100), WiaUiUtil::MulDivNoRound(rcScreen.bottom - rcScreen.top,nMaxScreenPercent,100) };
  160. //
  161. // Create a mem dc to hold the bitmap
  162. //
  163. CSimpleDC MemDC;
  164. if (MemDC.CreateCompatibleDC(hDesktopDC))
  165. {
  166. //
  167. // Use the default UI font
  168. //
  169. SelectObject( MemDC, GetStockObject( DEFAULT_GUI_FONT ) );
  170. //
  171. // Figure out how big the bitmap has to be
  172. //
  173. DrawText( MemDC, pszText, lstrlen(pszText), &rcImage, DT_NOPREFIX|DT_WORDBREAK|DT_CALCRECT|DT_RTLREADING );
  174. //
  175. // Create the bitmap
  176. //
  177. m_hBitmap = CreateCompatibleBitmap( hDesktopDC, rcImage.right, rcImage.bottom );
  178. if (m_hBitmap)
  179. {
  180. //
  181. // Set the appropriate colors and select the bitmap into the DC
  182. //
  183. SetBkColor( MemDC, RGB(0,0,0) );
  184. SetTextColor( MemDC, RGB(255,255,255) );
  185. SelectBitmap( MemDC, m_hBitmap );
  186. //
  187. // Draw the actual text
  188. //
  189. DrawText( MemDC, pszText, lstrlen(pszText), &rcImage, DT_NOPREFIX|DT_WORDBREAK|DT_RTLREADING );
  190. }
  191. }
  192. //
  193. // Free the desktop DC
  194. //
  195. ReleaseDC(NULL,hDesktopDC);
  196. }
  197. return m_hBitmap != NULL;
  198. }
  199. bool CBitmapImage::Load( CSimpleDC &dc,
  200. LPCTSTR pszFilename,
  201. const RECT &rcScreen,
  202. int nMaxScreenPercent,
  203. bool bAllowStretching,
  204. bool bDisplayFilename
  205. )
  206. {
  207. //
  208. // Clean up, if necessary
  209. //
  210. Destroy();
  211. //
  212. // Validate the arguments
  213. //
  214. if (!pszFilename || !lstrlen(pszFilename))
  215. {
  216. return false;
  217. }
  218. //
  219. // Try to load and scale the image using GDI plus
  220. //
  221. CGdiPlusHelper GdiPlusHelper;
  222. if (SUCCEEDED(GdiPlusHelper.LoadAndScale( m_hBitmap, pszFilename, WiaUiUtil::MulDivNoRound(rcScreen.right - rcScreen.left,nMaxScreenPercent,100), WiaUiUtil::MulDivNoRound(rcScreen.bottom - rcScreen.top,nMaxScreenPercent,100), bAllowStretching )) && m_hBitmap)
  223. {
  224. //
  225. // Get the size of the image
  226. //
  227. SIZE sizeImage = ImageSize();
  228. //
  229. // Prepare the image's palette, if it has one
  230. //
  231. m_hPalette = PreparePalette( dc, m_hBitmap );
  232. //
  233. // Add the image title
  234. //
  235. if (bDisplayFilename && *pszFilename)
  236. {
  237. CSimpleDC MemoryDC;
  238. if (MemoryDC.CreateCompatibleDC(dc))
  239. {
  240. //
  241. // Prepare the DC and select the current image into it
  242. //
  243. ScreenSaverUtil::SelectPalette( MemoryDC, Palette(), FALSE );
  244. SelectBitmap( MemoryDC, m_hBitmap );
  245. SetBkMode( MemoryDC, TRANSPARENT );
  246. //
  247. // Create the title DC
  248. //
  249. CSimpleDC ImageTitleDC;
  250. if (ImageTitleDC.CreateCompatibleDC(dc))
  251. {
  252. //
  253. // Prepare the title DC
  254. //
  255. ScreenSaverUtil::SelectPalette( ImageTitleDC, Palette(), FALSE );
  256. SelectFont( ImageTitleDC, (HFONT)GetStockObject(DEFAULT_GUI_FONT) );
  257. SetBkMode( ImageTitleDC, TRANSPARENT );
  258. //
  259. // Calculate the rectangle needed to print the filename
  260. //
  261. RECT rcText;
  262. rcText.left = 0;
  263. rcText.top = 0;
  264. rcText.right = sizeImage.cx;
  265. rcText.bottom = sizeImage.cy;
  266. //
  267. // Make a nice margin
  268. //
  269. InflateRect( &rcText, -2, -2 );
  270. DrawText( ImageTitleDC, pszFilename, lstrlen(pszFilename), &rcText, DT_PATH_ELLIPSIS|DT_SINGLELINE|DT_NOPREFIX|DT_TOP|DT_LEFT|DT_CALCRECT );
  271. InflateRect( &rcText, 2, 2 );
  272. //
  273. // If the text rect is bigger than the scaled image, make it the same size
  274. //
  275. if (rcText.right > sizeImage.cx)
  276. rcText.right = sizeImage.cx;
  277. if (rcText.bottom > sizeImage.cy)
  278. rcText.bottom = sizeImage.cy;
  279. //
  280. // Create the bitmap we'll use for the filename
  281. //
  282. BITMAPINFO bmi;
  283. ZeroMemory( &bmi, sizeof(BITMAPINFO) );
  284. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  285. bmi.bmiHeader.biWidth = rcText.right - rcText.left;
  286. bmi.bmiHeader.biHeight = rcText.bottom - rcText.top;
  287. bmi.bmiHeader.biPlanes = 1;
  288. bmi.bmiHeader.biBitCount = 24;
  289. bmi.bmiHeader.biCompression = BI_RGB;
  290. PBYTE pBitmapData = NULL;
  291. HBITMAP hBmpImageTitle = CreateDIBSection( dc, &bmi, DIB_RGB_COLORS, (LPVOID*)&pBitmapData, NULL, 0 );
  292. if (hBmpImageTitle)
  293. {
  294. //
  295. // Initialize the Alpha blend stuff
  296. //
  297. BLENDFUNCTION BlendFunction;
  298. ZeroMemory( &BlendFunction, sizeof(BlendFunction) );
  299. BlendFunction.BlendOp = AC_SRC_OVER;
  300. BlendFunction.SourceConstantAlpha = 128;
  301. //
  302. // Select our new bitmap into the memory dc
  303. //
  304. HBITMAP hOldBitmap = SelectBitmap( ImageTitleDC, hBmpImageTitle );
  305. //
  306. // White background
  307. //
  308. FillRect( ImageTitleDC, &rcText, (HBRUSH)GetStockObject(WHITE_BRUSH));
  309. //
  310. // Alpha blend from the stretched bitmap to our text rect
  311. //
  312. AlphaBlend( ImageTitleDC, 0, 0, rcText.right - rcText.left, rcText.bottom - rcText.top, MemoryDC, rcText.left, rcText.top, rcText.right, rcText.bottom, BlendFunction );
  313. //
  314. // Draw the actual text
  315. //
  316. InflateRect( &rcText, -2, -2 );
  317. DrawText( ImageTitleDC, pszFilename, lstrlen(pszFilename), &rcText, DT_PATH_ELLIPSIS|DT_SINGLELINE|DT_NOPREFIX|DT_TOP|DT_LEFT );
  318. InflateRect( &rcText, 2, 2 );
  319. //
  320. // Copy back to the current image
  321. //
  322. BitBlt( MemoryDC, rcText.left, rcText.top, rcText.right - rcText.left, rcText.bottom - rcText.top, ImageTitleDC, 0, 0, SRCCOPY );
  323. //
  324. // Restore the dc's bitmap, and delete our title background
  325. //
  326. DeleteObject( SelectObject( ImageTitleDC, hOldBitmap ) );
  327. }
  328. }
  329. }
  330. }
  331. }
  332. return (m_hBitmap != NULL);
  333. }