1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Direct2D: Avoid creating multiple MemoryFontFileLoaders all referencing the same data

This commit is contained in:
reuk 2025-11-27 13:25:55 +00:00
parent 230340dbfc
commit eecf40ba95
2 changed files with 60 additions and 16 deletions

View file

@ -1010,6 +1010,12 @@ public:
Uuid getUuid() const { return uuid; } Uuid getUuid() const { return uuid; }
Span<const std::byte> asSpan() const&& = delete;
Span<const std::byte> asSpan() const&
{
return { static_cast<const std::byte*> (block->getData()), block->getSize() };
}
private: private:
std::shared_ptr<const MemoryBlock> block; std::shared_ptr<const MemoryBlock> block;
Uuid uuid; Uuid uuid;
@ -1061,20 +1067,54 @@ DirectWriteCustomFontCollectionLoader::DirectWriteCustomFontCollectionLoader (ID
DirectWriteCustomFontCollectionLoader::~DirectWriteCustomFontCollectionLoader() DirectWriteCustomFontCollectionLoader::~DirectWriteCustomFontCollectionLoader()
{ {
for (const auto& loader : fileLoaders) for (auto& loader : loaders)
factory.UnregisterFontFileLoader (loader); factory.UnregisterFontFileLoader (loader);
} }
auto DirectWriteCustomFontCollectionLoader::findLoaderForUuid (const Uuid& uuid) const -> ComSmartPtr<MemoryFontFileLoader>
{
const auto compareUuidAndLoader = [] (ComSmartPtr<MemoryFontFileLoader> loader, const Uuid& comparisonUuid)
{
return loader->getUuid() < comparisonUuid;
};
const auto iter = std::lower_bound (loaders.begin(), loaders.end(), uuid, compareUuidAndLoader);
if (iter == loaders.end() || iter->get()->getUuid() != uuid)
return {};
return *iter;
}
Uuid DirectWriteCustomFontCollectionLoader::addRawFontData (Span<const std::byte> blob) Uuid DirectWriteCustomFontCollectionLoader::addRawFontData (Span<const std::byte> blob)
{ {
const std::string_view blobAsString (reinterpret_cast<const char*> (blob.data()), blob.size());
const auto hashValue = std::hash<std::string_view>{} (blobAsString);
auto& uuids = uuidsForHash[hashValue];
for (const auto& uuid : uuids)
{
const auto matchingLoader = findLoaderForUuid (uuid);
if (matchingLoader == nullptr)
continue;
const auto loaderData = matchingLoader->asSpan();
if (! std::equal (blob.begin(), blob.end(), loaderData.begin(), loaderData.end()))
continue;
return matchingLoader->getUuid();
}
ComSmartPtr loader { new MemoryFontFileLoader { { blob.data(), blob.size() } }, ComSmartPtr loader { new MemoryFontFileLoader { { blob.data(), blob.size() } },
IncrementRef::no }; IncrementRef::no };
factory.RegisterFontFileLoader (loader); factory.RegisterFontFileLoader (loader);
fileLoaders.push_back (loader); const auto compareUuids = [] (const auto& a, const auto& b) { return a->getUuid() < b->getUuid(); };
OrderedContainerHelpers::insertOrAssign (loaders, loader, compareUuids);
return fileLoaders.back()->getUuid(); uuids.push_back (loader->getUuid());
return loader->getUuid();
} }
HRESULT WINAPI DirectWriteCustomFontCollectionLoader::CreateEnumeratorFromKey (IDWriteFactory* factoryIn, HRESULT WINAPI DirectWriteCustomFontCollectionLoader::CreateEnumeratorFromKey (IDWriteFactory* factoryIn,
@ -1087,16 +1127,13 @@ HRESULT WINAPI DirectWriteCustomFontCollectionLoader::CreateEnumeratorFromKey (I
const Uuid requestedCollectionKey { static_cast<const uint8*> (collectionKey) }; const Uuid requestedCollectionKey { static_cast<const uint8*> (collectionKey) };
for (const auto& loader : fileLoaders) const auto matchingLoader = findLoaderForUuid (requestedCollectionKey);
{
if (loader->getUuid() != requestedCollectionKey)
continue;
*fontFileEnumerator = new FontFileEnumerator { *factoryIn, loader };
return S_OK;
}
if (matchingLoader == nullptr)
return E_INVALIDARG; return E_INVALIDARG;
*fontFileEnumerator = new FontFileEnumerator { *factoryIn, matchingLoader };
return S_OK;
} }
//============================================================================== //==============================================================================

View file

@ -399,8 +399,15 @@ private:
class MemoryFontFileLoader; class MemoryFontFileLoader;
class FontFileEnumerator; class FontFileEnumerator;
ComSmartPtr<MemoryFontFileLoader> findLoaderForUuid (const Uuid&) const;
IDWriteFactory& factory; IDWriteFactory& factory;
std::vector<ComSmartPtr<MemoryFontFileLoader>> fileLoaders;
// Allows lookup of Uuids of all loaders with data matching a particular hash
std::map<size_t, std::vector<Uuid>> uuidsForHash;
// Sorted by Uuid
std::vector<ComSmartPtr<MemoryFontFileLoader>> loaders;
}; };
//============================================================================== //==============================================================================