| Index: content/common/child_process_host.cc
|
| ===================================================================
|
| --- content/common/child_process_host.cc (revision 112358)
|
| +++ content/common/child_process_host.cc (working copy)
|
| @@ -19,6 +19,8 @@
|
|
|
| #if defined(OS_LINUX)
|
| #include "base/linux_util.h"
|
| +#elif defined(OS_WIN)
|
| +#include "content/common/font_cache_dispatcher_win.h"
|
| #endif // OS_LINUX
|
|
|
| #if defined(OS_MACOSX)
|
| @@ -67,17 +69,12 @@
|
| } // namespace
|
| #endif // OS_MACOSX
|
|
|
| -#if defined (OS_WIN)
|
| -// Types used in PreCacheFont
|
| -namespace {
|
| -typedef std::vector<string16> FontNameVector;
|
| -typedef std::map<int, FontNameVector> PidToFontNames;
|
| -}
|
| -#endif // OS_WIN
|
| -
|
| ChildProcessHost::ChildProcessHost()
|
| : ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
|
| opening_channel_(false) {
|
| +#if defined(OS_WIN)
|
| + AddFilter(new FontCacheDispatcher());
|
| +#endif
|
| }
|
|
|
| ChildProcessHost::~ChildProcessHost() {
|
| @@ -139,132 +136,6 @@
|
| return child_path;
|
| }
|
|
|
| -#if defined(OS_WIN)
|
| -ChildProcessHost::FontCache::CacheElement::CacheElement()
|
| - : font_(NULL), dc_(NULL), ref_count_(0) {
|
| -}
|
| -
|
| -ChildProcessHost::FontCache::CacheElement::~CacheElement() {
|
| - if (font_) {
|
| - DeleteObject(font_);
|
| - }
|
| - if (dc_) {
|
| - DeleteDC(dc_);
|
| - }
|
| -}
|
| -
|
| -ChildProcessHost::FontCache::FontCache() {
|
| -}
|
| -
|
| -ChildProcessHost::FontCache::~FontCache() {
|
| -}
|
| -
|
| -// static
|
| -ChildProcessHost::FontCache* ChildProcessHost::FontCache::GetInstance() {
|
| - return Singleton<ChildProcessHost::FontCache>::get();
|
| -}
|
| -
|
| -void ChildProcessHost::FontCache::PreCacheFont(LOGFONT font, int process_id) {
|
| - typedef std::map<string16, ChildProcessHost::FontCache::CacheElement>
|
| - FontNameToElement;
|
| -
|
| - base::AutoLock lock(mutex_);
|
| -
|
| - // Fetch the font into memory.
|
| - // No matter the font is cached or not, we load it to avoid GDI swapping out
|
| - // that font file.
|
| - HDC hdc = GetDC(NULL);
|
| - HFONT font_handle = CreateFontIndirect(&font);
|
| - DCHECK(NULL != font_handle);
|
| -
|
| - HGDIOBJ old_font = SelectObject(hdc, font_handle);
|
| - DCHECK(NULL != old_font);
|
| -
|
| - TEXTMETRIC tm;
|
| - BOOL ret = GetTextMetrics(hdc, &tm);
|
| - DCHECK(ret);
|
| -
|
| - string16 font_name = font.lfFaceName;
|
| - int ref_count_inc = 1;
|
| - FontNameVector::iterator it =
|
| - std::find(process_id_font_map_[process_id].begin(),
|
| - process_id_font_map_[process_id].end(),
|
| - font_name);
|
| - if (it == process_id_font_map_[process_id].end()) {
|
| - // Requested font is new to cache.
|
| - process_id_font_map_[process_id].push_back(font_name);
|
| - } else {
|
| - ref_count_inc = 0;
|
| - }
|
| -
|
| - if (cache_[font_name].ref_count_ == 0) { // Requested font is new to cache.
|
| - cache_[font_name].ref_count_ = 1;
|
| - } else { // Requested font is already in cache, release old handles.
|
| - DeleteObject(cache_[font_name].font_);
|
| - DeleteDC(cache_[font_name].dc_);
|
| - }
|
| - cache_[font_name].font_ = font_handle;
|
| - cache_[font_name].dc_ = hdc;
|
| - cache_[font_name].ref_count_ += ref_count_inc;
|
| -}
|
| -
|
| -void ChildProcessHost::FontCache::ReleaseCachedFonts(int process_id) {
|
| - typedef std::map<string16, ChildProcessHost::FontCache::CacheElement>
|
| - FontNameToElement;
|
| -
|
| - base::AutoLock lock(mutex_);
|
| -
|
| - PidToFontNames::iterator it;
|
| - it = process_id_font_map_.find(process_id);
|
| - if (it == process_id_font_map_.end()) {
|
| - return;
|
| - }
|
| -
|
| - for (FontNameVector::iterator i = it->second.begin(), e = it->second.end();
|
| - i != e; ++i) {
|
| - FontNameToElement::iterator element;
|
| - element = cache_.find(*i);
|
| - if (element != cache_.end()) {
|
| - --((*element).second.ref_count_);
|
| - }
|
| - }
|
| -
|
| - process_id_font_map_.erase(it);
|
| - for (FontNameToElement::iterator i = cache_.begin(); i != cache_.end(); ) {
|
| - if (i->second.ref_count_ == 0) {
|
| - cache_.erase(i++);
|
| - } else {
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -// static
|
| -void ChildProcessHost::PreCacheFont(LOGFONT font, int pid) {
|
| - // If a child process is running in a sandbox, GetTextMetrics()
|
| - // can sometimes fail. If a font has not been loaded
|
| - // previously, GetTextMetrics() will try to load the font
|
| - // from the font file. However, the sandboxed process does
|
| - // not have permissions to access any font files and
|
| - // the call fails. So we make the browser pre-load the
|
| - // font for us by using a dummy call to GetTextMetrics of
|
| - // the same font.
|
| - // This means the browser process just loads the font into memory so that
|
| - // when GDI attempt to query that font info in child process, it does not
|
| - // need to load that file, hence no permission issues there. Therefore,
|
| - // when a font is asked to be cached, we always recreates the font object
|
| - // to avoid the case that an in-cache font is swapped out by GDI.
|
| - ChildProcessHost::FontCache::GetInstance()->PreCacheFont(font, pid);
|
| -}
|
| -
|
| -// static
|
| -void ChildProcessHost::ReleaseCachedFonts(int pid) {
|
| - // Release cached fonts that requested from a pid by decrementing the ref
|
| - // count. When ref count is zero, the handles are released.
|
| - ChildProcessHost::FontCache::GetInstance()->ReleaseCachedFonts(pid);
|
| -}
|
| -#endif // OS_WIN
|
| -
|
| void ChildProcessHost::ForceShutdown() {
|
| Send(new ChildProcessMsg_Shutdown());
|
| }
|
|
|