|
|
/****************************************************************************
ROTATE.c
The ROTATE module handles rotating a rectangular object.
****************************************************************************/
#include "stdafx.h"
#include "global.h"
#include "pbrush.h"
#include "pbrusdoc.h"
#include "imgwnd.h"
#include "imgbrush.h"
#include "imgsuprt.h"
#include "bmobject.h"
#include "undo.h"
#include "props.h"
#ifdef _DEBUG
#undef THIS_FILE
static CHAR BASED_CODE THIS_FILE[] = __FILE__; #endif
#include "memtrace.h"
/***************************************************************************/
void CImgWnd::CmdRot90() { HideBrush();
CRect rotRect; HDC hdcSrc; CPalette* ppalOld = NULL;
if (! theImgBrush.m_pImg && ! g_bCustomBrush) { rotRect.SetRect( 0, 0, m_pImg->cxWidth, m_pImg->cyHeight );
hdcSrc = m_pImg->hDC; } else { PrepareForBrushChange( TRUE, TRUE );
ppalOld = SetImgPalette( &theImgBrush.m_dc );
hdcSrc = theImgBrush.m_dc.GetSafeHdc();
rotRect = rcDragBrush; rotRect.right -= 1; rotRect.bottom -= 1; }
ASSERT( hdcSrc != NULL);
if (rotRect.IsRectEmpty() || ! hdcSrc) { if (ppalOld) theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
return; }
int iWidth = rotRect.Width(); int iHeight = rotRect.Height();
CRect destRect( 0, 0, iHeight, iWidth );
destRect.OffsetRect( rotRect.left + iWidth / 2 - iHeight / 2, rotRect.top + iHeight / 2 - iWidth / 2 ); CBitmap bmRotated; CDC dcRotated; CDC* pdcImg = CDC::FromHandle( m_pImg->hDC );
if (! bmRotated.CreateCompatibleBitmap( pdcImg, iHeight, iWidth ) || ! dcRotated.CreateCompatibleDC ( pdcImg )) { if (ppalOld) theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
theApp.SetGdiEmergency( TRUE ); return; }
CBitmap* pbmOld = dcRotated.SelectObject( &bmRotated ); CPalette* ppalRotated = SetImgPalette( &dcRotated );
BeginWaitCursor();
int iRow; int iCol; BOOL bDone = FALSE;
// Need code here to get select RECT from the hdcSrc
HDC rowDC = ::CreateCompatibleDC ( hdcSrc ); HDC colDC = ::CreateCompatibleDC ( hdcSrc ); HBITMAP hrowBM = ::CreateCompatibleBitmap( hdcSrc, iWidth, 1 ); HBITMAP hcolBM = ::CreateCompatibleBitmap( hdcSrc, 1, iWidth );
if (rowDC && colDC && hrowBM && hcolBM) { HBITMAP scolBM = (HBITMAP)::SelectObject( colDC, hcolBM ); HBITMAP srowBM = (HBITMAP)::SelectObject( rowDC, hrowBM );
::PatBlt( rowDC, 0, 0, iWidth, 1, BLACKNESS ); ::PatBlt( colDC, 0, 0, 1, iWidth, BLACKNESS );
HPALETTE hpalRow = SetImgPalette( rowDC ); // save to replace later
HPALETTE hpalCol = SetImgPalette( colDC ); // save to replace later
::SelectObject( colDC, scolBM ); ::SelectObject( rowDC, srowBM );
DWORD dwLen;
LPSTR lpDibRow = (LPSTR) DibFromBitmap( hrowBM, DIB_RGB_COLORS, 24, theApp.m_pPalette, NULL, dwLen, m_pImg->cXPelsPerMeter, m_pImg->cYPelsPerMeter);
LPSTR lpDibCol = (LPSTR) DibFromBitmap( hcolBM, DIB_RGB_COLORS, 24, theApp.m_pPalette, NULL, dwLen, m_pImg->cXPelsPerMeter, m_pImg->cYPelsPerMeter);
if (lpDibRow && lpDibCol) { VOID* pBitsRow = FindDIBBits( lpDibRow ); VOID* pBitsCol = FindDIBBits( lpDibCol );
for (iRow = 0, iCol = iHeight - 1; iRow < iHeight; iRow++, iCol--) { ::SelectObject( rowDC, hrowBM ); ::BitBlt( rowDC, 0, 0, iWidth, 1, hdcSrc, 0, iRow, SRCCOPY ); ::SelectObject( rowDC, srowBM );
if (! GetDIBits( hdcSrc, hrowBM, 0, 1, pBitsRow, (LPBITMAPINFO)lpDibRow, DIB_RGB_COLORS )) break;
LPBYTE pRow = (LPBYTE)pBitsRow; LPDWORD pCol = (LPDWORD)pBitsCol;
union { DWORD pixel; char byte[sizeof( DWORD )]; } u;
u.byte[3] = 0;
for (register int index = iWidth - 1; index >= 0; index--) { u.byte[0] = *pRow++; u.byte[1] = *pRow++; u.byte[2] = *pRow++;
pCol[index] = u.pixel; }
if (! SetDIBits( hdcSrc, hcolBM, 0, iWidth, pBitsCol, (LPBITMAPINFO)lpDibCol, DIB_RGB_COLORS )) break;
::SelectObject( colDC, hcolBM ); ::BitBlt( dcRotated.m_hDC, iCol, 0, 1, iWidth, colDC, 0, 0, SRCCOPY ); ::SelectObject( colDC, scolBM ); }
bDone = (iRow == iHeight);
if (! bDone) theApp.SetGdiEmergency( TRUE ); } else theApp.SetMemoryEmergency( TRUE );
if (lpDibRow) FreeDib( lpDibRow );
if (lpDibCol) FreeDib( lpDibCol );
if (hpalRow) ::SelectPalette( rowDC, hpalRow, FALSE );
if (hpalCol) ::SelectPalette( colDC, hpalCol, FALSE ); } else theApp.SetGdiEmergency( TRUE );
// clean up
if (rowDC) ::DeleteDC( rowDC );
if (colDC) ::DeleteDC( colDC );
if (hrowBM) ::DeleteObject( hrowBM );
if (hcolBM) ::DeleteObject( hcolBM );
EndWaitCursor();
if (! bDone) // do the brute force method
{ if (ppalOld) theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
if (ppalRotated) dcRotated.SelectPalette( ppalRotated, FALSE );
dcRotated.SelectObject( pbmOld ); dcRotated.DeleteDC(); bmRotated.DeleteObject(); return; }
if (ppalOld) theImgBrush.m_dc.SelectPalette( ppalOld, FALSE );
if ( theImgBrush.m_pImg && ! theImgBrush.m_bFirstDrag || g_bCustomBrush) { if (ppalRotated) dcRotated.SelectPalette( ppalRotated, FALSE );
dcRotated.SelectObject( pbmOld );
CBitmap bmMask;
if (! bmMask.CreateBitmap( iHeight, iWidth, 1, 1, NULL )) { theApp.SetMemoryEmergency( TRUE ); return; }
theImgBrush.m_dc.SelectObject( &bmRotated ); theImgBrush.m_bitmap.DeleteObject(); theImgBrush.m_bitmap.Attach( bmRotated.Detach() );
theImgBrush.m_size.cx = iHeight; theImgBrush.m_size.cy = iWidth;
VERIFY( theImgBrush.m_maskDC.SelectObject( &bmMask ) == &theImgBrush.m_maskBitmap );
theImgBrush.m_maskBitmap.DeleteObject(); theImgBrush.m_maskBitmap.Attach( bmMask.Detach() ); theImgBrush.RecalcMask( crRight );
MoveBrush( destRect ); } else { theUndo.BeginUndo( TEXT("Resize Bitmap") );
m_pImg->m_pBitmapObj->SetSizeProp( P_Size, CSize( iHeight, iWidth ) );
m_pImg->cxWidth = iHeight; m_pImg->cyHeight = iWidth;
SetUndo( m_pImg );
pdcImg->BitBlt( 0, 0, m_pImg->cxWidth, m_pImg->cyHeight, &dcRotated, 0, 0, SRCCOPY );
dcRotated.SelectObject( pbmOld );
if (ppalRotated) dcRotated.SelectPalette( ppalRotated, FALSE );
bmRotated.DeleteObject();
InvalImgRect ( m_pImg, &rotRect ); CommitImgRect( m_pImg, &rotRect );
FinishUndo ( rotRect );
theUndo.EndUndo();
DirtyImg ( m_pImg );
InvalidateRect( NULL ); UpdateWindow(); }
dcRotated.DeleteDC(); }
/***************************************************************************/
|