Backed out 4 changesets (bug 1455848) for windows wrench failures. CLOSED TREE
authorRazvan Maries <rmaries@mozilla.com>
Thu, 24 Jan 2019 00:56:40 +0200
changeset 455118 a237a1078ce34f063400b3ec9beff1a692d8dbdb
parent 455117 d9ca9091f36c9f4622a15f4d1d0f8afcd94aae66
child 455119 143af10f6e44656bf48b6cf63a3a7adda3c393c9
push id111408
push userrmaries@mozilla.com
push dateWed, 23 Jan 2019 22:57:52 +0000
treeherdermozilla-inbound@a237a1078ce3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1455848
milestone66.0a1
backs outd56504db04eae60a686340716dd8e5b95eae31f1
f2279ecacb813c22dcfbe1bd8021e63b0dbc2101
44a36f0fe512edff298758ebe736bfbcfa6d9842
b8444f241aca60ed9f7520b89bb0865c61da96f3
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
Backed out 4 changesets (bug 1455848) for windows wrench failures. CLOSED TREE Backed out changeset d56504db04ea (bug 1455848) Backed out changeset f2279ecacb81 (bug 1455848) Backed out changeset 44a36f0fe512 (bug 1455848) Backed out changeset b8444f241aca (bug 1455848)
Cargo.lock
gfx/2d/ScaledFontDWrite.cpp
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/webrender_bindings/Cargo.toml
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/src/moz2d_renderer.rs
gfx/wr/Cargo.lock
gfx/wr/webrender/Cargo.toml
gfx/wr/webrender/src/platform/unix/font.rs
gfx/wr/webrender/src/platform/windows/font.rs
gfx/wr/webrender_api/Cargo.toml
gfx/wr/webrender_api/src/font.rs
gfx/wr/webrender_api/src/lib.rs
gfx/wr/wrench/Cargo.toml
gfx/wr/wrench/src/wrench.rs
gfx/wr/wrench/src/yaml_frame_writer.rs
third_party/rust/dwrote/.cargo-checksum.json
third_party/rust/dwrote/Cargo.toml
third_party/rust/dwrote/src/font_file.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -815,17 +815,17 @@ dependencies = [
 name = "dump_syms_rust_demangle"
 version = "0.1.0"
 dependencies = [
  "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "dwrote"
-version = "0.8.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
@@ -3016,17 +3016,17 @@ dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3049,16 +3049,17 @@ version = "0.58.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "wr_malloc_size_of 0.0.1",
 ]
@@ -3066,17 +3067,17 @@ dependencies = [
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring 0.1.0",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3294,17 +3295,17 @@ dependencies = [
 "checksum devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
 "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
-"checksum dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c31c624339dab99c223a4b26c2e803b7c248adaca91549ce654c76f39a03f5c8"
+"checksum dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2ea0fd88d96838ce5ed30326338cc04a0eb4cff10e3e15d188d74112777103"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621"
 "checksum encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "769ecb8b33323998e482b218c0d13cd64c267609023b4b7ec3ee740714c318ee"
 "checksum encoding_rs 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "a69d152eaa438a291636c1971b0a370212165ca8a75759eb66818c5ce9b538f7"
 "checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
 "checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -313,91 +313,176 @@ bool UnscaledFontDWrite::GetFontFileData
   aDataCallback((uint8_t*)fragmentStart, fileSize, mFontFace->GetIndex(),
                 aBaton);
 
   stream->ReleaseFileFragment(context);
 
   return true;
 }
 
-static bool GetFontFileName(RefPtr<IDWriteFontFace> aFontFace,
-                            std::vector<WCHAR>& aFileName) {
+static bool GetDWriteName(RefPtr<IDWriteLocalizedStrings> aNames,
+                          std::vector<WCHAR>& aOutName) {
+  BOOL exists = false;
+  UINT32 index = 0;
+  HRESULT hr = aNames->FindLocaleName(L"en-us", &index, &exists);
+  if (FAILED(hr)) {
+    return false;
+  }
+  if (!exists) {
+    // No english found, use whatever is first in the list.
+    index = 0;
+  }
+
+  UINT32 length;
+  hr = aNames->GetStringLength(index, &length);
+  if (FAILED(hr)) {
+    return false;
+  }
+  aOutName.resize(length + 1);
+  hr = aNames->GetString(index, aOutName.data(), length + 1);
+  return SUCCEEDED(hr);
+}
+
+static bool GetDWriteFamilyName(const RefPtr<IDWriteFontFamily>& aFamily,
+                                std::vector<WCHAR>& aOutName) {
+  RefPtr<IDWriteLocalizedStrings> names;
+  HRESULT hr = aFamily->GetFamilyNames(getter_AddRefs(names));
+  if (FAILED(hr)) {
+    return false;
+  }
+  return GetDWriteName(names, aOutName);
+}
+
+static void GetFontFileNames(RefPtr<IDWriteFontFace> aFontFace,
+                             std::vector<WCHAR>& aFamilyName,
+                             std::vector<WCHAR>& aFileNames) {
+  MOZ_ASSERT(aFamilyName.size() >= 1 && aFamilyName.back() == 0);
+
   UINT32 numFiles;
   HRESULT hr = aFontFace->GetFiles(&numFiles, nullptr);
   if (FAILED(hr)) {
-    gfxDebug() << "Failed getting file count for WR font";
-    return false;
-  } else if (numFiles != 1) {
-    gfxDebug() << "Invalid file count " << numFiles << " for WR font";
-    return false;
+    gfxCriticalNote << "Failed getting file count for font \""
+                    << &aFamilyName[0] << "\"";
+    return;
+  } else if (!numFiles) {
+    gfxCriticalNote << "No files found for font \"" << &aFamilyName[0] << "\"";
+    return;
   }
-
-  RefPtr<IDWriteFontFile> file;
-  hr = aFontFace->GetFiles(&numFiles, getter_AddRefs(file));
+  std::vector<RefPtr<IDWriteFontFile>> files;
+  files.resize(numFiles);
+  hr = aFontFace->GetFiles(&numFiles, getter_AddRefs(files[0]));
   if (FAILED(hr)) {
-    gfxDebug() << "Failed getting file for WR font";
-    return false;
+    gfxCriticalNote << "Failed getting files for font \"" << &aFamilyName[0]
+                    << "\"";
+    return;
   }
 
-  const void* key;
-  UINT32 keySize;
-  hr = file->GetReferenceKey(&key, &keySize);
-  if (FAILED(hr)) {
-    gfxDebug() << "Failed getting file ref key for WR font";
-    return false;
-  }
-  RefPtr<IDWriteFontFileLoader> loader;
-  hr = file->GetLoader(getter_AddRefs(loader));
-  if (FAILED(hr)) {
-    gfxDebug() << "Failed getting file loader for WR font";
-    return false;
-  }
-  RefPtr<IDWriteLocalFontFileLoader> localLoader;
-  loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader),
-                         (void**)getter_AddRefs(localLoader));
-  if (!localLoader) {
-    gfxDebug() << "Failed querying loader interface for WR font";
-    return false;
+  for (auto& file : files) {
+    const void* key;
+    UINT32 keySize;
+    hr = file->GetReferenceKey(&key, &keySize);
+    if (FAILED(hr)) {
+      gfxCriticalNote << "Failed getting file ref key for font \""
+                      << &aFamilyName[0] << "\"";
+      return;
+    }
+    RefPtr<IDWriteFontFileLoader> loader;
+    hr = file->GetLoader(getter_AddRefs(loader));
+    if (FAILED(hr)) {
+      gfxCriticalNote << "Failed getting file loader for font \""
+                      << &aFamilyName[0] << "\"";
+      return;
+    }
+    RefPtr<IDWriteLocalFontFileLoader> localLoader;
+    loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader),
+                           (void**)getter_AddRefs(localLoader));
+    if (!localLoader) {
+      gfxCriticalNote << "Failed querying loader interface for font \""
+                      << &aFamilyName[0] << "\"";
+      return;
+    }
+    UINT32 pathLen;
+    hr = localLoader->GetFilePathLengthFromKey(key, keySize, &pathLen);
+    if (FAILED(hr)) {
+      gfxCriticalNote << "Failed getting path length for font \""
+                      << &aFamilyName[0] << "\"";
+      return;
+    }
+    size_t offset = aFileNames.size();
+    aFileNames.resize(offset + pathLen + 1);
+    hr = localLoader->GetFilePathFromKey(key, keySize, &aFileNames[offset],
+                                         pathLen + 1);
+    if (FAILED(hr)) {
+      aFileNames.resize(offset);
+      gfxCriticalNote << "Failed getting path for font \"" << &aFamilyName[0]
+                      << "\"";
+      return;
+    }
+    MOZ_ASSERT(aFileNames.back() == 0);
+    DWORD attribs = GetFileAttributesW(&aFileNames[offset]);
+    if (attribs == INVALID_FILE_ATTRIBUTES) {
+      gfxCriticalNote << "sending font family \"" << &aFamilyName[0]
+                      << "\" with invalid file \"" << &aFileNames[offset]
+                      << "\"";
+    }
   }
-  UINT32 pathLen;
-  hr = localLoader->GetFilePathLengthFromKey(key, keySize, &pathLen);
-  if (FAILED(hr)) {
-    gfxDebug() << "Failed getting path length for WR font";
-    return false;
-  }
-  aFileName.resize(pathLen + 1);
-  hr = localLoader->GetFilePathFromKey(key, keySize, aFileName.data(),
-                                       pathLen + 1);
-  if (FAILED(hr) || aFileName.back() != 0) {
-    gfxDebug() << "Failed getting path for WR font";
-    return false;
-  }
-  DWORD attribs = GetFileAttributesW(aFileName.data());
-  if (attribs == INVALID_FILE_ATTRIBUTES) {
-    gfxDebug() << "Invalid file \"" << aFileName.data() << "\" for WR font";
-    return false;
-  }
-  aFileName.pop_back();
-  return true;
 }
 
 bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
                                              void* aBaton) {
   if (!mFont) {
     return false;
   }
 
-  std::vector<WCHAR> fileName;
-  if (!GetFontFileName(mFontFace, fileName)) {
+  RefPtr<IDWriteFontFamily> family;
+  HRESULT hr = mFont->GetFontFamily(getter_AddRefs(family));
+  if (FAILED(hr)) {
+    return false;
+  }
+
+  DWRITE_FONT_WEIGHT weight = mFont->GetWeight();
+  DWRITE_FONT_STRETCH stretch = mFont->GetStretch();
+  DWRITE_FONT_STYLE style = mFont->GetStyle();
+
+  RefPtr<IDWriteFont> match;
+  hr = family->GetFirstMatchingFont(weight, stretch, style,
+                                    getter_AddRefs(match));
+  if (FAILED(hr) || match->GetWeight() != weight ||
+      match->GetStretch() != stretch || match->GetStyle() != style) {
+    return false;
+  }
+
+  std::vector<WCHAR> familyName;
+  if (!GetDWriteFamilyName(family, familyName)) {
     return false;
   }
-  uint32_t index = mFontFace->GetIndex();
+
+  RefPtr<IDWriteFontCollection> systemFonts = Factory::GetDWriteSystemFonts();
+  if (!systemFonts) {
+    return false;
+  }
 
-  aCb(reinterpret_cast<const uint8_t*>(fileName.data()),
-      fileName.size() * sizeof(WCHAR), index, aBaton);
+  UINT32 idx;
+  BOOL exists;
+  hr = systemFonts->FindFamilyName(familyName.data(), &idx, &exists);
+  if (FAILED(hr) || !exists) {
+    return false;
+  }
+
+  // FIXME: Debugging kluge for bug 1455848. Remove once debugged!
+  GetFontFileNames(mFontFace, familyName, familyName);
+
+  // The style information that identifies the font can be encoded easily in
+  // less than 32 bits. Since the index is needed for font descriptors, only
+  // the family name and style information, pass along the style in the index
+  // data to avoid requiring a more complicated structure packing for it in
+  // the data payload.
+  uint32_t index = weight | (stretch << 16) | (style << 24);
+  aCb(reinterpret_cast<const uint8_t*>(familyName.data()),
+      familyName.size() * sizeof(WCHAR), index, aBaton);
   return true;
 }
 
 ScaledFontDWrite::InstanceData::InstanceData(
     const wr::FontInstanceOptions* aOptions,
     const wr::FontInstancePlatformOptions* aPlatformOptions)
     : mUseEmbeddedBitmap(false),
       mForceGDIMode(false),
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -77,16 +77,19 @@ parent:
   sync SetTestSampleTime(TimeStamp sampleTime);
   sync LeaveTestMode();
   sync GetAnimationValue(uint64_t aCompositorAnimationsId) returns (OMTAValue value);
   sync SetAsyncScrollOffset(ViewID scrollId, float x, float y);
   sync SetAsyncZoom(ViewID scrollId, float zoom);
   async FlushApzRepaints();
   sync GetAPZTestData() returns (APZTestData data);
 
+  // Debugging routine for bug 1455848.
+  async ValidateFontDescriptor(uint8_t[] desc);
+
   async Shutdown();
   sync ShutdownSync();
 child:
   async WrUpdated(IdNamespace aNewIdNamespace, TextureFactoryIdentifier textureFactoryIdentifier);
   async WrReleasedImages(ExternalImageKeyPair[] pairs);
   async __delete__();
 };
 
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -221,16 +221,26 @@ static void WriteFontFileData(const uint
 }
 
 static void WriteFontDescriptor(const uint8_t* aData, uint32_t aLength,
                                 uint32_t aIndex, void* aBaton) {
   FontFileDataSink* sink = static_cast<FontFileDataSink*>(aBaton);
 
   *sink->mFontKey = sink->mWrBridge->GetNextFontKey();
 
+#ifdef XP_WIN
+  // FIXME: Debugging kluge for bug 1455848. Remove once debugged!
+  nsTArray<uint8_t> data;
+  data.AppendElements(aData, aLength);
+  sink->mWrBridge->SendValidateFontDescriptor(data);
+  aLength =
+      uint32_t(wcsnlen_s((const wchar_t*)aData, aLength / sizeof(wchar_t)) *
+               sizeof(wchar_t));
+#endif
+
   sink->mResources->AddFontDescriptor(
       *sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength),
       aIndex);
 }
 
 void WebRenderBridgeChild::PushGlyphs(
     wr::DisplayListBuilder& aBuilder, Range<const wr::GlyphInstance> aGlyphs,
     gfx::ScaledFont* aFont, const wr::ColorF& aColor,
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -31,16 +31,20 @@
 #include "mozilla/layers/WebRenderImageHost.h"
 #include "mozilla/layers/WebRenderTextureHost.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Unused.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 
+#ifdef XP_WIN
+#  include "dwrite.h"
+#endif
+
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerMarkerPayload.h"
 #endif
 
 bool is_in_main_thread() { return NS_IsMainThread(); }
 
 bool is_in_compositor_thread() {
   return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
@@ -697,16 +701,59 @@ void WebRenderBridgeParent::ObserveShare
   if (!mDestroyed) {
     Unused << SendWrReleasedImages(aPairs);
   }
   for (const auto& pair : aPairs) {
     SharedSurfacesParent::Release(pair.id);
   }
 }
 
+// Debugging kluge for bug 1455848. Remove once debugged!
+mozilla::ipc::IPCResult WebRenderBridgeParent::RecvValidateFontDescriptor(
+    nsTArray<uint8_t>&& aData) {
+  if (mDestroyed) {
+    return IPC_OK();
+  }
+#ifdef XP_WIN
+  nsTArray<uint8_t> data(aData);
+  wchar_t* family = (wchar_t*)data.Elements();
+  size_t remaining = data.Length() / sizeof(wchar_t);
+  size_t familyLength = wcsnlen_s(family, remaining);
+  MOZ_ASSERT(familyLength < remaining && family[familyLength] == 0);
+  remaining -= familyLength + 1;
+  wchar_t* files = family + familyLength + 1;
+  BOOL exists = FALSE;
+  if (RefPtr<IDWriteFontCollection> systemFonts =
+          Factory::GetDWriteSystemFonts()) {
+    UINT32 idx;
+    systemFonts->FindFamilyName(family, &idx, &exists);
+  }
+  if (!remaining) {
+    gfxCriticalNote << (exists ? "found" : "MISSING") << " font family \""
+                    << family << "\" has no files!";
+  }
+  while (remaining > 0) {
+    size_t fileLength = wcsnlen_s(files, remaining);
+    MOZ_ASSERT(fileLength < remaining && files[fileLength] == 0);
+    DWORD attribs = GetFileAttributesW(files);
+    if (!exists || attribs == INVALID_FILE_ATTRIBUTES) {
+      gfxCriticalNote << (exists ? "found" : "MISSING") << " font family \""
+                      << family << "\" has "
+                      << (attribs == INVALID_FILE_ATTRIBUTES ? "INVALID"
+                                                             : "valid")
+                      << "(" << hexa(attribs) << ")"
+                      << " file \"" << files << "\"";
+    }
+    remaining -= fileLength + 1;
+    files += fileLength + 1;
+  }
+#endif
+  return IPC_OK();
+}
+
 mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(
     nsTArray<OpUpdateResource>&& aResourceUpdates,
     nsTArray<RefCountedShmem>&& aSmallShmems,
     nsTArray<ipc::Shmem>&& aLargeShmems) {
   if (mDestroyed) {
     wr::IpcResourceUpdateQueue::ReleaseShmems(this, aSmallShmems);
     wr::IpcResourceUpdateQueue::ReleaseShmems(this, aLargeShmems);
     return IPC_OK();
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -120,16 +120,19 @@ class WebRenderBridgeParent final : publ
       const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
       const nsCString& aTxnURL, const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvSetFocusTarget(
       const FocusTarget& aFocusTarget) override;
   mozilla::ipc::IPCResult RecvParentCommands(
       nsTArray<WebRenderParentCommand>&& commands) override;
   mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
 
+  mozilla::ipc::IPCResult RecvValidateFontDescriptor(
+      nsTArray<uint8_t>&& aData) override;
+
   mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
       const LayersObserverEpoch& aChildEpoch) override;
 
   mozilla::ipc::IPCResult RecvClearCachedResources() override;
   mozilla::ipc::IPCResult RecvScheduleComposite() override;
   mozilla::ipc::IPCResult RecvCapture() override;
   mozilla::ipc::IPCResult RecvSyncWithCompositor() override;
 
--- a/gfx/webrender_bindings/Cargo.toml
+++ b/gfx/webrender_bindings/Cargo.toml
@@ -18,15 +18,15 @@ fxhash = "0.2.1"
 
 [dependencies.webrender]
 path = "../wr/webrender"
 version = "0.59.0"
 default-features = false
 features = ["capture", "serialize_program"]
 
 [target.'cfg(target_os = "windows")'.dependencies]
-dwrote = "0.8"
+dwrote = "0.7"
 
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation = "0.6"
 core-graphics = "0.17.1"
 foreign-types = "0.3.0"
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1,15 +1,9 @@
 use std::ffi::{CStr, CString};
-#[cfg(not(target_os = "macos"))]
-use std::ffi::OsString;
-#[cfg(target_os = "windows")]
-use std::os::windows::ffi::OsStringExt;
-#[cfg(not(any(target_os = "macos", target_os = "windows")))]
-use std::os::unix::ffi::OsStringExt;
 use std::io::Cursor;
 use std::{mem, slice, ptr, env};
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::cell::RefCell;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::ops::Range;
@@ -29,16 +23,19 @@ use webrender::{Device, Shaders, WrShade
 use thread_profiler::register_thread_with_profiler;
 use moz2d_renderer::Moz2dBlobImageHandler;
 use program_cache::{WrProgramCache, remove_disk_cache};
 use app_units::Au;
 use rayon;
 use euclid::SideOffsets2D;
 use nsstring::nsAString;
 
+#[cfg(target_os = "windows")]
+use dwrote::{FontDescriptor, FontWeight, FontStretch, FontStyle};
+
 #[cfg(target_os = "macos")]
 use core_foundation::string::CFString;
 #[cfg(target_os = "macos")]
 use core_graphics::font::CGFont;
 
 extern "C" {
     #[cfg(target_os = "android")]
     fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int;
@@ -1711,19 +1708,21 @@ pub extern "C" fn wr_api_capture(
 }
 
 #[cfg(target_os = "windows")]
 fn read_font_descriptor(
     bytes: &mut WrVecU8,
     index: u32
 ) -> NativeFontHandle {
     let wchars = bytes.convert_into_vec::<u16>();
-    NativeFontHandle {
-        path: PathBuf::from(OsString::from_wide(&wchars)),
-        index,
+    FontDescriptor {
+        family_name: String::from_utf16(&wchars).unwrap(),
+        weight: FontWeight::from_u32(index & 0xffff),
+        stretch: FontStretch::from_u32((index >> 16) & 0xff),
+        style: FontStyle::from_u32((index >> 24) & 0xff),
     }
 }
 
 #[cfg(target_os = "macos")]
 fn read_font_descriptor(
     bytes: &mut WrVecU8,
     _index: u32
 ) -> NativeFontHandle {
@@ -1733,19 +1732,19 @@ fn read_font_descriptor(
     NativeFontHandle(font)
 }
 
 #[cfg(not(any(target_os = "macos", target_os = "windows")))]
 fn read_font_descriptor(
     bytes: &mut WrVecU8,
     index: u32
 ) -> NativeFontHandle {
-    let chars = bytes.flush_into_vec();
+    let cstr = CString::new(bytes.flush_into_vec()).unwrap();
     NativeFontHandle {
-        path: PathBuf::from(OsString::from_vec(chars)),
+        pathname: String::from(cstr.to_str().unwrap()),
         index,
     }
 }
 
 #[no_mangle]
 pub extern "C" fn wr_resource_updates_add_font_descriptor(
     txn: &mut Transaction,
     key: WrFontKey,
--- a/gfx/webrender_bindings/src/moz2d_renderer.rs
+++ b/gfx/webrender_bindings/src/moz2d_renderer.rs
@@ -25,18 +25,16 @@ use std;
 #[cfg(target_os = "windows")]
 use dwrote;
 
 #[cfg(target_os = "macos")]
 use foreign_types::ForeignType;
 
 #[cfg(not(any(target_os = "macos", target_os = "windows")))]
 use std::ffi::CString;
-#[cfg(not(any(target_os = "macos", target_os = "windows")))]
-use std::os::unix::ffi::OsStrExt;
 
 /// Local print-debugging utility
 macro_rules! dlog {
     ($($e:expr),*) => { {$(let _ = $e;)*} }
     //($($t:tt)*) => { println!($($t)*) }
 }
 
 /// Debug prints a blob's item bounds, indicating whether the bounds are dirty or not.
@@ -652,29 +650,30 @@ impl Moz2dBlobImageHandler {
     }
 
     /// Does early preprocessing of a blob's resources.
     ///
     /// Currently just sets up fonts found in the blob.
     fn prepare_request(&self, blob: &[u8], resources: &BlobImageResources) {
         #[cfg(target_os = "windows")]
         fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
-            let file = dwrote::FontFile::new_from_path(&handle.path).unwrap();
-            let face = file.create_face(handle.index, dwrote::DWRITE_FONT_SIMULATIONS_NONE).unwrap();
+            let system_fc = dwrote::FontCollection::system();
+            let font = system_fc.get_font_from_descriptor(handle).unwrap();
+            let face = font.create_font_face();
             unsafe { AddNativeFontHandle(key, face.as_ptr() as *mut c_void, 0) };
         }
 
         #[cfg(target_os = "macos")]
         fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
             unsafe { AddNativeFontHandle(key, handle.0.as_ptr() as *mut c_void, 0) };
         }
 
         #[cfg(not(any(target_os = "macos", target_os = "windows")))]
         fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
-            let cstr = CString::new(handle.path.as_os_str().as_bytes()).unwrap();
+            let cstr = CString::new(handle.pathname.clone()).unwrap();
             unsafe { AddNativeFontHandle(key, cstr.as_ptr() as *mut c_void, handle.index) };
         }
 
         fn process_fonts(
             mut extra_data: BufReader,
             resources: &BlobImageResources,
             unscaled_fonts: &mut Vec<FontKey>,
             scaled_fonts: &mut Vec<FontInstanceKey>,
--- a/gfx/wr/Cargo.lock
+++ b/gfx/wr/Cargo.lock
@@ -372,17 +372,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "dtoa"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "dwrote"
-version = "0.8.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1599,17 +1599,17 @@ dependencies = [
  "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1656,16 +1656,17 @@ version = "0.58.0"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "wr_malloc_size_of 0.0.1",
@@ -1752,17 +1753,17 @@ dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1881,17 +1882,17 @@ dependencies = [
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
 "checksum deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "32c8120d981901a9970a3a1c97cf8b630e0fa8c3ca31e75b6fd6fd5f9f427b31"
 "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
 "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
 "checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
-"checksum dwrote 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c31c624339dab99c223a4b26c2e803b7c248adaca91549ce654c76f39a03f5c8"
+"checksum dwrote 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2ea0fd88d96838ce5ed30326338cc04a0eb4cff10e3e15d188d74112777103"
 "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
 "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
 "checksum euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dbbf962bb6f877239a34491f2e0a12c6b824f389bc789eb90f1d70d4780b0727"
 "checksum expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c470ccb972f2088549b023db8029ed9da9426f5affbf9b62efff7009ab8ed5b1"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum font-loader 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd330f40acb3016432cbfa4c54b3d6e6e893a538df79d8df8fd8c26e21c36aaa"
 "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
--- a/gfx/wr/webrender/Cargo.toml
+++ b/gfx/wr/webrender/Cargo.toml
@@ -76,14 +76,14 @@ optional = true
 mozangle = "0.1"
 rand = "0.4"
 
 [target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
 freetype = { version = "0.4", default-features = false }
 libc = "0.2"
 
 [target.'cfg(target_os = "windows")'.dependencies]
-dwrote = "0.8"
+dwrote = "0.7"
 
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation = "0.6"
 core-graphics = "0.17.1"
 core-text = { version = "13", default-features = false }
--- a/gfx/wr/webrender/src/platform/unix/font.rs
+++ b/gfx/wr/webrender/src/platform/unix/font.rs
@@ -314,18 +314,17 @@ impl FontContext {
             if let Some(face) = new_ft_face(font_key, self.lib, &file, index) {
                 self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() });
             }
         }
     }
 
     pub fn add_native_font(&mut self, font_key: &FontKey, native_font_handle: NativeFontHandle) {
         if !self.faces.contains_key(&font_key) {
-            let cstr = CString::new(native_font_handle.path.as_os_str().to_str().unwrap()).unwrap();
-            let file = FontFile::Pathname(cstr);
+            let file = FontFile::Pathname(CString::new(native_font_handle.pathname).unwrap());
             let index = native_font_handle.index;
             if let Some(face) = new_ft_face(font_key, self.lib, &file, index) {
                 self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() });
             }
         }
     }
 
     pub fn delete_font(&mut self, font_key: &FontKey) {
@@ -961,12 +960,11 @@ impl Drop for FontContext {
         }
     }
 }
 
 #[cfg(feature = "pathfinder")]
 impl<'a> Into<pf_freetype::FontDescriptor> for NativeFontHandleWrapper<'a> {
     fn into(self) -> pf_freetype::FontDescriptor {
         let NativeFontHandleWrapper(font_handle) = self;
-        let str = font_handle.path.as_os_str().to_str().unwrap();
-        pf_freetype::FontDescriptor::new(str.into(), font_handle.index)
+        pf_freetype::FontDescriptor::new(font_handle.pathname.clone().into(), font_handle.index)
     }
 }
--- a/gfx/wr/webrender/src/platform/windows/font.rs
+++ b/gfx/wr/webrender/src/platform/windows/font.rs
@@ -1,24 +1,20 @@
 /* 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/. */
 
 use api::{FontInstanceFlags, FontKey, FontRenderMode, FontVariation};
-use api::{ColorU, GlyphDimensions, NativeFontHandle};
+use api::{ColorU, GlyphDimensions};
 use dwrote;
 use gamma_lut::ColorLut;
 use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey};
-use internal_types::{FastHashMap, FastHashSet, ResourceCacheError};
-use std::borrow::Borrow;
+use internal_types::{FastHashMap, ResourceCacheError};
 use std::collections::hash_map::Entry;
-use std::hash::{Hash, Hasher};
-use std::path::Path;
-use std::sync::{Arc, Mutex};
-
+use std::sync::Arc;
 cfg_if! {
     if #[cfg(feature = "pathfinder")] {
         use pathfinder_font_renderer::{PathfinderComPtr, IDWriteFontFace};
         use glyph_rasterizer::NativeFontHandleWrapper;
     } else if #[cfg(not(feature = "pathfinder"))] {
         use api::FontInstancePlatformOptions;
         use glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph};
         use gamma_lut::GammaLut;
@@ -29,60 +25,18 @@ lazy_static! {
     static ref DEFAULT_FONT_DESCRIPTOR: dwrote::FontDescriptor = dwrote::FontDescriptor {
         family_name: "Arial".to_owned(),
         weight: dwrote::FontWeight::Regular,
         stretch: dwrote::FontStretch::Normal,
         style: dwrote::FontStyle::Normal,
     };
 }
 
-type CachedFontKey = Arc<Path>;
-
-// A cached dwrote font file that is shared among all faces.
-// Each face holds a CachedFontKey to keep track of how many users of the font there are.
-struct CachedFont {
-    key: CachedFontKey,
-    file: dwrote::FontFile,
-}
-
-impl PartialEq for CachedFont {
-    fn eq(&self, other: &CachedFont) -> bool {
-        self.key == other.key
-    }
-}
-impl Eq for CachedFont {}
-
-impl Hash for CachedFont {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.key.hash(state);
-    }
-}
-
-impl Borrow<Path> for CachedFont {
-    fn borrow(&self) -> &Path {
-        &*self.key
-    }
-}
-
-lazy_static! {
-    // This is effectively a weak map of dwrote FontFiles. CachedFonts are entered into the
-    // cache when there are any FontFaces using them. CachedFonts are removed from the cache
-    // when there are no more FontFaces using them at all.
-    static ref FONT_CACHE: Mutex<FastHashSet<CachedFont>> = Mutex::new(FastHashSet::default());
-}
-
-struct FontFace {
-    cached: Option<CachedFontKey>,
-    file: dwrote::FontFile,
-    index: u32,
-    face: dwrote::FontFace,
-}
-
 pub struct FontContext {
-    fonts: FastHashMap<FontKey, FontFace>,
+    fonts: FastHashMap<FontKey, dwrote::FontFace>,
     variations: FastHashMap<(FontKey, dwrote::DWRITE_FONT_SIMULATIONS, Vec<FontVariation>), dwrote::FontFace>,
     #[cfg(not(feature = "pathfinder"))]
     gamma_luts: FastHashMap<(u16, u16), GammaLut>,
 }
 
 // DirectWrite is safe to use on multiple threads and non-shareable resources are
 // all hidden inside their font context.
 unsafe impl Send for FontContext {}
@@ -151,89 +105,83 @@ impl FontContext {
             gamma_luts: FastHashMap::default(),
         })
     }
 
     pub fn has_font(&self, font_key: &FontKey) -> bool {
         self.fonts.contains_key(font_key)
     }
 
-    fn add_font_descriptor(&mut self, font_key: &FontKey, desc: &dwrote::FontDescriptor) {
-        let system_fc = dwrote::FontCollection::get_system(false);
-        if let Some(font) = system_fc.get_font_from_descriptor(desc) {
-            let face = font.create_font_face();
-            let file = face.get_files().pop().unwrap();
-            let index = face.get_index();
-            self.fonts.insert(*font_key, FontFace { cached: None, file, index, face });
-        }
-    }
-
     pub fn add_raw_font(&mut self, font_key: &FontKey, data: Arc<Vec<u8>>, index: u32) {
         if self.fonts.contains_key(font_key) {
             return;
         }
 
-        if let Some(file) = dwrote::FontFile::new_from_data(data) {
-            if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
-                self.fonts.insert(*font_key, FontFace { cached: None, file, index, face });
-                return;
-            }
+        if let Some(font_file) = dwrote::FontFile::new_from_data(data) {
+            let face = font_file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE);
+            self.fonts.insert(*font_key, face);
+        } else {
+            // XXX add_raw_font needs to have a way to return an error
+            debug!("DWrite WR failed to load font from data, using Arial instead");
+            self.add_native_font(font_key, DEFAULT_FONT_DESCRIPTOR.clone());
         }
-        // XXX add_raw_font needs to have a way to return an error
-        debug!("DWrite WR failed to load font from data, using Arial instead");
-        self.add_font_descriptor(font_key, &DEFAULT_FONT_DESCRIPTOR);
     }
 
-    pub fn add_native_font(&mut self, font_key: &FontKey, font_handle: NativeFontHandle) {
+    pub fn load_system_font(font_handle: &dwrote::FontDescriptor, update: bool) -> Result<dwrote::Font, String> {
+        let system_fc = dwrote::FontCollection::get_system(update);
+        // A version of get_font_from_descriptor() that panics early to help with bug 1455848
+        if let Some(family) = system_fc.get_font_family_by_name(&font_handle.family_name) {
+            let font = family.get_first_matching_font(font_handle.weight, font_handle.stretch, font_handle.style);
+            // Exact matches only here
+            if font.weight() == font_handle.weight &&
+                font.stretch() == font_handle.stretch &&
+                font.style() == font_handle.style
+            {
+                Ok(font)
+            } else {
+                // We can't depend on the family's fonts being in a particular order, so the first match may not
+                // be an exact match, even though it is sufficiently close to be a match. As a slower fallback,
+                // try looking through all of the fonts in the family for an exact match. The caller should have
+                // verified that an exact match exists so that this search shouldn't fail.
+                (0 .. family.get_font_count()).filter_map(|idx| {
+                    let alt = family.get_font(idx);
+                    if alt.weight() == font_handle.weight &&
+                        alt.stretch() == font_handle.stretch &&
+                        alt.style() == font_handle.style
+                    {
+                        Some(alt)
+                    } else {
+                        None
+                    }
+                }).next().ok_or_else(|| {
+                    format!("font mismatch for descriptor {:?} {:?}", font_handle, font.to_descriptor())
+                })
+            }
+        } else {
+            Err(format!("missing font family for descriptor {:?}", font_handle))
+        }
+    }
+
+    pub fn add_native_font(&mut self, font_key: &FontKey, font_handle: dwrote::FontDescriptor) {
         if self.fonts.contains_key(font_key) {
             return;
         }
-
-        let index = font_handle.index;
-        let mut cache = FONT_CACHE.lock().unwrap();
-        // Check to see if the font is already in the cache. If so, reuse it.
-        if let Some(font) = cache.get(font_handle.path.as_path()) {
-            if let Ok(face) = font.file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
-                self.fonts.insert(
-                    *font_key,
-                    FontFace { cached: Some(font.key.clone()), file: font.file.clone(), index, face },
-                );
-                return;
-            }
-        }
-        if let Some(file) = dwrote::FontFile::new_from_path(&font_handle.path) {
-            // The font is not in the cache yet, so try to create the font and insert it in the cache.
-            if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
-                let key: CachedFontKey = font_handle.path.into();
-                self.fonts.insert(
-                    *font_key,
-                    FontFace { cached: Some(key.clone()), file: file.clone(), index, face },
-                );
-                cache.insert(CachedFont { key, file });
-                return;
-            }
-        }
-
-        // XXX add_native_font needs to have a way to return an error
-        debug!("DWrite WR failed to load font from path, using Arial instead");
-        self.add_font_descriptor(font_key, &DEFAULT_FONT_DESCRIPTOR);
+        // First try to load the font without updating the system font collection.
+        // If the font can't be found, try again after updating the system font collection.
+        // If even that fails, panic...
+        let font = Self::load_system_font(&font_handle, false).unwrap_or_else(|_| {
+            Self::load_system_font(&font_handle, true).unwrap()
+        });
+        let face = font.create_font_face();
+        self.fonts.insert(*font_key, face);
     }
 
     pub fn delete_font(&mut self, font_key: &FontKey) {
-        if let Some(face) = self.fonts.remove(font_key) {
+        if let Some(_) = self.fonts.remove(font_key) {
             self.variations.retain(|k, _| k.0 != *font_key);
-            // Check if this was a cached font.
-            if let Some(key) = face.cached {
-                let mut cache = FONT_CACHE.lock().unwrap();
-                // If there are only two references left, that means only this face and
-                // the cache are using the font. So remove it from the cache.
-                if Arc::strong_count(&key) == 2 {
-                    cache.remove(&*key);
-                }
-            }
         }
     }
 
     pub fn delete_font_instance(&mut self, instance: &FontInstance) {
         // Ensure we don't keep around excessive amounts of stale variations.
         if !instance.variations.is_empty() {
             let sims = if instance.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) {
                 dwrote::DWRITE_FONT_SIMULATIONS_BOLD
@@ -263,45 +211,42 @@ impl FontContext {
     }
 
     fn get_font_face(
         &mut self,
         font: &FontInstance,
     ) -> &dwrote::FontFace {
         if !font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) &&
            font.variations.is_empty() {
-            return &self.fonts.get(&font.font_key).unwrap().face;
+            return self.fonts.get(&font.font_key).unwrap();
         }
         let sims = if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) {
             dwrote::DWRITE_FONT_SIMULATIONS_BOLD
         } else {
             dwrote::DWRITE_FONT_SIMULATIONS_NONE
         };
         match self.variations.entry((font.font_key, sims, font.variations.clone())) {
             Entry::Occupied(entry) => entry.into_mut(),
             Entry::Vacant(entry) => {
                 let normal_face = self.fonts.get(&font.font_key).unwrap();
                 if !font.variations.is_empty() {
-                    if let Some(var_face) = normal_face.face.create_font_face_with_variations(
+                    if let Some(var_face) = normal_face.create_font_face_with_variations(
                         sims,
                         &font.variations.iter().map(|var| {
                             dwrote::DWRITE_FONT_AXIS_VALUE {
                                 // OpenType tags are big-endian, but DWrite wants little-endian.
                                 axisTag: var.tag.swap_bytes(),
                                 value: var.value,
                             }
                         }).collect::<Vec<_>>(),
                     ) {
                         return entry.insert(var_face);
                     }
                 }
-                let var_face = normal_face.file
-                    .create_face(normal_face.index, sims)
-                    .unwrap_or_else(|_| normal_face.face.clone());
-                entry.insert(var_face)
+                entry.insert(normal_face.create_font_face_with_simulations(sims))
             }
         }
     }
 
     fn create_glyph_analysis(
         &mut self,
         font: &FontInstance,
         key: &GlyphKey,
@@ -365,17 +310,17 @@ impl FontContext {
             if bounds2.left != bounds2.right && bounds2.top != bounds2.bottom {
                 return Ok((analysis2, dwrote::DWRITE_TEXTURE_ALIASED_1x1, bounds2));
             }
         }
         Ok((analysis, texture_type, bounds))
     }
 
     pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
-        let face = &self.fonts.get(&font_key).unwrap().face;
+        let face = self.fonts.get(&font_key).unwrap();
         let indices = face.get_glyph_indices(&[ch as u32]);
         indices.first().map(|idx| *idx as u32)
     }
 
     pub fn get_glyph_dimensions(
         &mut self,
         font: &FontInstance,
         key: &GlyphKey,
@@ -597,17 +542,17 @@ impl FontContext {
             bytes: bgra_pixels,
         })
     }
 }
 
 #[cfg(feature = "pathfinder")]
 impl<'a> From<NativeFontHandleWrapper<'a>> for PathfinderComPtr<IDWriteFontFace> {
     fn from(font_handle: NativeFontHandleWrapper<'a>) -> Self {
-        if let Some(file) = dwrote::FontFile::new_from_path(font_handle.0.path) {
-            let index = font_handle.0.index;
-            if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
-                return unsafe { PathfinderComPtr::new(face.as_ptr()) };
-            }
-        }
-        panic!("missing font {:?}", font_handle.0)
+        let system_fc = ::dwrote::FontCollection::system();
+        let font = match system_fc.get_font_from_descriptor(&font_handle.0) {
+            Some(font) => font,
+            None => panic!("missing descriptor {:?}", font_handle.0),
+        };
+        let face = font.create_font_face();
+        unsafe { PathfinderComPtr::new(face.as_ptr()) }
     }
 }
--- a/gfx/wr/webrender_api/Cargo.toml
+++ b/gfx/wr/webrender_api/Cargo.toml
@@ -25,8 +25,11 @@ serde = { version = "=1.0.80", features 
 serde_derive = { version = "=1.0.80", features = ["deserialize_in_place"] }
 serde_bytes = "0.10"
 time = "0.1"
 wr_malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of" }
 
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation = "0.6"
 core-graphics = "0.17.1"
+
+[target.'cfg(target_os = "windows")'.dependencies]
+dwrote = "0.7"
--- a/gfx/wr/webrender_api/src/font.rs
+++ b/gfx/wr/webrender_api/src/font.rs
@@ -2,32 +2,32 @@
  * 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/. */
 
 use app_units::Au;
 #[cfg(target_os = "macos")]
 use core_foundation::string::CFString;
 #[cfg(target_os = "macos")]
 use core_graphics::font::CGFont;
+#[cfg(target_os = "windows")]
+pub use dwrote::FontDescriptor as NativeFontHandle;
 #[cfg(target_os = "macos")]
 use serde::de::{self, Deserialize, Deserializer};
 #[cfg(target_os = "macos")]
 use serde::ser::{Serialize, Serializer};
 use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
-#[cfg(not(target_os = "macos"))]
-use std::path::PathBuf;
 use std::sync::Arc;
 use {ColorU, IdNamespace, LayoutPoint};
 
 
-#[cfg(not(target_os = "macos"))]
+#[cfg(not(any(target_os = "macos", target_os = "windows")))]
 #[derive(Clone, Debug, Serialize, Deserialize)]
 pub struct NativeFontHandle {
-    pub path: PathBuf,
+    pub pathname: String,
     pub index: u32,
 }
 
 #[cfg(target_os = "macos")]
 #[derive(Clone)]
 pub struct NativeFontHandle(pub CGFont);
 
 #[cfg(target_os = "macos")]
--- a/gfx/wr/webrender_api/src/lib.rs
+++ b/gfx/wr/webrender_api/src/lib.rs
@@ -22,16 +22,18 @@ extern crate byteorder;
 #[cfg(feature = "nightly")]
 extern crate core;
 #[cfg(target_os = "macos")]
 extern crate core_foundation;
 #[cfg(target_os = "macos")]
 extern crate core_graphics;
 #[macro_use]
 extern crate derive_more;
+#[cfg(target_os = "windows")]
+extern crate dwrote;
 pub extern crate euclid;
 #[cfg(feature = "ipc")]
 extern crate ipc_channel;
 #[macro_use]
 extern crate malloc_size_of_derive;
 extern crate serde;
 #[macro_use]
 extern crate serde_derive;
--- a/gfx/wr/wrench/Cargo.toml
+++ b/gfx/wr/wrench/Cargo.toml
@@ -34,13 +34,13 @@ serde = {version = "1.0", features = ["d
 core-graphics = "0.17.1"
 core-foundation = "0.6"
 
 [features]
 headless = [ "osmesa-sys", "osmesa-src" ]
 pathfinder = [ "webrender/pathfinder" ]
 
 [target.'cfg(target_os = "windows")'.dependencies]
-dwrote = "0.8"
+dwrote = "0.7"
 mozangle = {version = "0.1.5", features = ["egl"]}
 
 [target.'cfg(all(unix, not(target_os = "android")))'.dependencies]
 font-loader = "0.7"
--- a/gfx/wr/wrench/src/wrench.rs
+++ b/gfx/wr/wrench/src/wrench.rs
@@ -386,55 +386,46 @@ impl Wrench {
         let mut txn = Transaction::new();
         txn.add_native_font(key, descriptor.clone());
         self.api.update_resources(txn.resource_updates);
         key
     }
 
     #[cfg(target_os = "windows")]
     pub fn font_key_from_name(&mut self, font_name: &str) -> FontKey {
-        self.font_key_from_properties(
-            font_name,
-            dwrote::FontWeight::Regular.to_u32(),
-            dwrote::FontStyle::Normal.to_u32(),
-            dwrote::FontStretch::Normal.to_u32(),
-        )
+        let system_fc = dwrote::FontCollection::system();
+        let family = system_fc.get_font_family_by_name(font_name).unwrap();
+        let font = family.get_first_matching_font(
+            dwrote::FontWeight::Regular,
+            dwrote::FontStretch::Normal,
+            dwrote::FontStyle::Normal,
+        );
+        let descriptor = font.to_descriptor();
+        self.font_key_from_native_handle(&descriptor)
     }
 
     #[cfg(target_os = "windows")]
     pub fn font_key_from_properties(
         &mut self,
         family: &str,
         weight: u32,
         style: u32,
         stretch: u32,
     ) -> FontKey {
         let weight = dwrote::FontWeight::from_u32(weight);
         let style = dwrote::FontStyle::from_u32(style);
         let stretch = dwrote::FontStretch::from_u32(stretch);
+
         let desc = dwrote::FontDescriptor {
             family_name: family.to_owned(),
             weight,
             style,
             stretch,
         };
-        let system_fc = dwrote::FontCollection::system();
-        if let Some(font) = system_fc.get_font_from_descriptor(&desc) {
-            let face = font.create_font_face();
-            let files = face.get_files();
-            if files.len() == 1 {
-                if let Some(path) = files[0].get_font_file_path() {
-                    return self.font_key_from_native_handle(&NativeFontHandle {
-                        path,
-                        index: face.get_index(),
-                    });
-                }
-            }
-        }
-        panic!("failed loading font from properties {:?}", desc)
+        self.font_key_from_native_handle(&desc)
     }
 
     #[cfg(all(unix, not(target_os = "android")))]
     pub fn font_key_from_properties(
         &mut self,
         family: &str,
         _weight: u32,
         _style: u32,
--- a/gfx/wr/wrench/src/yaml_frame_writer.rs
+++ b/gfx/wr/wrench/src/yaml_frame_writer.rs
@@ -263,16 +263,29 @@ fn write_stacking_context(
                 filters.push(Yaml::String("linear-to-srgb".to_string()))
             }
         }
     }
 
     yaml_node(parent, "filters", Yaml::Array(filters));
 }
 
+#[cfg(target_os = "windows")]
+fn native_font_handle_to_yaml(
+    _rsrc: &mut ResourceGenerator,
+    handle: &NativeFontHandle,
+    parent: &mut yaml_rust::yaml::Hash,
+    _: &mut Option<PathBuf>,
+) {
+    str_node(parent, "family", &handle.family_name);
+    u32_node(parent, "weight", handle.weight.to_u32());
+    u32_node(parent, "style", handle.style.to_u32());
+    u32_node(parent, "stretch", handle.stretch.to_u32());
+}
+
 #[cfg(target_os = "macos")]
 fn native_font_handle_to_yaml(
     rsrc: &mut ResourceGenerator,
     handle: &NativeFontHandle,
     parent: &mut yaml_rust::yaml::Hash,
     path_opt: &mut Option<PathBuf>,
 ) {
     let path = match *path_opt {
@@ -289,27 +302,24 @@ fn native_font_handle_to_yaml(
             *path_opt = Some(path.clone());
             path
         }
     };
 
     path_node(parent, "font", &path);
 }
 
-#[cfg(not(target_os = "macos"))]
+#[cfg(not(any(target_os = "macos", target_os = "windows")))]
 fn native_font_handle_to_yaml(
     _rsrc: &mut ResourceGenerator,
     handle: &NativeFontHandle,
     parent: &mut yaml_rust::yaml::Hash,
     _: &mut Option<PathBuf>,
 ) {
-    str_node(parent, "font", handle.path.as_os_str().to_str().unwrap());
-    if handle.index != 0 {
-        u32_node(parent, "font-index", handle.index);
-    }
+    str_node(parent, "font", &handle.pathname);
 }
 
 fn radial_gradient_to_yaml(
     table: &mut Table,
     gradient: &webrender::api::RadialGradient,
     stops_range: ItemRange<GradientStop>,
     display_list: &BuiltDisplayList
 ) {
--- a/third_party/rust/dwrote/.cargo-checksum.json
+++ b/third_party/rust/dwrote/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"97226421832e89c8a4c1b25a5e86493fc13b0d085ceb913a04f501f5c3859b0b","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","appveyor.yml":"6a91cdfbcc8c363ead82321b3be509bb7bf9cf8b90c63518d6484371abcfed48","src/bitmap_render_target.rs":"fc13525d7459515e4bf9769c8a8961b046b4d1ba4042591aaf0925dd5edebf64","src/com_helpers.rs":"02535b27bfb0cee6e4d8db3abd22f2d2e8137a4ce3ab3504beaf4fa3ca9370df","src/comptr.rs":"84794cf04b772398e75fdb5d55fd8fa015abf26c61b1f9c761a597133682b2e1","src/font.rs":"a79b944f2f5125bbef9e24921355dc6996f073e3742ddd410b8efaa0df3a3ee2","src/font_collection.rs":"67cd566714f4c0a20cba24dd064ba471e75016fa2672b2153a19878e6b71f24d","src/font_collection_impl.rs":"a585a6ce62083b3346d67619ea47fec46423a7fb04cc11372828389ab26c5a05","src/font_face.rs":"7f78c4132df39857d8118ac3eacbb57e11bca1d69f9d7f8e1c1c24b7a2b69749","src/font_family.rs":"4e948542dba0c158187d0cb2d72343c443380480cacd12894070d0ef1351dd0a","src/font_file.rs":"4bfcaa94c97174e7ab98130011c76ba56c4d25673c02cd46463bb258eecc823b","src/font_file_loader_impl.rs":"71c4153971dbfc21d42ba2e33f159fcb145f7dcfbd17e856e9fd75f0571d41e0","src/gdi_interop.rs":"04dbef7c34bb0fe62c4f2c2ceca62ca94c75a964d744b29b3322a6c3bbb4eabd","src/geometry_sink_impl.rs":"d615de212e55b8b8d95c8d605fc5d78044b4ae4dfd846f706911a16cc3afc049","src/glyph_run_analysis.rs":"23c674e892287884ad92faf02813397e4347d61d3b363f6acb8d578c14e65051","src/helpers.rs":"2f3c57642b24b80c45bbd012e7d6ca1fc524b1b42a8be004cb9b52ea13f4166d","src/lib.rs":"16cc8c236226047bc5ca65f921d2aebec4a3a6101a2c8f2853f39a5db4639e16","src/outline_builder.rs":"0f5c842b2ffe75e21d68f93be6a3834c120bd43303d4e490fdfee9f4f964cdc4","src/rendering_params.rs":"850a51143790f5d29422dc49cbceddc232d814ecd0e6933434ad644e6eec539b","src/test.rs":"158aa4d03655f4efef00327fe72a03dfb504659176aa0eef976ca2485b2c1d74","src/types.rs":"9374d8c5bac80e5e0b66188c5ff4f5f49264e15db837049932d4fd703c33746e"},"package":"c31c624339dab99c223a4b26c2e803b7c248adaca91549ce654c76f39a03f5c8"}
\ No newline at end of file
+{"files":{"Cargo.toml":"2456adfd958e59ec20d4c380e7621684d07817fc015c2372d1cb50473499d359","README.md":"d69d75705e2582721cbfb2d3b4b2af052c71679057a0b2ac53a22c03f1755bba","appveyor.yml":"6a91cdfbcc8c363ead82321b3be509bb7bf9cf8b90c63518d6484371abcfed48","src/bitmap_render_target.rs":"fc13525d7459515e4bf9769c8a8961b046b4d1ba4042591aaf0925dd5edebf64","src/com_helpers.rs":"02535b27bfb0cee6e4d8db3abd22f2d2e8137a4ce3ab3504beaf4fa3ca9370df","src/comptr.rs":"84794cf04b772398e75fdb5d55fd8fa015abf26c61b1f9c761a597133682b2e1","src/font.rs":"a79b944f2f5125bbef9e24921355dc6996f073e3742ddd410b8efaa0df3a3ee2","src/font_collection.rs":"67cd566714f4c0a20cba24dd064ba471e75016fa2672b2153a19878e6b71f24d","src/font_collection_impl.rs":"a585a6ce62083b3346d67619ea47fec46423a7fb04cc11372828389ab26c5a05","src/font_face.rs":"7f78c4132df39857d8118ac3eacbb57e11bca1d69f9d7f8e1c1c24b7a2b69749","src/font_family.rs":"4e948542dba0c158187d0cb2d72343c443380480cacd12894070d0ef1351dd0a","src/font_file.rs":"1c012d0b436c2831d31cd76f77a59dab1edc5d63881c495eb486cd4febe23031","src/font_file_loader_impl.rs":"71c4153971dbfc21d42ba2e33f159fcb145f7dcfbd17e856e9fd75f0571d41e0","src/gdi_interop.rs":"04dbef7c34bb0fe62c4f2c2ceca62ca94c75a964d744b29b3322a6c3bbb4eabd","src/geometry_sink_impl.rs":"d615de212e55b8b8d95c8d605fc5d78044b4ae4dfd846f706911a16cc3afc049","src/glyph_run_analysis.rs":"23c674e892287884ad92faf02813397e4347d61d3b363f6acb8d578c14e65051","src/helpers.rs":"2f3c57642b24b80c45bbd012e7d6ca1fc524b1b42a8be004cb9b52ea13f4166d","src/lib.rs":"16cc8c236226047bc5ca65f921d2aebec4a3a6101a2c8f2853f39a5db4639e16","src/outline_builder.rs":"0f5c842b2ffe75e21d68f93be6a3834c120bd43303d4e490fdfee9f4f964cdc4","src/rendering_params.rs":"850a51143790f5d29422dc49cbceddc232d814ecd0e6933434ad644e6eec539b","src/test.rs":"158aa4d03655f4efef00327fe72a03dfb504659176aa0eef976ca2485b2c1d74","src/types.rs":"9374d8c5bac80e5e0b66188c5ff4f5f49264e15db837049932d4fd703c33746e"},"package":"2d2ea0fd88d96838ce5ed30326338cc04a0eb4cff10e3e15d188d74112777103"}
\ No newline at end of file
--- a/third_party/rust/dwrote/Cargo.toml
+++ b/third_party/rust/dwrote/Cargo.toml
@@ -7,17 +7,17 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "dwrote"
-version = "0.8.0"
+version = "0.7.0"
 authors = ["Vladimir Vukicevic <vladimir@pobox.com>"]
 description = "Lightweight binding to DirectWrite."
 license = "MPL-2.0"
 repository = "https://github.com/servo/dwrote-rs"
 
 [lib]
 name = "dwrote"
 [dependencies.lazy_static]
--- a/third_party/rust/dwrote/src/font_file.rs
+++ b/third_party/rust/dwrote/src/font_file.rs
@@ -16,17 +16,16 @@ use std::sync::Arc;
 use comptr::ComPtr;
 
 use winapi::Interface;
 use winapi::ctypes::c_void;
 use winapi::um::dwrite::{IDWriteFontFace, IDWriteFontFile, IDWriteFontFileStream};
 use winapi::um::dwrite::{IDWriteFontFileLoader, IDWriteLocalFontFileLoader};
 use winapi::um::dwrite::{DWRITE_FONT_SIMULATIONS, DWRITE_FONT_FACE_TYPE_UNKNOWN};
 use winapi::um::dwrite::{DWRITE_FONT_FACE_TYPE, DWRITE_FONT_FILE_TYPE_UNKNOWN};
-use winapi::um::winnt::HRESULT;
 
 use font_file_loader_impl::DataFontHelper;
 use font_face::FontFace;
 use super::DWriteFactory;
 
 pub struct FontFile {
     native: UnsafeCell<ComPtr<IDWriteFontFile>>,
     stream: UnsafeCell<Option<ComPtr<IDWriteFontFileStream>>>,
@@ -43,28 +42,22 @@ impl FontFile {
             let mut font_file: ComPtr<IDWriteFontFile> = ComPtr::new();
             let hr = (*DWriteFactory()).CreateFontFileReference(path.as_ptr(),
                                                                 ptr::null(),
                                                                 font_file.getter_addrefs());
             if hr != 0 || font_file.is_null() {
                 return None
             }
 
-            let mut ff = FontFile {
+            Some(FontFile {
                 native: UnsafeCell::new(font_file),
                 stream: UnsafeCell::new(None),
                 data_key: 0,
                 face_type: DWRITE_FONT_FACE_TYPE_UNKNOWN,
-            };
-
-            if ff.analyze() == 0 {
-                None
-            } else {
-                Some(ff)
-            }
+            })
         }
     }
 
     pub fn new_from_data(data: Arc<Vec<u8>>) -> Option<FontFile> {
         let (font_file, font_file_stream, key) = DataFontHelper::register_font_data(data);
 
         let mut ff = FontFile {
             native: UnsafeCell::new(font_file),
@@ -206,30 +199,24 @@ impl FontFile {
             if let Some(&0) = file_path_buf.last() {
                 file_path_buf.pop();
             }
 
             Some(PathBuf::from(OsString::from_wide(&file_path_buf)))
         }
     }
 
-    pub fn create_face(&self,
-                       face_index: u32,
-                       simulations: DWRITE_FONT_SIMULATIONS,
-    ) -> Result<FontFace, HRESULT> {
+    pub fn create_face(&self, face_index: u32, simulations: DWRITE_FONT_SIMULATIONS) -> FontFace {
         unsafe {
             let mut face: ComPtr<IDWriteFontFace> = ComPtr::new();
             let ptr = self.as_com_ptr();
             let hr = (*DWriteFactory()).CreateFontFace(self.face_type, 1, &ptr.as_ptr(),
                                                        face_index, simulations, face.getter_addrefs());
-            if hr != 0 {
-                Err(hr)
-            } else {
-                Ok(FontFace::take(face))
-            }
+            assert!(hr == 0);
+            FontFace::take(face)
         }
     }
 }
 
 impl Clone for FontFile {
     fn clone(&self) -> FontFile {
         unsafe {
             FontFile {