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:
parent
230340dbfc
commit
eecf40ba95
2 changed files with 60 additions and 16 deletions
|
|
@ -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 };
|
if (matchingLoader == nullptr)
|
||||||
return S_OK;
|
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")
|
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
|
||||||
d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
d2d1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
__uuidof (ID2D1Factory),
|
__uuidof (ID2D1Factory),
|
||||||
&options,
|
&options,
|
||||||
(void**) result.resetAndGetPointerAddress());
|
(void**) result.resetAndGetPointerAddress());
|
||||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue