Fix gfx unit-tests so they do not crash on Windows, prior to Windows 7
Also fix failing Font test.
TEST=unit tests
BUG=46733
Review URL: http://codereview.chromium.org/3615001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61725 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gfx/canvas_direct2d_unittest.cc b/gfx/canvas_direct2d_unittest.cc
index a4d2c52..3163cfe 100644
--- a/gfx/canvas_direct2d_unittest.cc
+++ b/gfx/canvas_direct2d_unittest.cc
@@ -17,6 +17,7 @@
 #include "gfx/codec/png_codec.h"
 #include "gfx/native_theme_win.h"
 #include "gfx/window_impl.h"
+#include "gfx/win_util.h"
 #include "grit/gfx_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -98,14 +99,27 @@
   return bitmap;
 }
 
+bool CheckForD2DCompatibility() {
+  if (!gfx::Direct2dIsAvailable()) {
+    LOG(WARNING) << "Test is disabled as it requires either Windows 7 or " <<
+                    "Vista with Platform Update KB971644";
+    return false;
+  }
+  return true;
+}
+
 }  // namespace
 
 TEST(CanvasDirect2D, CreateCanvas) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 }
 
 TEST(CanvasDirect2D, SaveRestoreNesting) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -137,6 +151,8 @@
 }
 
 TEST(CanvasDirect2D, SaveLayerAlpha) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -149,6 +165,8 @@
 }
 
 TEST(CanvasDirect2D, SaveLayerAlphaWithBounds) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -161,6 +179,8 @@
 }
 
 TEST(CanvasDirect2D, FillRect) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -168,6 +188,8 @@
 }
 
 TEST(CanvasDirect2D, PlatformPainting) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -183,6 +205,8 @@
 }
 
 TEST(CanvasDirect2D, ClipRect) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -192,6 +216,8 @@
 }
 
 TEST(CanvasDirect2D, ClipRectWithTranslate) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -211,6 +237,8 @@
 }
 
 TEST(CanvasDirect2D, ClipRectWithScale) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -232,6 +260,8 @@
 }
 
 TEST(CanvasDirect2D, DrawRectInt) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -241,6 +271,8 @@
 }
 
 TEST(CanvasDirect2D, DrawLineInt) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -250,6 +282,8 @@
 }
 
 TEST(CanvasDirect2D, DrawBitmapInt) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -261,6 +295,8 @@
 }
 
 TEST(CanvasDirect2D, DrawBitmapInt2) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
@@ -274,6 +310,8 @@
 }
 
 TEST(CanvasDirect2D, TileImageInt) {
+  if (!CheckForD2DCompatibility())
+    return;
   TestWindow window;
   gfx::CanvasDirect2D canvas(window.rt());
 
diff --git a/gfx/font_unittest.cc b/gfx/font_unittest.cc
index d2eda1c..1cf1b11 100644
--- a/gfx/font_unittest.cc
+++ b/gfx/font_unittest.cc
@@ -4,6 +4,9 @@
 
 #include "gfx/font.h"
 
+#if defined(OS_WIN)
+#include "gfx/platform_font_win.h"
+#endif  // defined(OS_WIN)
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -13,6 +16,34 @@
 class FontTest : public testing::Test {
 };
 
+#if defined(OS_WIN)
+class ScopedMinimumFontSizeCallback {
+ public:
+  explicit ScopedMinimumFontSizeCallback(int minimum_size) {
+    minimum_size_ = minimum_size;
+    old_callback_ = gfx::PlatformFontWin::get_minimum_font_size_callback;
+    gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;
+  }
+
+  ~ScopedMinimumFontSizeCallback() {
+    gfx::PlatformFontWin::get_minimum_font_size_callback = old_callback_;
+  }
+
+ private:
+  static int GetMinimumFontSize() {
+    return minimum_size_;
+  }
+
+  gfx::PlatformFontWin::GetMinimumFontSizeCallback old_callback_;
+  static int minimum_size_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedMinimumFontSizeCallback);
+};
+
+int ScopedMinimumFontSizeCallback::minimum_size_ = 0;
+#endif  // defined(OS_WIN)
+
+
 TEST_F(FontTest, LoadArial) {
   Font cf(L"Arial", 16);
   ASSERT_TRUE(cf.GetNativeFont());
@@ -58,10 +89,12 @@
 }
 
 #if defined(OS_WIN)
-// http://crbug.com/46733
-TEST_F(FontTest, FAILS_DeriveFontResizesIfSizeTooSmall) {
+TEST_F(FontTest, DeriveFontResizesIfSizeTooSmall) {
   // This creates font of height -8.
   Font cf(L"Arial", 6);
+  // The minimum font size is set to 5 in browser_main.cc.
+  ScopedMinimumFontSizeCallback minimum_size(5);
+
   Font derived_font = cf.DeriveFont(-4);
   LOGFONT font_info;
   GetObject(derived_font.GetNativeFont(), sizeof(LOGFONT), &font_info);
@@ -71,6 +104,9 @@
 TEST_F(FontTest, DeriveFontKeepsOriginalSizeIfHeightOk) {
   // This creates font of height -8.
   Font cf(L"Arial", 6);
+  // The minimum font size is set to 5 in browser_main.cc.
+  ScopedMinimumFontSizeCallback minimum_size(5);
+
   Font derived_font = cf.DeriveFont(-2);
   LOGFONT font_info;
   GetObject(derived_font.GetNativeFont(), sizeof(LOGFONT), &font_info);
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp
index b6bfce9..ba3d9e6 100644
--- a/gfx/gfx.gyp
+++ b/gfx/gfx.gyp
@@ -50,6 +50,10 @@
           ],
           'msvs_settings': {
             'VCLinkerTool': {
+              'DelayLoadDLLs': [
+                'd2d1.dll',
+                'd3d10_1.dll',
+              ],
               'AdditionalDependencies': [
                 'd2d1.lib',
                 'd3d10_1.lib',
@@ -142,7 +146,9 @@
             'native_theme_win.cc',
             'native_theme_win.h',
             'window_impl.cc',
-            'window_impl.h'
+            'window_impl.h',
+            'win_util.cc',
+            'win_util.h',
           ],
           'include_dirs': [
             '..',
diff --git a/gfx/win_util.cc b/gfx/win_util.cc
new file mode 100644
index 0000000..edd1a01
--- /dev/null
+++ b/gfx/win_util.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gfx/win_util.h"
+
+#include <windows.h>
+
+#include "base/win_util.h"
+
+namespace {
+
+bool DynamicLibraryPresent(const wchar_t* lib_name) {
+  HINSTANCE lib = LoadLibrary(lib_name);
+  if (lib) {
+    FreeLibrary(lib);
+    return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+namespace gfx {
+
+// Returns true if Direct2d is available, false otherwise.
+bool Direct2dIsAvailable() {
+  static bool checked = false;
+  static bool available = false;
+
+  if (!checked) {
+    win_util::WinVersion version = win_util::GetWinVersion();
+    if (version < win_util::WINVERSION_VISTA)
+      available = false;
+    else if (version >= win_util::WINVERSION_WIN7)
+      available = true;
+    else
+      available = DynamicLibraryPresent(L"d2d1.dll");
+    checked = true;
+  }
+  return available;
+}
+
+// Returns true if DirectWrite is available, false otherwise.
+bool DirectWriteIsAvailable() {
+  static bool checked = false;
+  static bool available = false;
+
+  if (!checked) {
+    win_util::WinVersion version = win_util::GetWinVersion();
+    if (version < win_util::WINVERSION_VISTA)
+      available = false;
+    else if (version >= win_util::WINVERSION_WIN7)
+      available = true;
+    else
+      available = DynamicLibraryPresent(L"dwrite.dll");
+    checked = true;
+  }
+  return available;
+}
+
+}  // namespace gfx
+
diff --git a/gfx/win_util.h b/gfx/win_util.h
new file mode 100644
index 0000000..3daa00f
--- /dev/null
+++ b/gfx/win_util.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GFX_WIN_UTIL_H_
+#define GFX_WIN_UTIL_H_
+#pragma once
+
+namespace gfx {
+
+// Returns true if Direct2d is available, false otherwise.
+bool Direct2dIsAvailable();
+
+// Returns true if DirectWrite is available, false otherwise.
+bool DirectWriteIsAvailable();
+
+}  // namespace gfx;
+
+#endif  // GFX_WIN_UTIL_H_
+