Skip to content

Commit

Permalink
libtxt: Skia font manager implementation for Fuchsia (flutter#4630)
Browse files Browse the repository at this point in the history
Based on the FontCacheFuchsia used in the Blink renderer
  • Loading branch information
jason-simmons authored Feb 2, 2018
1 parent d5338ed commit c375ff5
Show file tree
Hide file tree
Showing 5 changed files with 1,432 additions and 1,161 deletions.
3 changes: 3 additions & 0 deletions content_handler/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ template("flutter_content_handler") {
"app.h",
"application_controller_impl.cc",
"application_controller_impl.h",
"fuchsia_font_manager.cc",
"fuchsia_font_manager.h",
"main.cc",
"rasterizer.cc",
"rasterizer.h",
Expand Down Expand Up @@ -53,6 +55,7 @@ template("flutter_content_handler") {
"$flutter_root/lib/ui",
"$flutter_root/runtime",
"$flutter_root/sky/engine/platform",
"$flutter_root/third_party/txt",
"$flutter_root/vulkan",
"//garnet/public/lib/app/cpp",
"//garnet/public/lib/fsl",
Expand Down
10 changes: 9 additions & 1 deletion content_handler/app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/content_handler/fuchsia_font_manager.h"
#include "flutter/lib/ui/text/font_collection.h"
#include "flutter/sky/engine/platform/fonts/fuchsia/FontCacheFuchsia.h"
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fxl/macros.h"
Expand Down Expand Up @@ -67,8 +69,14 @@ App::App() {
settings.enable_dart_profiling = true;
blink::Settings::Set(settings);

blink::SetFontProvider(
fonts::FontProviderPtr font_provider(
context_->ConnectToEnvironmentService<fonts::FontProvider>());
if (settings.using_blink) {
blink::SetFontProvider(std::move(font_provider));
} else {
blink::FontCollection::ForProcess().GetFontCollection()->PushFront(
sk_make_sp<txt::FuchsiaFontManager>(std::move(font_provider)));
}

context_->outgoing_services()->AddService<app::ApplicationRunner>(
[this](fidl::InterfaceRequest<app::ApplicationRunner> request) {
Expand Down
168 changes: 168 additions & 0 deletions content_handler/fuchsia_font_manager.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "flutter/content_handler/fuchsia_font_manager.h"

#include <zx/vmar.h>

#include "lib/fsl/vmo/sized_vmo.h"
#include "lib/fxl/logging.h"
#include "txt/asset_font_style_set.h"

namespace txt {

namespace {

void UnmapMemory(const void* buffer, void* context) {
static_assert(sizeof(void*) == sizeof(uint64_t), "pointers aren't 64-bit");
const uint64_t size = reinterpret_cast<uint64_t>(context);
zx::vmar::root_self().unmap(reinterpret_cast<uintptr_t>(buffer), size);
}

sk_sp<SkData> MakeSkDataFromVMO(const fsl::SizedVmoTransportPtr& vmo) {
if (!fsl::SizedVmo::IsSizeValid(vmo->vmo, vmo->size) ||
vmo->size > std::numeric_limits<size_t>::max()) {
return nullptr;
}
uint64_t size = vmo->size;
uintptr_t buffer = 0;
zx_status_t status = zx::vmar::root_self().map(0, vmo->vmo, 0, size,
ZX_VM_FLAG_PERM_READ, &buffer);
if (status != ZX_OK)
return nullptr;
return SkData::MakeWithProc(reinterpret_cast<void*>(buffer), size,
UnmapMemory, reinterpret_cast<void*>(size));
}

fonts::FontSlant ToFontSlant(SkFontStyle::Slant slant) {
return (slant == SkFontStyle::kItalic_Slant) ? fonts::FontSlant::ITALIC
: fonts::FontSlant::UPRIGHT;
}

} // anonymous namespace

FuchsiaFontManager::FuchsiaFontManager(fonts::FontProviderPtr provider)
: font_provider_(std::move(provider)) {}

FuchsiaFontManager::~FuchsiaFontManager() = default;

int FuchsiaFontManager::onCountFamilies() const {
FXL_DCHECK(false);
return 0;
}

void FuchsiaFontManager::onGetFamilyName(int index, SkString* familyName) const {
FXL_DCHECK(false);
}

SkFontStyleSet* FuchsiaFontManager::onCreateStyleSet(int index) const {
FXL_DCHECK(false);
return nullptr;
}

SkFontStyleSet* FuchsiaFontManager::onMatchFamily(
const char family_name[]) const {
sk_sp<SkTypeface> typeface(onMatchFamilyStyle(family_name, SkFontStyle()));
if (!typeface)
return nullptr;

sk_sp<txt::AssetFontStyleSet> font_style_set(
sk_make_sp<txt::AssetFontStyleSet>());
font_style_set->registerTypeface(typeface);

return font_style_set.release();
}

SkTypeface* FuchsiaFontManager::onMatchFamilyStyle(
const char family_name[], const SkFontStyle& style) const {
auto request = fonts::FontRequest::New();
request->family = family_name;
request->weight = style.weight();
request->width = style.width();
request->slant = ToFontSlant(style.slant());

fonts::FontResponsePtr response;
font_provider_->GetFont(
std::move(request),
[&response](fonts::FontResponsePtr r) { response = std::move(r); });
font_provider_.WaitForResponse();

FXL_DCHECK(response)
<< "Unable to contact the font provider. Did you run "
"Flutter in an environment that has a font manager?\n";

if (!response)
return nullptr;

sk_sp<SkData> data = MakeSkDataFromVMO(response->data->vmo);
if (!data)
return nullptr;

sk_sp<SkTypeface> typeface =
SkFontMgr::RefDefault()->makeFromData(std::move(data));

return typeface.release();
}

SkTypeface* FuchsiaFontManager::onMatchFamilyStyleCharacter(
const char familyName[],
const SkFontStyle&,
const char* bcp47[],
int bcp47Count,
SkUnichar character) const {
return nullptr;
}

SkTypeface* FuchsiaFontManager::onMatchFaceStyle(const SkTypeface*,
const SkFontStyle&) const {
FXL_DCHECK(false);
return nullptr;
}

sk_sp<SkTypeface> FuchsiaFontManager::onMakeFromData(sk_sp<SkData>,
int ttcIndex) const {
FXL_DCHECK(false);
return nullptr;
}

sk_sp<SkTypeface> FuchsiaFontManager::onMakeFromStreamIndex(
std::unique_ptr<SkStreamAsset>,
int ttcIndex) const {
FXL_DCHECK(false);
return nullptr;
}

sk_sp<SkTypeface> FuchsiaFontManager::onMakeFromStreamArgs(
std::unique_ptr<SkStreamAsset>,
const SkFontArguments&) const {
FXL_DCHECK(false);
return nullptr;
}

sk_sp<SkTypeface> FuchsiaFontManager::onMakeFromFile(const char path[],
int ttcIndex) const {
FXL_DCHECK(false);
return nullptr;
}

sk_sp<SkTypeface> FuchsiaFontManager::onLegacyMakeTypeface(
const char familyName[],
SkFontStyle) const {
FXL_DCHECK(false);
return nullptr;
}

} // namespace txt
89 changes: 89 additions & 0 deletions content_handler/fuchsia_font_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef TXT_FUCHSIA_FONT_MANAGER_H_
#define TXT_FUCHSIA_FONT_MANAGER_H_

#include <memory>
#include "lib/fonts/fidl/font_provider.fidl.h"
#include "lib/fxl/macros.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/ports/SkFontMgr.h"

namespace txt {

class FuchsiaFontManager : public SkFontMgr {
public:
FuchsiaFontManager(fonts::FontProviderPtr provider);

~FuchsiaFontManager() override;

protected:
// |SkFontMgr|
int onCountFamilies() const override;

// |SkFontMgr|
void onGetFamilyName(int index, SkString* familyName) const override;

// |SkFontMgr|
SkFontStyleSet* onMatchFamily(const char familyName[]) const override;

// |SkFontMgr|
SkFontStyleSet* onCreateStyleSet(int index) const override;

// |SkFontMgr|
SkTypeface* onMatchFamilyStyle(const char familyName[],
const SkFontStyle&) const override;

// |SkFontMgr|
SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
const SkFontStyle&,
const char* bcp47[],
int bcp47Count,
SkUnichar character) const override;
// |SkFontMgr|
SkTypeface* onMatchFaceStyle(const SkTypeface*,
const SkFontStyle&) const override;

// |SkFontMgr|
sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override;

// |SkFontMgr|
sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
int ttcIndex) const override;

// |SkFontMgr|
sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
const SkFontArguments&) const override;

// |SkFontMgr|
sk_sp<SkTypeface> onMakeFromFile(const char path[],
int ttcIndex) const override;

// |SkFontMgr|
sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[],
SkFontStyle) const override;

FXL_DISALLOW_COPY_AND_ASSIGN(FuchsiaFontManager);

private:
mutable fonts::FontProviderPtr font_provider_;
};

} // namespace txt

#endif // TXT_FUCHSIA_FONT_MANAGER_H_
Loading

0 comments on commit c375ff5

Please sign in to comment.