[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] TortoiseIDiff background color and pixel offset

From: Harun Vos <hvos_at_lynx.com.au>
Date: 2007-08-24 06:14:11 CEST

Hi,

I've added a menu entry to choose the background color of the images in
IDiff,
for viewing images with transparent areas. Its accelerator key is set to
'b'.
This is attached as BackColor.patch

Using this feature also highlights an existing bug - when zoomed in, the
image is offset to the
top and left by half a pixel due to the GDI+ default PixelOffsetMode,
and the border pixels
are blended with transparency from outside the image.
I have included a fix to this separately in PixelOffset.patch, since it
is not tied to the background color feature.
I was unable to test this on a system without GDI+, but I don't think it
should affect other rendering modes.

Thanks for all the great work

Harun Vos

Index: src/Utils/MiscUI/Picture.cpp
===================================================================
--- src/Utils/MiscUI/Picture.cpp (revision 10407)
+++ src/Utils/MiscUI/Picture.cpp (working copy)
@@ -479,8 +479,11 @@
         {
                 Graphics graphics(hDC);
                 graphics.SetInterpolationMode(m_ip);
+ graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality);
+ ImageAttributes attr;
+ attr.SetWrapMode(WrapModeTileFlipXY);
                 Rect rect(DrawRect.left, DrawRect.top, DrawRect.right-DrawRect.left, DrawRect.bottom-DrawRect.top);
- graphics.DrawImage(pBitmap, rect);
+ graphics.DrawImage(pBitmap, rect, 0, 0, m_Width, m_Height, UnitPixel, &attr);
                 return true;
         }
 

Index: src/TortoiseIDiff/MainWindow.cpp
===================================================================
--- src/TortoiseIDiff/MainWindow.cpp (revision 10407)
+++ src/TortoiseIDiff/MainWindow.cpp (working copy)
@@ -104,6 +104,8 @@
         if (hdwp) EndDeferWindowPos(hdwp);
         picWindow1.SetupScrollBars();
         picWindow2.SetupScrollBars();
+ picWindow1.SetBackColor(backColor);
+ picWindow2.SetBackColor(backColor);
         InvalidateRect(*this, NULL, FALSE);
 }
 
@@ -357,6 +359,26 @@
                         picWindow1.SetSecondPicAlpha(m_BlendType, picWindow1.GetSecondPicAlpha());
                 }
                 break;
+ case ID_VIEW_BACKGROUNDCOLOR:
+ {
+ static COLORREF customColors[16] = {0};
+ CHOOSECOLOR ccDlg;
+ memset(&ccDlg, 0, sizeof(ccDlg));
+ ccDlg.lStructSize = sizeof(ccDlg);
+ ccDlg.hwndOwner = m_hwnd;
+ ccDlg.rgbResult = backColor;
+ ccDlg.lpCustColors = customColors;
+ ccDlg.Flags = CC_RGBINIT | CC_FULLOPEN;
+ if(ChooseColor(&ccDlg))
+ {
+ backColor = ccDlg.rgbResult;
+ picWindow1.SetBackColor(backColor);
+ picWindow2.SetBackColor(backColor);
+ // The color picker takes the focus and we don't get it back.
+ ::SetFocus(picWindow1);
+ }
+ }
+ break;
         case ID_VIEW_FITTOGETHER:
                 {
                         bFitTogether = !bFitTogether;
Index: src/TortoiseIDiff/MainWindow.h
===================================================================
--- src/TortoiseIDiff/MainWindow.h (revision 10407)
+++ src/TortoiseIDiff/MainWindow.h (working copy)
@@ -47,6 +47,7 @@
                 , bVertical(false)
                 , bLinked(true)
                 , bFitTogether(false)
+ , backColor(::GetSysColor(COLOR_WINDOW))
                 , m_BlendType(CPicWindow::BLEND_ALPHA)
         {
                 SetWindowTitle((LPCTSTR)ResString(hResource, IDS_APP_TITLE));
@@ -101,6 +102,7 @@
         CPicWindow picWindow1;
         CPicWindow picWindow2;
         bool bShowInfo;
+ COLORREF backColor;
 
         // splitter data
         int oldx;
Index: src/TortoiseIDiff/PicWindow.cpp
===================================================================
--- src/TortoiseIDiff/PicWindow.cpp (revision 10407)
+++ src/TortoiseIDiff/PicWindow.cpp (working copy)
@@ -933,6 +933,34 @@
         SetZoom(GetZoom(), false);
 }
 
+void CPicWindow::ShowPicWithBorder(HDC hdc, const RECT &bounds, CPicture &pic, double scale)
+{
+ ::SetBkColor(hdc, ::GetSysColor(COLOR_WINDOW));
+ ::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &bounds, NULL, 0, NULL);
+
+ RECT picrect;
+ picrect.left = bounds.left - nHScrollPos;
+ picrect.right = (picrect.left + LONG(double(pic.m_Width) * scale));
+ picrect.top = bounds.top - nVScrollPos;
+ picrect.bottom = (picrect.top + LONG(double(pic.m_Height) * scale));
+
+ if ((bounds.left < picrect.left) ||
+ (bounds.top < picrect.top) ||
+ (bounds.right > picrect.right) ||
+ (bounds.bottom > picrect.bottom))
+ {
+ RECT border;
+ border.left = picrect.left-1;
+ border.top = picrect.top-1;
+ border.right = picrect.right+1;
+ border.bottom = picrect.bottom+1;
+ ::FillRect(hdc, &border, (HBRUSH)(COLOR_3DDKSHADOW+1));
+ }
+ ::SetBkColor(hdc, backColor);
+ ::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &picrect, NULL, 0, NULL);
+ pic.Show(hdc, picrect);
+}
+
 void CPicWindow::Paint(HWND hwnd)
 {
         PAINTSTRUCT ps;
@@ -955,26 +983,7 @@
                 GetClientRect(&rect);
                 if (bValid)
                 {
- RECT picrect;
- picrect.left = rect.left-nHScrollPos;
- picrect.right = (picrect.left + LONG(double(picture.m_Width)*picscale));
- picrect.top = rect.top-nVScrollPos;
- picrect.bottom = (picrect.top + LONG(double(picture.m_Height)*picscale));
-
- SetBkColor(memDC, ::GetSysColor(COLOR_WINDOW));
- ::ExtTextOut(memDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
-
- if ((rect.left < picrect.left)&&(rect.top < picrect.top)&&(rect.right > picrect.right)&&(rect.bottom > picrect.bottom))
- {
- RECT border;
- border.left = picrect.left-1;
- border.top = picrect.top-1;
- border.right = picrect.right+1;
- border.bottom = picrect.bottom+1;
- FillRect(memDC, &border, (HBRUSH)(COLOR_3DDKSHADOW+1));
- ::ExtTextOut(memDC, 0, 0, ETO_OPAQUE, &picrect, NULL, 0, NULL);
- }
- picture.Show(memDC, picrect);
+ ShowPicWithBorder(memDC, rect, picture, picscale);
                         if (pSecondPic)
                         {
                                 HDC secondhdc = CreateCompatibleDC(hdc);
@@ -982,28 +991,8 @@
                                 HBITMAP hOldBitmap = (HBITMAP)SelectObject(secondhdc, hBitmap);
                                 SetWindowOrgEx(secondhdc, rect.left, rect.top, NULL);
 
- RECT picrect2;
- picrect2.left = rect.left-nHScrollPos;
- picrect2.right = (picrect2.left + LONG(double(pSecondPic->m_Width)*picscale2));
- picrect2.top = rect.top-nVScrollPos;
- picrect2.bottom = (picrect2.top + LONG(double(pSecondPic->m_Height)*picscale2));
+ ShowPicWithBorder(secondhdc, rect, *pSecondPic, picscale2);
 
- SetBkColor(secondhdc, ::GetSysColor(COLOR_WINDOW));
- ::ExtTextOut(secondhdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
-
- if ((rect.left < picrect2.left)&&(rect.top < picrect2.top)&&(rect.right > picrect2.right)&&(rect.bottom > picrect2.bottom))
- {
- RECT border;
- border.left = picrect2.left-1;
- border.top = picrect2.top-1;
- border.right = picrect2.right+1;
- border.bottom = picrect2.bottom+1;
- FillRect(secondhdc, &border, (HBRUSH)(COLOR_3DDKSHADOW+1));
- ::ExtTextOut(secondhdc, 0, 0, ETO_OPAQUE, &picrect2, NULL, 0, NULL);
- }
-
- pSecondPic->Show(secondhdc, picrect2);
-
                                 if (m_blend == BLEND_ALPHA)
                                 {
                                         BLENDFUNCTION blender;
@@ -1050,6 +1039,7 @@
                         m_inforect.right = rect.right+sliderwidth;
                         m_inforect.bottom = rect.bottom;
 
+ SetBkColor(memDC, ::GetSysColor(COLOR_WINDOW));
                         if (bShowInfo)
                         {
                                 TCHAR infostring[8192];
Index: src/TortoiseIDiff/PicWindow.h
===================================================================
--- src/TortoiseIDiff/PicWindow.h (revision 10407)
+++ src/TortoiseIDiff/PicWindow.h (working copy)
@@ -60,6 +60,8 @@
                 , nHScrollPos(0)
                 , nVScrollPos(0)
                 , picscale(1.0)
+ , picscale2(1.0)
+ , backColor(0)
                 , pSecondPic(NULL)
                 , alphalive(0)
                 , bShowInfo(false)
@@ -121,6 +123,10 @@
                 else
                         SetSecondPicAlpha(m_blend, (BYTE)SendMessage(hwndAlphaSlider, ALPHA_GETRIGHTPOS, 0, 0));
         }
+
+ /// Set the color that this PicWindow will display behind transparent images.
+ void SetBackColor(COLORREF back) { backColor = back; InvalidateRect(*this, NULL, false); }
+
         /// Resizes the image to fit into the window. Small images are not enlarged.
         void FitImageInWindow();
         /// Makes both images the same size, fitting into the window
@@ -162,6 +168,8 @@
         void GetClientRect(RECT * pRect);
         /// the WM_PAINT function
         void Paint(HWND hwnd);
+ /// Draw pic to hdc, with a border, scaled by scale.
+ void ShowPicWithBorder(HDC hdc, const RECT &bounds, CPicture &pic, double scale);
         /// Positions the buttons
         void PositionChildren();
         /// Rounds a double to a given precision
@@ -185,6 +193,7 @@
         bool bValid; ///< true if the picture object is valid, i.e. if the image could be loaded and can be shown
         double picscale; ///< the scale factor of the image
         double picscale2; ///< the scale factor of the second image
+ COLORREF backColor; ///< the colour to draw under the images
         bool bFirstpaint; ///< true if the image is painted the first time. Used to initialize some stuff when the window is valid for sure.
         CPicture * pSecondPic; ///< if set, this is the picture to draw transparently above the original
         CPicWindow * pTheOtherPic; ///< pointer to the other picture window. Used for "linking" the two windows when scrolling/zooming/...
Index: src/TortoiseIDiff/resource.h
===================================================================
--- src/TortoiseIDiff/resource.h (revision 10407)
+++ src/TortoiseIDiff/resource.h (working copy)
@@ -70,6 +70,7 @@
 #define ID_VIEW_BLENDALPHA 32812
 #define ID_ 32813
 #define ID_ABOUT 32814
+#define ID_VIEW_BACKGROUNDCOLOR 32815
 #define IDC_STATIC -1
 
 // Next default values for new objects
@@ -78,7 +79,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NO_MFC 1
 #define _APS_NEXT_RESOURCE_VALUE 154
-#define _APS_NEXT_COMMAND_VALUE 32815
+#define _APS_NEXT_COMMAND_VALUE 32816
 #define _APS_NEXT_CONTROL_VALUE 1006
 #define _APS_NEXT_SYMED_VALUE 110
 #endif
Index: src/TortoiseIDiff/TortoiseIDiff.rc
===================================================================
--- src/TortoiseIDiff/TortoiseIDiff.rc (revision 10407)
+++ src/TortoiseIDiff/TortoiseIDiff.rc (working copy)
@@ -90,6 +90,7 @@
         MENUITEM "&Fit Images in window", ID_VIEW_FITIMAGESINWINDOW
         MENUITEM "Fit Images &together", ID_VIEW_FITTOGETHER
         MENUITEM "Ori&ginal size", ID_VIEW_ORININALSIZE
+ MENUITEM "Background &color...", ID_VIEW_BACKGROUNDCOLOR
         MENUITEM SEPARATOR
         MENUITEM "Zoo&m out", ID_VIEW_ZOOMOUT
         MENUITEM "Zoom i&n", ID_VIEW_ZOOMIN
@@ -180,6 +181,7 @@
     VK_SPACE, ID_VIEW_ALPHATOGGLE, VIRTKEY, NOINVERT
     "V", ID_VIEW_ARRANGEVERTICAL, VIRTKEY, CONTROL, NOINVERT
     "F", ID_VIEW_FITIMAGESINWINDOW, VIRTKEY, NOINVERT
+ "b", ID_VIEW_BACKGROUNDCOLOR, ASCII, NOINVERT
     "i", ID_VIEW_IMAGEINFO, ASCII, NOINVERT
     "S", ID_VIEW_ORININALSIZE, VIRTKEY, NOINVERT
     "O", ID_VIEW_OVERLAPIMAGES, VIRTKEY, NOINVERT

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tortoisesvn.tigris.org
For additional commands, e-mail: dev-help@tortoisesvn.tigris.org
Received on Fri Aug 24 06:15:15 2007

This is an archived mail posted to the TortoiseSVN Dev mailing list.