Skip to content

Commit 42f5d25

Browse files
committed
Comparer: alpha-blended overlay, larger cells, 'D' toggle
- Grid cells widened from 24px to 48px on screen so dots are less dense. - Each differing cell now shows both a translucent rectangle outline and a center dot, drawn with GDI+ alpha blending over the source image. - 'D' key toggles the overlay on and off; default is on.
1 parent 0bf11eb commit 42f5d25

5 files changed

Lines changed: 48 additions & 19 deletions

File tree

Comparer/Comparer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
#include "ComparerDoc.h"
1111

12+
#include <gdiplus.h>
13+
#pragma comment(lib, "gdiplus.lib")
14+
1215
#ifdef _DEBUG
1316
#define new DEBUG_NEW
1417
#endif
@@ -62,6 +65,9 @@ BOOL CComparerApp::InitInstance()
6265
{
6366
CWinApp::InitInstance();
6467

68+
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
69+
Gdiplus::GdiplusStartup(&mGdiplusToken, &gdiplusStartupInput, NULL);
70+
6571
SetRegistryKey(_T("Chammoru"));
6672
LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
6773

@@ -108,6 +114,12 @@ BOOL CComparerApp::InitInstance()
108114
return TRUE;
109115
}
110116

117+
int CComparerApp::ExitInstance()
118+
{
119+
Gdiplus::GdiplusShutdown(mGdiplusToken);
120+
return CWinApp::ExitInstance();
121+
}
122+
111123

112124

113125
// CAboutDlg dialog used for App About

Comparer/Comparer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ class CComparerApp : public CWinApp
2424
// Overrides
2525
public:
2626
virtual BOOL InitInstance();
27+
virtual int ExitInstance();
2728

2829
// Implementation
2930
afx_msg void OnAppAbout();
3031
DECLARE_MESSAGE_MAP()
3132
afx_msg void OnFileOpen();
33+
34+
private:
35+
ULONG_PTR mGdiplusToken;
3236
};
3337

3438
extern CComparerApp theApp;

Comparer/ComparerDoc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ CComparerDoc::CComparerDoc()
6464
, mFps(COMPARER_DEF_FPS)
6565
, mInterpol(false)
6666
, mDiffRes(false)
67+
, mDiffOverlay(true)
6768
{
6869
BITMAPINFOHEADER &bmiHeader = mBmi.bmiHeader;
6970
bmiHeader.biSize = (DWORD)sizeof(BITMAPINFOHEADER);

Comparer/ComparerDoc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class CComparerDoc : public CDocument
7979
double mFps;
8080
bool mInterpol;
8181
bool mDiffRes;
82+
bool mDiffOverlay;
8283

8384
// Operations
8485
public:

Comparer/ComparerView.cpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <QViewerCmn.h>
1717
#include <QImageStr.h>
1818

19+
#include <gdiplus.h>
20+
1921
// CComparerView
2022

2123
CComparerView::CComparerView()
@@ -249,12 +251,15 @@ void CComparerView::OnDraw(CDC *pDC)
249251
mProcessing = false;
250252
}
251253

252-
// Pilot: draw a pink dot in every grid cell that contains at least one pixel
253-
// that differs from the reference pane. Cell size is fixed in display pixels,
254-
// so zooming in implicitly subdivides the source region each cell covers —
255-
// at maximum zoom the dot resolves to an individual differing pixel.
254+
// Pilot: draw a semi-transparent pink cell outline + center dot in every
255+
// grid cell that contains at least one pixel that differs from the reference
256+
// pane. Cell size is fixed in display pixels, so zooming in implicitly
257+
// subdivides the source region each cell covers — at maximum zoom each dot
258+
// resolves to a single differing source pixel.
256259
void CComparerView::DrawDiffOverlay(CDC *pDC, CComparerDoc *pDoc, ComparerPane *pane)
257260
{
261+
if (!pDoc->mDiffOverlay)
262+
return;
258263
if (!pane || !pane->isAvail() || !pane->rgbBuf)
259264
return;
260265

@@ -276,21 +281,24 @@ void CComparerView::DrawDiffOverlay(CDC *pDC, CComparerDoc *pDoc, ComparerPane *
276281
const BYTE *bufA = pane->rgbBuf;
277282
const BYTE *bufB = other->rgbBuf;
278283

279-
const int cellPx = 24; // grid cell size in display pixels
280-
const int dotR = 3; // dot radius
281-
const COLORREF kPink = RGB(0xff, 0x3d, 0x8a);
284+
const int cellPx = 48; // grid cell size in display pixels
285+
const int dotR = 3; // center dot radius
286+
287+
Gdiplus::Graphics g(pDC->m_hDC);
288+
g.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
289+
g.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
282290

283-
CBrush dotBrush(kPink);
284-
CBrush *prevBrush = pDC->SelectObject(&dotBrush);
285-
HGDIOBJ prevPen = pDC->SelectObject(::GetStockObject(NULL_PEN));
291+
const Gdiplus::Color cellColor(110, 0xff, 0x3d, 0x8a); // ~43% alpha pink
292+
const Gdiplus::Color dotColor (220, 0xff, 0x3d, 0x8a); // ~86% alpha pink
293+
Gdiplus::Pen cellPen(cellColor, 1.5f);
294+
Gdiplus::SolidBrush dotBrush(dotColor);
286295

287296
const float invN = (pDoc->mN > 0.0f) ? (1.0f / pDoc->mN) : 1.0f;
288297

289298
for (int cy = 0; cy < mHCanvas; cy += cellPx) {
290299
int cellBot = cy + cellPx;
291300
if (cellBot > mHCanvas) cellBot = mHCanvas;
292301

293-
// Map canvas y range -> source y range.
294302
int sy0 = (int)floorf((cy - mYDst) * invN);
295303
int sy1 = (int)ceilf ((cellBot - mYDst) * invN);
296304
if (sy0 < 0) sy0 = 0;
@@ -307,7 +315,6 @@ void CComparerView::DrawDiffOverlay(CDC *pDC, CComparerDoc *pDoc, ComparerPane *
307315
if (sx1 > pDoc->mW) sx1 = pDoc->mW;
308316
if (sx0 >= sx1) continue;
309317

310-
// Scan the source rectangle for any differing byte; early exit.
311318
bool hasDiff = false;
312319
const int byteStart = sx0 * QIMG_DST_RGB_BYTES;
313320
const int byteLen = (sx1 - sx0) * QIMG_DST_RGB_BYTES;
@@ -321,16 +328,17 @@ void CComparerView::DrawDiffOverlay(CDC *pDC, CComparerDoc *pDoc, ComparerPane *
321328
}
322329

323330
if (hasDiff) {
324-
int dotX = (cx + cellRight) / 2;
325-
int dotY = (cy + cellBot) / 2;
326-
pDC->Ellipse(dotX - dotR, dotY - dotR,
327-
dotX + dotR + 1, dotY + dotR + 1);
331+
g.DrawRectangle(&cellPen,
332+
cx + 0.5f, cy + 0.5f,
333+
(float)(cellRight - cx - 1), (float)(cellBot - cy - 1));
334+
335+
float dotX = (cx + cellRight) * 0.5f;
336+
float dotY = (cy + cellBot) * 0.5f;
337+
g.FillEllipse(&dotBrush,
338+
dotX - dotR, dotY - dotR, 2.0f * dotR, 2.0f * dotR);
328339
}
329340
}
330341
}
331-
332-
pDC->SelectObject(prevBrush);
333-
pDC->SelectObject(prevPen);
334342
}
335343

336344
void CComparerView::DrawEmptyPane(CDC *pDC, CComparerDoc *pDoc)
@@ -764,6 +772,9 @@ void CComparerView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
764772
pDoc->mInterpol = !pDoc->mInterpol;
765773
Invalidate(FALSE);
766774
break;
775+
case 'D':
776+
pDoc->mDiffOverlay = !pDoc->mDiffOverlay;
777+
break;
767778
}
768779

769780
// Most shortcuts affect shared document/view state, so refresh once at the end.

0 commit comments

Comments
 (0)