Bug 699258 - Part 2: [Skia] Get Skia backend working on Windows.
☠☠ backed out by c02f29cef915 ☠ ☠
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Fri, 11 Nov 2011 15:51:00 -0500
changeset 81823 5ddda2b25e287b389a356da31de1dc816ef16b35
parent 81822 3abfdb807a4fc1293c3fb1f94c4e366eebbb64d8
child 81824 8ac0226cb220d3cd0378519a594b5f682336206f
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 - Part 2: [Skia] Get Skia backend working on Windows.
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/core/SkPreConfig.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
@@ -983,23 +983,17 @@ NS_INTERFACE_MAP_END
 // Initialize our static variables.
 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() !=
-      gfxWindowsPlatform::RENDER_DIRECT2D ||
-      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-#elif !defined(XP_MACOSX) && !defined(ANDROID)
+#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(ANDROID)
   return NS_ERROR_NOT_AVAILABLE;
 #endif
 
   nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
   if (!ctx)
     return NS_ERROR_OUT_OF_MEMORY;
 
   *aResult = ctx.forget().get();
--- 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
@@ -102,19 +102,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/core/SkPreConfig.h
+++ b/gfx/skia/include/core/SkPreConfig.h
@@ -54,16 +54,17 @@
     #endif
 #endif
 
 #ifdef SK_BUILD_FOR_WIN32
     #if !defined(SK_RESTRICT)
         #define SK_RESTRICT __restrict
     #endif
     #include "sk_stdint.h"
+    #define SK_IGNORE_STDINT_DOT_H
 #endif
 
 //////////////////////////////////////////////////////////////////////
 
 #if !defined(SK_RESTRICT)
     #define SK_RESTRICT __restrict__
 #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))