| Index: components/font_service/public/cpp/font_service_thread.cc
|
| diff --git a/components/font_service/public/cpp/font_service_thread.cc b/components/font_service/public/cpp/font_service_thread.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e7f2c89ee228ef3e08f738c36a9aba1cea5e675d
|
| --- /dev/null
|
| +++ b/components/font_service/public/cpp/font_service_thread.cc
|
| @@ -0,0 +1,158 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/font_service/public/cpp/font_service_thread.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/files/file.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "components/font_service/public/cpp/mapped_font_file.h"
|
| +#include "mojo/common/message_pump_mojo.h"
|
| +#include "mojo/platform_handle/platform_handle_functions.h"
|
| +
|
| +namespace font_service {
|
| +namespace internal {
|
| +
|
| +namespace {
|
| +const char kFontThreadName[] = "Font_Proxy_Thread";
|
| +} // namespace
|
| +
|
| +FontServiceThread::FontServiceThread(FontServicePtr font_service)
|
| + : base::Thread(kFontThreadName),
|
| + font_service_info_(font_service.PassInterface().Pass()) {
|
| + base::Thread::Options options;
|
| + options.message_pump_factory =
|
| + base::Bind(&mojo::common::MessagePumpMojo::Create);
|
| + StartWithOptions(options);
|
| +}
|
| +
|
| +bool FontServiceThread::MatchFamilyName(
|
| + const char family_name[],
|
| + SkTypeface::Style requested_style,
|
| + SkFontConfigInterface::FontIdentity* out_font_identity,
|
| + SkString* out_family_name,
|
| + SkTypeface::Style* out_style) {
|
| + DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
|
| +
|
| + bool out_valid = false;
|
| + // This proxies to the other thread, which proxies to mojo. Only on the reply
|
| + // from mojo do we return from this.
|
| + base::WaitableEvent done_event(false, false);
|
| + task_runner()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&FontServiceThread::MatchFamilyNameImpl, this, &done_event,
|
| + family_name, requested_style, &out_valid, out_font_identity,
|
| + out_family_name, out_style));
|
| + done_event.Wait();
|
| +
|
| + return out_valid;
|
| +}
|
| +
|
| +scoped_refptr<MappedFontFile> FontServiceThread::OpenStream(
|
| + const SkFontConfigInterface::FontIdentity& identity) {
|
| + DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId());
|
| +
|
| + base::File stream_file;
|
| + // This proxies to the other thread, which proxies to mojo. Only on the reply
|
| + // from mojo do we return from this.
|
| + base::WaitableEvent done_event(false, false);
|
| + task_runner()->PostTask(FROM_HERE,
|
| + base::Bind(&FontServiceThread::OpenStreamImpl, this,
|
| + &done_event, &stream_file, identity.fID));
|
| + done_event.Wait();
|
| +
|
| + if (!stream_file.IsValid()) {
|
| + NOTREACHED();
|
| + return nullptr;
|
| + }
|
| +
|
| + // Converts the file to out internal type.
|
| + scoped_refptr<MappedFontFile> mapped_font_file =
|
| + new MappedFontFile(identity.fID);
|
| + if (!mapped_font_file->Initialize(stream_file.Pass()))
|
| + return nullptr;
|
| +
|
| + return mapped_font_file;
|
| +}
|
| +
|
| +FontServiceThread::~FontServiceThread() {
|
| + Stop();
|
| +}
|
| +
|
| +void FontServiceThread::MatchFamilyNameImpl(
|
| + base::WaitableEvent* done_event,
|
| + const char family_name[],
|
| + SkTypeface::Style requested_style,
|
| + bool* out_valid,
|
| + SkFontConfigInterface::FontIdentity* out_font_identity,
|
| + SkString* out_family_name,
|
| + SkTypeface::Style* out_style) {
|
| + DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
|
| +
|
| + font_service_->MatchFamilyName(
|
| + mojo::String(family_name), static_cast<TypefaceStyle>(requested_style),
|
| + base::Bind(&FontServiceThread::OnMatchFamilyNameComplete, this,
|
| + done_event, out_valid, out_font_identity, out_family_name,
|
| + out_style));
|
| +}
|
| +
|
| +void FontServiceThread::OnMatchFamilyNameComplete(
|
| + base::WaitableEvent* done_event,
|
| + bool* out_valid,
|
| + SkFontConfigInterface::FontIdentity* out_font_identity,
|
| + SkString* out_family_name,
|
| + SkTypeface::Style* out_style,
|
| + FontIdentityPtr font_identity,
|
| + mojo::String family_name,
|
| + TypefaceStyle style) {
|
| + DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
|
| +
|
| + *out_valid = font_identity;
|
| + if (font_identity) {
|
| + out_font_identity->fID = font_identity->id;
|
| + out_font_identity->fTTCIndex = font_identity->ttc_index;
|
| + out_font_identity->fString = font_identity->str_representation.data();
|
| + // TODO(erg): fStyle isn't set. This is rather odd, however it matches the
|
| + // behaviour of the current Linux IPC version.
|
| +
|
| + *out_family_name = family_name.data();
|
| + *out_style = static_cast<SkTypeface::Style>(style);
|
| + }
|
| +
|
| + done_event->Signal();
|
| +}
|
| +
|
| +void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event,
|
| + base::File* output_file,
|
| + const uint32_t id_number) {
|
| + DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
|
| +
|
| + font_service_->OpenStream(
|
| + id_number, base::Bind(&FontServiceThread::OnOpenStreamComplete, this,
|
| + done_event, output_file));
|
| +}
|
| +
|
| +void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event,
|
| + base::File* output_file,
|
| + mojo::ScopedHandle handle) {
|
| + if (handle.is_valid()) {
|
| + MojoPlatformHandle platform_handle;
|
| + CHECK(MojoExtractPlatformHandle(handle.release().value(),
|
| + &platform_handle) == MOJO_RESULT_OK);
|
| + *output_file = base::File(platform_handle).Pass();
|
| + }
|
| +
|
| + done_event->Signal();
|
| +}
|
| +
|
| +void FontServiceThread::Init() {
|
| + font_service_.Bind(font_service_info_.Pass());
|
| +}
|
| +
|
| +void FontServiceThread::CleanUp() {
|
| + font_service_.reset();
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace font_service
|
|
|