10#include <fuchsia/fonts/cpp/fidl.h>
11#include <lib/zx/vmar.h>
14#include <unordered_map>
38 struct ReleaseSkDataContext {
43 static void ReleaseSkData(
const void*
buffer,
void* context);
44 void OnBufferDeleted(
int bufferId);
47 std::unordered_map<int, SkData*> fBuffers
SK_GUARDED_BY(fMutex);
51 const fuchsia::mem::Buffer&
buffer) {
54 auto iter = fBuffers.find(bufferId);
55 if (iter != fBuffers.end()) {
60 uint64_t size =
buffer.size;
61 uintptr_t mapped_addr = 0;
63 zx::vmar::root_self()->map(ZX_VM_PERM_READ, 0,
buffer.vmo, 0, size, &mapped_addr);
64 if (status != ZX_OK)
return nullptr;
66 auto context =
new ReleaseSkDataContext{
sk_ref_sp(
this), bufferId};
68 reinterpret_cast<void*
>(mapped_addr), size, ReleaseSkData, context);
71 fBuffers[bufferId] = data.get();
75void SkFuchsiaFontDataCache::OnBufferDeleted(
int bufferId) {
76 zx_vaddr_t unmap_addr;
80 auto it = fBuffers.find(bufferId);
82 unmap_addr =
reinterpret_cast<zx_vaddr_t
>(it->second->data());
83 unmap_size = it->second->size();
87 zx::vmar::root_self()->unmap(unmap_addr, unmap_size);
91void SkFuchsiaFontDataCache::ReleaseSkData(
const void*
buffer,
void* context) {
92 auto releaseSkDataContext =
reinterpret_cast<ReleaseSkDataContext*
>(context);
93 releaseSkDataContext->fCache->OnBufferDeleted(releaseSkDataContext->fBufferId);
94 delete releaseSkDataContext;
100 return fuchsia::fonts::Slant::OBLIQUE;
102 return fuchsia::fonts::Slant::ITALIC;
105 return fuchsia::fonts::Slant::UPRIGHT;
111 case fuchsia::fonts::Slant::OBLIQUE:
113 case fuchsia::fonts::Slant::ITALIC:
115 case fuchsia::fonts::Slant::UPRIGHT:
124 return fuchsia::fonts::Width::ULTRA_CONDENSED;
126 return fuchsia::fonts::Width::EXTRA_CONDENSED;
128 return fuchsia::fonts::Width::CONDENSED;
130 return fuchsia::fonts::Width::SEMI_CONDENSED;
132 return fuchsia::fonts::Width::NORMAL;
134 return fuchsia::fonts::Width::SEMI_EXPANDED;
136 return fuchsia::fonts::Width::EXPANDED;
138 return fuchsia::fonts::Width::EXTRA_EXPANDED;
140 return fuchsia::fonts::Width::ULTRA_EXPANDED;
159 case fuchsia::fonts::Width::ULTRA_CONDENSED:
161 case fuchsia::fonts::Width::EXTRA_CONDENSED:
163 case fuchsia::fonts::Width::CONDENSED:
165 case fuchsia::fonts::Width::SEMI_CONDENSED:
167 case fuchsia::fonts::Width::NORMAL:
169 case fuchsia::fonts::Width::SEMI_EXPANDED:
171 case fuchsia::fonts::Width::EXPANDED:
173 case fuchsia::fonts::Width::EXTRA_EXPANDED:
175 case fuchsia::fonts::Width::ULTRA_EXPANDED:
181 fuchsia::fonts::Style2 fuchsiaStyle;
184 fuchsia::fonts::Width fuchsiaWidth = fuchsia::fonts::Width::NORMAL;
186 fuchsiaStyle.set_width(fuchsiaWidth);
196 {
"sans", fuchsia::fonts::GenericFontFamily::SANS_SERIF},
197 {
"sans-serif", fuchsia::fonts::GenericFontFamily::SANS_SERIF},
198 {
"mono", fuchsia::fonts::GenericFontFamily::MONOSPACE},
199 {
"monospace", fuchsia::fonts::GenericFontFamily::MONOSPACE},
200 {
"cursive", fuchsia::fonts::GenericFontFamily::CURSIVE},
201 {
"fantasy", fuchsia::fonts::GenericFontFamily::FANTASY},
202 {
"system-ui", fuchsia::fonts::GenericFontFamily::SYSTEM_UI},
203 {
"emoji", fuchsia::fonts::GenericFontFamily::EMOJI},
204 {
"math", fuchsia::fonts::GenericFontFamily::MATH},
205 {
"fangsong", fuchsia::fonts::GenericFontFamily::FANGSONG}};
209 fuchsia::fonts::GenericFontFamily* outGenericFamily) {
210 if (!
name)
return false;
212 if (strcasecmp(genericFamily.fName,
name) == 0) {
213 *outGenericFamily = genericFamily.fGenericFontFamily;
248 if (!fontScanner.
scanFace(stream.get(),
args.getCollectionIndex(), &numInstances)) {
256 args.getCollectionIndex(),
269 auto fontData = std::make_unique<SkFontData>(
270 std::move(stream),
args.getCollectionIndex(),
args.getPalette().index,
271 axisValues.
get(), axisDefinitions.
size(),
272 args.getPalette().overrides,
args.getPalette().overrideCount);
273 return sk_make_sp<SkTypeface_Fuchsia>(std::move(fontData), style, isFixedPitch,
name,
id);
294 const char* bcp47[],
int bcp47Count,
298 int ttcIndex)
const override;
309 bool allow_fallback,
bool exact_style_match)
const;
313 mutable fuchsia::fonts::ProviderSyncPtr fFontProvider;
317 mutable SkMutex fCacheMutex;
324 std::vector<SkFontStyle> styles)
325 : fFontManager(font_manager), fFamilyName(familyName), fStyles(styles) {}
329 int count()
override {
return fStyles.size(); }
332 SkASSERT(index >= 0 && index <
static_cast<int>(fStyles.size()));
333 if (style) *style = fStyles[index];
336 if (styleName) styleName->
reset();
340 SkASSERT(index >= 0 && index <
static_cast<int>(fStyles.size()));
342 if (fTypefaces.empty()) fTypefaces.resize(fStyles.size());
344 if (!fTypefaces[index]) {
345 fTypefaces[index] = fFontManager->FetchTypeface(
346 fFamilyName.c_str(), fStyles[index],
nullptr,
351 return fTypefaces[index];
360 std::string fFamilyName;
361 std::vector<SkFontStyle> fStyles;
362 std::vector<sk_sp<SkTypeface>> fTypefaces;
386 fuchsia::fonts::FamilyName typedFamilyName;
387 typedFamilyName.name = familyName;
389 fuchsia::fonts::FontFamilyInfo familyInfo;
390 int result = fFontProvider->GetFontFamilyInfo(typedFamilyName, &familyInfo);
391 if (
result != ZX_OK || !familyInfo.has_styles() || familyInfo.styles().empty())
return nullptr;
393 std::vector<SkFontStyle> styles;
394 for (
auto& style : familyInfo.styles()) {
405 return FetchTypeface(familyName, style,
nullptr, 0, 0,
411 const char* bcp47[],
int bcp47Count,
414 return FetchTypeface(familyName, style, bcp47, bcp47Count,
character,
419 return makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
423 int ttcIndex)
const {
433 return makeFromStream(std::make_unique<SkFILEStream>(path), ttcIndex);
445 bool exact_style_match)
const {
446 fuchsia::fonts::TypefaceQuery query;
449 if (bcp47Count > 0) {
450 std::vector<fuchsia::intl::LocaleId> languages{};
451 for (
int i = 0; i < bcp47Count; i++) {
452 fuchsia::intl::LocaleId localeId;
453 localeId.id = bcp47[i];
454 languages.push_back(localeId);
456 query.set_languages(std::move(languages));
460 query.set_code_points({
static_cast<uint32_t
>(
character)});
465 fuchsia::fonts::GenericFontFamily genericFontFamily =
466 fuchsia::fonts::GenericFontFamily::SANS_SERIF;
468 if (!familyName || *familyName ==
'\0' || isGenericFontFamily) {
469 if (isGenericFontFamily) {
470 query.set_fallback_family(genericFontFamily);
472 allow_fallback =
true;
474 fuchsia::fonts::FamilyName typedFamilyName{};
475 typedFamilyName.name = familyName;
476 query.set_family(typedFamilyName);
479 fuchsia::fonts::TypefaceRequestFlags
flags{};
480 if (!allow_fallback)
flags |= fuchsia::fonts::TypefaceRequestFlags::EXACT_FAMILY;
481 if (exact_style_match)
flags |= fuchsia::fonts::TypefaceRequestFlags::EXACT_STYLE;
483 fuchsia::fonts::TypefaceRequest request;
484 request.set_query(std::move(query));
485 request.set_flags(
flags);
487 fuchsia::fonts::TypefaceResponse response;
488 int result = fFontProvider->GetTypeface(std::move(request), &response);
489 if (
result != ZX_OK)
return nullptr;
492 if (response.IsEmpty())
return nullptr;
494 return GetOrCreateTypeface(
TypefaceId{response.buffer_id(), response.font_index()},
502 return cachedFuchsiaTypeface->
id() == *
id;
506 const fuchsia::mem::Buffer&
buffer)
const {
510 if (cached)
return cached;
513 if (!data)
return nullptr;
516 fTypefaceCache.add(
result);
521 return sk_make_sp<SkFontMgr_Fuchsia>(std::move(provider));
static bool FindByTypefaceId(SkTypeface *cachedTypeface, void *ctx)
constexpr struct @426 kGenericFontFamiliesByName[]
struct TypefaceId kNullTypefaceId
sk_sp< SkFontMgr > SkFontMgr_New_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider)
SkFontStyle::Slant FuchsiaToSkSlant(fuchsia::fonts::Slant slant)
sk_sp< SkTypeface > CreateTypefaceFromSkStream(std::unique_ptr< SkStreamAsset > stream, const SkFontArguments &args, TypefaceId id)
fuchsia::fonts::GenericFontFamily fGenericFontFamily
bool GetGenericFontFamilyByName(const char *name, fuchsia::fonts::GenericFontFamily *outGenericFamily)
fuchsia::fonts::Slant SkToFuchsiaSlant(SkFontStyle::Slant slant)
sk_sp< SkTypeface > CreateTypefaceFromSkData(sk_sp< SkData > data, TypefaceId id)
fuchsia::fonts::Style2 SkToFuchsiaStyle(const SkFontStyle &style)
SkFontStyle::Width FuchsiaToSkWidth(fuchsia::fonts::Width width)
fuchsia::fonts::Width SkToFuchsiaWidth(SkFontStyle::Width width)
sk_sp< T > sk_make_sp(Args &&... args)
sk_sp< T > sk_ref_sp(T *obj)
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
~SkFontMgr_Fuchsia() override
friend class SkFontStyleSet_Fuchsia
sk_sp< SkFontStyleSet > onMatchFamily(const char familyName[]) const override
sk_sp< SkTypeface > onMakeFromStreamArgs(std::unique_ptr< SkStreamAsset >, const SkFontArguments &) const override
void onGetFamilyName(int index, SkString *familyName) const override
SkFontMgr_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider)
sk_sp< SkTypeface > onMatchFamilyStyle(const char familyName[], const SkFontStyle &) const override
int onCountFamilies() const override
sk_sp< SkFontStyleSet > onCreateStyleSet(int index) const override
sk_sp< SkTypeface > onMakeFromStreamIndex(std::unique_ptr< SkStreamAsset >, int ttcIndex) const override
sk_sp< SkTypeface > onMakeFromData(sk_sp< SkData >, int ttcIndex) const override
sk_sp< SkTypeface > onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, const char *bcp47[], int bcp47Count, SkUnichar character) const override
sk_sp< SkTypeface > onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override
sk_sp< SkTypeface > onMakeFromFile(const char path[], int ttcIndex) const override
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
sk_sp< SkTypeface > matchFamilyStyle(const char familyName[], const SkFontStyle &) const
bool scanFace(SkStreamAsset *stream, int faceIndex, int *numInstances) const override
static void computeAxisValues(AxisDefinitions axisDefinitions, const SkFontArguments::VariationPosition position, SkFixed *axisValues, const SkString &name, SkFontStyle *style, const SkFontArguments::VariationPosition::Coordinate *currentPosition=nullptr)
bool scanInstance(SkStreamAsset *stream, int faceIndex, int instanceIndex, SkString *name, SkFontStyle *style, bool *isFixedPitch, AxisDefinitions *axes) const override
void getStyle(int index, SkFontStyle *style, SkString *styleName) override
SkFontStyleSet_Fuchsia(sk_sp< SkFontMgr_Fuchsia > font_manager, std::string familyName, std::vector< SkFontStyle > styles)
sk_sp< SkTypeface > matchStyle(const SkFontStyle &pattern) override
~SkFontStyleSet_Fuchsia() override=default
sk_sp< SkTypeface > createTypeface(int index) override
sk_sp< SkTypeface > matchStyleCSS3(const SkFontStyle &pattern)
sk_sp< SkData > GetOrCreateSkData(int bufferId, const fuchsia::mem::Buffer &buffer)
~SkFuchsiaFontDataCache()
SkFuchsiaFontDataCache()=default
SkTypeface_Fuchsia(std::unique_ptr< SkFontData > fontData, const SkFontStyle &style, bool isFixedPitch, const SkString familyName, TypefaceId id)
bool isFixedPitch() const
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
bool operator==(TypefaceId &other) const