- Add SkewDIB helper function in dib.cpp.
- Implement Stretch and Skew feature by SelectionModel::StretchSkew and ImageModel::StretchSkew.
- Move ColorKeyedMaskBlt function.
CORE-16634
/* INCLUDES *********************************************************/
#include "precomp.h"
+#include <math.h>
/* FUNCTIONS ********************************************************/
DeleteDC(hDC2);
return hbm2;
}
+
+#ifndef M_PI
+ #define M_PI 3.14159265
+#endif
+
+HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical)
+{
+ if (nDegree == 0)
+ return CopyDIBImage(hbm);
+
+ const double eTan = tan(abs(nDegree) * M_PI / 180);
+
+ BITMAP bm;
+ GetObjectW(hbm, sizeof(bm), &bm);
+ INT cx = bm.bmWidth, cy = bm.bmHeight, dx = 0, dy = 0;
+ if (bVertical)
+ dy = INT(cx * eTan);
+ else
+ dx = INT(cy * eTan);
+
+ if (dx == 0 && dy == 0)
+ return CopyDIBImage(hbm);
+
+ HBITMAP hbmNew = CreateColorDIB(cx + dx, cy + dy, RGB(255, 255, 255));
+ if (!hbmNew)
+ return NULL;
+
+ HDC hDC2 = CreateCompatibleDC(NULL);
+ HGDIOBJ hbm2Old = SelectObject(hDC2, hbmNew);
+ if (bVertical)
+ {
+ for (INT x = 0; x < cx; ++x)
+ {
+ INT delta = INT(x * eTan);
+ if (nDegree > 0)
+ BitBlt(hDC2, x, (dy - delta), 1, cy, hDC1, x, 0, SRCCOPY);
+ else
+ BitBlt(hDC2, x, delta, 1, cy, hDC1, x, 0, SRCCOPY);
+ }
+ }
+ else
+ {
+ for (INT y = 0; y < cy; ++y)
+ {
+ INT delta = INT(y * eTan);
+ if (nDegree > 0)
+ BitBlt(hDC2, (dx - delta), y, cx, 1, hDC1, 0, y, SRCCOPY);
+ else
+ BitBlt(hDC2, delta, y, cx, 1, hDC1, 0, y, SRCCOPY);
+ }
+ }
+ SelectObject(hDC2, hbm2Old);
+ DeleteDC(hDC2);
+ return hbmNew;
+}
HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile);
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight);
+
+HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical);
RestoreDC(hdc, iSaveDC); // Restore
}
+
+BOOL
+ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
+ HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask,
+ DWORD dwRop, COLORREF keyColor)
+{
+ HDC hTempDC;
+ HDC hTempDC2;
+ HBITMAP hTempBm;
+ HBRUSH hTempBrush;
+ HBITMAP hTempMask;
+
+ hTempDC = CreateCompatibleDC(hdcSrc);
+ hTempDC2 = CreateCompatibleDC(hdcSrc);
+ hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
+ SelectObject(hTempDC, hTempBm);
+ hTempBrush = CreateSolidBrush(keyColor);
+ SelectObject(hTempDC, hTempBrush);
+ BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
+ PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT);
+ hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
+ SelectObject(hTempDC2, hTempMask);
+ BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY);
+ SelectObject(hTempDC, hbmMask);
+ BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND);
+ MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask, xMask, yMask, dwRop);
+ DeleteDC(hTempDC);
+ DeleteDC(hTempDC2);
+ DeleteObject(hTempBm);
+ DeleteObject(hTempBrush);
+ DeleteObject(hTempMask);
+ return TRUE;
+}
void SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF system_selection_color);
void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style);
+
+extern BOOL
+ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
+ HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask,
+ DWORD dwRop, COLORREF keyColor);
int oldHeight = GetHeight();
INT newWidth = oldWidth * nStretchPercentX / 100;
INT newHeight = oldHeight * nStretchPercentY / 100;
- Insert(CopyDIBImage(hBms[currInd], newWidth, newHeight));
+ if (oldWidth != newWidth || oldHeight != newHeight)
+ {
+ HBITMAP hbm0 = CopyDIBImage(hBms[currInd], newWidth, newHeight);
+ Insert(hbm0);
+ }
+ if (nSkewDegX)
+ {
+ HBITMAP hbm1 = SkewDIB(hDrawingDC, hBms[currInd], nSkewDegX, FALSE);
+ Insert(hbm1);
+ }
+ if (nSkewDegY)
+ {
+ HBITMAP hbm2 = SkewDIB(hDrawingDC, hBms[currInd], nSkewDegY, TRUE);
+ Insert(hbm2);
+ }
if (GetWidth() != oldWidth || GetHeight() != oldHeight)
NotifyDimensionsChanged();
NotifyImageChanged();
IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
};
-BOOL
-ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
- HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask,
- DWORD dwRop, COLORREF keyColor)
-{
- HDC hTempDC;
- HDC hTempDC2;
- HBITMAP hTempBm;
- HBRUSH hTempBrush;
- HBITMAP hTempMask;
-
- hTempDC = CreateCompatibleDC(hdcSrc);
- hTempDC2 = CreateCompatibleDC(hdcSrc);
- hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
- SelectObject(hTempDC, hTempBm);
- hTempBrush = CreateSolidBrush(keyColor);
- SelectObject(hTempDC, hTempBrush);
- BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
- PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT);
- hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
- SelectObject(hTempDC2, hTempMask);
- BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY);
- SelectObject(hTempDC, hbmMask);
- BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND);
- MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask, xMask, yMask, dwRop);
- DeleteDC(hTempDC);
- DeleteDC(hTempDC2);
- DeleteObject(hTempBm);
- DeleteObject(hTempBrush);
- DeleteObject(hTempMask);
- return TRUE;
-}
-
void CSelectionWindow::ForceRefreshSelectionContents()
{
if (::IsWindowVisible(selectionWindow))
Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg, 0, 1);
}
-extern BOOL
-ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, DWORD dwRop, COLORREF keyColor);
-
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
{
if (!bBgTransparent)
NotifyRefreshNeeded();
}
+void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
+{
+ if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0)
+ return;
+
+ imageModel.DeleteSelection();
+ imageModel.CopyPrevious();
+
+ INT oldWidth = RECT_WIDTH(m_rcDest);
+ INT oldHeight = RECT_HEIGHT(m_rcDest);
+ INT newWidth = oldWidth * nStretchPercentX / 100;
+ INT newHeight = oldHeight * nStretchPercentY / 100;
+
+ if (oldWidth != newWidth || oldHeight != newHeight)
+ {
+ SelectObject(m_hDC, m_hBm);
+ HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight);
+ InsertFromHBITMAP(hbm0, m_rcDest.left, m_rcDest.top);
+ DeleteObject(hbm0);
+ }
+
+ if (nSkewDegX)
+ {
+ SelectObject(m_hDC, m_hBm);
+ HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE);
+ InsertFromHBITMAP(hbm1, m_rcDest.left, m_rcDest.top);
+ DeleteObject(hbm1);
+ }
+
+ if (nSkewDegY)
+ {
+ SelectObject(m_hDC, m_hBm);
+ HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE);
+ InsertFromHBITMAP(hbm2, m_rcDest.left, m_rcDest.top);
+ DeleteObject(hbm2);
+ }
+
+ selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
+ selectionWindow.ForceRefreshSelectionContents();
+ placeSelWin();
+ NotifyRefreshNeeded();
+}
+
HBITMAP SelectionModel::GetBitmap() const
{
return m_hBm;
void FlipHorizontally();
void FlipVertically();
void RotateNTimes90Degrees(int iN);
+ void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX = 0, int nSkewDegY = 0);
HBITMAP GetBitmap() const;
int PtStackSize() const;
void DrawFramePoly(HDC hDCImage);
{
if (stretchSkewDialog.DoModal(mainWindow.m_hWnd))
{
- imageModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,
- stretchSkewDialog.angle.x, stretchSkewDialog.angle.y);
+ if (::IsWindowVisible(selectionWindow))
+ {
+ selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,
+ stretchSkewDialog.angle.x, stretchSkewDialog.angle.y);
+ }
+ else
+ {
+ imageModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,
+ stretchSkewDialog.angle.x, stretchSkewDialog.angle.y);
+ }
}
break;
}