mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-08 23:24:19 +00:00
Direct2D: Avoid creating multiple MemoryFontFileLoaders all referencing the same data
This commit is contained in:
parent
230340dbfc
commit
eecf40ba95
2 changed files with 60 additions and 16 deletions
|
|
@ -1010,6 +1010,12 @@ public:
|
|||
|
||||
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:
|
||||
std::shared_ptr<const MemoryBlock> block;
|
||||
Uuid uuid;
|
||||
|
|
@ -1061,20 +1067,54 @@ DirectWriteCustomFontCollectionLoader::DirectWriteCustomFontCollectionLoader (ID
|
|||
|
||||
DirectWriteCustomFontCollectionLoader::~DirectWriteCustomFontCollectionLoader()
|
||||
{
|
||||
for (const auto& loader : fileLoaders)
|
||||
for (auto& loader : loaders)
|
||||
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)
|
||||
{
|
||||
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() } },
|
||||
IncrementRef::no };
|
||||
|
||||
factory.RegisterFontFileLoader (loader);
|
||||
|
||||
fileLoaders.push_back (loader);
|
||||
|
||||
return fileLoaders.back()->getUuid();
|
||||
const auto compareUuids = [] (const auto& a, const auto& b) { return a->getUuid() < b->getUuid(); };
|
||||
OrderedContainerHelpers::insertOrAssign (loaders, loader, compareUuids);
|
||||
uuids.push_back (loader->getUuid());
|
||||
return loader->getUuid();
|
||||
}
|
||||
|
||||
HRESULT WINAPI DirectWriteCustomFontCollectionLoader::CreateEnumeratorFromKey (IDWriteFactory* factoryIn,
|
||||
|
|
@ -1087,16 +1127,13 @@ HRESULT WINAPI DirectWriteCustomFontCollectionLoader::CreateEnumeratorFromKey (I
|
|||
|
||||
const Uuid requestedCollectionKey { static_cast<const uint8*> (collectionKey) };
|
||||
|
||||
for (const auto& loader : fileLoaders)
|
||||
{
|
||||
if (loader->getUuid() != requestedCollectionKey)
|
||||
continue;
|
||||
const auto matchingLoader = findLoaderForUuid (requestedCollectionKey);
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -1119,8 +1156,8 @@ Direct2DFactories::Direct2DFactories()
|
|||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
|
||||
d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof (ID2D1Factory),
|
||||
&options,
|
||||
__uuidof (ID2D1Factory),
|
||||
&options,
|
||||
(void**) result.resetAndGetPointerAddress());
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
|
|
|
|||
|
|
@ -399,8 +399,15 @@ private:
|
|||
class MemoryFontFileLoader;
|
||||
class FontFileEnumerator;
|
||||
|
||||
ComSmartPtr<MemoryFontFileLoader> findLoaderForUuid (const Uuid&) const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue