未验证 提交 aadd5a34 编写于 作者: C chunhtai 提交者: GitHub

Add system font change listener for windows (#12276)

* Add windows font change logic

* update

* fix comment
上级 eea7dd45
......@@ -1036,6 +1036,7 @@ FILE: ../../../flutter/third_party/txt/src/txt/platform_android.cc
FILE: ../../../flutter/third_party/txt/src/txt/platform_fuchsia.cc
FILE: ../../../flutter/third_party/txt/src/txt/platform_linux.cc
FILE: ../../../flutter/third_party/txt/src/txt/platform_mac.mm
FILE: ../../../flutter/third_party/txt/src/txt/platform_windows.cc
FILE: ../../../flutter/vulkan/vulkan_application.cc
FILE: ../../../flutter/vulkan/vulkan_application.h
FILE: ../../../flutter/vulkan/vulkan_backbuffer.cc
......
......@@ -26,6 +26,8 @@
#include "flutter/shell/common/skia_event_tracer_impl.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/common/vsync_waiter.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/tonic/common/log.h"
......@@ -33,6 +35,9 @@
namespace flutter {
constexpr char kSkiaChannel[] = "flutter/skia";
constexpr char kSystemChannel[] = "flutter/system";
constexpr char kTypeKey[] = "type";
constexpr char kFontChange[] = "fontsChange";
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
DartVMRef vm,
......@@ -1351,4 +1356,35 @@ fml::Status Shell::WaitForFirstFrame(fml::TimeDelta timeout) {
}
}
bool Shell::ReloadSystemFonts() {
FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
if (!engine_) {
return false;
}
engine_->GetFontCollection().GetFontCollection()->SetupDefaultFontManager();
engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
// After system fonts are reloaded, we send a system channel message
// to notify flutter framework.
rapidjson::Document document;
document.SetObject();
auto& allocator = document.GetAllocator();
rapidjson::Value message_value;
message_value.SetString(kFontChange, allocator);
document.AddMember(kTypeKey, message_value, allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
std::string message = buffer.GetString();
fml::RefPtr<PlatformMessage> fontsChangeMessage =
fml::MakeRefCounted<flutter::PlatformMessage>(
kSystemChannel, std::vector<uint8_t>(message.begin(), message.end()),
nullptr);
OnPlatformViewDispatchPlatformMessage(fontsChangeMessage);
return true;
}
} // namespace flutter
......@@ -284,6 +284,16 @@ class Shell final : public PlatformView::Delegate,
///
fml::Status WaitForFirstFrame(fml::TimeDelta timeout);
//----------------------------------------------------------------------------
/// @brief Used by embedders to reload the system fonts in
/// FontCollection.
/// It also clears the cached font families and send system
/// channel message to framework to rebuild affected widgets.
///
/// @return Returns if shell reloads system fonts successfully.
///
bool ReloadSystemFonts();
//----------------------------------------------------------------------------
/// @brief Used by embedders to get the last error from the Dart UI
/// Isolate, if one exists.
......
......@@ -144,6 +144,11 @@ bool ShellTest::GetNeedsReportTimings(Shell* shell) {
return shell->needs_report_timings_;
}
std::shared_ptr<txt::FontCollection> ShellTest::GetFontCollection(
Shell* shell) {
return shell->weak_engine_->GetFontCollection().GetFontCollection();
}
Settings ShellTest::CreateSettingsForFixture() {
Settings settings;
settings.leak_vm = false;
......
......@@ -51,6 +51,8 @@ class ShellTest : public ThreadTest {
static bool GetNeedsReportTimings(Shell* shell);
static void SetNeedsReportTimings(Shell* shell, bool value);
std::shared_ptr<txt::FontCollection> GetFontCollection(Shell* shell);
// Do not assert |UnreportedTimingsCount| to be positive in any tests.
// Otherwise those tests will be flaky as the clearing of unreported timings
// is unpredictive.
......
......@@ -519,6 +519,36 @@ TEST_F(ShellTest, ReportTimingsIsCalledImmediatelyAfterTheFirstFrame) {
ASSERT_EQ(timestamps.size(), FrameTiming::kCount);
}
TEST_F(ShellTest, ReloadSystemFonts) {
auto settings = CreateSettingsForFixture();
fml::MessageLoop::EnsureInitializedForCurrentThread();
auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
auto shell = CreateShell(std::move(settings), std::move(task_runners));
auto fontCollection = GetFontCollection(shell.get());
std::vector<std::string> families(1, "Robotofake");
auto font =
fontCollection->GetMinikinFontCollectionForFamilies(families, "en");
if (font == nullptr) {
// The system does not have default font. Aborts this test.
return;
}
unsigned int id = font->getId();
// The result should be cached.
font = fontCollection->GetMinikinFontCollectionForFamilies(families, "en");
ASSERT_EQ(font->getId(), id);
bool result = shell->ReloadSystemFonts();
// The cache is cleared, and FontCollection will be assigned a new id.
font = fontCollection->GetMinikinFontCollectionForFamilies(families, "en");
ASSERT_NE(font->getId(), id);
ASSERT_TRUE(result);
shell.reset();
}
TEST_F(ShellTest, WaitForFirstFrame) {
auto settings = CreateSettingsForFixture();
std::unique_ptr<Shell> shell = CreateShell(settings);
......
......@@ -1279,6 +1279,22 @@ FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine)
return kSuccess;
}
FlutterEngineResult FlutterEngineReloadSystemFonts(
FLUTTER_API_SYMBOL(FlutterEngine) engine) {
if (engine == nullptr) {
return LOG_EMBEDDER_ERROR(kInvalidArguments);
}
TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");
if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
->ReloadSystemFonts()) {
return LOG_EMBEDDER_ERROR(kInternalInconsistency);
}
return kSuccess;
}
void FlutterEngineTraceEventDurationBegin(const char* name) {
fml::tracing::TraceEvent0("flutter", name);
}
......
......@@ -1200,6 +1200,17 @@ FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine)
uint64_t frame_start_time_nanos,
uint64_t frame_target_time_nanos);
//------------------------------------------------------------------------------
/// @brief Reloads the system fonts in engine.
///
/// @param[in] engine. A running engine instance.
///
/// @return The result of the call.
///
FLUTTER_EXPORT
FlutterEngineResult FlutterEngineReloadSystemFonts(
FLUTTER_API_SYMBOL(FlutterEngine) engine);
//------------------------------------------------------------------------------
/// @brief A profiling utility. Logs a trace duration begin event to the
/// timeline. If the timeline is unavailable or disabled, this has
......
......@@ -186,6 +186,10 @@ bool EmbedderEngine::OnVsyncEvent(intptr_t baton,
frame_target_time);
}
bool EmbedderEngine::ReloadSystemFonts() {
return shell_->ReloadSystemFonts();
}
bool EmbedderEngine::PostRenderThreadTask(fml::closure task) {
if (!IsValid()) {
return false;
......
......@@ -67,6 +67,8 @@ class EmbedderEngine {
fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time);
bool ReloadSystemFonts();
bool PostRenderThreadTask(fml::closure task);
bool RunTask(const FlutterTask* task);
......
......@@ -235,6 +235,17 @@ TEST(EmbedderTestNoFixture, CanGetCurrentTimeInNanoseconds) {
ASSERT_LT((point2 - point1), fml::TimeDelta::FromMilliseconds(1));
}
TEST_F(EmbedderTest, CanReloadSystemFonts) {
auto& context = GetEmbedderContext();
EmbedderConfigBuilder builder(context);
builder.SetSoftwareRendererConfig();
auto engine = builder.LaunchEngine();
ASSERT_TRUE(engine.is_valid());
auto result = FlutterEngineReloadSystemFonts(engine.get());
ASSERT_EQ(result, kSuccess);
}
TEST_F(EmbedderTest, CanCreateOpenGLRenderingEngine) {
EmbedderConfigBuilder builder(GetEmbedderContext());
builder.SetOpenGLRendererConfig(SkISize::Make(1, 1));
......
......@@ -147,6 +147,13 @@ void Win32FlutterWindow::OnClose() {
messageloop_running_ = false;
}
void Win32FlutterWindow::OnFontChange() {
if (engine_ == nullptr) {
return;
}
FlutterEngineReloadSystemFonts(engine_);
}
// Sends new size information to FlutterEngine.
void Win32FlutterWindow::SendWindowMetrics() {
if (engine_ == nullptr) {
......
......@@ -65,6 +65,9 @@ class Win32FlutterWindow : public Win32Window {
// |Win32Window|
void OnClose();
// |Win32Window|
void OnFontChange() override;
// Configures the window instance with an instance of a running Flutter engine
// returning a configured FlutterDesktopWindowControllerRef.
void SetState(FLUTTER_API_SYMBOL(FlutterEngine) state);
......
......@@ -129,7 +129,9 @@ Win32Window::MessageHandler(HWND hwnd,
current_height_ = height;
window->HandleResize(width, height);
break;
case WM_FONTCHANGE:
window->OnFontChange();
break;
case WM_MOUSEMOVE:
xPos = GET_X_LPARAM(lparam);
yPos = GET_Y_LPARAM(lparam);
......
......@@ -97,9 +97,12 @@ class Win32Window {
// Called when mouse scrollwheel input occurs.
virtual void OnScroll(double delta_x, double delta_y) = 0;
// Called when the user closes the Windows
// Called when the user closes the Windows.
virtual void OnClose() = 0;
// Called when the system font change.
virtual void OnFontChange() = 0;
UINT GetCurrentDPI();
UINT GetCurrentWidth();
......
......@@ -160,6 +160,8 @@ source_set("txt") {
sources += [ "src/txt/platform_linux.cc" ]
} else if (is_fuchsia) {
sources += [ "src/txt/platform_fuchsia.cc" ]
} else if (is_win) {
sources += [ "src/txt/platform_windows.cc" ]
} else {
sources += [ "src/txt/platform.cc" ]
}
......
// Copyright 2013 The Flutter 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 "third_party/skia/include/ports/SkTypeface_win.h"
#include "txt/platform.h"
namespace txt {
std::string GetDefaultFontFamily() {
return "Arial";
}
sk_sp<SkFontMgr> GetDefaultFontManager() {
return SkFontMgr_New_DirectWrite();
}
} // namespace txt
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册