Chromium Code Reviews| Index: content/renderer/hyphenator/hyphenator.cc |
| =================================================================== |
| --- content/renderer/hyphenator/hyphenator.cc (revision 152650) |
| +++ content/renderer/hyphenator/hyphenator.cc (working copy) |
| @@ -4,11 +4,18 @@ |
| #include "content/renderer/hyphenator/hyphenator.h" |
| +#include "base/bind.h" |
| #include "base/file_util.h" |
| #include "base/logging.h" |
| +#include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/message_loop_proxy.h" |
| #include "base/string_util.h" |
| #include "base/utf_string_conversions.h" |
| +#include "content/common/hyphenator_messages.h" |
| +#include "content/public/renderer/render_thread.h" |
|
jam
2012/08/23 21:34:29
nit: not needed
Hironori Bono
2012/08/27 06:57:28
Done. I have removed redundant headers. (I do not
|
| +#include "content/renderer/render_thread_impl.h" |
| +#include "ipc/ipc_channel_proxy.h" |
| #include "third_party/hyphen/hyphen.h" |
| #include "unicode/uscript.h" |
| @@ -176,6 +183,56 @@ |
| return !hyphen_offsets->empty(); |
| } |
| +// A message filter that listens HyphenatorMsg_SetDictionary messages and |
| +// initializes the specified Hyphenator object. This class has a weak reference |
| +// to the Hyphenator object so a renderer can delete it while a browser opens a |
| +// dictionary file. |
| +class MessageFilter : public IPC::ChannelProxy::MessageFilter { |
|
jam
2012/08/23 21:34:29
you don't need a message filter, since you're real
Hironori Bono
2012/08/27 06:57:28
Done. Thanks for your suggestion. The RenderProces
|
| + public: |
| + explicit MessageFilter(base::WeakPtr<content::Hyphenator> hyphenator); |
| + |
| + // IPC::ChannelProxy::MessageFilter implementation. |
| + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| + |
| + private: |
| + virtual ~MessageFilter(); |
| + |
| + // Called when a browser sends a HyphenatorMsg_SetDictionary message, i.e. |
|
jam
2012/08/23 21:34:29
nit: by convention we don't comment IPC message ha
Hironori Bono
2012/08/27 06:57:28
Done. Thanks for your comment. (I have removed com
|
| + // when a browser opens the hyphenation dictionary requested by the |
| + // Hyphenator object. |
| + void OnSetDictionary(IPC::PlatformFileForTransit rule_file); |
| + |
| + base::WeakPtr<content::Hyphenator> hyphenator_; |
| + scoped_refptr<base::MessageLoopProxy> message_loop_; |
| +}; |
| + |
| +MessageFilter::MessageFilter(base::WeakPtr<content::Hyphenator> hyphenator) |
| + : hyphenator_(hyphenator), |
| + message_loop_(base::MessageLoopProxy::current()) { |
| +} |
| + |
| +MessageFilter::~MessageFilter() { |
| +} |
| + |
| +bool MessageFilter::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(MessageFilter, message) |
| + IPC_MESSAGE_HANDLER(HyphenatorMsg_SetDictionary, OnSetDictionary) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void MessageFilter::OnSetDictionary(IPC::PlatformFileForTransit rule_file) { |
| + base::PlatformFile file = |
| + IPC::PlatformFileForTransitToPlatformFile(rule_file); |
| + if (file == base::kInvalidPlatformFileValue) |
| + return; |
| + message_loop_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&content::Hyphenator::SetDictionary, hyphenator_, file)); |
| +} |
| + |
| } // namespace |
| namespace content { |
| @@ -183,29 +240,52 @@ |
| Hyphenator::Hyphenator(base::PlatformFile file) |
| : dictionary_(NULL), |
| rule_file_(file), |
| - result_(0) { |
| + result_(0), |
| + weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| } |
| Hyphenator::~Hyphenator() { |
| if (dictionary_) |
| hnj_hyphen_free(dictionary_); |
| + if (rule_file_ != base::kInvalidPlatformFileValue) |
| + base::ClosePlatformFile(rule_file_); |
| } |
| bool Hyphenator::Initialize() { |
| if (dictionary_) |
| return true; |
| + // Attach the dictionary file to the MemoryMappedFile object. When it |
| + // succeeds, this class does not have to close this file because it is closed |
| + // by the MemoryMappFile class. To prevent this class from closing this file, |
|
tony
2012/08/22 19:05:50
Nit: typo: MemoryMappFile -> MemoryMappedFile
Hironori Bono
2012/08/27 06:57:28
Done. Thanks for noticing my typo.
|
| + // we reset its handle. |
| rule_map_.reset(new file_util::MemoryMappedFile); |
| if (!rule_map_->Initialize(rule_file_)) |
| return false; |
| + rule_file_ = base::kInvalidPlatformFileValue; |
| dictionary_ = hnj_hyphen_load(rule_map_->data(), rule_map_->length()); |
| return !!dictionary_; |
| } |
| +bool Hyphenator::Attach(content::RenderThread* thread, const string16& locale) { |
|
jam
2012/08/23 21:34:29
ditto
Hironori Bono
2012/08/27 06:57:28
Done. I have removed this redundant comment.
|
| + // Create a new message filter for Hyphenator messages and attach it to the |
| + // given thread with a weak reference to this object so a renderer can delete |
| + // this object while a browser opens a dictionary. |
| + if (!thread) |
| + return false; |
| + locale_.assign(locale); |
| + thread->AddFilter(new MessageFilter(weak_factory_.GetWeakPtr())); |
| + return thread->Send(new HyphenatorHostMsg_OpenDictionary(locale)); |
| +} |
| + |
| +bool Hyphenator::CanHyphenate(const string16& locale) { |
| + return !locale_.compare(locale); |
| +} |
| + |
| size_t Hyphenator::ComputeLastHyphenLocation(const string16& word, |
| size_t before_index) { |
| - if (!dictionary_ || word.empty()) |
| + if (!Initialize() || word.empty()) |
| return 0; |
| // Call the hyphen library to get all hyphenation points, i.e. positions where |
| @@ -228,4 +308,20 @@ |
| return 0; |
| } |
| +void Hyphenator::SetDictionary(base::PlatformFile rule_file) { |
| + // Delete the current dictionary and save the given file to this object. We |
| + // initialize the hyphens library the first time when WebKit actually |
| + // hyphenates a word, i.e. when WebKit calls the ComputeLastHyphenLocation |
| + // function. (WebKit does not always hyphenate words even when it calls the |
| + // CanHyphenate function, e.g. WebKit does not have to hyphenate words when it |
| + // does not have to break text into lines.) |
| + DCHECK(rule_file != base::kInvalidPlatformFileValue); |
| + if (dictionary_) { |
| + hnj_hyphen_free(dictionary_); |
| + dictionary_ = NULL; |
| + } |
| + rule_map_.reset(); |
| + rule_file_ = rule_file; |
| +} |
| + |
| } // namespace content |