1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_FONT_DATA_FONT_DATA_MANAGER_H_
#define CONTENT_RENDERER_FONT_DATA_FONT_DATA_MANAGER_H_
#include <list>
#include <map>
#include <memory>
#include <string>
#include "base/containers/lru_cache.h"
#include "base/hash/hash.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/unguessable_token.h"
#include "components/services/font_data/public/mojom/font_data_service.mojom.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/freetype_buildflags.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkFontStyle.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace base {
class MemoryMappedFile;
}
namespace font_data_service {
// Replaces the default font manager in the renderer.
// Does the following:
// - Instantiate renderer -> browser connection.
// - Request font from the browser based on family name and font style.
// - Convert shared memory region to a SkTypeface and cache the results.
//
// Instantiated in the renderer on startup. Font fallback mechanism is still in
// place/has not changed. Only runs on renderers for TopChrome WebUI on Windows
// as part of an experiment: see crbug.com/335680565 for more details.
//
// The methods of this class (as imposed by blink requirements) may be called on
// any thread.
class CONTENT_EXPORT FontDataManager : public SkFontMgr {
public:
FontDataManager();
FontDataManager(const FontDataManager&) = delete;
FontDataManager& operator=(const FontDataManager&) = delete;
~FontDataManager() override;
// SkFontMgr:
int onCountFamilies() const override;
void onGetFamilyName(int index, SkString* familyName) const override;
sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override;
/** May return NULL if the name is not found. */
sk_sp<SkFontStyleSet> onMatchFamily(const char familyName[]) const override;
sk_sp<SkTypeface> onMatchFamilyStyle(const char familyName[],
const SkFontStyle&) const override;
sk_sp<SkTypeface> onMatchFamilyStyleCharacter(
const char familyName[],
const SkFontStyle&,
const char* bcp47[],
int bcp47Count,
SkUnichar character) const override;
sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override;
sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
int ttcIndex) const override;
sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
const SkFontArguments&) const override;
sk_sp<SkTypeface> onMakeFromFile(const char path[],
int ttcIndex) const override;
sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[],
SkFontStyle) const override;
void SetFontServiceForTesting(
mojo::PendingRemote<font_data_service::mojom::FontDataService>
font_data_service);
private:
font_data_service::mojom::FontDataService& GetRemoteFontDataService() const;
sk_sp<SkTypeface> CreateTypefaceFromMatchResult(
mojom::MatchFamilyNameResultPtr match_result) const;
// This must be const to allow being called from onCountFamilies and
// onGetFamilyNames, but it does mutate family_names_.
void GetAllFamilyNames() const;
// Key of the typeface_cache_.
struct MatchFamilyRequest {
std::string name;
int weight;
int width;
SkFontStyle::Slant slant;
};
struct MatchFamilyRequestHash {
size_t operator()(const MatchFamilyRequest& key) const {
return base::HashCombine(0ull, key.name, key.weight, key.width,
key.slant);
}
};
struct MatchFamilyRequestEqual {
size_t operator()(const MatchFamilyRequest& lhs,
const MatchFamilyRequest& rhs) const {
return lhs.name == rhs.name && lhs.weight == rhs.weight &&
lhs.width == rhs.width && lhs.slant == rhs.slant;
}
};
// Cache of the font requests to existing typefaces.
mutable base::HashingLRUCache<MatchFamilyRequest,
sk_sp<SkTypeface>,
MatchFamilyRequestHash,
MatchFamilyRequestEqual>
typeface_cache_;
// Calls to this class can be on any thread hence there is a lock to guard
// the cache.
mutable base::Lock lock_;
// Cache of the shared memory region by GUID to known font mappings.
mutable std::map<base::UnguessableToken, base::ReadOnlySharedMemoryMapping>
mapped_regions_;
// Cache of the memory mapped files to ensure the mapping lives.
mutable std::list<std::unique_ptr<base::MemoryMappedFile>> mapped_files_;
// A cache of all the font family names that could be returned by
// onGetFamilyName. When populated, this has the same amount of elements as
// returned by onCountFamilies. This is populated on the first call to either
// onCountFamilies or onGetFamilyName.
mutable std::vector<std::string> family_names_;
#if BUILDFLAG(ENABLE_FREETYPE)
sk_sp<SkFontMgr> custom_fnt_mgr_;
#endif
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
mutable base::SequenceLocalStorageSlot<
mojo::Remote<font_data_service::mojom::FontDataService>>
font_data_service_slot_;
};
} // namespace font_data_service
#endif // CONTENT_RENDERER_FONT_DATA_FONT_DATA_MANAGER_H_
|