[MSPAINT] Split master image from history items

CORE-19237
This commit is contained in:
Katayama Hirofumi MZ 2023-11-18 11:19:38 +09:00
parent bf95b7e8e5
commit 7c0615fa05
3 changed files with 44 additions and 30 deletions

View file

@ -49,3 +49,11 @@ BOOL OpenMailer(HWND hWnd, LPCWSTR pszPathName);
#define DEG2RAD(degree) (((degree) * M_PI) / 180) #define DEG2RAD(degree) (((degree) * M_PI) / 180)
#define RAD2DEG(radian) ((LONG)(((radian) * 180) / M_PI)) #define RAD2DEG(radian) ((LONG)(((radian) * 180) / M_PI))
template <typename T>
void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}

View file

@ -32,21 +32,18 @@ ImageModel::ImageModel()
{ {
ZeroMemory(m_hBms, sizeof(m_hBms)); ZeroMemory(m_hBms, sizeof(m_hBms));
m_hBms[0] = CreateColorDIB(1, 1, RGB(255, 255, 255)); m_hbmMaster = CreateColorDIB(1, 1, RGB(255, 255, 255));
m_hbmOld = ::SelectObject(m_hDrawingDC, m_hBms[0]); m_hbmOld = ::SelectObject(m_hDrawingDC, m_hbmMaster);
g_imageSaved = TRUE; g_imageSaved = TRUE;
} }
ImageModel::~ImageModel() ImageModel::~ImageModel()
{ {
::SelectObject(m_hDrawingDC, m_hbmOld); // De-select
::DeleteDC(m_hDrawingDC); ::DeleteDC(m_hDrawingDC);
::DeleteObject(m_hbmMaster);
for (size_t i = 0; i < HISTORYSIZE; ++i) ClearHistory();
{
if (m_hBms[i])
::DeleteObject(m_hBms[i]);
}
} }
void ImageModel::Undo(BOOL bClearRedo) void ImageModel::Undo(BOOL bClearRedo)
@ -57,9 +54,13 @@ void ImageModel::Undo(BOOL bClearRedo)
selectionModel.HideSelection(); selectionModel.HideSelection();
// Select previous item m_currInd = (m_currInd + HISTORYSIZE - 1) % HISTORYSIZE; // Go previous
m_currInd = (m_currInd + HISTORYSIZE - 1) % HISTORYSIZE;
::SelectObject(m_hDrawingDC, m_hBms[m_currInd]); ATLASSERT(m_hbmMaster != NULL);
ATLASSERT(m_hBms[m_currInd] != NULL);
Swap(m_hbmMaster, m_hBms[m_currInd]);
::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select
m_undoSteps--; m_undoSteps--;
if (bClearRedo) if (bClearRedo)
@ -78,9 +79,12 @@ void ImageModel::Redo()
selectionModel.HideSelection(); selectionModel.HideSelection();
// Select next item ATLASSERT(m_hbmMaster != NULL);
m_currInd = (m_currInd + 1) % HISTORYSIZE; ATLASSERT(m_hBms[m_currInd] != NULL);
::SelectObject(m_hDrawingDC, m_hBms[m_currInd]);
Swap(m_hbmMaster, m_hBms[m_currInd]);
m_currInd = (m_currInd + 1) % HISTORYSIZE; // Go next
::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select
m_redoSteps--; m_redoSteps--;
if (m_undoSteps < HISTORYSIZE - 1) if (m_undoSteps < HISTORYSIZE - 1)
@ -93,7 +97,7 @@ void ImageModel::ClearHistory()
{ {
for (int i = 0; i < HISTORYSIZE; ++i) for (int i = 0; i < HISTORYSIZE; ++i)
{ {
if (m_hBms[i] && i != m_currInd) if (m_hBms[i])
{ {
::DeleteObject(m_hBms[i]); ::DeleteObject(m_hBms[i]);
m_hBms[i] = NULL; m_hBms[i] = NULL;
@ -126,11 +130,12 @@ void ImageModel::PushImageForUndo(HBITMAP hbm)
return; return;
} }
// Go to the next item with an HBITMAP or current item INT iNextItem = (m_currInd + 1) % HISTORYSIZE;
::DeleteObject(m_hBms[(m_currInd + 1) % HISTORYSIZE]); ::DeleteObject(m_hBms[iNextItem]);
m_hBms[(m_currInd + 1) % HISTORYSIZE] = hbm; m_hBms[m_currInd] = m_hbmMaster;
m_currInd = (m_currInd + 1) % HISTORYSIZE; m_hbmMaster = hbm;
::SelectObject(m_hDrawingDC, m_hBms[m_currInd]); m_currInd = iNextItem;
::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select
if (m_undoSteps < HISTORYSIZE - 1) if (m_undoSteps < HISTORYSIZE - 1)
m_undoSteps++; m_undoSteps++;
@ -181,7 +186,7 @@ void ImageModel::Crop(int nWidth, int nHeight, int nOffsetX, int nOffsetY)
void ImageModel::SaveImage(LPCWSTR lpFileName) void ImageModel::SaveImage(LPCWSTR lpFileName)
{ {
SaveDIBToFile(m_hBms[m_currInd], lpFileName, TRUE); SaveDIBToFile(m_hbmMaster, lpFileName, TRUE);
} }
BOOL ImageModel::IsImageSaved() const BOOL ImageModel::IsImageSaved() const
@ -197,17 +202,17 @@ void ImageModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSk
INT newHeight = oldHeight * nStretchPercentY / 100; INT newHeight = oldHeight * nStretchPercentY / 100;
if (oldWidth != newWidth || oldHeight != newHeight) if (oldWidth != newWidth || oldHeight != newHeight)
{ {
HBITMAP hbm0 = CopyDIBImage(m_hBms[m_currInd], newWidth, newHeight); HBITMAP hbm0 = CopyDIBImage(m_hbmMaster, newWidth, newHeight);
PushImageForUndo(hbm0); PushImageForUndo(hbm0);
} }
if (nSkewDegX) if (nSkewDegX)
{ {
HBITMAP hbm1 = SkewDIB(m_hDrawingDC, m_hBms[m_currInd], nSkewDegX, FALSE); HBITMAP hbm1 = SkewDIB(m_hDrawingDC, m_hbmMaster, nSkewDegX, FALSE);
PushImageForUndo(hbm1); PushImageForUndo(hbm1);
} }
if (nSkewDegY) if (nSkewDegY)
{ {
HBITMAP hbm2 = SkewDIB(m_hDrawingDC, m_hBms[m_currInd], nSkewDegY, TRUE); HBITMAP hbm2 = SkewDIB(m_hDrawingDC, m_hbmMaster, nSkewDegY, TRUE);
PushImageForUndo(hbm2); PushImageForUndo(hbm2);
} }
NotifyImageChanged(); NotifyImageChanged();
@ -215,12 +220,12 @@ void ImageModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSk
int ImageModel::GetWidth() const int ImageModel::GetWidth() const
{ {
return GetDIBWidth(m_hBms[m_currInd]); return GetDIBWidth(m_hbmMaster);
} }
int ImageModel::GetHeight() const int ImageModel::GetHeight() const
{ {
return GetDIBHeight(m_hBms[m_currInd]); return GetDIBHeight(m_hbmMaster);
} }
void ImageModel::InvertColors() void ImageModel::InvertColors()
@ -309,15 +314,15 @@ HBITMAP ImageModel::LockBitmap()
{ {
// NOTE: An app cannot select a bitmap into more than one device context at a time. // NOTE: An app cannot select a bitmap into more than one device context at a time.
::SelectObject(m_hDrawingDC, m_hbmOld); // De-select ::SelectObject(m_hDrawingDC, m_hbmOld); // De-select
HBITMAP hbmLocked = m_hBms[m_currInd]; HBITMAP hbmLocked = m_hbmMaster;
m_hBms[m_currInd] = NULL; m_hbmMaster = NULL;
return hbmLocked; return hbmLocked;
} }
void ImageModel::UnlockBitmap(HBITMAP hbmLocked) void ImageModel::UnlockBitmap(HBITMAP hbmLocked)
{ {
m_hBms[m_currInd] = hbmLocked; m_hbmMaster = hbmLocked;
m_hbmOld = ::SelectObject(m_hDrawingDC, hbmLocked); // Re-select m_hbmOld = ::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select
} }
void ImageModel::SelectionClone(BOOL bUndoable) void ImageModel::SelectionClone(BOOL bUndoable)

View file

@ -45,6 +45,7 @@ public:
protected: protected:
HDC m_hDrawingDC; // The device context for this class HDC m_hDrawingDC; // The device context for this class
HBITMAP m_hbmMaster; // The master bitmap
int m_currInd; // The current index in m_hBms int m_currInd; // The current index in m_hBms
int m_undoSteps; // The undo-able count int m_undoSteps; // The undo-able count
int m_redoSteps; // The redo-able count int m_redoSteps; // The redo-able count