Bug 1501482. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 13 Nov 2018 09:41:58 -0500
changeset 446770 6c28ad7f98a7629f5a1b2f123aaad66f1f6233f0
parent 446769 a43822d30dcf77d0734df7da40b39f882ab852a8
child 446771 d6ac0dc85306b753c1d1d5f3084f73f0d1286b86
child 446773 95c0c22616c161aff925f1ddc124f0da40561905
push id35049
push userrgurzau@mozilla.com
push dateFri, 16 Nov 2018 17:09:01 +0000
treeherdermozilla-central@d6ac0dc85306 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1501482
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1501482. r=tnikkel Differential Revision: https://phabricator.services.mozilla.com/D11897
image/DecoderFactory.cpp
image/DecoderFactory.h
image/decoders/nsBMPDecoder.cpp
image/decoders/nsBMPDecoder.h
netwerk/mime/nsMimeTypes.h
widget/windows/moz.build
widget/windows/nsClipboard.cpp
widget/windows/nsDataObj.cpp
widget/windows/nsImageClipboard.cpp
widget/windows/nsImageClipboard.h
widget/windows/nsNativeThemeWin.cpp
--- a/image/DecoderFactory.cpp
+++ b/image/DecoderFactory.cpp
@@ -55,16 +55,20 @@ DecoderFactory::GetDecoderType(const cha
     type = DecoderType::JPEG;
 
   // BMP
   } else if (!strcmp(aMimeType, IMAGE_BMP)) {
     type = DecoderType::BMP;
   } else if (!strcmp(aMimeType, IMAGE_BMP_MS)) {
     type = DecoderType::BMP;
 
+  // BMP_CLIPBOARD
+  } else if (!strcmp(aMimeType, IMAGE_BMP_MS_CLIPBOARD)) {
+    type = DecoderType::BMP_CLIPBOARD;
+
   // ICO
   } else if (!strcmp(aMimeType, IMAGE_ICO)) {
     type = DecoderType::ICO;
   } else if (!strcmp(aMimeType, IMAGE_ICO_MS)) {
     type = DecoderType::ICO;
 
   // Icon
   } else if (!strcmp(aMimeType, IMAGE_ICON_MS)) {
@@ -98,16 +102,19 @@ DecoderFactory::GetDecoder(DecoderType a
       // a progressive decode.
       decoder = new nsJPEGDecoder(aImage,
                                   aIsRedecode ? Decoder::SEQUENTIAL
                                               : Decoder::PROGRESSIVE);
       break;
     case DecoderType::BMP:
       decoder = new nsBMPDecoder(aImage);
       break;
+    case DecoderType::BMP_CLIPBOARD:
+      decoder = new nsBMPDecoder(aImage, /* aForClipboard */ true);
+      break;
     case DecoderType::ICO:
       decoder = new nsICODecoder(aImage);
       break;
     case DecoderType::ICON:
       decoder = new nsIconDecoder(aImage);
       break;
     case DecoderType::WEBP:
       decoder = new nsWebPDecoder(aImage);
--- a/image/DecoderFactory.h
+++ b/image/DecoderFactory.h
@@ -30,16 +30,17 @@ class SourceBufferIterator;
  * DecoderFactory::GetDecoderType().
  */
 enum class DecoderType
 {
   PNG,
   GIF,
   JPEG,
   BMP,
+  BMP_CLIPBOARD,
   ICO,
   ICON,
   WEBP,
   UNKNOWN
 };
 
 class DecoderFactory
 {
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -180,19 +180,21 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* 
   , mPreGapLength(0)
   , mPixelRowSize(0)
   , mCurrentRow(0)
   , mCurrentPos(0)
   , mAbsoluteModeNumPixels(0)
 {
 }
 
-// Constructor for normal BMP files.
-nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
-  : nsBMPDecoder(aImage, State::FILE_HEADER, FILE_HEADER_LENGTH)
+// Constructor for normal BMP files or from the clipboard.
+nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, bool aForClipboard)
+  : nsBMPDecoder(aImage,
+                 aForClipboard ? State::CLIPBOARD_HEADER : State::FILE_HEADER,
+                 aForClipboard ? BIHSIZE_FIELD_LENGTH : FILE_HEADER_LENGTH)
 {
 }
 
 // Constructor used for WinBMPv3-ICO files, which lack a file header.
 nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset)
   : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH)
 {
   SetIsWithinICO();
@@ -450,16 +452,17 @@ LexerResult
 nsBMPDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
 {
   MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
 
   return mLexer.Lex(aIterator, aOnResume,
                     [=](State aState, const char* aData, size_t aLength) {
     switch (aState) {
       case State::FILE_HEADER:      return ReadFileHeader(aData, aLength);
+      case State::CLIPBOARD_HEADER: return ReadClipboardHeader(aData, aLength);
       case State::INFO_HEADER_SIZE: return ReadInfoHeaderSize(aData, aLength);
       case State::INFO_HEADER_REST: return ReadInfoHeaderRest(aData, aLength);
       case State::BITFIELDS:        return ReadBitfields(aData, aLength);
       case State::COLOR_TABLE:      return ReadColorTable(aData, aLength);
       case State::GAP:              return SkipGap();
       case State::AFTER_GAP:        return AfterGap();
       case State::PIXEL_ROW:        return ReadPixelRow(aData);
       case State::RLE_SEGMENT:      return ReadRLESegment(aData);
@@ -483,16 +486,24 @@ nsBMPDecoder::ReadFileHeader(const char*
 
   // We ignore the filesize (aData + 2) and reserved (aData + 6) fields.
 
   mH.mDataOffset = LittleEndian::readUint32(aData + 10);
 
   return Transition::To(State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH);
 }
 
+LexerTransition<nsBMPDecoder::State>
+nsBMPDecoder::ReadClipboardHeader(const char* aData, size_t aLength)
+{
+  // With the clipboard, the data offset is the header length.
+  mH.mDataOffset = LittleEndian::readUint32(aData);
+  return ReadInfoHeaderSize(aData, aLength);
+}
+
 // We read the info header in two steps: (a) read the mBIHSize field to
 // determine how long the header is; (b) read the rest of the header.
 LexerTransition<nsBMPDecoder::State>
 nsBMPDecoder::ReadInfoHeaderSize(const char* aData, size_t aLength)
 {
   mPreGapLength += aLength;
 
   mH.mBIHSize = LittleEndian::readUint32(aData);
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -152,44 +152,46 @@ public:
   nsresult BeforeFinishInternal() override;
   nsresult FinishInternal() override;
 
 private:
   friend class DecoderFactory;
 
   enum class State {
     FILE_HEADER,
+    CLIPBOARD_HEADER,
     INFO_HEADER_SIZE,
     INFO_HEADER_REST,
     BITFIELDS,
     COLOR_TABLE,
     GAP,
     AFTER_GAP,
     PIXEL_ROW,
     RLE_SEGMENT,
     RLE_DELTA,
     RLE_ABSOLUTE
   };
 
-  // This is the constructor used for normal BMP images.
-  explicit nsBMPDecoder(RasterImage* aImage);
+  // This is the constructor used for normal and clipboard BMP images.
+  explicit nsBMPDecoder(RasterImage* aImage, bool aForClipboard = false);
 
   // This is the constructor used for BMP resources in ICO images.
   nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
 
   // Helper constructor called by the other two.
   nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength);
 
   int32_t AbsoluteHeight() const { return abs(mH.mHeight); }
 
   uint32_t* RowBuffer();
 
   void FinishRow();
 
   LexerTransition<State> ReadFileHeader(const char* aData, size_t aLength);
+  LexerTransition<State> ReadClipboardHeader(const char* aData, size_t aLength);
   LexerTransition<State> ReadInfoHeaderSize(const char* aData, size_t aLength);
   LexerTransition<State> ReadInfoHeaderRest(const char* aData, size_t aLength);
   LexerTransition<State> ReadBitfields(const char* aData, size_t aLength);
   LexerTransition<State> ReadColorTable(const char* aData, size_t aLength);
   LexerTransition<State> SkipGap();
   LexerTransition<State> AfterGap();
   LexerTransition<State> ReadPixelRow(const char* aData);
   LexerTransition<State> ReadRLESegment(const char* aData);
--- a/netwerk/mime/nsMimeTypes.h
+++ b/netwerk/mime/nsMimeTypes.h
@@ -103,16 +103,19 @@
 #define IMAGE_PPM                           "image/x-portable-pixmap"
 #define IMAGE_XBM                           "image/x-xbitmap"
 #define IMAGE_XBM2                          "image/x-xbm"
 #define IMAGE_XBM3                          "image/xbm"
 #define IMAGE_ART                           "image/x-jg"
 #define IMAGE_TIFF                          "image/tiff"
 #define IMAGE_BMP                           "image/bmp"
 #define IMAGE_BMP_MS                        "image/x-ms-bmp"
+// This is used internally to represent Windows clipboard BMPs which remove
+// part of the header.
+#define IMAGE_BMP_MS_CLIPBOARD              "image/x-ms-clipboard-bmp"
 #define IMAGE_ICO                           "image/x-icon"
 #define IMAGE_ICO_MS                        "image/vnd.microsoft.icon"
 #define IMAGE_ICON_MS                       "image/icon"
 #define IMAGE_MNG                           "video/x-mng"
 #define IMAGE_JNG                           "image/x-jng"
 #define IMAGE_SVG_XML                       "image/svg+xml"
 #define IMAGE_WEBP                          "image/webp"
 
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -55,17 +55,16 @@ UNIFIED_SOURCES += [
     'LSPAnnotator.cpp',
     'nsAppShell.cpp',
     'nsClipboard.cpp',
     'nsColorPicker.cpp',
     'nsDataObj.cpp',
     'nsDataObjCollection.cpp',
     'nsDragService.cpp',
     'nsIdleServiceWin.cpp',
-    'nsImageClipboard.cpp',
     'nsLookAndFeel.cpp',
     'nsNativeDragSource.cpp',
     'nsNativeDragTarget.cpp',
     'nsNativeThemeWin.cpp',
     'nsSound.cpp',
     'nsToolkit.cpp',
     'nsUXThemeData.cpp',
     'nsWindow.cpp',
--- a/widget/windows/nsClipboard.cpp
+++ b/widget/windows/nsClipboard.cpp
@@ -20,26 +20,27 @@
 #include "nsIFormatConverter.h"
 #include "nsITransferable.h"
 #include "nsCOMPtr.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsPrimitiveHelpers.h"
-#include "nsImageClipboard.h"
 #include "nsIWidget.h"
 #include "nsIComponentManager.h"
 #include "nsWidgetsCID.h"
 #include "nsCRT.h"
 #include "nsNetUtil.h"
 #include "nsIFileProtocolHandler.h"
 #include "nsIOutputStream.h"
 #include "nsEscape.h"
 #include "nsIObserverService.h"
+#include "nsMimeTypes.h"
+#include "imgITools.h"
 
 using mozilla::LogLevel;
 
 static mozilla::LazyLogModule gWin32ClipboardLog("nsClipboard");
 
 // oddly, this isn't in the MSVC headers anywhere.
 UINT nsClipboard::CF_HTML = ::RegisterClipboardFormatW(L"HTML Format");
 UINT nsClipboard::CF_CUSTOMTYPES = ::RegisterClipboardFormatW(L"application/x-moz-custom-clipdata");
@@ -469,27 +470,49 @@ nsresult nsClipboard::GetNativeDataOffCl
                   result = NS_OK;
                 }
               } break;
 
             case CF_DIBV5:
               if (aMIMEImageFormat)
               {
                 uint32_t allocLen = 0;
-                unsigned char * clipboardData;
+                const char* clipboardData;
                 if (NS_SUCCEEDED(GetGlobalData(stm.hGlobal, (void **)&clipboardData, &allocLen)))
                 {
-                  nsImageFromClipboard converter;
-                  nsIInputStream * inputStream;
-                  converter.GetEncodedImageStream(clipboardData, aMIMEImageFormat, &inputStream);   // addrefs for us, don't release
-                  if ( inputStream ) {
-                    *aData = inputStream;
-                    *aLen = sizeof(nsIInputStream*);
-                    result = NS_OK;
+                  nsCOMPtr<imgIContainer> container;
+                  nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+                  result = imgTools->DecodeImageFromBuffer(clipboardData, allocLen,
+                                                           NS_LITERAL_CSTRING(IMAGE_BMP_MS_CLIPBOARD),
+                                                           getter_AddRefs(container));
+                  if (NS_FAILED(result)) {
+                    break;
+                  }
+
+                  nsAutoCString mimeType;
+                  if (strcmp(aMIMEImageFormat, kJPGImageMime) == 0) {
+                    mimeType.Assign(IMAGE_JPEG);
+                  } else {
+                    mimeType.Assign(aMIMEImageFormat);
                   }
+
+                  nsCOMPtr<nsIInputStream> inputStream;
+                  result = imgTools->EncodeImage(container, mimeType, EmptyString(),
+                                                 getter_AddRefs(inputStream));
+                  if (NS_FAILED(result)) {
+                    break;
+                  }
+
+                  if (!inputStream) {
+                    result = NS_ERROR_FAILURE;
+                    break;
+                  }
+
+                  *aData = inputStream.forget().take();
+                  *aLen = sizeof(nsIInputStream*);
                 }
               } break;
 
             case CF_HDROP : 
               {
                 // in the case of a file drop, multiple files are stashed within a
                 // single data object. In order to match mozilla's D&D apis, we
                 // just pull out the file at the requested index, pretending as
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -12,17 +12,16 @@
 #include "nsArrayUtils.h"
 #include "nsClipboard.h"
 #include "nsReadableUtils.h"
 #include "nsITransferable.h"
 #include "nsISupportsPrimitives.h"
 #include "IEnumFE.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsString.h"
-#include "nsImageClipboard.h"
 #include "nsCRT.h"
 #include "nsPrintfCString.h"
 #include "nsIStringBundle.h"
 #include "nsEscape.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "mozilla/Services.h"
 #include "nsIOutputStream.h"
@@ -30,25 +29,28 @@
 #include "nsDirectoryServiceDefs.h"
 #include "nsITimer.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsIContentPolicy.h"
 #include "nsContentUtils.h"
 #include "nsIPrincipal.h"
 #include "nsNativeCharsetUtils.h"
+#include "nsMimeTypes.h"
+#include "imgITools.h"
 
 #include "WinUtils.h"
 #include "mozilla/LazyIdleThread.h"
 #include <algorithm>
 
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
+#define BFH_LENGTH 14
 #define DEFAULT_THREAD_TIMEOUT_MS 30000
 
 NS_IMPL_ISUPPORTS(nsDataObj::CStream, nsIStreamListener)
 
 //-----------------------------------------------------------------------------
 // CStream implementation
 nsDataObj::CStream::CStream() :
   mChannelRead(false),
@@ -897,30 +899,70 @@ nsDataObj::GetDib(const nsACString& inFl
                   STGMEDIUM & aSTG)
 {
   ULONG result = E_FAIL;
   uint32_t len = 0;
   nsCOMPtr<nsISupports> genericDataWrapper;
   mTransferable->GetTransferData(PromiseFlatCString(inFlavor).get(), getter_AddRefs(genericDataWrapper), &len);
   nsCOMPtr<imgIContainer> image ( do_QueryInterface(genericDataWrapper) );
   if ( image ) {
-    // use the |nsImageToClipboard| helper class to build up a bitmap. We now own
-    // the bits, and pass them back to the OS in |aSTG|.
-    nsImageToClipboard converter(image, aFormat.cfFormat == CF_DIBV5);
-    HANDLE bits = nullptr;
-    nsresult rv = converter.GetPicture ( &bits );
-    if ( NS_SUCCEEDED(rv) && bits ) {
-      aSTG.hGlobal = bits;
-      aSTG.tymed = TYMED_HGLOBAL;
-      result = S_OK;
+    nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+
+    nsAutoString options;
+    if (aFormat.cfFormat == CF_DIBV5) {
+      options.AppendLiteral("version=5");
+    } else {
+      options.AppendLiteral("version=3");
+    }
+
+    nsCOMPtr<nsIInputStream> inputStream;
+    nsresult rv = imgTools->EncodeImage(image, NS_LITERAL_CSTRING(IMAGE_BMP),
+                                        options, getter_AddRefs(inputStream));
+    if (NS_FAILED(rv) || !inputStream) {
+      return E_FAIL;
+    }
+
+    nsCOMPtr<imgIEncoder> encoder = do_QueryInterface(inputStream);
+    if (!encoder) {
+      return E_FAIL;
+    }
+
+    uint32_t size = 0;
+    rv = encoder->GetImageBufferUsed(&size);
+    if (NS_FAILED(rv) || size <= BFH_LENGTH) {
+      return E_FAIL;
     }
-  } // if we have an image
-  else  
+
+    char *src = nullptr;
+    rv = encoder->GetImageBuffer(&src);
+    if (NS_FAILED(rv) || !src) {
+      return E_FAIL;
+    }
+
+    // We don't want the file header.
+    src += BFH_LENGTH;
+    size -= BFH_LENGTH;
+
+    HGLOBAL glob = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
+    if (!glob) {
+      DWORD err = ::GetLastError();
+      return E_FAIL;
+    }
+
+    char *dst = (char*) ::GlobalLock(glob);
+    ::CopyMemory(dst, src, size);
+    ::GlobalUnlock(glob);
+
+    aSTG.hGlobal = glob;
+    aSTG.tymed = TYMED_HGLOBAL;
+    result = S_OK;
+  } else {
     NS_WARNING ( "Definitely not an image on clipboard" );
-	return result;
+  }
+  return result;
 }
 
 
 
 //
 // GetFileDescriptor
 //
 
@@ -1499,89 +1541,81 @@ HRESULT nsDataObj::DropImage(FORMATETC& 
     uint32_t len = 0;
     nsCOMPtr<nsISupports> genericDataWrapper;
 
     mTransferable->GetTransferData(kNativeImageMime, getter_AddRefs(genericDataWrapper), &len);
     nsCOMPtr<imgIContainer> image(do_QueryInterface(genericDataWrapper));
     if (!image) 
       return E_FAIL;
 
-    // Use the clipboard helper class to build up a memory bitmap.
-    nsImageToClipboard converter(image);
-    HANDLE bits = nullptr;
-    rv = converter.GetPicture(&bits); // Clipboard routines return a global handle we own.
+    nsCOMPtr<imgITools> imgTools = do_CreateInstance("@mozilla.org/image/tools;1");
+    nsCOMPtr<nsIInputStream> inputStream;
+    rv = imgTools->EncodeImage(image, NS_LITERAL_CSTRING(IMAGE_BMP),
+                               NS_LITERAL_STRING("version=3"),
+                               getter_AddRefs(inputStream));
+    if (NS_FAILED(rv) || !inputStream) {
+      return E_FAIL;
+    }
 
-    if (NS_FAILED(rv) || !bits)
+    nsCOMPtr<imgIEncoder> encoder = do_QueryInterface(inputStream);
+    if (!encoder) {
       return E_FAIL;
+    }
 
-    // We now own these bits!
-    uint32_t bitmapSize = GlobalSize(bits);
-    if (!bitmapSize) {
-      GlobalFree(bits);
+    uint32_t size = 0;
+    rv = encoder->GetImageBufferUsed(&size);
+    if (NS_FAILED(rv)) {
+      return E_FAIL;
+    }
+
+    char *src = nullptr;
+    rv = encoder->GetImageBuffer(&src);
+    if (NS_FAILED(rv) || !src) {
       return E_FAIL;
     }
 
     // Save the bitmap to a temporary location.      
     nsCOMPtr<nsIFile> dropFile;
     rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(dropFile));
     if (!dropFile) {
-      GlobalFree(bits);
       return E_FAIL;
     }
 
     // Filename must be random so as not to confuse apps like
     // Photoshop which handle multiple drags into a single window.
     char buf[13];
     nsCString filename;
     NS_MakeRandomString(buf, 8);
     memcpy(buf+8, ".bmp", 5);
     filename.Append(nsDependentCString(buf, 12));
     dropFile->AppendNative(filename);
     rv = dropFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0660);
     if (NS_FAILED(rv)) { 
-      GlobalFree(bits);
       return E_FAIL;
     }
 
     // Cache the temp file so we can delete it later and so
     // it doesn't get recreated over and over on multiple calls
     // which does occur from windows shell.
     dropFile->Clone(getter_AddRefs(mCachedTempFile));
 
     // Write the data to disk.
     nsCOMPtr<nsIOutputStream> outStream;
     rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), dropFile);
     if (NS_FAILED(rv)) { 
-      GlobalFree(bits);
       return E_FAIL;
     }
 
-    char * bm = (char *)GlobalLock(bits);
-
-    BITMAPFILEHEADER	fileHdr;
-    BITMAPINFOHEADER *bmpHdr = (BITMAPINFOHEADER*)bm;
-
-    fileHdr.bfType        = ((WORD) ('M' << 8) | 'B');
-    fileHdr.bfSize        = GlobalSize (bits) + sizeof(fileHdr);
-    fileHdr.bfReserved1   = 0;
-    fileHdr.bfReserved2   = 0;
-    fileHdr.bfOffBits     = (DWORD) (sizeof(fileHdr) + bmpHdr->biSize);
-
-    uint32_t writeCount = 0;
-    if (NS_FAILED(outStream->Write((const char *)&fileHdr, sizeof(fileHdr), &writeCount)) ||
-        NS_FAILED(outStream->Write((const char *)bm, bitmapSize, &writeCount)))
-      rv = NS_ERROR_FAILURE;
+    uint32_t written = 0;
+    rv = outStream->Write(src, size, &written);
+    if (NS_FAILED(rv) || written != size) {
+      return E_FAIL;
+    }
 
     outStream->Close();
-
-    GlobalUnlock(bits);
-    GlobalFree(bits);
-
-    if (NS_FAILED(rv))
-      return E_FAIL;
   }
   
   // Pass the file name back to the drop target so that it can access the file.
   nsAutoString path;
   rv = mCachedTempFile->GetPath(path);
   if (NS_FAILED(rv))
     return E_FAIL;
 
deleted file mode 100644
--- a/widget/windows/nsImageClipboard.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- 
-#include "nsImageClipboard.h"
-
-#include "gfxUtils.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/gfx/DataSurfaceHelpers.h"
-#include "mozilla/RefPtr.h"
-#include "nsITransferable.h"
-#include "nsGfxCIID.h"
-#include "nsMemory.h"
-#include "imgIEncoder.h"
-#include "nsLiteralString.h"
-#include "nsComponentManagerUtils.h"
-
-#define BFH_LENGTH 14
-
-using namespace mozilla;
-using namespace mozilla::gfx;
-
-/* Things To Do 11/8/00
-
-Check image metrics, can we support them? Do we need to?
-Any other render format? HTML?
-
-*/
-
-
-//
-// nsImageToClipboard ctor
-//
-// Given an imgIContainer, convert it to a DIB that is ready to go on the win32 clipboard
-//
-nsImageToClipboard::nsImageToClipboard(imgIContainer* aInImage, bool aWantDIBV5)
-  : mImage(aInImage)
-  , mWantDIBV5(aWantDIBV5)
-{
-  // nothing to do here
-}
-
-
-//
-// nsImageToClipboard dtor
-//
-// Clean up after ourselves. We know that we have created the bitmap
-// successfully if we still have a pointer to the header.
-//
-nsImageToClipboard::~nsImageToClipboard()
-{
-}
-
-
-//
-// GetPicture
-//
-// Call to get the actual bits that go on the clipboard. If an error 
-// ocurred during conversion, |outBits| will be null.
-//
-// NOTE: The caller owns the handle and must delete it with ::GlobalRelease()
-//
-nsresult
-nsImageToClipboard :: GetPicture ( HANDLE* outBits )
-{
-  NS_ASSERTION ( outBits, "Bad parameter" );
-
-  return CreateFromImage ( mImage, outBits );
-
-} // GetPicture
-
-
-//
-// CalcSize
-//
-// Computes # of bytes needed by a bitmap with the specified attributes.
-//
-int32_t 
-nsImageToClipboard :: CalcSize ( int32_t aHeight, int32_t aColors, WORD aBitsPerPixel, int32_t aSpanBytes )
-{
-  int32_t HeaderMem = sizeof(BITMAPINFOHEADER);
-
-  // add size of pallette to header size
-  if (aBitsPerPixel < 16)
-    HeaderMem += aColors * sizeof(RGBQUAD);
-
-  if (aHeight < 0)
-    aHeight = -aHeight;
-
-  return (HeaderMem + (aHeight * aSpanBytes));
-}
-
-
-//
-// CalcSpanLength
-//
-// Computes the span bytes for determining the overall size of the image
-//
-int32_t 
-nsImageToClipboard::CalcSpanLength(uint32_t aWidth, uint32_t aBitCount)
-{
-  int32_t spanBytes = (aWidth * aBitCount) >> 5;
-  
-  if ((aWidth * aBitCount) & 0x1F)
-    spanBytes++;
-  spanBytes <<= 2;
-
-  return spanBytes;
-}
-
-
-//
-// CreateFromImage
-//
-// Do the work to setup the bitmap header and copy the bits out of the
-// image. 
-//
-nsresult
-nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap )
-{
-    nsresult rv;
-    *outBitmap = nullptr;
-
-    RefPtr<SourceSurface> surface =
-      inImage->GetFrame(imgIContainer::FRAME_CURRENT,
-                        imgIContainer::FLAG_SYNC_DECODE);
-    NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
-
-    MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
-               surface->GetFormat() == SurfaceFormat::B8G8R8X8);
-
-    RefPtr<DataSourceSurface> dataSurface;
-    if (surface->GetFormat() == SurfaceFormat::B8G8R8A8) {
-      dataSurface = surface->GetDataSurface();
-    } else {
-      // XXXjwatt Bug 995923 - get rid of this copy and handle B8G8R8X8
-      // directly below once bug 995807 is fixed.
-      dataSurface = gfxUtils::
-        CopySurfaceToDataSourceSurfaceWithFormat(surface,
-                                                 SurfaceFormat::B8G8R8A8);
-    }
-    NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
-
-    nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-    
-    uint32_t format;
-    nsAutoString options;
-    if (mWantDIBV5) {
-      options.AppendLiteral("version=5;bpp=");
-    } else {
-      options.AppendLiteral("version=3;bpp=");
-    }
-    switch (dataSurface->GetFormat()) {
-    case SurfaceFormat::B8G8R8A8:
-        format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
-        options.AppendInt(32);
-        break;
-#if 0
-    // XXXjwatt Bug 995923 - fix |format| and reenable once bug 995807 is fixed.
-    case SurfaceFormat::B8G8R8X8:
-        format = imgIEncoder::INPUT_FORMAT_RGB;
-        options.AppendInt(24);
-        break;
-#endif
-    default:
-        MOZ_ASSERT_UNREACHABLE("Unexpected surface format");
-        return NS_ERROR_INVALID_ARG;  
-    }
-
-    DataSourceSurface::MappedSurface map;
-    bool mappedOK = dataSurface->Map(DataSourceSurface::MapType::READ, &map);
-    NS_ENSURE_TRUE(mappedOK, NS_ERROR_FAILURE);
-
-    rv = encoder->InitFromData(map.mData, 0,
-                               dataSurface->GetSize().width,
-                               dataSurface->GetSize().height,
-                               map.mStride,
-                               format, options);
-    dataSurface->Unmap();
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    uint32_t size;
-    encoder->GetImageBufferUsed(&size);
-    NS_ENSURE_TRUE(size > BFH_LENGTH, NS_ERROR_FAILURE);
-    HGLOBAL glob = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT,
-                                 size - BFH_LENGTH);
-    if (!glob)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    char *dst = (char*) ::GlobalLock(glob);
-    char *src;
-    rv = encoder->GetImageBuffer(&src);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    ::CopyMemory(dst, src + BFH_LENGTH, size - BFH_LENGTH);
-    ::GlobalUnlock(glob);
-    
-    *outBitmap = (HANDLE)glob;
-    return NS_OK;
-}
-
-nsImageFromClipboard :: nsImageFromClipboard ()
-{
-  // nothing to do here
-}
-
-nsImageFromClipboard :: ~nsImageFromClipboard ( )
-{
-}
-
-//
-// GetEncodedImageStream
-//
-// Take the raw clipboard image data and convert it to aMIMEFormat in the form of a nsIInputStream
-//
-nsresult 
-nsImageFromClipboard ::GetEncodedImageStream (unsigned char * aClipboardData, const char * aMIMEFormat, nsIInputStream** aInputStream )
-{
-  NS_ENSURE_ARG_POINTER (aInputStream);
-  NS_ENSURE_ARG_POINTER (aMIMEFormat);
-  nsresult rv;
-  *aInputStream = nullptr;
-
-  // pull the size information out of the BITMAPINFO header and
-  // initialize the image
-  BITMAPINFO* header = (BITMAPINFO *) aClipboardData;
-  int32_t width  = header->bmiHeader.biWidth;
-  int32_t height = header->bmiHeader.biHeight;
-  // neg. heights mean the Y axis is inverted and we don't handle that case
-  NS_ENSURE_TRUE(height > 0, NS_ERROR_FAILURE); 
-
-  unsigned char * rgbData = new unsigned char[width * height * 3 /* RGB */];
-
-  if (rgbData) {
-    BYTE  * pGlobal = (BYTE *) aClipboardData;
-    // Convert the clipboard image into RGB packed pixel data
-    rv = ConvertColorBitMap((unsigned char *) (pGlobal + header->bmiHeader.biSize), header, rgbData);
-    // if that succeeded, encode the bitmap as aMIMEFormat data. Don't return early or we risk leaking rgbData
-    if (NS_SUCCEEDED(rv)) {
-      nsAutoCString encoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/encoder;2?type="));
-
-      // Map image/jpg to image/jpeg (which is how the encoder is registered).
-      if (strcmp(aMIMEFormat, kJPGImageMime) == 0)
-        encoderCID.AppendLiteral("image/jpeg");
-      else
-        encoderCID.Append(aMIMEFormat);
-      nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(encoderCID.get(), &rv);
-      if (NS_SUCCEEDED(rv)){
-        rv = encoder->InitFromData(rgbData, 0, width, height, 3 * width /* RGB * # pixels in a row */, 
-                                   imgIEncoder::INPUT_FORMAT_RGB, EmptyString());
-        if (NS_SUCCEEDED(rv)) {
-          encoder.forget(aInputStream);
-        }
-      }
-    }
-    delete [] rgbData;
-  } 
-  else 
-    rv = NS_ERROR_OUT_OF_MEMORY;
-
-  return rv;
-} // GetImage
-
-//
-// InvertRows
-//
-// Take the image data from the clipboard and invert the rows. Modifying aInitialBuffer in place.
-//
-void
-nsImageFromClipboard::InvertRows(unsigned char * aInitialBuffer, uint32_t aSizeOfBuffer, uint32_t aNumBytesPerRow)
-{
-  if (!aNumBytesPerRow) 
-    return; 
-
-  uint32_t numRows = aSizeOfBuffer / aNumBytesPerRow;
-  unsigned char * row = new unsigned char[aNumBytesPerRow];
-
-  uint32_t currentRow = 0;
-  uint32_t lastRow = (numRows - 1) * aNumBytesPerRow;
-  while (currentRow < lastRow)
-  {
-    // store the current row into a temporary buffer
-    memcpy(row, &aInitialBuffer[currentRow], aNumBytesPerRow);
-    memcpy(&aInitialBuffer[currentRow], &aInitialBuffer[lastRow], aNumBytesPerRow);
-    memcpy(&aInitialBuffer[lastRow], row, aNumBytesPerRow);
-    lastRow -= aNumBytesPerRow;
-    currentRow += aNumBytesPerRow;
-  }
-
-  delete[] row;
-}
-
-//
-// ConvertColorBitMap
-//
-// Takes the clipboard bitmap and converts it into a RGB packed pixel values.
-//
-nsresult 
-nsImageFromClipboard::ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer)
-{
-  uint8_t bitCount = pBitMapInfo->bmiHeader.biBitCount; 
-  uint32_t imageSize = pBitMapInfo->bmiHeader.biSizeImage; // may be zero for BI_RGB bitmaps which means we need to calculate by hand
-  uint32_t bytesPerPixel = bitCount / 8;
-  
-  if (bitCount <= 4)
-    bytesPerPixel = 1;
-
-  // rows are DWORD aligned. Calculate how many real bytes are in each row in the bitmap. This number won't 
-  // correspond to biWidth.
-  uint32_t rowSize = (bitCount * pBitMapInfo->bmiHeader.biWidth + 7) / 8; // +7 to round up
-  if (rowSize % 4)
-    rowSize += (4 - (rowSize % 4)); // Pad to DWORD Boundary
-  
-  // if our buffer includes a color map, skip over it 
-  if (bitCount <= 8)
-  {
-    int32_t bytesToSkip = (pBitMapInfo->bmiHeader.biClrUsed ? pBitMapInfo->bmiHeader.biClrUsed : (1 << bitCount) ) * sizeof(RGBQUAD);
-    aInputBuffer +=  bytesToSkip;
-  }
-
-  bitFields colorMasks; // only used if biCompression == BI_BITFIELDS
-
-  if (pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS)
-  {
-    // color table consists of 3 DWORDS containing the color masks...
-    colorMasks.red = (*((uint32_t*)&(pBitMapInfo->bmiColors[0]))); 
-    colorMasks.green = (*((uint32_t*)&(pBitMapInfo->bmiColors[1]))); 
-    colorMasks.blue = (*((uint32_t*)&(pBitMapInfo->bmiColors[2]))); 
-    CalcBitShift(&colorMasks);
-    aInputBuffer += 3 * sizeof(DWORD);
-  } 
-  else if (pBitMapInfo->bmiHeader.biCompression == BI_RGB && !imageSize)  // BI_RGB can have a size of zero which means we figure it out
-  {
-    // XXX: note use rowSize here and not biWidth. rowSize accounts for the DWORD padding for each row
-    imageSize = rowSize * pBitMapInfo->bmiHeader.biHeight;
-  }
-
-  // The windows clipboard image format inverts the rows 
-  InvertRows(aInputBuffer, imageSize, rowSize);
-
-  if (!pBitMapInfo->bmiHeader.biCompression || pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS) 
-  {  
-    uint32_t index = 0;
-    uint32_t writeIndex = 0;
-     
-    unsigned char redValue, greenValue, blueValue;
-    uint8_t colorTableEntry = 0;
-    int8_t bit; // used for grayscale bitmaps where each bit is a pixel
-    uint32_t numPixelsLeftInRow = pBitMapInfo->bmiHeader.biWidth; // how many more pixels do we still need to read for the current row
-    uint32_t pos = 0;
-
-    while (index < imageSize)
-    {
-      switch (bitCount) 
-      {
-        case 1:
-          for (bit = 7; bit >= 0 && numPixelsLeftInRow; bit--)
-          {
-            colorTableEntry = (aInputBuffer[index] >> bit) & 1;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
-            numPixelsLeftInRow--;
-          }
-          pos += 1;
-          break;
-        case 4:
-          {
-            // each aInputBuffer[index] entry contains data for two pixels.
-            // read the first pixel
-            colorTableEntry = aInputBuffer[index] >> 4;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
-            aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
-            numPixelsLeftInRow--;
-
-            if (numPixelsLeftInRow) // now read the second pixel
-            {
-              colorTableEntry = aInputBuffer[index] & 0xF;
-              aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbRed;
-              aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbGreen;
-              aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[colorTableEntry].rgbBlue;
-              numPixelsLeftInRow--;
-            }
-            pos += 1;
-          }
-          break;
-        case 8:
-          aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbRed;
-          aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbGreen;
-          aOutBuffer[writeIndex++] = pBitMapInfo->bmiColors[aInputBuffer[index]].rgbBlue;
-          numPixelsLeftInRow--;
-          pos += 1;    
-          break;
-        case 16:
-          {
-            uint16_t num = 0;
-            num = (uint8_t) aInputBuffer[index+1];
-            num <<= 8;
-            num |= (uint8_t) aInputBuffer[index];
-
-            redValue = ((uint32_t) (((float)(num & 0xf800) / 0xf800) * 0xFF0000) & 0xFF0000)>> 16;
-            greenValue =  ((uint32_t)(((float)(num & 0x07E0) / 0x07E0) * 0x00FF00) & 0x00FF00)>> 8;
-            blueValue =  ((uint32_t)(((float)(num & 0x001F) / 0x001F) * 0x0000FF) & 0x0000FF);
-
-            // now we have the right RGB values...
-            aOutBuffer[writeIndex++] = redValue;
-            aOutBuffer[writeIndex++] = greenValue;
-            aOutBuffer[writeIndex++] = blueValue;
-            numPixelsLeftInRow--;
-            pos += 2;          
-          }
-          break;
-        case 32:
-        case 24:
-          if (pBitMapInfo->bmiHeader.biCompression == BI_BITFIELDS)
-          {
-            uint32_t val = *((uint32_t*) (aInputBuffer + index) );
-            aOutBuffer[writeIndex++] = (val & colorMasks.red) >> colorMasks.redRightShift << colorMasks.redLeftShift;
-            aOutBuffer[writeIndex++] =  (val & colorMasks.green) >> colorMasks.greenRightShift << colorMasks.greenLeftShift;
-            aOutBuffer[writeIndex++] = (val & colorMasks.blue) >> colorMasks.blueRightShift << colorMasks.blueLeftShift;
-            numPixelsLeftInRow--;
-            pos += 4; // we read in 4 bytes of data in order to process this pixel
-          }
-          else
-          {
-            aOutBuffer[writeIndex++] = aInputBuffer[index+2];
-            aOutBuffer[writeIndex++] =  aInputBuffer[index+1];
-            aOutBuffer[writeIndex++] = aInputBuffer[index];
-            numPixelsLeftInRow--;
-            pos += bytesPerPixel; // 3 bytes for 24 bit data, 4 bytes for 32 bit data (we skip over the 4th byte)...
-          }
-          break;
-        default:
-          // This is probably the wrong place to check this...
-          return NS_ERROR_FAILURE;
-      }
-
-      index += bytesPerPixel; // increment our loop counter
-
-      if (!numPixelsLeftInRow)
-      {
-        if (rowSize != pos)
-        {
-          // advance index to skip over remaining padding bytes
-          index += (rowSize - pos);
-        }
-        numPixelsLeftInRow = pBitMapInfo->bmiHeader.biWidth;
-        pos = 0; 
-      }
-
-    } // while we still have bytes to process
-  }
-
-  return NS_OK;
-}
-
-void nsImageFromClipboard::CalcBitmask(uint32_t aMask, uint8_t& aBegin, uint8_t& aLength)
-{
-  // find the rightmost 1
-  uint8_t pos;
-  bool started = false;
-  aBegin = aLength = 0;
-  for (pos = 0; pos <= 31; pos++) 
-  {
-    if (!started && (aMask & (1 << pos))) 
-    {
-      aBegin = pos;
-      started = true;
-    }
-    else if (started && !(aMask & (1 << pos))) 
-    {
-      aLength = pos - aBegin;
-      break;
-    }
-  }
-}
-
-void nsImageFromClipboard::CalcBitShift(bitFields * aColorMask)
-{
-  uint8_t begin, length;
-  // red
-  CalcBitmask(aColorMask->red, begin, length);
-  aColorMask->redRightShift = begin;
-  aColorMask->redLeftShift = 8 - length;
-  // green
-  CalcBitmask(aColorMask->green, begin, length);
-  aColorMask->greenRightShift = begin;
-  aColorMask->greenLeftShift = 8 - length;
-  // blue
-  CalcBitmask(aColorMask->blue, begin, length);
-  aColorMask->blueRightShift = begin;
-  aColorMask->blueLeftShift = 8 - length;
-}
deleted file mode 100644
--- a/widget/windows/nsImageClipboard.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsImageClipboard_h
-#define nsImageClipboard_h
-
-/* Things To Do 11/8/00
-
-Check image metrics, can we support them? Do we need to?
-Any other render format? HTML?
-
-*/
-
-#include "nsError.h"
-#include <windows.h>
-
-#include "nsCOMPtr.h"
-#include "imgIContainer.h"
-#include "nsIInputStream.h"
-
-
-//
-// nsImageToClipboard
-//
-// A utility class that takes an imgIContainer and does all the bitmap magic
-// to allow us to put it on the clipboard
-//
-class nsImageToClipboard
-{
-public:
-  explicit nsImageToClipboard(imgIContainer* aInImage, bool aWantDIBV5 = true);
-  ~nsImageToClipboard();
-
-    // Call to get the actual bits that go on the clipboard. If |nullptr|, the
-    // setup operations have failed.
-    //
-    // NOTE: The caller owns the handle and must delete it with ::GlobalRelease()
-  nsresult GetPicture ( HANDLE* outBits ) ;
-
-private:
-
-    // Computes # of bytes needed by a bitmap with the specified attributes.
-  int32_t CalcSize(int32_t aHeight, int32_t aColors, WORD aBitsPerPixel, int32_t aSpanBytes);
-  int32_t CalcSpanLength(uint32_t aWidth, uint32_t aBitCount);
-
-    // Do the work
-  nsresult CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap );
-
-  nsCOMPtr<imgIContainer> mImage;            // the image we're working with
-  bool mWantDIBV5;
-
-}; // class nsImageToClipboard
-
-
-struct bitFields {
-    uint32_t red;
-    uint32_t green;
-    uint32_t blue;
-    uint8_t redLeftShift;
-    uint8_t redRightShift;
-    uint8_t greenLeftShift;
-    uint8_t greenRightShift;
-    uint8_t blueLeftShift;
-    uint8_t blueRightShift;
-};
-
-//
-// nsImageFromClipboard
-//
-// A utility class that takes a DIB from the win32 clipboard and does
-// all the bitmap magic to convert it to a PNG or a JPEG in the form of a nsIInputStream
-//
-class nsImageFromClipboard
-{
-public:
-  nsImageFromClipboard () ;
-  ~nsImageFromClipboard ( ) ;
-  
-    // Retrieve the newly created image
-  nsresult GetEncodedImageStream (unsigned char * aClipboardData, const char * aMIMEFormat, nsIInputStream** outImage);
-
-private:
-
-  void InvertRows(unsigned char * aInitialBuffer, uint32_t aSizeOfBuffer, uint32_t aNumBytesPerRow);
-  nsresult ConvertColorBitMap(unsigned char * aInputBuffer, PBITMAPINFO pBitMapInfo, unsigned char * aOutBuffer);
-  void CalcBitmask(uint32_t aMask, uint8_t& aBegin, uint8_t& aLength);
-  void CalcBitShift(bitFields * aColorMask);
-
-}; // nsImageFromClipboard
-
-#endif
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -6,16 +6,17 @@
 #include "nsNativeThemeWin.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Logging.h"
 #include "mozilla/RelativeLuminanceUtils.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/WindowsVersion.h"
+#include "mozilla/gfx/Types.h" // for Color::FromABGR
 #include "nsColor.h"
 #include "nsDeviceContext.h"
 #include "nsRect.h"
 #include "nsSize.h"
 #include "nsTransform2D.h"
 #include "nsStyleConsts.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
@@ -39,16 +40,17 @@
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsNativeDrawing.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include <algorithm>
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 using namespace mozilla::widget;
 
 extern mozilla::LazyLogModule gWindowsLog;
 
 NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeWin, nsNativeTheme, nsITheme)
 
 nsNativeThemeWin::nsNativeThemeWin() :
   mProgressDeterminateTimeStamp(TimeStamp::Now()),