Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make the toolbar icon DPI-aware. fixes #370, fixes #276
  • Loading branch information
sdottaka committed Sep 16, 2020
1 parent a66d22c commit 212bc1a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 27 deletions.
128 changes: 105 additions & 23 deletions Src/MainFrm.cpp
Expand Up @@ -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<class DocClass>
DocClass * GetMergeDocForDiff(CMultiDocTemplate *pTemplate, CDirDoc *pDirDoc, int nFiles, bool bMakeVisible = true);
Expand Down Expand Up @@ -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]);
Expand All @@ -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<BYTE>(
(static_cast<int>(0.114 * 256) * (((255 - b) >> 1) + b)
+ static_cast<int>(0.587 * 256) * (((255 - g) >> 1) + g)
+ static_cast<int>(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<BYTE> buf(stride * nHeight);
convert24bitImageTo32bit(nWidth * nCount, nHeight, bGrayscale, reinterpret_cast<BYTE*>(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);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions Src/Merge.cpp
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Src/Merge.h
Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions Src/Merge2.rc
Expand Up @@ -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"
Expand Down
Binary file removed Src/res/ToolbarEnabledMask.bmp
Binary file not shown.
Binary file removed Src/res/ToolbarEnabledMask32.bmp
Binary file not shown.
2 changes: 0 additions & 2 deletions Src/resource.h
Expand Up @@ -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
Expand Down

0 comments on commit 212bc1a

Please sign in to comment.