diff --git a/Src/MainFrm.cpp b/Src/MainFrm.cpp index 959a7464835..ef7148e6c48 100644 --- a/Src/MainFrm.cpp +++ b/Src/MainFrm.cpp @@ -70,7 +70,7 @@ using boost::end; #define new DEBUG_NEW #endif -static void LoadToolbarImageList(int imageWidth, UINT nIDResource, UINT nIDResourceMask, bool bGrayscale, CImageList& ImgList); +static void LoadToolbarImageList(int orgImageWidth, int newImageHeight, UINT nIDResource, bool bGrayscale, CImageList& ImgList); static CPtrList &GetDocList(CMultiDocTemplate *pTemplate); template DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles, bool bMakeVisible = true); @@ -2024,22 +2024,22 @@ BOOL CMainFrame::CreateToolbar() /** @brief Load toolbar images from the resource. */ void CMainFrame::LoadToolbarImages() { - const int toolbarSize = 16 << GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE); + const int toolbarNewImgSize = MulDiv(16, GetSystemMetrics(SM_CXSMICON), 16) << GetOptionsMgr()->GetInt(OPT_TOOLBAR_SIZE); + const int toolbarOrgImgSize = toolbarNewImgSize == 16 ? 16 : 32; CToolBarCtrl& BarCtrl = m_wndToolBar.GetToolBarCtrl(); m_ToolbarImages[TOOLBAR_IMAGES_ENABLED].DeleteImageList(); m_ToolbarImages[TOOLBAR_IMAGES_DISABLED].DeleteImageList(); CSize sizeButton(0, 0); - LoadToolbarImageList(toolbarSize, - toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32, - toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED_MASK : IDB_TOOLBAR_ENABLED_MASK32, + LoadToolbarImageList(toolbarOrgImgSize, toolbarNewImgSize, + toolbarOrgImgSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32, false, m_ToolbarImages[TOOLBAR_IMAGES_ENABLED]); - LoadToolbarImageList(toolbarSize, - toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32, - toolbarSize <= 16 ? IDB_TOOLBAR_ENABLED_MASK : IDB_TOOLBAR_ENABLED_MASK32, + LoadToolbarImageList(toolbarOrgImgSize, toolbarNewImgSize, + toolbarOrgImgSize <= 16 ? IDB_TOOLBAR_ENABLED : IDB_TOOLBAR_ENABLED32, true, m_ToolbarImages[TOOLBAR_IMAGES_DISABLED]); - sizeButton = CSize(toolbarSize + 8, toolbarSize + 8); + + sizeButton = CSize(toolbarNewImgSize + 8, toolbarNewImgSize + 8); BarCtrl.SetButtonSize(sizeButton); BarCtrl.SetImageList(&m_ToolbarImages[TOOLBAR_IMAGES_ENABLED]); @@ -2056,29 +2056,111 @@ void CMainFrame::LoadToolbarImages() /** - * @brief Load a transparent 24-bit color image list. + * @brief Load a transparent 32-bit color image list. */ -static void LoadHiColImageList(UINT nIDResource, UINT nIDResourceMask, int nWidth, int nHeight, int nCount, bool bGrayscale, CImageList& ImgList) -{ - CBitmap bm, bmMask; - bm.Attach(LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, nWidth * nCount, nHeight, LR_DEFAULTCOLOR)); - bmMask.Attach(LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResourceMask), IMAGE_BITMAP, nWidth * nCount, nHeight, LR_MONOCHROME)); - if (bGrayscale) - GrayScale(&bm); - VERIFY(ImgList.Create(nWidth, nHeight, ILC_COLORDDB|ILC_MASK, nCount, 0)); - int nIndex = ImgList.Add(&bm, &bmMask); +static void LoadHiColImageList(UINT nIDResource, int nWidth, int nHeight, int nNewWidth, int nNewHeight, int nCount, bool bGrayscale, CImageList& ImgList) +{ + auto convert24bitImageTo32bit = [](int width, int height, bool grayscale, const BYTE* src, BYTE* dst) + { + for (int y = 0; y < height; ++y) + { + const BYTE* pSrc = src + y * ((width * 3 * 4 + 3) / 4); + BYTE* pDst = dst + (height - 1 - y) * ((width * 4 * 4 + 3) / 4); + if (!grayscale) + { + for (int x = 0; x < width; ++x) + { + if (pSrc[x * 3] == 0xff && pSrc[x * 3 + 1] == 0 && pSrc[x * 3 + 2] == 0xff) // rgb(0xff, 0, 0xff) == mask color + { + pDst[x * 4] = 0; + pDst[x * 4 + 1] = 0; + pDst[x * 4 + 2] = 0; + pDst[x * 4 + 3] = 0; + } + else + { + pDst[x * 4 + 0] = pSrc[x * 3 + 0]; + pDst[x * 4 + 1] = pSrc[x * 3 + 1]; + pDst[x * 4 + 2] = pSrc[x * 3 + 2]; + pDst[x * 4 + 3] = 0xff; + } + } + } + else + { + for (int x = 0; x < width; ++x) + { + if (pSrc[x * 3] == 0xff && pSrc[x * 3 + 1] == 0 && pSrc[x * 3 + 2] == 0xff) // rgb(0xff, 0, 0xff) == mask color + { + pDst[x * 4] = 0; + pDst[x * 4 + 1] = 0; + pDst[x * 4 + 2] = 0; + pDst[x * 4 + 3] = 0; + } + else + { + const BYTE b = pSrc[x * 3]; + const BYTE g = pSrc[x * 3 + 1]; + const BYTE r = pSrc[x * 3 + 2]; + const BYTE gray = static_cast( + (static_cast(0.114 * 256) * (((255 - b) >> 1) + b) + + static_cast(0.587 * 256) * (((255 - g) >> 1) + g) + + static_cast(0.299 * 256) * (((255 - r) >> 1) + r)) >> 8); + pDst[x * 4 + 0] = gray; + pDst[x * 4 + 1] = gray; + pDst[x * 4 + 2] = gray; + pDst[x * 4 + 3] = 0xff; + } + } + } + } + }; + + auto createImageListFromBitmap = [](CImageList& imgList, Gdiplus::Bitmap& bitmap, int width, int height, int count) + { + CBitmap bm; + HBITMAP hBitmap; + bitmap.GetHBITMAP(Gdiplus::Color::Transparent, &hBitmap); + bm.Attach(hBitmap); + + VERIFY(imgList.Create(width, height, ILC_COLOR32, count, 0)); + int nIndex = imgList.Add(&bm, nullptr); ASSERT(-1 != nIndex); + }; + + ATL::CImage img; + img.Attach((HBITMAP)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, nWidth * nCount, nHeight, LR_CREATEDIBSECTION), ATL::CImage::DIBOR_TOPDOWN); + const int stride = (nWidth * nCount * 4 * 4 + 3) / 4; + std::vector buf(stride * nHeight); + convert24bitImageTo32bit(nWidth * nCount, nHeight, bGrayscale, reinterpret_cast(img.GetBits()), buf.data()); + + if (nWidth != nNewWidth && nHeight != nNewHeight) + { + Gdiplus::Bitmap bitmapSrc(nWidth * nCount, nHeight, stride, PixelFormat32bppPARGB, buf.data()); + Gdiplus::Bitmap bitmapDst(nNewWidth * nCount, nNewHeight, PixelFormat32bppPARGB); + Gdiplus::Graphics dcDst(&bitmapDst); + dcDst.SetInterpolationMode(Gdiplus::InterpolationMode::InterpolationModeHighQualityBicubic); + dcDst.DrawImage(&bitmapSrc, 0, 0, nNewWidth * nCount, nNewHeight); + + createImageListFromBitmap(ImgList, bitmapDst, nNewWidth, nNewHeight, nCount); + } + else + { + Gdiplus::Bitmap bitmapDst(nWidth * nCount, nHeight, stride, PixelFormat32bppPARGB, buf.data()); + + createImageListFromBitmap(ImgList, bitmapDst, nNewWidth, nNewHeight, nCount); + } } /** * @brief Load toolbar image list. */ -static void LoadToolbarImageList(int imageWidth, UINT nIDResource, UINT nIDResourceMask, bool bGrayscale, - CImageList& ImgList) +static void LoadToolbarImageList(int orgImageWidth, int newImageWidth, UINT nIDResource, bool bGrayscale, CImageList& ImgList) { const int ImageCount = 22; - const int imageHeight = imageWidth - 1; - LoadHiColImageList(nIDResource, nIDResourceMask, imageWidth, imageHeight, ImageCount, bGrayscale, ImgList); + const int orgImageHeight = orgImageWidth - 1; + const int newImageHeight = newImageWidth - 1; + LoadHiColImageList(nIDResource, orgImageWidth, orgImageHeight, newImageWidth, newImageHeight, ImageCount, bGrayscale, ImgList); } /** diff --git a/Src/Merge.cpp b/Src/Merge.cpp index c5130614ecd..c960e84fc6d 100644 --- a/Src/Merge.cpp +++ b/Src/Merge.cpp @@ -150,6 +150,8 @@ BOOL CMergeApp::InitInstance() InitCommonControls(); // initialize common control library CWinApp::InitInstance(); // call parent class method + m_imageForInitializingGdiplus.Load((IStream*)nullptr); // initialize GDI+ + // Runtime switch so programmer may set this in interactive debugger int dbgmem = 0; if (dbgmem) diff --git a/Src/Merge.h b/Src/Merge.h index b5d27c6e946..adf7dcd841a 100644 --- a/Src/Merge.h +++ b/Src/Merge.h @@ -169,6 +169,7 @@ class CMergeApp : public CWinApp LONG m_nActiveOperations; /**< Active operations count. */ bool m_bMergingMode; /**< Merging or Edit mode */ CFont m_fontGUI; + ATL::CImage m_imageForInitializingGdiplus; }; extern CMergeApp theApp; diff --git a/Src/Merge2.rc b/Src/Merge2.rc index 6469eb8a7fb..01a3e6e41db 100644 --- a/Src/Merge2.rc +++ b/Src/Merge2.rc @@ -113,8 +113,6 @@ IDR_MARGIN_ICONS_PNG IMAGE "res\\mg_icons.png" IDB_TOOLBAR_ENABLED8BIT BITMAP "res\\ToolbarEnabled8bit.bmp" IDB_TOOLBAR_ENABLED BITMAP "res\\ToolbarEnabled.bmp" IDB_TOOLBAR_ENABLED32 BITMAP "res\\ToolbarEnabled32.bmp" -IDB_TOOLBAR_ENABLED_MASK BITMAP "res\\ToolbarEnabledMask.bmp" -IDB_TOOLBAR_ENABLED_MASK32 BITMAP "res\\ToolbarEnabledMask32.bmp" IDB_EDIT_COPY BITMAP "res\\copy.bmp" IDB_EDIT_CUT BITMAP "res\\cut.bmp" IDB_EDIT_PASTE BITMAP "res\\paste.bmp" diff --git a/Src/res/ToolbarEnabledMask.bmp b/Src/res/ToolbarEnabledMask.bmp deleted file mode 100644 index 14f353cd601..00000000000 Binary files a/Src/res/ToolbarEnabledMask.bmp and /dev/null differ diff --git a/Src/res/ToolbarEnabledMask32.bmp b/Src/res/ToolbarEnabledMask32.bmp deleted file mode 100644 index d12f9cd7c1e..00000000000 Binary files a/Src/res/ToolbarEnabledMask32.bmp and /dev/null differ diff --git a/Src/resource.h b/Src/resource.h index f070888e27c..26033656653 100644 --- a/Src/resource.h +++ b/Src/resource.h @@ -125,8 +125,6 @@ #define IDB_COPY_FROM_LEFT 376 #define IDB_COPY_FROM_RIGHT 377 #define IDB_TOOLBAR_ENABLED 378 -#define IDB_TOOLBAR_ENABLED_MASK 379 -#define IDB_TOOLBAR_ENABLED_MASK32 380 #define IDI_FOLDER 500 #define IDI_LFOLDER 501 #define IDI_MFOLDER 502