浏览代码

Feat/faster thumbnail (#585)

* refactor GetCBitmap

* add Fast thumbnail mode

---------

Co-authored-by: sabrogden <[email protected]>
Minha, Jeong 1 年之前
父节点
当前提交
1936cfbe8d
共有 4 个文件被更改,包括 77 次插入42 次删除
  1. 16 3
      AdvGeneral.cpp
  2. 44 39
      BitmapHelper.cpp
  3. 13 0
      Options.cpp
  4. 4 0
      Options.h

+ 16 - 3
AdvGeneral.cpp

@@ -139,8 +139,8 @@ END_MESSAGE_MAP()
 #define SETTING_IGNORE_FALSE_COPIES_DELAY 88
 #define SETTING_REFRESH_VIEW_AFTER_PASTE 89
 #define SETTING_SLUGIFY_SEPARATOR 90
-#define SETTING_CLIPBOARD_RESTORE_AFTER_COPY_BUFFER_DELAY 91
-
+#define SETTING_FAST_THUMBNAIL_MODE 91
+#define SETTING_CLIPBOARD_RESTORE_AFTER_COPY_BUFFER_DELAY 92
 
 BOOL CAdvGeneral::OnInitDialog()
 {
@@ -199,6 +199,9 @@ BOOL CAdvGeneral::OnInitDialog()
 	AddTrueFalse(pGroupTest, _T("Elevated privileges to paste into elevated apps"), CGetSetOptions::GetPasteAsAdmin(), SETTING_PASTE_AS_ADMIN);
 	AddTrueFalse(pGroupTest, _T("Ensure Ditto is always connected to the clipboard"), CGetSetOptions::GetEnsureConnectToClipboard(), SETTING_ENSURE_CONNECTED);
 	AddTrueFalse(pGroupTest, _T("Ensure entire window is visible"), CGetSetOptions::GetEnsureEntireWindowCanBeSeen(), SETTING_ENSURE_WINDOW_IS_VISIBLE);
+
+	AddTrueFalse(pGroupTest, _T("Fast thumbnail mode (default: true means NearestNeighbor, low quality but fast. false means HighQualityBicubic, high quality but slow)"), CGetSetOptions::GetFastThumbnailMode(), SETTING_FAST_THUMBNAIL_MODE);
+
 	AddTrueFalse(pGroupTest, _T("Find as you type"), CGetSetOptions::GetFindAsYouType(), SETTING_FIND_AS_TYPE);
 
 	pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("First ten hot keys start index"), (long)CGetSetOptions::GetFirstTenHotKeysStart(), _T(""), SETTING_FIRST_TEN_HOTKEYS_START));
@@ -244,7 +247,6 @@ BOOL CAdvGeneral::OnInitDialog()
 
 	pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Send keys delay (ms)"), (long)CGetSetOptions::RealSendKeysDelay(), _T(""), SETTING_SEND_KEYS_DELAY));
 
-	
 
 	AddTrueFalse(pGroupTest, _T("Show clips that are in groups in main list"), CGetSetOptions::GetShowAllClipsInMainList(), SETTING_SHOW_GROUP_CLIPS_IN_LIST);
 	AddTrueFalse(pGroupTest, _T("Show leading whitespace"), CGetSetOptions::GetDescShowLeadingWhiteSpace(), SETTING_SHOW_LEADING_WHITESPACE);
@@ -503,6 +505,17 @@ void CAdvGeneral::OnBnClickedOk()
 					CGetSetOptions::SetDrawThumbnail(val);
 				}
 				break;
+			case SETTING_FAST_THUMBNAIL_MODE:
+				if (wcscmp(pNewValue->bstrVal, pOrigValue->bstrVal) != 0)
+				{
+					BOOL val = false;
+					if (wcscmp(pNewValue->bstrVal, L"True") == 0)
+					{
+						val = true;
+					}
+					CGetSetOptions::SetFastThumbnailMode(val);
+				}
+				break;
 			case SETTING_DRAW_RTF:
 				if (wcscmp(pNewValue->bstrVal, pOrigValue->bstrVal) != 0)
 				{

+ 44 - 39
BitmapHelper.cpp

@@ -42,56 +42,61 @@ int CBitmapHelper::GetCBitmapHeight(const CBitmap & cbm)
 
 BOOL CBitmapHelper::GetCBitmap(void	*pClip2, CDC *pDC, CBitmap *pBitMap, int nMaxHeight)
 {
-	BOOL bRet = FALSE;
-
 	CClipFormat		*pClip = (CClipFormat *)pClip2;
 
-	if(pClip->m_cfType == CF_DIB ||
-		pClip->m_cfType == theApp.m_PNG_Format)
-	{
-			if(pBitMap)
-			{
-				if (nMaxHeight < INT_MAX)
-				{
-					Gdiplus::Bitmap *gdipBitmap = pClip->CreateGdiplusBitmap();
-
-					if (gdipBitmap != NULL &&
-						gdipBitmap->GetHeight() > 0 &&
-						gdipBitmap->GetWidth() > 0)
-					{
-						int nHeight = min(nMaxHeight, (int)gdipBitmap->GetHeight());
-						int nWidth = (nHeight * gdipBitmap->GetWidth()) / gdipBitmap->GetHeight();
-
-						//do the resize
-						pBitMap->CreateCompatibleBitmap(pDC, nWidth, nHeight);
-						ASSERT(pBitMap->m_hObject != NULL);
+	if(pClip->m_cfType != CF_DIB &&
+		pClip->m_cfType != theApp.m_PNG_Format)
+		return false;
+	if(!pBitMap)
+		return false;
+	if (nMaxHeight < 0)
+		return false;
 
-						CDC MemDc2;
-						MemDc2.CreateCompatibleDC(pDC);
-
-						CBitmap* oldBitmap2 = MemDc2.SelectObject(pBitMap);
+	Gdiplus::Bitmap *gdipBitmap = pClip->CreateGdiplusBitmap();
+	if (gdipBitmap == NULL)
+	{
+		delete gdipBitmap;
+		return false;
+	}
 
-						Gdiplus::ImageAttributes attrs;
-						Gdiplus::Rect dest(0, 0, nWidth, nHeight);
+	const UINT gdipHeight = gdipBitmap->GetHeight();
+	const UINT gdipWidth = gdipBitmap->GetWidth();
+	if (gdipHeight == 0 || gdipWidth == 0) 
+	{
+		delete gdipBitmap;
+		return false;
+	}
 
-						Gdiplus::Graphics graphics(MemDc2);
-						graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
-						graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
+	const int nHeight = min(nMaxHeight, (int)gdipHeight);
+	const int nWidth = (nHeight * gdipWidth) / gdipHeight;
 
-						graphics.DrawImage(gdipBitmap, dest, 0, 0, gdipBitmap->GetWidth(), gdipBitmap->GetHeight(), Gdiplus::UnitPixel, &attrs);
+	//do the resize
+	pBitMap->CreateCompatibleBitmap(pDC, nWidth, nHeight);
+	ASSERT(pBitMap->m_hObject != NULL);
 
-						MemDc2.SelectObject(oldBitmap2);
-					}
+	CDC MemDc2;
+	MemDc2.CreateCompatibleDC(pDC);
 
-					delete gdipBitmap;
-				}
+	CBitmap* oldBitmap2 = MemDc2.SelectObject(pBitMap);
 
-				bRet = TRUE;
-			}
-	}
+	Gdiplus::Rect dest(0, 0, nWidth, nHeight);
+	Gdiplus::ImageAttributes attrs;
+	Gdiplus::Graphics graphics(MemDc2);
 	
+	Gdiplus::InterpolationMode interpolationMode = Gdiplus::InterpolationModeHighQualityBicubic;
+	if (CGetSetOptions::GetFastThumbnailMode())
+	{
+		interpolationMode = Gdiplus::InterpolationModeNearestNeighbor;
+	}
+	graphics.SetInterpolationMode(interpolationMode);
+	graphics.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
+	graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf);
+	graphics.DrawImage(gdipBitmap, dest, 0, 0, gdipWidth, gdipHeight, Gdiplus::UnitPixel, &attrs);
 
-	return bRet;
+	MemDc2.SelectObject(oldBitmap2);
+	delete gdipBitmap;
+
+	return true;
 }
 
 BOOL CBitmapHelper::GetCBitmap(CClipFormats &clips, CDC* pDC, CBitmap* pBitMap, BOOL horizontal)

+ 13 - 0
Options.cpp

@@ -41,6 +41,7 @@ BOOL CGetSetOptions::m_bLogSendReceiveErrors;
 BOOL CGetSetOptions::m_HideDittoOnHotKeyIfAlreadyShown;
 long CGetSetOptions::m_lPort;
 BOOL CGetSetOptions::m_bDrawThumbnail;
+BOOL CGetSetOptions::m_bFastThumbnailMode;
 CStringA CGetSetOptions::m_csPassword;
 BOOL CGetSetOptions::m_bDrawRTF;
 BOOL CGetSetOptions::m_bMultiPasteReverse;
@@ -185,6 +186,7 @@ void CGetSetOptions::LoadSettings()
 	m_HideDittoOnHotKeyIfAlreadyShown = GetHideDittoOnHotKeyIfAlreadyShown();
 	m_lPort = GetPort();
 	m_bDrawThumbnail = GetDrawThumbnail();
+	m_bFastThumbnailMode = GetFastThumbnailMode();
 	m_csPassword = GetNetworkPassword();
 	m_bDrawRTF = GetDrawRTF();
 	m_bMultiPasteReverse = GetMultiPasteReverse();
@@ -1508,6 +1510,17 @@ BOOL CGetSetOptions::GetDrawThumbnail()
 	return GetProfileLong("DrawThumbnail", bDrawThumbnails);
 }
 
+void CGetSetOptions::SetFastThumbnailMode(BOOL thumbnailDrawMode)
+{
+	SetProfileLong("FastThumbnailMode", thumbnailDrawMode); 
+	m_bFastThumbnailMode = thumbnailDrawMode;
+}
+
+BOOL CGetSetOptions::GetFastThumbnailMode()
+{
+	return GetProfileLong("FastThumbnailMode", TRUE);
+}
+
 void CGetSetOptions::SetExtraNetworkPassword(CString csPassword)
 {
 	SetProfileString("NetworkExtraPassword", csPassword);

+ 4 - 0
Options.h

@@ -271,6 +271,10 @@ public:
 	static void		SetDrawThumbnail(long bDraw);
 	static BOOL		GetDrawThumbnail();
 
+	static BOOL		m_bFastThumbnailMode;
+	static void		SetFastThumbnailMode(BOOL bval);
+	static BOOL		GetFastThumbnailMode();
+
 	static CStringA	m_csPassword;
 	static void		SetNetworkPassword(CString csPassword);
 	static CStringA	GetNetworkPassword();