293 lines
7.8 KiB
C++
293 lines
7.8 KiB
C++
/****************************************************************************
|
|
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();
|
|
}
|
|
|
|
/***************************************************************************/
|