diff options
Diffstat (limited to 'chromium/components/services/font/public')
5 files changed, 390 insertions, 33 deletions
diff --git a/chromium/components/services/font/public/cpp/font_loader.cc b/chromium/components/services/font/public/cpp/font_loader.cc index 618c22f73a8..4974393ebb4 100644 --- a/chromium/components/services/font/public/cpp/font_loader.cc +++ b/chromium/components/services/font/public/cpp/font_loader.cc @@ -9,13 +9,14 @@ #include "base/bind.h" #include "base/trace_event/trace_event.h" #include "components/services/font/public/cpp/font_service_thread.h" +#include "components/services/font/public/interfaces/constants.mojom.h" #include "services/service_manager/public/cpp/connector.h" namespace font_service { FontLoader::FontLoader(service_manager::Connector* connector) { mojom::FontServicePtr font_service; - connector->BindInterface("font_service", &font_service); + connector->BindInterface(font_service::mojom::kServiceName, &font_service); thread_ = new internal::FontServiceThread(std::move(font_service)); } @@ -66,6 +67,41 @@ SkStreamAsset* FontLoader::openStream(const FontIdentity& identity) { } } +// Additional cross-thread accessible methods. +bool FontLoader::FallbackFontForCharacter( + uint32_t character, + std::string locale, + mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic) { + return thread_->FallbackFontForCharacter(character, std::move(locale), + out_font_identity, out_family_name, + out_is_bold, out_is_italic); +} + +bool FontLoader::FontRenderStyleForStrike( + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + mojom::FontRenderStylePtr* out_font_render_style) { + return thread_->FontRenderStyleForStrike(std::move(family), size, is_italic, + is_bold, device_scale_factor, + out_font_render_style); +} + +void FontLoader::MatchFontWithFallback(std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallback_family_type, + base::File* out_font_file_handle) { + thread_->MatchFontWithFallback(std::move(family), is_bold, is_italic, charset, + fallback_family_type, out_font_file_handle); +} + void FontLoader::OnMappedFontFileDestroyed(internal::MappedFontFile* f) { TRACE_EVENT1("font_loader", "FontLoader::OnMappedFontFileDestroyed", "identity", f->font_id()); diff --git a/chromium/components/services/font/public/cpp/font_loader.h b/chromium/components/services/font/public/cpp/font_loader.h index 7f9d7d22e00..4eebdeac1f9 100644 --- a/chromium/components/services/font/public/cpp/font_loader.h +++ b/chromium/components/services/font/public/cpp/font_loader.h @@ -49,6 +49,35 @@ class FontLoader : public SkFontConfigInterface, SkFontStyle* out_style) override; SkStreamAsset* openStream(const FontIdentity& identity) override; + // Additional cross-thread accessible methods below. + + // Out parameters are only guaranteed to be initialized when method returns + // true. + bool FallbackFontForCharacter(uint32_t character, + std::string locale, + mojom::FontIdentityPtr* out_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic); + // Out parameters are only guaranteed to be initialized when method returns + // true. + bool FontRenderStyleForStrike( + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + mojom::FontRenderStylePtr* out_font_render_style); + // Out parameter out_font_file_handle should always be an opened file handle + // to a matched or default font file. out_font_file_handle is a default + // initialized base::File on error. + void MatchFontWithFallback(std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallbackFamilyType, + base::File* out_font_file_handle); + private: // internal::MappedFontFile::Observer: void OnMappedFontFileDestroyed(internal::MappedFontFile* f) override; diff --git a/chromium/components/services/font/public/cpp/font_service_thread.cc b/chromium/components/services/font/public/cpp/font_service_thread.cc index d1ecf77b032..b4f3aa45c34 100644 --- a/chromium/components/services/font/public/cpp/font_service_thread.cc +++ b/chromium/components/services/font/public/cpp/font_service_thread.cc @@ -22,6 +22,7 @@ FontServiceThread::FontServiceThread(mojom::FontServicePtr font_service) : base::Thread(kFontThreadName), font_service_info_(font_service.PassInterface()), weak_factory_(this) { + DETACH_FROM_THREAD(thread_checker_); Start(); } @@ -36,32 +37,85 @@ bool FontServiceThread::MatchFamilyName( 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( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); + base::WaitableEvent done_event; 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)); + base::BindOnce(&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; } +bool FontServiceThread::FallbackFontForCharacter( + uint32_t character, + std::string locale, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic) { + DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); + bool out_valid = false; + base::WaitableEvent done_event; + task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&FontServiceThread::FallbackFontForCharacterImpl, this, + &done_event, character, std::move(locale), &out_valid, + out_font_identity, out_family_name, out_is_bold, + out_is_italic)); + done_event.Wait(); + + return out_valid; +} + +bool FontServiceThread::FontRenderStyleForStrike( + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + font_service::mojom::FontRenderStylePtr* out_font_render_style) { + DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); + bool out_valid = false; + base::WaitableEvent done_event; + task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&FontServiceThread::FontRenderStyleForStrikeImpl, this, + &done_event, family, size, is_italic, is_bold, + device_scale_factor, &out_valid, out_font_render_style)); + done_event.Wait(); + return out_valid; +} + +void FontServiceThread::MatchFontWithFallback( + std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallback_family_type, + base::File* out_font_file_handle) { + DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); + base::WaitableEvent done_event; + task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&FontServiceThread::MatchFontWithFallbackImpl, this, + &done_event, std::move(family), is_bold, is_italic, + charset, fallback_family_type, out_font_file_handle)); + done_event.Wait(); +} + 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( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - task_runner()->PostTask(FROM_HERE, - base::Bind(&FontServiceThread::OpenStreamImpl, this, - &done_event, &stream_file, identity.fID)); + // 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; + task_runner()->PostTask( + FROM_HERE, base::BindOnce(&FontServiceThread::OpenStreamImpl, this, + &done_event, &stream_file, identity.fID)); done_event.Wait(); if (!stream_file.IsValid()) { @@ -79,6 +133,7 @@ scoped_refptr<MappedFontFile> FontServiceThread::OpenStream( } FontServiceThread::~FontServiceThread() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); Stop(); } @@ -90,7 +145,7 @@ void FontServiceThread::MatchFamilyNameImpl( SkFontConfigInterface::FontIdentity* out_font_identity, SkString* out_family_name, SkFontStyle* out_style) { - DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (font_service_.encountered_error()) { *out_valid = false; @@ -103,12 +158,14 @@ void FontServiceThread::MatchFamilyNameImpl( style->width = requested_style.width(); style->slant = static_cast<mojom::TypefaceSlant>(requested_style.slant()); + const char* arg_family = family_name ? family_name : ""; + pending_waitable_events_.insert(done_event); font_service_->MatchFamilyName( - family_name, std::move(style), - base::Bind(&FontServiceThread::OnMatchFamilyNameComplete, this, - done_event, out_valid, out_font_identity, out_family_name, - out_style)); + arg_family, std::move(style), + base::BindOnce(&FontServiceThread::OnMatchFamilyNameComplete, this, + done_event, out_valid, out_font_identity, out_family_name, + out_style)); } void FontServiceThread::OnMatchFamilyNameComplete( @@ -120,7 +177,7 @@ void FontServiceThread::OnMatchFamilyNameComplete( mojom::FontIdentityPtr font_identity, const std::string& family_name, mojom::TypefaceStylePtr style) { - DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); pending_waitable_events_.erase(done_event); *out_valid = !font_identity.is_null(); @@ -142,7 +199,7 @@ void FontServiceThread::OnMatchFamilyNameComplete( void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event, base::File* output_file, const uint32_t id_number) { - DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (font_service_.encountered_error()) { done_event->Signal(); return; @@ -150,18 +207,139 @@ void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event, pending_waitable_events_.insert(done_event); font_service_->OpenStream( - id_number, base::Bind(&FontServiceThread::OnOpenStreamComplete, this, - done_event, output_file)); + id_number, base::BindOnce(&FontServiceThread::OnOpenStreamComplete, this, + done_event, output_file)); } void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event, base::File* output_file, base::File file) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); pending_waitable_events_.erase(done_event); *output_file = std::move(file); done_event->Signal(); } +void FontServiceThread::FallbackFontForCharacterImpl( + base::WaitableEvent* done_event, + uint32_t character, + std::string locale, + bool* out_valid, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (font_service_.encountered_error()) { + *out_valid = false; + done_event->Signal(); + return; + } + + pending_waitable_events_.insert(done_event); + font_service_->FallbackFontForCharacter( + character, std::move(locale), + base::BindOnce(&FontServiceThread::OnFallbackFontForCharacterComplete, + this, done_event, out_valid, out_font_identity, + out_family_name, out_is_bold, out_is_italic)); +} + +void FontServiceThread::OnFallbackFontForCharacterComplete( + base::WaitableEvent* done_event, + bool* out_valid, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic, + mojom::FontIdentityPtr font_identity, + const std::string& family_name, + bool is_bold, + bool is_italic) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + pending_waitable_events_.erase(done_event); + + *out_valid = !font_identity.is_null(); + if (font_identity) { + *out_font_identity = std::move(font_identity); + *out_family_name = family_name.data(); + *out_is_bold = is_bold; + *out_is_italic = is_italic; + } + done_event->Signal(); +} + +void FontServiceThread::FontRenderStyleForStrikeImpl( + base::WaitableEvent* done_event, + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + bool* out_valid, + mojom::FontRenderStylePtr* out_font_render_style) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + if (font_service_.encountered_error()) { + *out_valid = false; + done_event->Signal(); + return; + } + + pending_waitable_events_.insert(done_event); + font_service_->FontRenderStyleForStrike( + std::move(family), size, is_italic, is_bold, device_scale_factor, + base::BindOnce(&FontServiceThread::OnFontRenderStyleForStrikeComplete, + this, done_event, out_valid, out_font_render_style)); +} + +void FontServiceThread::OnFontRenderStyleForStrikeComplete( + base::WaitableEvent* done_event, + bool* out_valid, + mojom::FontRenderStylePtr* out_font_render_style, + mojom::FontRenderStylePtr font_render_style) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + pending_waitable_events_.erase(done_event); + + *out_valid = !font_render_style.is_null(); + if (font_render_style) { + *out_font_render_style = std::move(font_render_style); + } + done_event->Signal(); +} + +void FontServiceThread::MatchFontWithFallbackImpl( + base::WaitableEvent* done_event, + std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallback_family_type, + base::File* out_font_file_handle) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + *out_font_file_handle = base::File(); + if (font_service_.encountered_error()) { + done_event->Signal(); + return; + } + pending_waitable_events_.insert(done_event); + font_service_->MatchFontWithFallback( + family, is_bold, is_italic, charset, fallback_family_type, + base::BindOnce(&FontServiceThread::OnMatchFontWithFallbackComplete, this, + done_event, out_font_file_handle)); +} + +void FontServiceThread::OnMatchFontWithFallbackComplete( + base::WaitableEvent* done_event, + base::File* out_font_file_handle, + base::File file) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + pending_waitable_events_.erase(done_event); + + *out_font_file_handle = std::move(file); + done_event->Signal(); +} + void FontServiceThread::OnFontServiceConnectionError() { std::set<base::WaitableEvent*> events; events.swap(pending_waitable_events_); @@ -172,8 +350,8 @@ void FontServiceThread::OnFontServiceConnectionError() { void FontServiceThread::Init() { font_service_.Bind(std::move(font_service_info_)); font_service_.set_connection_error_handler( - base::Bind(&FontServiceThread::OnFontServiceConnectionError, - weak_factory_.GetWeakPtr())); + base::BindOnce(&FontServiceThread::OnFontServiceConnectionError, + weak_factory_.GetWeakPtr())); } void FontServiceThread::CleanUp() { diff --git a/chromium/components/services/font/public/cpp/font_service_thread.h b/chromium/components/services/font/public/cpp/font_service_thread.h index 2069a290492..865c587b398 100644 --- a/chromium/components/services/font/public/cpp/font_service_thread.h +++ b/chromium/components/services/font/public/cpp/font_service_thread.h @@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" +#include "base/threading/thread_checker.h" #include "components/services/font/public/interfaces/font_service.mojom.h" #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypeface.h" @@ -45,6 +46,27 @@ class FontServiceThread : public base::Thread, scoped_refptr<MappedFontFile> OpenStream( const SkFontConfigInterface::FontIdentity& identity); + bool FallbackFontForCharacter( + uint32_t character, + std::string locale, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic); + bool FontRenderStyleForStrike( + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + font_service::mojom::FontRenderStylePtr* out_font_render_style); + void MatchFontWithFallback(std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallbackFamilyType, + base::File* out_font_file_handle); + private: friend class base::RefCountedThreadSafe<FontServiceThread>; ~FontServiceThread() override; @@ -82,6 +104,53 @@ class FontServiceThread : public base::Thread, base::File* output_file, base::File file); + void FallbackFontForCharacterImpl( + base::WaitableEvent* done_event, + uint32_t character, + std::string locale, + bool* out_is_valid, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic); + void OnFallbackFontForCharacterComplete( + base::WaitableEvent* done_event, + bool* out_valid, + font_service::mojom::FontIdentityPtr* out_font_identity, + std::string* out_family_name, + bool* out_is_bold, + bool* out_is_italic, + mojom::FontIdentityPtr font_identity, + const std::string& family_name, + bool is_bold, + bool is_italic); + + void FontRenderStyleForStrikeImpl( + base::WaitableEvent* done_event, + std::string family, + uint32_t size, + bool is_italic, + bool is_bold, + float device_scale_factor, + bool* out_valid, + mojom::FontRenderStylePtr* out_font_render_style); + void OnFontRenderStyleForStrikeComplete( + base::WaitableEvent* done_event, + bool* out_valid, + mojom::FontRenderStylePtr* out_font_render_style, + mojom::FontRenderStylePtr font_render_style); + + void MatchFontWithFallbackImpl(base::WaitableEvent* done_event, + std::string family, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallbackFamilyType, + base::File* out_font_file_handle); + void OnMatchFontWithFallbackComplete(base::WaitableEvent* done_event, + base::File* out_font_file_handle, + base::File file); + // Connection to |font_service_| has gone away. Called on the background // thread. void OnFontServiceConnectionError(); @@ -98,14 +167,17 @@ class FontServiceThread : public base::Thread, // non-thread bound, and binds it to the newly created thread. mojo::InterfacePtr<mojom::FontService> font_service_; - // All WaitableEvents supplied to OpenStreamImpl() are added here while - // waiting on the response from the |font_service_| (FontService::OpenStream() - // was called, but the callback has not been processed yet). If - // |font_service_| gets an error during this time all events in - // |pending_waitable_events_| are signaled. This is necessary as when the - // pipe is closed the callbacks are never received. + // All WaitableEvents supplied to OpenStreamImpl() and the other *Impl() + // functions are added here while waiting on the response from the + // |font_service_| (FontService::OpenStream() or other such functions were + // called, but the callbacks have not been processed yet). If |font_service_| + // gets an error during this time all events in |pending_waitable_events_| are + // signaled. This is necessary as when the pipe is closed the callbacks are + // never received. std::set<base::WaitableEvent*> pending_waitable_events_; + THREAD_CHECKER(thread_checker_); + base::WeakPtrFactory<FontServiceThread> weak_factory_; DISALLOW_COPY_AND_ASSIGN(FontServiceThread); diff --git a/chromium/components/services/font/public/interfaces/font_service.mojom b/chromium/components/services/font/public/interfaces/font_service.mojom index 6359889efd3..346499fe414 100644 --- a/chromium/components/services/font/public/interfaces/font_service.mojom +++ b/chromium/components/services/font/public/interfaces/font_service.mojom @@ -30,7 +30,26 @@ struct FontIdentity { string str_representation; }; -// Loads and resolves fonts. +enum RenderStyleSwitch { + OFF = 0, + ON = 1, + NO_PREFERENCE = 2, +}; + +struct FontRenderStyle { + RenderStyleSwitch use_bitmaps; // use embedded bitmap strike if possible + RenderStyleSwitch use_autohint; // use 'auto' hinting (FreeType specific) + RenderStyleSwitch use_hinting; // hint glyphs to the pixel grid + uint8 hint_style; // level of hinting, 0..3 + RenderStyleSwitch use_antialias; // antialias glyph shapes + // use subpixel rendering (partially-filled pixels) + RenderStyleSwitch use_subpixel_rendering; + // use subpixel positioning (fractional X positions for glyphs) + RenderStyleSwitch use_subpixel_positioning; +}; + +// Loads and resolves fonts & returns additional information accessible from +// FontConfig only outside the sandbox. // // We still need to load fonts from within a sandboxed process. We set // up a service to match fonts and load them. This service needs full @@ -45,4 +64,27 @@ interface FontService { // Returns a handle to the raw font specified by |id_number|. OpenStream(uint32 id_number) => (mojo_base.mojom.File? font_handle); + + // Returns a fallback FontIdentity and Typeface style for the given character + // and locale. If no fallback font can be found, returns a null identity. + FallbackFontForCharacter(uint32 character, string locale) => + (FontIdentity? identity, + string family_name, + bool is_bold, + bool is_italic); + + // Fill out the given WebFontRenderStyle with the user's preferences for + // rendering the given font at the given size (in pixels), given weight + // (is_bold or not), and given slant (is_italic or not). + FontRenderStyleForStrike(string family, + uint32 size, + bool is_italic, + bool is_bold, + float device_scale_factor) => + (FontRenderStyle? font_render_style); + + // PPAPI Specific font call to match a font family and charset. + MatchFontWithFallback(string family, bool is_bold, bool is_italic, + uint32 charset, uint32 fallback_family_type) => + (mojo_base.mojom.File? font_file_handle); }; |