Bug 1337856 Part 1 - Use a better up/down-scaling method for the stub installer background. r?agashlin draft
authorMatt Howell <mhowell@mozilla.com>
Tue, 10 Oct 2017 08:50:31 -0700
changeset 681030 f3122a35c43c1facf2d7956b179bc91963a17ba1
parent 680782 c6a2643362a67cdf7a87ac165454fce4b383debb
child 681031 1b39c396f64f683cc8c2ffdc7534895cf97dc295
push id84733
push usermhowell@mozilla.com
push dateMon, 16 Oct 2017 21:22:46 +0000
reviewersagashlin
bugs1337856
milestone58.0a1
Bug 1337856 Part 1 - Use a better up/down-scaling method for the stub installer background. r?agashlin MozReview-Commit-ID: Ag02ni4nJ00
browser/installer/windows/nsis/stub.nsi
toolkit/mozapps/installer/windows/nsis/common.nsh
--- a/browser/installer/windows/nsis/stub.nsi
+++ b/browser/installer/windows/nsis/stub.nsi
@@ -464,17 +464,18 @@ Function .onInit
   ${EndIf}
 
   CreateFont $FontInstalling "$0" "28" "400"
   CreateFont $FontBlurb      "$0" "15" "400"
   CreateFont $FontFooter     "$0" "13" "400"
   CreateFont $FontCheckbox   "$0" "10" "400"
 
   InitPluginsDir
-  File /oname=$PLUGINSDIR\bgstub.bmp "bgstub.bmp"
+  File /oname=$PLUGINSDIR\bgstub.jpg "bgstub.jpg"
+  File /oname=$PLUGINSDIR\bgstub_2x.jpg "bgstub_2x.jpg"
 
   SetShellVarContext all ; Set SHCTX to All Users
   ; If the user doesn't have write access to the installation directory set
   ; the installation directory to a subdirectory of the All Users application
   ; directory and if the user can't write to that location set the installation
   ; directory to a subdirectory of the users local application directory
   ; (e.g. non-roaming).
   Call CanWrite
@@ -560,16 +561,36 @@ Function .onUserAbort
   ${EndIf}
 
   ; Aborting the abort will allow SendPing which is called by
   ; DisplayDownloadError to hide the installer window and close the installer
   ; after it sends the metrics ping.
   Abort
 FunctionEnd
 
+Function DrawBackgroundImage
+  ${NSD_CreateBitmap} 0 0 100% 100% ""
+  Pop $HwndBgBitmapControl
+
+  ; If the scaling factor is 100%, use the 1x image; the 2x images scaled down
+  ; by that much don't always look good because some of them use thinner lines
+  ; and a darker background (over which aliasing is more visible).
+  System::Call 'user32::GetWindowDC(i $HWNDPARENT) i .r0'
+  System::Call 'gdi32::GetDeviceCaps(i $0, i 88) i .r1' ; 88 = LOGPIXELSX
+  System::Call 'user32::ReleaseDC(i $HWNDPARENT, i $0)'
+  ${If} $1 <= 96
+    ${SetStretchedImageOLE} $HwndBgBitmapControl $PLUGINSDIR\bgstub.jpg $BgBitmapImage
+  ${Else}
+    ${SetStretchedImageOLE} $HwndBgBitmapControl $PLUGINSDIR\bgstub_2x.jpg $BgBitmapImage
+  ${EndIf}
+
+  ; transparent bg on control prevents flicker on redraw
+  SetCtlColors $HwndBgBitmapControl ${INSTALL_BLURB_TEXT_COLOR} transparent
+FunctionEnd
+
 Function createProfileCleanup
   Call ShouldPromptForProfileCleanup
   ${Select} $ProfileCleanupPromptType
   ${Case} 0
     StrCpy $CheckboxCleanupProfile 0
     Abort ; Skip this page
   ${Case} 1
     StrCpy $ProfileCleanupHeaderString $(STUB_CLEANUP_REINSTALL_HEADER)
@@ -697,21 +718,17 @@ Function createProfileCleanup
     nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_RIGHT} \
       ${WS_EX_TRANSPARENT} 175u ${INSTALL_FOOTER_TOP_DU} ${INSTALL_FOOTER_WIDTH_DU} \
       "$R2u" "$(STUB_BLURB_FOOTER2)"
   !endif
   Pop $0
   SendMessage $0 ${WM_SETFONT} $FontFooter 0
   SetCtlColors $0 ${INSTALL_BLURB_TEXT_COLOR} transparent
 
-  ${NSD_CreateBitmap} 0 0 100% 100% ""
-  Pop $HwndBgBitmapControl
-  ${NSD_SetStretchedImage} $HwndBgBitmapControl $PLUGINSDIR\bgstub.bmp $BgBitmapImage
-  ; transparent bg on control prevents flicker on redraw
-  SetCtlColors $HwndBgBitmapControl ${INSTALL_BLURB_TEXT_COLOR} transparent
+  Call DrawBackgroundImage
 
   LockWindow off
   nsDialogs::Show
 
   ${NSD_FreeImage} $BgBitmapImage
 FunctionEnd
 
 Function RedrawWindow
@@ -779,21 +796,17 @@ Function createInstall
   SetCtlColors $0 ${INSTALL_BLURB_TEXT_COLOR} transparent
 
   ${NSD_CreateProgressBar} 20% ${PROGRESS_BAR_TOP_DU} 60% 12u ""
   Pop $Progressbar
   ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
   SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \
               $ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N
 
-  ${NSD_CreateBitmap} 0 0 100% 100% ""
-  Pop $HwndBgBitmapControl
-  ${NSD_SetStretchedImage} $HwndBgBitmapControl $PLUGINSDIR\bgstub.bmp $BgBitmapImage
-  ; transparent bg on control prevents flicker on redraw
-  SetCtlColors $HwndBgBitmapControl ${INSTALL_BLURB_TEXT_COLOR} transparent
+  Call DrawBackgroundImage
 
   GetDlgItem $0 $HWNDPARENT 1 ; Install button
   EnableWindow $0 0
   ShowWindow $0 ${SW_HIDE}
 
   GetDlgItem $0 $HWNDPARENT 3 ; Back button
   EnableWindow $0 0
   ShowWindow $0 ${SW_HIDE}
--- a/toolkit/mozapps/installer/windows/nsis/common.nsh
+++ b/toolkit/mozapps/installer/windows/nsis/common.nsh
@@ -7398,55 +7398,101 @@
 !ifmacrodef __NSD_DefineControl
 !insertmacro __NSD_DefineControl LabelCenter
 !define __NSD_LabelCenter_CLASS STATIC
 !define __NSD_LabelCenter_STYLE ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_CENTER}
 !define __NSD_LabelCenter_EXSTYLE ${WS_EX_TRANSPARENT}
 !endif
 
 /**
- * Modified version of the __NSD_SetStretchedImage macro from nsDialogs.nsh that
- * supports transparency. See nsDialogs documentation for additional info.
+ * Draws an image file (BMP, GIF, or JPG) onto a bitmap control, with scaling.
+ * Adapted from https://stackoverflow.com/a/13405711/1508094
+ *
+ * @param CONTROL bitmap control created by NSD_CreateBitmap
+ * @param IMAGE path to image file to draw to the bitmap
+ * @param HANDLE output bitmap handle which must be freed via NSD_FreeImage
+ *               after nsDialogs::Show has been called
  */
-!macro __SetStretchedTransparentImage CONTROL IMAGE HANDLE
-  Push $0
-  Push $1
-  Push $2
-  Push $R0
+!macro __SetStretchedImageOLE CONTROL IMAGE HANDLE
+  !ifndef IID_IPicture
+    !define IID_IPicture {7BF80980-BF32-101A-8BBB-00AA00300CAB}
+  !endif
+  !ifndef SRCCOPY
+    !define SRCCOPY 0xCC0020
+  !endif
+  !ifndef HALFTONE
+    !define HALFTONE 4
+  !endif
+
+  Push $0 ; HANDLE
+  Push $1 ; memory DC
+  Push $2 ; IPicture created from IMAGE
+  Push $3 ; HBITMAP obtained from $2
+  Push $4 ; BITMAPINFO obtained from $3
+  Push $5 ; width of IMAGE
+  Push $6 ; height of IMAGE
+  Push $7 ; width of CONTROL
+  Push $8 ; height of CONTROL
+  Push $R0 ; CONTROL
 
   StrCpy $R0 ${CONTROL} ; in case ${CONTROL} is $0
-  StrCpy $1 ""
-  StrCpy $2 ""
+  StrCpy $7 ""
+  StrCpy $8 ""
 
   System::Call '*(i, i, i, i) i.s'
   Pop $0
 
   ${If} $0 <> 0
     System::Call 'user32::GetClientRect(i R0, i r0)'
     System::Call '*$0(i, i, i .s, i .s)'
     System::Free $0
-    Pop $1
-    Pop $2
+    Pop $7
+    Pop $8
   ${EndIf}
 
-  System::Call 'user32::LoadImageW(i 0, t s, i ${IMAGE_BITMAP}, i r1, i r2, \
-                                   i ${MOZ_LOADTRANSPARENT}) i .s' "${IMAGE}"
-  Pop $0
-  SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0
-
-  SetCtlColors $R0 "" transparent
-  ${NSD_AddExStyle} $R0 ${WS_EX_TRANSPARENT}|${WS_EX_TOPMOST}
+  ${If} $7 > 0
+  ${AndIf} $8 > 0
+    System::Call 'oleaut32::OleLoadPicturePath(w"${IMAGE}",i0,i0,i0,g"${IID_IPicture}",*i.r2)i.r1'
+    ${If} $1 = 0
+      System::Call 'user32::GetDC(i0)i.s'
+      System::Call 'gdi32::CreateCompatibleDC(iss)i.r1'
+      System::Call 'gdi32::CreateCompatibleBitmap(iss,ir7,ir8)i.r0'
+      System::Call 'user32::ReleaseDC(i0,is)'
+      System::Call '$2->3(*i.r3)i.r4' ; IPicture->get_Handle
+      ${If} $4 = 0
+        System::Call 'gdi32::SetStretchBltMode(ir1,i${HALFTONE})'
+        System::Call '*(&i40,&i1024)i.r4' ; BITMAP / BITMAPINFO
+        System::Call 'gdi32::GetObject(ir3,i24,ir4)'
+        System::Call 'gdi32::SelectObject(ir1,ir0)i.s'
+        System::Call '*$4(i40,i.r5,i.r6,i0,i,i.s)' ; Grab size and bits-ptr AND init as BITMAPINFOHEADER
+        System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFOHEADER
+        System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFO
+        System::Call 'gdi32::StretchDIBits(ir1,i0,i0,ir7,ir8,i0,i0,ir5,ir6,is,ir4,i0,i${SRCCOPY})'
+        System::Call 'gdi32::SelectObject(ir1,is)'
+        System::Free $4
+        SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0
+      ${EndIf}
+      System::Call 'gdi32::DeleteDC(ir1)'
+      System::Call '$2->2()' ; IPicture->release()
+    ${EndIf}
+  ${EndIf}
 
   Pop $R0
+  Pop $8
+  Pop $7
+  Pop $6
+  Pop $5
+  Pop $4
+  Pop $3
   Pop $2
   Pop $1
   Exch $0
   Pop ${HANDLE}
 !macroend
-!define SetStretchedTransparentImage "!insertmacro __SetStretchedTransparentImage"
+!define SetStretchedImageOLE "!insertmacro __SetStretchedImageOLE"
 
 /**
  * Removes a single style from a control.
  *
  * _HANDLE the handle of the control
  * _STYLE  the style to remove
  */
 !macro _RemoveStyle _HANDLE _STYLE