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
|
// 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 COMPONENTS_SERVICES_FONT_DATA_FONT_DATA_SERVICE_IMPL_H_
#define COMPONENTS_SERVICES_FONT_DATA_FONT_DATA_SERVICE_IMPL_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <vector>
#include "base/files/file.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/sequence_checker.h"
#include "components/services/font_data/public/mojom/font_data_service.mojom.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace font_data_service {
// FontDataService (receiver) manages font requests from the renderer.
// Does the following:
// 1) Construct the SkTypeface based on the font request details via
// DWriteFactory.
// 2) Store that SkTypeface as an SkStreamAsset (wrapper of the font data as
// raw bytes) into a shared memory map to be fetched by the renderer.
// 3) Cache the value for future requests.
//
// Instantiated in the browser process and lives on a sequence running in the
// thread pool.
//
// This is meant to replace the existing renderer font integration.
// FontDataServiceImpl is the replacement to DWriteFontProxyImpl. This currently
// only runs on Windows desktop browser as part of an experiment: see
// crbug.com/335680565 for more details.
class FontDataServiceImpl : public mojom::FontDataService {
public:
FontDataServiceImpl();
FontDataServiceImpl(const FontDataServiceImpl&) = delete;
FontDataServiceImpl& operator=(const FontDataServiceImpl&) = delete;
~FontDataServiceImpl() override;
void BindReceiver(mojo::PendingReceiver<mojom::FontDataService> receiver);
static void ConnectToFontService(
mojo::PendingReceiver<mojom::FontDataService> receiver);
size_t GetCacheSizeForTesting() const {
return typeface_to_asset_index_.size();
}
// FontDataService:
// Provides font data from a cache that is populated on-demand. Font data will
// match based on the `family_name` and `style` inputs. If there is no such
// match, the font data will be null.
void MatchFamilyName(const std::string& family_name,
mojom::TypefaceStylePtr style,
MatchFamilyNameCallback callback) override;
// Provides fallback font data for `character`.
void MatchFamilyNameCharacter(
const std::string& family_name,
mojom::TypefaceStylePtr style,
const std::vector<std::string>& bcp47s,
int32_t character,
MatchFamilyNameCharacterCallback callback) override;
// Gets all the available font families on the system. Usage of this function
// is strongly discouraged as it iterates over all installed fonts.
void GetAllFamilyNames(GetAllFamilyNamesCallback callback) override;
// Gets a typeface matching `family_name` and `style`, or the default typeface
// if `family_name` is `nullopt`.
void LegacyMakeTypeface(const std::optional<std::string>& family_name,
mojom::TypefaceStylePtr style,
LegacyMakeTypefaceCallback callback) override;
protected:
// Returns a file handle based on the SkTypeface. The file handle may be empty
// if there is no file associated with the typeface or if the typeface is
// null. This is a helper method that can be overridden for testing purposes.
virtual base::File GetFileHandle(SkTypeface& typeface);
private:
// Checks the shared memory region cache and returns an index if found. On
// cache miss, creates a new entry caching the data.
size_t GetOrCreateAssetIndex(std::unique_ptr<SkStreamAsset> asset);
// Prepares a MatchFamilyNameResult representing `typeface` that can be sent
// over mojo from `MatchFamilyName*` calls.
mojom::MatchFamilyNameResultPtr CreateMatchFamilyNameResult(
sk_sp<SkTypeface> typeface);
mojo::ReceiverSet<mojom::FontDataService> receivers_;
// The default font manager in the browser that creates the SkTypeface. On
// Windows, this would be the DWrite font manager (SkFontMgr_DirectWrite).
sk_sp<SkFontMgr> font_manager_;
// Wrapper that binds the SkStreamAsset and its shared memory
// map region. Used by the `assets_` cache.
struct MappedAsset {
MappedAsset() = delete;
MappedAsset(std::unique_ptr<SkStreamAsset> asset,
base::MappedReadOnlyRegion shared_memory);
~MappedAsset();
MappedAsset(const MappedAsset&) = delete;
MappedAsset& operator=(const MappedAsset&) = delete;
std::unique_ptr<SkStreamAsset> asset;
base::MappedReadOnlyRegion shared_memory;
};
// The primary font cache. Items must not be reordered after insertion.
std::vector<std::unique_ptr<MappedAsset>> assets_;
// Wrapper that binds the index and a ttc_index. Used for
// typeface-to-asset-index lookup.
struct MappedTypeface {
size_t asset_index;
// Set to index of this Typeface or 0 if the stream is not a collection.
int ttc_index;
};
// A mapping of a typeface's identifier to the index in the cache (i.e.,
// assets_).
std::map<SkTypefaceID, MappedTypeface> typeface_to_asset_index_;
// A mapping from a font data's base address to its index in the primary font
// cache (i.e., assets_).
std::map<intptr_t, size_t> address_to_asset_index_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace font_data_service
#endif // COMPONENTS_SERVICES_FONT_DATA_FONT_DATA_SERVICE_IMPL_H_
|