Browse Source

Text: return a bool from AbstractFont::fillGlyphCache().

So the font implementations can actually return something reasonable on
failure, instead of asserting.
pull/638/head
Vladimír Vondruš 2 years ago
parent
commit
c56ca4c3f2
  1. 2
      doc/changelog.dox
  2. 15
      src/Magnum/Text/AbstractFont.cpp
  3. 9
      src/Magnum/Text/AbstractFont.h
  4. 33
      src/Magnum/Text/Test/AbstractFontTest.cpp

2
doc/changelog.dox

@ -837,6 +837,8 @@ See also:
- Added a @ref Text::GlyphCache::GlyphCache(NoCreateT) and - Added a @ref Text::GlyphCache::GlyphCache(NoCreateT) and
@ref Text::DistanceFieldGlyphCache::DistanceFieldGlyphCache(NoCreateT) @ref Text::DistanceFieldGlyphCache::DistanceFieldGlyphCache(NoCreateT)
constructor allowing to construct the object without a GL context present constructor allowing to construct the object without a GL context present
- @ref Text::AbstractFont::fillGlyphCache() now returns a @cpp bool @ce to
allow font plugin implementations to gracefully report failures
@subsubsection changelog-latest-changes-texturetools TextureTools library @subsubsection changelog-latest-changes-texturetools TextureTools library

15
src/Magnum/Text/AbstractFont.cpp

@ -272,21 +272,22 @@ Vector2 AbstractFont::glyphAdvance(const UnsignedInt glyph) {
return doGlyphAdvance(glyph); return doGlyphAdvance(glyph);
} }
void AbstractFont::fillGlyphCache(AbstractGlyphCache& cache, const Containers::StringView characters) { bool AbstractFont::fillGlyphCache(AbstractGlyphCache& cache, const Containers::StringView characters) {
CORRADE_ASSERT(isOpened(), CORRADE_ASSERT(isOpened(),
"Text::AbstractFont::fillGlyphCache(): no font opened", ); "Text::AbstractFont::fillGlyphCache(): no font opened", {});
CORRADE_ASSERT(!(features() & FontFeature::PreparedGlyphCache), CORRADE_ASSERT(!(features() & FontFeature::PreparedGlyphCache),
"Text::AbstractFont::fillGlyphCache(): feature not supported", ); "Text::AbstractFont::fillGlyphCache(): feature not supported", {});
const Containers::Optional<Containers::Array<char32_t>> utf32 = Utility::Unicode::utf32(characters); const Containers::Optional<Containers::Array<char32_t>> utf32 = Utility::Unicode::utf32(characters);
CORRADE_ASSERT(utf32, CORRADE_ASSERT(utf32,
"Text::AbstractFont::fillGlyphCache(): not a valid UTF-8 string:" << characters, ); "Text::AbstractFont::fillGlyphCache(): not a valid UTF-8 string:" << characters, {});
doFillGlyphCache(cache, *utf32); return doFillGlyphCache(cache, *utf32);
} }
void AbstractFont::doFillGlyphCache(AbstractGlyphCache&, Containers::ArrayView<const char32_t>) { bool AbstractFont::doFillGlyphCache(AbstractGlyphCache&, Containers::ArrayView<const char32_t>) {
CORRADE_ASSERT_UNREACHABLE("Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", ); CORRADE_ASSERT_UNREACHABLE("Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", {});
return {};
} }
Containers::Pointer<AbstractGlyphCache> AbstractFont::createGlyphCache() { Containers::Pointer<AbstractGlyphCache> AbstractFont::createGlyphCache() {

9
src/Magnum/Text/AbstractFont.h

@ -501,8 +501,13 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* @ref FontFeature::PreparedGlyphCache do not support partial glyph * @ref FontFeature::PreparedGlyphCache do not support partial glyph
* cache filling, use @ref createGlyphCache() instead. Expects that a * cache filling, use @ref createGlyphCache() instead. Expects that a
* font is opened and @p characters is valid UTF-8. * font is opened and @p characters is valid UTF-8.
*
* On success returns @cpp true @ce. On failure, for example if the
* @p cache doesn't have expected format or the @p characters can't
* fit, prints a message to @relativeref{Magnum,Error} and returns
* @cpp false @ce.
*/ */
void fillGlyphCache(AbstractGlyphCache& cache, Containers::StringView characters); bool fillGlyphCache(AbstractGlyphCache& cache, Containers::StringView characters);
/** /**
* @brief Create glyph cache * @brief Create glyph cache
@ -661,7 +666,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* The string is converted from UTF-8 to UTF-32, duplicate characters * The string is converted from UTF-8 to UTF-32, duplicate characters
* are *not* removed. * are *not* removed.
*/ */
virtual void doFillGlyphCache(AbstractGlyphCache& cache, Containers::ArrayView<const char32_t> characters); virtual bool doFillGlyphCache(AbstractGlyphCache& cache, Containers::ArrayView<const char32_t> characters);
/** @brief Implementation for @ref createGlyphCache() */ /** @brief Implementation for @ref createGlyphCache() */
virtual Containers::Pointer<AbstractGlyphCache> doCreateGlyphCache(); virtual Containers::Pointer<AbstractGlyphCache> doCreateGlyphCache();

33
src/Magnum/Text/Test/AbstractFontTest.cpp

@ -88,6 +88,7 @@ struct AbstractFontTest: TestSuite::Tester {
void glyphSizeAdvanceOutOfRange(); void glyphSizeAdvanceOutOfRange();
void fillGlyphCache(); void fillGlyphCache();
void fillGlyphCacheFailed();
void fillGlyphCacheNotSupported(); void fillGlyphCacheNotSupported();
void fillGlyphCacheNotImplemented(); void fillGlyphCacheNotImplemented();
void fillGlyphCacheNoFont(); void fillGlyphCacheNoFont();
@ -151,6 +152,7 @@ AbstractFontTest::AbstractFontTest() {
&AbstractFontTest::glyphSizeAdvanceOutOfRange, &AbstractFontTest::glyphSizeAdvanceOutOfRange,
&AbstractFontTest::fillGlyphCache, &AbstractFontTest::fillGlyphCache,
&AbstractFontTest::fillGlyphCacheFailed,
&AbstractFontTest::fillGlyphCacheNotSupported, &AbstractFontTest::fillGlyphCacheNotSupported,
&AbstractFontTest::fillGlyphCacheNotImplemented, &AbstractFontTest::fillGlyphCacheNotImplemented,
&AbstractFontTest::fillGlyphCacheNoFont, &AbstractFontTest::fillGlyphCacheNoFont,
@ -929,12 +931,13 @@ void AbstractFontTest::fillGlyphCache() {
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractShaper> doCreateShaper() override { return {}; } Containers::Pointer<AbstractShaper> doCreateShaper() override { return {}; }
void doFillGlyphCache(AbstractGlyphCache& cache, Containers::ArrayView<const char32_t> characters) override { bool doFillGlyphCache(AbstractGlyphCache& cache, Containers::ArrayView<const char32_t> characters) override {
CORRADE_COMPARE(cache.size(), (Vector3i{100, 100, 1})); CORRADE_COMPARE(cache.size(), (Vector3i{100, 100, 1}));
CORRADE_COMPARE_AS(characters, Containers::arrayView<char32_t>({ CORRADE_COMPARE_AS(characters, Containers::arrayView<char32_t>({
'h', 'e', 'l', 'o' 'h', 'e', 'l', 'o'
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
called = true; called = true;
return true;
} }
bool called = false; bool called = false;
@ -945,10 +948,36 @@ void AbstractFontTest::fillGlyphCache() {
DummyGlyphCache cache{PixelFormat::R8Unorm, {100, 100}}; DummyGlyphCache cache{PixelFormat::R8Unorm, {100, 100}};
font.fillGlyphCache(cache, "helo"); CORRADE_VERIFY(font.fillGlyphCache(cache, "helo"));
CORRADE_VERIFY(font.called); CORRADE_VERIFY(font.called);
} }
void AbstractFontTest::fillGlyphCacheFailed() {
struct MyFont: AbstractFont {
FontFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractShaper> doCreateShaper() override { return {}; }
bool doFillGlyphCache(AbstractGlyphCache&, Containers::ArrayView<const char32_t>) override {
return false;
}
bool called = false;
} font;
/* Capture correct function name */
CORRADE_VERIFY(true);
DummyGlyphCache cache{PixelFormat::R8Unorm, {100, 100}};
CORRADE_VERIFY(!font.fillGlyphCache(cache, ""));
}
void AbstractFontTest::fillGlyphCacheNotSupported() { void AbstractFontTest::fillGlyphCacheNotSupported() {
CORRADE_SKIP_IF_NO_ASSERT(); CORRADE_SKIP_IF_NO_ASSERT();

Loading…
Cancel
Save