summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authoredisonn@google.com <edisonn@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-21 01:14:56 +0000
committeredisonn@google.com <edisonn@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-21 01:14:56 +0000
commitfeb3237e3c328f51525f90ea41737fe6eee28eef (patch)
tree9c45f0489ca6174ad0bb253c155ecfce742393be /content
parente8a9892eefaf046b752e229d0af39ac2c855e0ae (diff)
downloadchromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.zip
chromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.tar.gz
chromium_src-feb3237e3c328f51525f90ea41737fe6eee28eef.tar.bz2
This is a fix for http://code.google.com/p/chromium/issues/detail?id=128506 - Random Chinese/Japanese characters are missing in documents printed via the system print dialog on Windows XP SP3
The cause of the bug is that ensureFontLoaded just does not work for the printing thread because GetTextMetrics(font) is not guaranteed to load the TrueType font for an HDC build from CreateEnhMetaFile. The only way I found to force font loading is to create a dummy HDC with CreateEnhMetaFile and then print the offending character(s). This change contains: - wirings for foo_CacheFontCharacters similar with foo_CacheFont, but with dispatch this message in RenderMessageFilter and defined in view_messages.h - SkFontHost::EnsureTypefaceCharactersAccessible similar with SkFontHost::EnsureTypefaceAccessible - Small refactoring of ExtTextOut call which would - Call ExtTextOut - If failed, calls SkFontHost::EnsureTypefaceCharactersAccessible - call ExtTextOutAgain and return success/failure - the calller will default to a skia paintPath (lower quality, but correct) if above fails Notice: No tests for now, lets's make sure the design is right, then I will add tests too. Contributed by edisonn@google.com Review URL: https://chromiumcodereview.appspot.com/11363008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168943 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_message_filter.cc34
-rw-r--r--content/browser/renderer_host/render_message_filter.h5
-rw-r--r--content/common/view_messages.h10
-rw-r--r--content/renderer/render_thread_impl.cc6
-rw-r--r--content/renderer/render_thread_impl.h5
-rw-r--r--content/renderer/renderer_main_platform_delegate_win.cc16
6 files changed, 76 insertions, 0 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index f5d3063..9d6b5b9 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -76,6 +76,7 @@
#endif
#if defined(OS_WIN)
#include "content/browser/renderer_host/backing_store_win.h"
+#include "content/common/font_cache_dispatcher_win.h"
#endif
using net::CookieStore;
@@ -362,6 +363,10 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok)
+#if defined(OS_WIN)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFontCharacters,
+ OnPreCacheFontCharacters)
+#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnMsgCreateWindow)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget)
@@ -1102,4 +1107,33 @@ void RenderMessageFilter::OnDidLose3DContext(
top_origin_url, guilt);
}
+#if defined(OS_WIN)
+void RenderMessageFilter::OnPreCacheFontCharacters(const LOGFONT& font,
+ const string16& str) {
+ // First, comments from FontCacheDispatcher::OnPreCacheFont do apply here too.
+ // Except that for True Type fonts,
+ // GetTextMetrics will not load the font in memory.
+ // The only way windows seem to load properly, it is to create a similar
+ // device (like the one in which we print), then do an ExtTextOut,
+ // as we do in the printing thread, which is sandboxed.
+ HDC hdc = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
+ HFONT font_handle = CreateFontIndirect(&font);
+ DCHECK(NULL != font_handle);
+
+ HGDIOBJ old_font = SelectObject(hdc, font_handle);
+ DCHECK(NULL != old_font);
+
+ ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, str.c_str(), str.length(), NULL);
+
+ SelectObject(hdc, old_font);
+ DeleteObject(font_handle);
+
+ HENHMETAFILE metafile = CloseEnhMetaFile(hdc);
+
+ if (metafile) {
+ DeleteEnhMetaFile(metafile);
+ }
+}
+#endif
+
} // namespace content
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 9431aca..f52f86f 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -144,6 +144,11 @@ class RenderMessageFilter : public BrowserMessageFilter {
void SendLoadFontReply(IPC::Message* reply, FontLoader::Result* result);
#endif
+#if defined(OS_WIN)
+ void OnPreCacheFontCharacters(const LOGFONT& log_font,
+ const string16& characters);
+#endif
+
void OnGetPlugins(bool refresh, IPC::Message* reply_msg);
void GetPluginsCallback(IPC::Message* reply_msg,
const std::vector<webkit::WebPluginInfo>& plugins);
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 2ab5da9..e67f08f 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -7,6 +7,7 @@
#include "base/process.h"
#include "base/shared_memory.h"
+#include "base/string16.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
#include "content/common/edit_command.h"
@@ -2425,3 +2426,12 @@ IPC_MESSAGE_CONTROL3(ViewHostMsg_DidLose3DContext,
GURL /* top_origin_url */,
content::ThreeDAPIType /* context_type */,
int /* arb_robustness_status_code */)
+
+#if defined(OS_WIN)
+// Request that the given font characters be loaded by the browser so it's
+// cached by the OS. Please see RenderMessageFilter::OnPreCacheFontCharacters
+// for details.
+IPC_SYNC_MESSAGE_CONTROL2_0(ViewHostMsg_PreCacheFontCharacters,
+ LOGFONT /* font_data */,
+ string16 /* characters */)
+#endif
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 8e46b50..502b930 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -19,6 +19,7 @@
#include "base/metrics/stats_table.h"
#include "base/path_service.h"
#include "base/shared_memory.h"
+#include "base/string16.h"
#include "base/string_number_conversions.h" // Temporary
#include "base/threading/thread_local.h"
#include "base/utf_string_conversions.h"
@@ -852,6 +853,11 @@ AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
}
#if defined(OS_WIN)
+void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
+ const string16& str) {
+ Send(new ViewHostMsg_PreCacheFontCharacters(log_font, str));
+}
+
void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) {
Send(new ChildProcessHostMsg_PreCacheFont(log_font));
}
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index c370d78..4a076a3 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/observer_list.h"
+#include "base/string16.h"
#include "base/timer.h"
#include "build/build_config.h"
#include "content/common/child_process.h"
@@ -239,6 +240,10 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
// first call.
AudioRendererMixerManager* GetAudioRendererMixerManager();
+#if defined(OS_WIN)
+ void PreCacheFontCharacters(const LOGFONT& log_font, const string16& str);
+#endif
+
// For producing custom V8 histograms. Custom histograms are produced if all
// RenderViews share the same host, and the host is in the pre-specified set
// of hosts we want to produce custom diagrams for. The name for a custom
diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc
index 316fcc0..27d2bbf 100644
--- a/content/renderer/renderer_main_platform_delegate_win.cc
+++ b/content/renderer/renderer_main_platform_delegate_win.cc
@@ -9,12 +9,15 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
#include "base/win/win_util.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/injection_test_win.h"
#include "content/public/renderer/render_thread.h"
+#include "content/renderer/render_thread_impl.h"
#include "sandbox/win/src/sandbox.h"
#include "skia/ext/skia_sandbox_support_win.h"
+#include "skia/ext/vector_platform_device_emf_win.h"
#include "unicode/timezone.h"
namespace content {
@@ -28,6 +31,17 @@ void SkiaPreCacheFont(const LOGFONT& logfont) {
}
}
+void SkiaPreCacheFontCharacters(const LOGFONT& logfont,
+ const wchar_t* text,
+ unsigned int text_length) {
+ content::RenderThreadImpl* render_thread_impl =
+ content::RenderThreadImpl::current();
+ if (render_thread_impl) {
+ render_thread_impl->PreCacheFontCharacters(logfont,
+ string16(text, text_length));
+ }
+}
+
void __cdecl ForceCrashOnSigAbort(int) {
*((int*)0) = 0x1337;
}
@@ -78,6 +92,8 @@ void RendererMainPlatformDelegate::PlatformInitialize() {
// is disabled, we don't have to make this dummy call.
scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
SetSkiaEnsureTypefaceAccessible(SkiaPreCacheFont);
+ skia::SetSkiaEnsureTypefaceCharactersAccessible(
+ SkiaPreCacheFontCharacters);
}
}