Index: content/renderer/renderer_main_platform_delegate_win.cc |
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc |
index 58fce15cc41f4c4400a749c489c7a34fde5de828..5fdaad3962dd7057726ebae65343b63cf2cca930 100644 |
--- a/content/renderer/renderer_main_platform_delegate_win.cc |
+++ b/content/renderer/renderer_main_platform_delegate_win.cc |
@@ -8,7 +8,9 @@ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/strings/string16.h" |
+#include "base/win/scoped_comptr.h" |
#include "base/win/win_util.h" |
+#include "base/win/windows_version.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/common/injection_test_win.h" |
#include "content/public/renderer/render_thread.h" |
@@ -22,10 +24,13 @@ |
#include "v8/src/third_party/vtune/v8-vtune.h" |
#endif |
+#include <dwrite.h> |
+ |
namespace content { |
namespace { |
// Windows-only skia sandbox support |
+// These are used for GDI-path rendering. |
void SkiaPreCacheFont(const LOGFONT& logfont) { |
RenderThread* render_thread = RenderThread::Get(); |
if (render_thread) { |
@@ -44,6 +49,59 @@ void SkiaPreCacheFontCharacters(const LOGFONT& logfont, |
} |
} |
+// Windows-only DirectWrite support. These warm up the DirectWrite paths |
+// before sandbox lock down to allow Skia access to font data. |
jschuh
2014/03/25 04:03:48
Nit: s/font data/the Font Manager service/
scottmg
2014/03/25 05:43:18
Done.
|
+bool CreateDirectWriteFactory(IDWriteFactory** factory) { |
+ typedef decltype(DWriteCreateFactory) * DWriteCreateFactoryProc; |
jschuh
2014/03/25 04:03:48
Nit: loose *
scottmg
2014/03/25 05:43:18
clang-format. But Done.
jschuh
2014/03/25 12:42:02
Yep, I've been bitten by clang-format repeatedly o
|
+ DWriteCreateFactoryProc dwrite_create_factory_proc = |
+ reinterpret_cast<DWriteCreateFactoryProc>( |
+ GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")); |
+ if (!dwrite_create_factory_proc) |
+ return false; |
+ CHECK(SUCCEEDED( |
+ dwrite_create_factory_proc(DWRITE_FACTORY_TYPE_SHARED, |
+ __uuidof(IDWriteFactory), |
+ reinterpret_cast<IUnknown**>(factory)))); |
+ return true; |
+} |
+ |
+void WarmupDirectWrite() { |
+ if (base::win::GetVersion() < base::win::VERSION_VISTA) |
+ return; |
+ |
+ base::win::ScopedComPtr<IDWriteFactory> factory; |
+ if (!CreateDirectWriteFactory(factory.Receive())) |
+ return; |
+ |
+ base::win::ScopedComPtr<IDWriteFontCollection> font_collection; |
+ CHECK(SUCCEEDED( |
+ factory->GetSystemFontCollection(font_collection.Receive(), FALSE))); |
+ base::win::ScopedComPtr<IDWriteFontFamily> font_family; |
+ |
+ UINT32 index; |
+ BOOL exists; |
+ CHECK(SUCCEEDED( |
+ font_collection->FindFamilyName(L"Times New Roman", &index, &exists))); |
+ CHECK(exists); |
+ CHECK( |
+ SUCCEEDED(font_collection->GetFontFamily(index, font_family.Receive()))); |
+ const DWRITE_FONT_WEIGHT weights[] = {DWRITE_FONT_WEIGHT_NORMAL, |
+ DWRITE_FONT_WEIGHT_BOLD}; |
+ base::win::ScopedComPtr<IDWriteFont> fonts[ARRAYSIZE(weights)]; |
+ base::win::ScopedComPtr<IDWriteFontFace> font_faces[ARRAYSIZE(weights)]; |
+ for (size_t i = 0; i < ARRAYSIZE(weights); ++i) { |
jschuh
2014/03/25 04:03:48
Do you really needed to enumerate through the weig
scottmg
2014/03/25 05:43:18
Oops, thanks, probably not any more. Done. I'll re
|
+ CHECK( |
+ SUCCEEDED(font_family->GetFirstMatchingFont(weights[i], |
+ DWRITE_FONT_STRETCH_NORMAL, |
+ DWRITE_FONT_STYLE_NORMAL, |
+ fonts[i].Receive()))); |
+ CHECK(SUCCEEDED(fonts[i]->CreateFontFace(font_faces[i].Receive()))); |
+ DWRITE_GLYPH_METRICS gm; |
+ UINT16 glyph = L'S'; |
+ CHECK(SUCCEEDED(font_faces[i]->GetDesignGlyphMetrics(&glyph, 1, &gm))); |
+ } |
+} |
+ |
} // namespace |
RendererMainPlatformDelegate::RendererMainPlatformDelegate( |
@@ -78,6 +136,8 @@ void RendererMainPlatformDelegate::PlatformInitialize() { |
SkTypeface_SetEnsureLOGFONTAccessibleProc(SkiaPreCacheFont); |
jschuh
2014/03/25 04:03:48
You'll need to disable the GDI setup and both ends
scottmg
2014/03/25 05:43:18
At the moment, the about:flag isn't conditionalize
jschuh
2014/03/25 12:42:02
Yeah, that works. As long as the browser makes the
|
skia::SetSkiaEnsureTypefaceCharactersAccessible( |
SkiaPreCacheFontCharacters); |
+ |
+ WarmupDirectWrite(); |
jschuh
2014/03/25 04:03:48
This should be scoped to run only when DW is enabl
|
} |
} |