Bug 699258 - Get skia backend compiling and running on Windows. r=mattwoodrow
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Fri, 18 Nov 2011 17:00:37 +1300
changeset 80410 215593486382ba9710ee70056a94f44b1ab846c7
parent 80409 e63e256daeccf68e93499bff52bc5f0b6bb258ea
child 80411 36b377464b44dce09299a5c896a2a6f892066113
push id3443
push usermwoodrow@mozilla.com
push dateFri, 18 Nov 2011 04:01:12 +0000
treeherdermozilla-inbound@4af4c72eafa7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs699258
milestone11.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 699258 - Get skia backend compiling and running on Windows. r=mattwoodrow
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
gfx/2d/Factory.cpp
gfx/2d/Makefile.in
gfx/2d/ScaledFontWin.cpp
gfx/2d/ScaledFontWin.h
gfx/2d/Tools.h
gfx/2d/Types.h
gfx/Makefile.in
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/d3d9/CanvasLayerD3D9.h
gfx/skia/Makefile.in
gfx/skia/include/config/SkUserConfig.h
gfx/thebes/Makefile.in
gfx/thebes/gfxWindowsPlatform.cpp
toolkit/library/libxul-config.mk
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -111,16 +111,17 @@
 #include <algorithm>
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
+#include "mozilla/Preferences.h"
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
 
 // windows.h (included by chromium code) defines this, in its infinite wisdom
 #undef DrawText
 
@@ -984,19 +985,20 @@ NS_INTERFACE_MAP_END
 PRUint32 nsCanvasRenderingContext2DAzure::sNumLivingContexts = 0;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sUnpremultiplyTable)[256] = nsnull;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nsnull;
 
 nsresult
 NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
 {
 #ifdef XP_WIN
-  if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
+  if ((gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
       gfxWindowsPlatform::RENDER_DIRECT2D ||
-      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
+      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) &&
+      !Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 #elif !defined(XP_MACOSX) && !defined(ANDROID)
   return NS_ERROR_NOT_AVAILABLE;
 #endif
 
   nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
   if (!ctx)
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -41,16 +41,19 @@
 #include "DrawTargetCairo.h"
 #endif
 
 #ifdef USE_SKIA
 #include "DrawTargetSkia.h"
 #ifdef XP_MACOSX
 #include "ScaledFontMac.h"
 #endif
+#ifdef WIN32
+#include "ScaledFontWin.h"
+#endif
 #include "ScaledFontSkia.h"
 #endif
 
 #ifdef WIN32
 #include "DrawTargetD2D.h"
 #include "ScaledFontDWrite.h"
 #include <d3d10_1.h>
 #endif
@@ -120,16 +123,22 @@ Factory::CreateScaledFontForNativeFont(c
 #endif
 #ifdef USE_SKIA
 #ifdef XP_MACOSX
   case NATIVE_FONT_MAC_FONT_FACE:
     {
       return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
     }
 #endif
+#ifdef WIN32
+  case NATIVE_FONT_GDI_FONT_FACE:
+    {
+      return new ScaledFontWin(static_cast<gfxGDIFont*>(aNativeFont.mFont), aSize);
+    }
+#endif
   case NATIVE_FONT_SKIA_FONT_FACE:
     {
       return new ScaledFontSkia(static_cast<gfxFont*>(aNativeFont.mFont), aSize);
     }
 #endif
   default:
     gfxWarning() << "Invalid native font type specified.";
     return NULL;
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -104,19 +104,23 @@ endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 CPPSRCS	+= \
         DrawTargetD2D.cpp \
         SourceSurfaceD2D.cpp \
         SourceSurfaceD2DTarget.cpp \
         PathD2D.cpp \
         ScaledFontDWrite.cpp \
-	$(NULL)
-
-DEFINES += -DWIN32
+        SourceSurfaceSkia.cpp \
+        DrawTargetSkia.cpp \
+        PathSkia.cpp \
+        ScaledFontSkia.cpp \
+        ScaledFontWin.cpp \
+        $(NULL)
+DEFINES += -DWIN32 -DUSE_SKIA
 endif
 
 #ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 #CPPSRCS	+= \
 #        DrawTargetCG.cpp \
 #        SourceSurfaceCG.cpp \
 #	$(NULL)
 #
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontWin.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Castelluccio <mar.castelluccio@studenti.unina.it>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ScaledFontWin.h"
+#include "skia/SkTypeface_win.h"
+
+namespace mozilla {
+namespace gfx {
+
+ScaledFontWin::ScaledFontWin(gfxGDIFont* aFont, Float aSize)
+  : ScaledFontSkia(aSize)
+{
+  LOGFONT lf;
+  GetObject(aFont->GetHFONT(), sizeof(LOGFONT), &lf);
+  mTypeface = SkCreateTypefaceFromLOGFONT(lf);
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontWin.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Castelluccio <mar.castelluccio@studenti.unina.it>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_SCALEDFONTWIN_H_
+#define MOZILLA_GFX_SCALEDFONTWIN_H_
+
+#include "ScaledFontSkia.h"
+#include "gfxGDIFont.h"
+
+namespace mozilla {
+namespace gfx {
+
+class ScaledFontWin : public ScaledFontSkia
+{
+public:
+  ScaledFontWin(gfxGDIFont* aFont, Float aSize);
+
+  virtual FontType GetType() const { return FONT_GDI; }
+
+private:
+  friend class DrawTargetSkia;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SCALEDFONTWIN_H_ */
--- a/gfx/2d/Tools.h
+++ b/gfx/2d/Tools.h
@@ -38,17 +38,17 @@
 #ifndef MOZILLA_GFX_TOOLS_H_
 #define MOZILLA_GFX_TOOLS_H_
 
 #include "Types.h"
 
 namespace mozilla {
 namespace gfx {
 
-bool
+static inline bool
 IsOperatorBoundByMask(CompositionOp aOp) {
   switch (aOp) {
   case OP_IN:
   case OP_OUT:
   case OP_DEST_IN:
   case OP_DEST_ATOP:
   case OP_SOURCE:
     return false;
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -86,28 +86,30 @@ enum BackendType
   BACKEND_COREGRAPHICS,
   BACKEND_CAIRO,
   BACKEND_SKIA
 };
 
 enum FontType
 {
   FONT_DWRITE,
+  FONT_GDI,
   FONT_MAC,
   FONT_SKIA
 };
 
 enum NativeSurfaceType
 {
   NATIVE_SURFACE_D3D10_TEXTURE
 };
 
 enum NativeFontType
 {
   NATIVE_FONT_DWRITE_FONT_FACE,
+  NATIVE_FONT_GDI_FONT_FACE,
   NATIVE_FONT_MAC_FONT_FACE,
   NATIVE_FONT_SKIA_FONT_FACE
 };
 
 enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
 enum ExtendMode { EXTEND_CLAMP, EXTEND_WRAP, EXTEND_MIRROR };
 enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
 enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
--- a/gfx/Makefile.in
+++ b/gfx/Makefile.in
@@ -45,17 +45,17 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= gfx
 
 ifdef MOZ_TREE_CAIRO
 DIRS		= cairo
 endif
 
 DIRS		+= 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
 
-ifeq (,$(filter-out cocoa android,$(MOZ_WIDGET_TOOLKIT)))
+ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
 DIRS        += skia
 endif
 
 ifdef ENABLE_TESTS
 TOOL_DIRS	+= tests
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp
+++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp
@@ -57,30 +57,34 @@ CanvasLayerD3D9::~CanvasLayerD3D9()
   }
 }
 
 void
 CanvasLayerD3D9::Initialize(const Data& aData)
 {
   NS_ASSERTION(mSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
 
-  if (aData.mSurface) {
+  if (aData.mDrawTarget) {
+    mDrawTarget = aData.mDrawTarget;
+    mNeedsYFlip = false;
+    mDataIsPremultiplied = true;
+  } else if (aData.mSurface) {
     mSurface = aData.mSurface;
     NS_ASSERTION(aData.mGLContext == nsnull,
                  "CanvasLayer can't have both surface and GLContext");
     mNeedsYFlip = false;
     mDataIsPremultiplied = true;
   } else if (aData.mGLContext) {
     NS_ASSERTION(aData.mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
     mGLContext = aData.mGLContext;
     mCanvasFramebuffer = mGLContext->GetOffscreenFBO();
     mDataIsPremultiplied = aData.mGLBufferIsPremultiplied;
     mNeedsYFlip = true;
   } else {
-    NS_ERROR("CanvasLayer created without mSurface or mGLContext?");
+    NS_ERROR("CanvasLayer created without mSurface, mGLContext or mDrawTarget?");
   }
 
   mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
 
   CreateTexture();
 }
 
 void
@@ -145,37 +149,44 @@ CanvasLayerD3D9::UpdateSurface()
     if (r.Pitch != mBounds.width * 4) {
       for (int y = 0; y < mBounds.height; y++) {
         memcpy((PRUint8*)r.pBits + r.Pitch * y,
                destination + mBounds.width * 4 * y,
                mBounds.width * 4);
       }
       delete [] destination;
     }
-  } else if (mSurface) {
+  } else {
     RECT r;
     r.left = mBounds.x;
     r.top = mBounds.y;
     r.right = mBounds.XMost();
     r.bottom = mBounds.YMost();
 
     LockTextureRectD3D9 textureLock(mTexture);
     if (!textureLock.HasLock()) {
       NS_WARNING("Failed to lock CanvasLayer texture.");
       return;
     }
 
     D3DLOCKED_RECT lockedRect = textureLock.GetLockRect();
 
     nsRefPtr<gfxImageSurface> sourceSurface;
+    nsRefPtr<gfxASurface> tempSurface;
+    if (mDrawTarget) {
+      tempSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
+    }
+    else {
+      tempSurface = mSurface;
+    }
 
-    if (mSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
-      sourceSurface = mSurface->GetAsImageSurface();
-    } else if (mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
-      sourceSurface = static_cast<gfxImageSurface*>(mSurface.get());
+    if (tempSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
+      sourceSurface = tempSurface->GetAsImageSurface();
+    } else if (tempSurface->GetType() == gfxASurface::SurfaceTypeImage) {
+      sourceSurface = static_cast<gfxImageSurface*>(tempSurface.get());
       if (sourceSurface->Format() != gfxASurface::ImageFormatARGB32 &&
           sourceSurface->Format() != gfxASurface::ImageFormatRGB24)
       {
         return;
       }
     } else {
       sourceSurface = new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
                                           gfxASurface::ImageFormatARGB32);
--- a/gfx/layers/d3d9/CanvasLayerD3D9.h
+++ b/gfx/layers/d3d9/CanvasLayerD3D9.h
@@ -80,16 +80,17 @@ public:
 protected:
   typedef mozilla::gl::GLContext GLContext;
 
   void UpdateSurface();
 
   nsRefPtr<gfxASurface> mSurface;
   nsRefPtr<GLContext> mGLContext;
   nsRefPtr<IDirect3DTexture9> mTexture;
+  RefPtr<gfx::DrawTarget> mDrawTarget;
 
   PRUint32 mCanvasFramebuffer;
 
   bool mDataIsPremultiplied;
   bool mNeedsYFlip;
   bool mHasAlpha;
 };
 
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -53,16 +53,17 @@ DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SH
 
 LOCAL_INCLUDES += \
 	-I$(srcdir)/include/core \
 	-I$(srcdir)/include/config \
 	-I$(srcdir)/include/ports \
 	-I$(srcdir)/src/core \
 	-I$(srcdir)/include/images \
 	-I$(srcdir)/include/utils/mac \
+	-I$(srcdir)/include/utils/win \
 	-I$(srcdir)/include/views \
 	-I$(srcdir)/include/effects \
 	$(NULL)
 
 VPATH += \
 	$(srcdir)/src/core \
 	$(srcdir)/src/ports \
 	$(srcdir)/src/opts \
@@ -167,17 +168,16 @@ EXPORTS_skia = \
 	include/core/SkAdvancedTypefaceMetrics.h \
 	include/config/SkUserConfig.h \
 	include/effects/SkGradientShader.h \
 	include/effects/SkBlurDrawLooper.h \
 	include/effects/SkBlurMaskFilter.h \
 	include/effects/SkLayerDrawLooper.h \
 	include/effects/SkLayerRasterizer.h \
 	include/effects/SkDashPathEffect.h \
-	include/ports/SkTypeface_mac.h \
 	$(NULL)
 
 DEFINES += -DUSE_SKIA
 
 CPPSRCS = \
 	Sk64.cpp \
 	SkAAClip.cpp \
 	SkAdvancedTypefaceMetrics.cpp \
@@ -225,17 +225,16 @@ CPPSRCS = \
 	SkFloat.cpp \
 	SkFloatBits.cpp \
 	SkFontHost.cpp \
 	SkGeometry.cpp \
 	SkGlobals.cpp \
 	SkGlyphCache.cpp \
 	SkGraphics.cpp \
 	SkLineClipper.cpp \
-	SkMMapStream.cpp \
 	SkMallocPixelRef.cpp \
 	SkMask.cpp \
 	SkMaskFilter.cpp \
 	SkMath.cpp \
 	SkMatrix.cpp \
 	SkMemory_stdlib.cpp \
 	SkMetaData.cpp \
 	SkPackBits.cpp \
@@ -281,17 +280,16 @@ CPPSRCS = \
 	SkUnPreMultiply.cpp \
 	SkUtils.cpp \
 	SkWriter32.cpp \
 	SkXfermode.cpp \
 	SkDebug_stdio.cpp \
 	SkGlobals_global.cpp \
 	SkOSFile_stdio.cpp \
 	SkThread_none.cpp \
-	SkTime_Unix.cpp \
 	SkGradientShader.cpp \
 	SkBitmapCache.cpp \
 	SkBlurDrawLooper.cpp \
 	SkBlurMaskFilter.cpp \
 	SkBlurMask.cpp \
 	SkColorFilters.cpp \
 	SkLayerDrawLooper.cpp \
 	SkLayerRasterizer.cpp \
@@ -303,26 +301,44 @@ EXPORTS_skia += \
 	include/ports/SkTypeface_mac.h \
 	$(NULL)
 CPPSRCS += \
 	SkFontHost_mac_coretext.cpp \
 	SkBitmapProcState_opts_SSE2.cpp \
 	SkBlitRow_opts_SSE2.cpp \
 	SkUtils_opts_SSE2.cpp \
 	opts_check_SSE2.cpp \
+	SkTime_Unix.cpp \
 	$(NULL)
 endif
 
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkBitmapProcState_opts_arm.cpp \
 	SkBlitRow_opts_arm.cpp \
 	SkFontHost_FreeType.cpp \
 	SkFontHost_android.cpp \
 	SkFontHost_gamma.cpp \
 	SkUtils_opts_none.cpp \
+	SkMMapStream.cpp \
+	SkTime_Unix.cpp \
 	$(NULL)
 
 DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
 OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
 
+ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
+EXPORTS_skia += \
+	include/config/sk_stdint.h \
+	include/ports/SkTypeface_win.h \
+	$(NULL)
+CPPSRCS += \
+	SkFontHost_win.cpp \
+	SkTime_win.cpp \
+	SkBitmapProcState_opts_SSE2.cpp \
+	SkBlitRow_opts_SSE2.cpp \
+	SkUtils_opts_SSE2.cpp \
+	opts_check_SSE2.cpp \
+	$(NULL)
+endif
+
 include $(topsrcdir)/config/rules.mk
--- a/gfx/skia/include/config/SkUserConfig.h
+++ b/gfx/skia/include/config/SkUserConfig.h
@@ -161,9 +161,13 @@
  */
 #ifdef SK_SAMPLES_FOR_X
         #define SK_R32_SHIFT    16
         #define SK_G32_SHIFT    8
         #define SK_B32_SHIFT    0
         #define SK_A32_SHIFT    24
 #endif
 
+#ifdef SK_BUILD_FOR_WIN32 
+        #define SK_IGNORE_STDINT_DOT_H 
+ #endif 
+
 #endif
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -146,16 +146,21 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 EXPORTS	+= \
 	gfxPDFSurface.h \
 	gfxWindowsPlatform.h \
 	gfxWindowsSurface.h \
 	gfxWindowsNativeDrawing.h \
 	WGLLibrary.h \
 	gfxDWriteFonts.h \
 	gfxD2DSurface.h \
+	gfxGDIFont.h \
+	gfxGDIFontList.h \
+	gfxPlatformFontList.h \
+	gfxAtoms.h \
+	gfxAtomList.h \
 	$(NULL)
 endif
 
 CPPSRCS	= \
 	gfx3DMatrix.cpp \
 	gfxASurface.cpp \
 	gfxAlphaRecovery.cpp \
 	gfxBlur.cpp \
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -477,16 +477,21 @@ gfxWindowsPlatform::CreateOffscreenSurfa
 RefPtr<DrawTarget>
 gfxWindowsPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
 {
 #ifdef CAIRO_HAS_D2D_SURFACE
   if (mRenderMode == RENDER_DIRECT2D) {
       return Factory::CreateDrawTarget(BACKEND_DIRECT2D, aSize, aFormat); 
   }
 #endif
+
+  if (Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
+    return Factory::CreateDrawTarget(BACKEND_SKIA, aSize, aFormat);
+  }
+
   return NULL;
 }
 
 RefPtr<ScaledFont>
 gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
 {
   if(mUseDirectWrite) {
     gfxDWriteFont *font = static_cast<gfxDWriteFont*>(aFont);
@@ -495,17 +500,23 @@ gfxWindowsPlatform::GetScaledFontForFont
     nativeFont.mType = NATIVE_FONT_DWRITE_FONT_FACE;
     nativeFont.mFont = font->GetFontFace();
     RefPtr<ScaledFont> scaledFont =
       mozilla::gfx::Factory::CreateScaledFontForNativeFont(nativeFont, font->GetAdjustedSize());
 
     return scaledFont;
   }
 
-  return NULL;
+  NativeFont nativeFont;
+  nativeFont.mType = NATIVE_FONT_GDI_FONT_FACE;
+  nativeFont.mFont = aFont;
+  RefPtr<ScaledFont> scaledFont =
+    Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
+
+  return scaledFont;
 }
 
 already_AddRefed<gfxASurface>
 gfxWindowsPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
 {
 #ifdef XP_WIN
   if (aTarget->GetType() == BACKEND_DIRECT2D) {
     RefPtr<ID3D10Texture2D> texture =
--- a/toolkit/library/libxul-config.mk
+++ b/toolkit/library/libxul-config.mk
@@ -357,17 +357,17 @@ ifeq ($(OS_ARCH),Linux)
 EXTRA_DSO_LDOPTS += $(MOZ_ALSA_LIBS)
 endif
 endif
 
 ifdef HAVE_CLOCK_MONOTONIC
 EXTRA_DSO_LDOPTS += $(REALTIME_LIBS)
 endif
 
-ifeq (,$(filter-out cocoa android,$(MOZ_WIDGET_TOOLKIT)))
+ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += $(MOZ_SKIA_LIBS)
 endif
 
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 OS_LIBS += -lGLESv2
 endif
 
 ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))