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.

292 lines
7.8 KiB

  1. /****************************************************************************
  2. ROTATE.c
  3. The ROTATE module handles rotating a rectangular object.
  4. ****************************************************************************/
  5. #include "stdafx.h"
  6. #include "global.h"
  7. #include "pbrush.h"
  8. #include "pbrusdoc.h"
  9. #include "imgwnd.h"
  10. #include "imgbrush.h"
  11. #include "imgsuprt.h"
  12. #include "bmobject.h"
  13. #include "undo.h"
  14. #include "props.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static CHAR BASED_CODE THIS_FILE[] = __FILE__;
  18. #endif
  19. #include "memtrace.h"
  20. /***************************************************************************/
  21. void CImgWnd::CmdRot90()
  22. {
  23. HideBrush();
  24. CRect rotRect;
  25. HDC hdcSrc;
  26. CPalette* ppalOld = NULL;
  27. if (! theImgBrush.m_pImg && ! g_bCustomBrush)
  28. {
  29. rotRect.SetRect( 0, 0, m_pImg->cxWidth, m_pImg->cyHeight );
  30. hdcSrc = m_pImg->hDC;
  31. }
  32. else
  33. {
  34. PrepareForBrushChange( TRUE, TRUE );
  35. ppalOld = SetImgPalette( &theImgBrush.m_dc );
  36. hdcSrc = theImgBrush.m_dc.GetSafeHdc();
  37. rotRect = rcDragBrush;
  38. rotRect.right -= 1;
  39. rotRect.bottom -= 1;
  40. }
  41. ASSERT( hdcSrc != NULL);
  42. if (rotRect.IsRectEmpty() || ! hdcSrc)
  43. {
  44. if (ppalOld)
  45. theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
  46. return;
  47. }
  48. int iWidth = rotRect.Width();
  49. int iHeight = rotRect.Height();
  50. CRect destRect( 0, 0, iHeight, iWidth );
  51. destRect.OffsetRect( rotRect.left + iWidth / 2 - iHeight / 2,
  52. rotRect.top + iHeight / 2 - iWidth / 2 );
  53. CBitmap bmRotated;
  54. CDC dcRotated;
  55. CDC* pdcImg = CDC::FromHandle( m_pImg->hDC );
  56. if (! bmRotated.CreateCompatibleBitmap( pdcImg, iHeight, iWidth )
  57. || ! dcRotated.CreateCompatibleDC ( pdcImg ))
  58. {
  59. if (ppalOld)
  60. theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
  61. theApp.SetGdiEmergency( TRUE );
  62. return;
  63. }
  64. CBitmap* pbmOld = dcRotated.SelectObject( &bmRotated );
  65. CPalette* ppalRotated = SetImgPalette( &dcRotated );
  66. BeginWaitCursor();
  67. int iRow;
  68. int iCol;
  69. BOOL bDone = FALSE;
  70. // Need code here to get select RECT from the hdcSrc
  71. HDC rowDC = ::CreateCompatibleDC ( hdcSrc );
  72. HDC colDC = ::CreateCompatibleDC ( hdcSrc );
  73. HBITMAP hrowBM = ::CreateCompatibleBitmap( hdcSrc, iWidth, 1 );
  74. HBITMAP hcolBM = ::CreateCompatibleBitmap( hdcSrc, 1, iWidth );
  75. if (rowDC && colDC && hrowBM && hcolBM)
  76. {
  77. HBITMAP scolBM = (HBITMAP)::SelectObject( colDC, hcolBM );
  78. HBITMAP srowBM = (HBITMAP)::SelectObject( rowDC, hrowBM );
  79. ::PatBlt( rowDC, 0, 0, iWidth, 1, BLACKNESS );
  80. ::PatBlt( colDC, 0, 0, 1, iWidth, BLACKNESS );
  81. HPALETTE hpalRow = SetImgPalette( rowDC ); // save to replace later
  82. HPALETTE hpalCol = SetImgPalette( colDC ); // save to replace later
  83. ::SelectObject( colDC, scolBM );
  84. ::SelectObject( rowDC, srowBM );
  85. DWORD dwLen;
  86. LPSTR lpDibRow = (LPSTR) DibFromBitmap(
  87. hrowBM, DIB_RGB_COLORS, 24,
  88. theApp.m_pPalette, NULL, dwLen,
  89. m_pImg->cXPelsPerMeter, m_pImg->cYPelsPerMeter);
  90. LPSTR lpDibCol = (LPSTR) DibFromBitmap(
  91. hcolBM, DIB_RGB_COLORS, 24,
  92. theApp.m_pPalette, NULL, dwLen,
  93. m_pImg->cXPelsPerMeter, m_pImg->cYPelsPerMeter);
  94. if (lpDibRow && lpDibCol)
  95. {
  96. VOID* pBitsRow = FindDIBBits( lpDibRow );
  97. VOID* pBitsCol = FindDIBBits( lpDibCol );
  98. for (iRow = 0, iCol = iHeight - 1; iRow < iHeight; iRow++, iCol--)
  99. {
  100. ::SelectObject( rowDC, hrowBM );
  101. ::BitBlt( rowDC, 0, 0, iWidth, 1, hdcSrc, 0, iRow, SRCCOPY );
  102. ::SelectObject( rowDC, srowBM );
  103. if (! GetDIBits( hdcSrc, hrowBM, 0, 1, pBitsRow, (LPBITMAPINFO)lpDibRow, DIB_RGB_COLORS ))
  104. break;
  105. LPBYTE pRow = (LPBYTE)pBitsRow;
  106. LPDWORD pCol = (LPDWORD)pBitsCol;
  107. union
  108. {
  109. DWORD pixel;
  110. char byte[sizeof( DWORD )];
  111. } u;
  112. u.byte[3] = 0;
  113. for (register int index = iWidth - 1; index >= 0; index--)
  114. {
  115. u.byte[0] = *pRow++;
  116. u.byte[1] = *pRow++;
  117. u.byte[2] = *pRow++;
  118. pCol[index] = u.pixel;
  119. }
  120. if (! SetDIBits( hdcSrc, hcolBM, 0, iWidth, pBitsCol, (LPBITMAPINFO)lpDibCol, DIB_RGB_COLORS ))
  121. break;
  122. ::SelectObject( colDC, hcolBM );
  123. ::BitBlt( dcRotated.m_hDC, iCol, 0, 1, iWidth, colDC, 0, 0, SRCCOPY );
  124. ::SelectObject( colDC, scolBM );
  125. }
  126. bDone = (iRow == iHeight);
  127. if (! bDone)
  128. theApp.SetGdiEmergency( TRUE );
  129. }
  130. else
  131. theApp.SetMemoryEmergency( TRUE );
  132. if (lpDibRow)
  133. FreeDib( lpDibRow );
  134. if (lpDibCol)
  135. FreeDib( lpDibCol );
  136. if (hpalRow)
  137. ::SelectPalette( rowDC, hpalRow, FALSE );
  138. if (hpalCol)
  139. ::SelectPalette( colDC, hpalCol, FALSE );
  140. }
  141. else
  142. theApp.SetGdiEmergency( TRUE );
  143. // clean up
  144. if (rowDC)
  145. ::DeleteDC( rowDC );
  146. if (colDC)
  147. ::DeleteDC( colDC );
  148. if (hrowBM)
  149. ::DeleteObject( hrowBM );
  150. if (hcolBM)
  151. ::DeleteObject( hcolBM );
  152. EndWaitCursor();
  153. if (! bDone) // do the brute force method
  154. {
  155. if (ppalOld)
  156. theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
  157. if (ppalRotated)
  158. dcRotated.SelectPalette( ppalRotated, FALSE );
  159. dcRotated.SelectObject( pbmOld );
  160. dcRotated.DeleteDC();
  161. bmRotated.DeleteObject();
  162. return;
  163. }
  164. if (ppalOld)
  165. theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
  166. if ( theImgBrush.m_pImg
  167. && ! theImgBrush.m_bFirstDrag || g_bCustomBrush)
  168. {
  169. if (ppalRotated)
  170. dcRotated.SelectPalette( ppalRotated, FALSE );
  171. dcRotated.SelectObject( pbmOld );
  172. CBitmap bmMask;
  173. if (! bmMask.CreateBitmap( iHeight, iWidth, 1, 1, NULL ))
  174. {
  175. theApp.SetMemoryEmergency( TRUE );
  176. return;
  177. }
  178. theImgBrush.m_dc.SelectObject( &bmRotated );
  179. theImgBrush.m_bitmap.DeleteObject();
  180. theImgBrush.m_bitmap.Attach( bmRotated.Detach() );
  181. theImgBrush.m_size.cx = iHeight;
  182. theImgBrush.m_size.cy = iWidth;
  183. VERIFY( theImgBrush.m_maskDC.SelectObject( &bmMask ) ==
  184. &theImgBrush.m_maskBitmap );
  185. theImgBrush.m_maskBitmap.DeleteObject();
  186. theImgBrush.m_maskBitmap.Attach( bmMask.Detach() );
  187. theImgBrush.RecalcMask( crRight );
  188. MoveBrush( destRect );
  189. }
  190. else
  191. {
  192. theUndo.BeginUndo( TEXT("Resize Bitmap") );
  193. m_pImg->m_pBitmapObj->SetSizeProp( P_Size, CSize( iHeight, iWidth ) );
  194. m_pImg->cxWidth = iHeight;
  195. m_pImg->cyHeight = iWidth;
  196. SetUndo( m_pImg );
  197. pdcImg->BitBlt( 0, 0, m_pImg->cxWidth, m_pImg->cyHeight, &dcRotated, 0, 0, SRCCOPY );
  198. dcRotated.SelectObject( pbmOld );
  199. if (ppalRotated)
  200. dcRotated.SelectPalette( ppalRotated, FALSE );
  201. bmRotated.DeleteObject();
  202. InvalImgRect ( m_pImg, &rotRect );
  203. CommitImgRect( m_pImg, &rotRect );
  204. FinishUndo ( rotRect );
  205. theUndo.EndUndo();
  206. DirtyImg ( m_pImg );
  207. InvalidateRect( NULL );
  208. UpdateWindow();
  209. }
  210. dcRotated.DeleteDC();
  211. }
  212. /***************************************************************************/