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
@ref Text::DistanceFieldGlyphCache::DistanceFieldGlyphCache(NoCreateT)
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

15
src/Magnum/Text/AbstractFont.cpp

@ -272,21 +272,22 @@ Vector2 AbstractFont::glyphAdvance(const UnsignedInt 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(),
"Text::AbstractFont::fillGlyphCache(): no font opened", );
"Text::AbstractFont::fillGlyphCache(): no font opened", {});
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);
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>) {
CORRADE_ASSERT_UNREACHABLE("Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", );
bool AbstractFont::doFillGlyphCache(AbstractGlyphCache&, Containers::ArrayView<const char32_t>) {
CORRADE_ASSERT_UNREACHABLE("Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", {});
return {};
}
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
* cache filling, use @ref createGlyphCache() instead. Expects that a
* 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
@ -661,7 +666,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* The string is converted from UTF-8 to UTF-32, duplicate characters
* 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() */
virtual Containers::Pointer<AbstractGlyphCache> doCreateGlyphCache();

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

@ -88,6 +88,7 @@ struct AbstractFontTest: TestSuite::Tester {
void glyphSizeAdvanceOutOfRange();
void fillGlyphCache();
void fillGlyphCacheFailed();
void fillGlyphCacheNotSupported();
void fillGlyphCacheNotImplemented();
void fillGlyphCacheNoFont();
@ -151,6 +152,7 @@ AbstractFontTest::AbstractFontTest() {
&AbstractFontTest::glyphSizeAdvanceOutOfRange,
&AbstractFontTest::fillGlyphCache,
&AbstractFontTest::fillGlyphCacheFailed,
&AbstractFontTest::fillGlyphCacheNotSupported,
&AbstractFontTest::fillGlyphCacheNotImplemented,
&AbstractFontTest::fillGlyphCacheNoFont,
@ -929,12 +931,13 @@ void AbstractFontTest::fillGlyphCache() {
Vector2 doGlyphAdvance(UnsignedInt) 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_AS(characters, Containers::arrayView<char32_t>({
'h', 'e', 'l', 'o'
}), TestSuite::Compare::Container);
called = true;
return true;
}
bool called = false;
@ -945,10 +948,36 @@ void AbstractFontTest::fillGlyphCache() {
DummyGlyphCache cache{PixelFormat::R8Unorm, {100, 100}};
font.fillGlyphCache(cache, "helo");
CORRADE_VERIFY(font.fillGlyphCache(cache, "helo"));
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() {
CORRADE_SKIP_IF_NO_ASSERT();

Loading…
Cancel
Save