Browse Source

Text: add AbstractFont::glyphSize().

Together with glyphCount() quite useful for querying font properties.
pull/168/head
Vladimír Vondruš 3 years ago
parent
commit
a28ebaef84
  1. 3
      doc/changelog.dox
  2. 1
      doc/snippets/MagnumText.cpp
  3. 7
      src/Magnum/Text/AbstractFont.cpp
  4. 23
      src/Magnum/Text/AbstractFont.h
  5. 1
      src/Magnum/Text/Test/AbstractFontConverterTest.cpp
  6. 63
      src/Magnum/Text/Test/AbstractFontTest.cpp
  7. 2
      src/Magnum/Text/Test/RendererGLTest.cpp
  8. 30
      src/MagnumPlugins/MagnumFont/MagnumFont.cpp
  9. 1
      src/MagnumPlugins/MagnumFont/MagnumFont.h
  10. 1
      src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp
  11. 3
      src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp

3
doc/changelog.dox

@ -767,7 +767,8 @@ See also:
@subsubsection changelog-latest-changes-text Text library
- Added @ref Text::AbstractFont::glyphCount()
- Added @ref Text::AbstractFont::glyphCount() and
@relativeref{Text::AbstractFont,glyphSize()}
- Added @ref Text::Renderer::fontSize()
@subsubsection changelog-latest-changes-trade Trade library

1
doc/snippets/MagnumText.cpp

@ -58,6 +58,7 @@ struct MyFont: Text::AbstractFont {
bool doIsOpened() const override { return false; }
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<Text::AbstractLayouter> doLayout(const Text::AbstractGlyphCache&, Float, Containers::StringView) override { return {}; }
};

7
src/Magnum/Text/AbstractFont.cpp

@ -250,6 +250,13 @@ UnsignedInt AbstractFont::glyphId(const char32_t character) {
return doGlyphId(character);
}
Vector2 AbstractFont::glyphSize(const UnsignedInt glyph) {
CORRADE_ASSERT(isOpened(), "Text::AbstractFont::glyphSize(): no font opened", {});
CORRADE_ASSERT(glyph < _glyphCount, "Text::AbstractFont::glyphSize(): index" << glyph << "out of range for" << _glyphCount << "glyphs", {});
return doGlyphSize(glyph);
}
Vector2 AbstractFont::glyphAdvance(const UnsignedInt glyph) {
CORRADE_ASSERT(isOpened(), "Text::AbstractFont::glyphAdvance(): no font opened", {});
CORRADE_ASSERT(glyph < _glyphCount, "Text::AbstractFont::glyphAdvance(): index" << glyph << "out of range for" << _glyphCount << "glyphs", {});

23
src/Magnum/Text/AbstractFont.h

@ -457,6 +457,23 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
*/
UnsignedInt glyphId(char32_t character);
/**
* @brief Glyph size in pixels
* @param glyph Glyph ID
* @m_since_latest
*
* Size of the glyph image in pixels when rasterized. Some
* implementations may return fractional values, in which case
* @ref Math::ceil() should be used to get the actual integer pixel
* size.
* @note This function is meant to be used only for font observations
* and conversions. In performance-critical code the
* @ref fillGlyphCache() and @ref layout() functions should be
* used instead.
* @see @ref glyphId(), @ref size()
*/
Vector2 glyphSize(UnsignedInt glyph);
/**
* @brief Glyph advance in pixels
* @param glyph Glyph ID
@ -609,6 +626,12 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
/** @brief Implementation for @ref glyphId() */
virtual UnsignedInt doGlyphId(char32_t character) = 0;
/**
* @brief Implementation for @ref glyphSize()
* @m_since_latest
*/
virtual Vector2 doGlyphSize(UnsignedInt glyph) = 0;
/** @brief Implementation for @ref glyphAdvance() */
virtual Vector2 doGlyphAdvance(UnsignedInt glyph) = 0;

1
src/Magnum/Text/Test/AbstractFontConverterTest.cpp

@ -159,6 +159,7 @@ struct DummyFont: AbstractFont {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;

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

@ -75,9 +75,9 @@ struct AbstractFontTest: TestSuite::Tester {
void glyphId();
void glyphIdNoFont();
void glyphAdvance();
void glyphAdvanceNoFont();
void glyphAdvanceOutOfRange();
void glyphSizeAdvance();
void glyphSizeAdvanceNoFont();
void glyphSizeAdvanceOutOfRange();
void layout();
void layoutNoFont();
@ -129,9 +129,9 @@ AbstractFontTest::AbstractFontTest() {
&AbstractFontTest::glyphId,
&AbstractFontTest::glyphIdNoFont,
&AbstractFontTest::glyphAdvance,
&AbstractFontTest::glyphAdvanceNoFont,
&AbstractFontTest::glyphAdvanceOutOfRange,
&AbstractFontTest::glyphSizeAdvance,
&AbstractFontTest::glyphSizeAdvanceNoFont,
&AbstractFontTest::glyphSizeAdvanceOutOfRange,
&AbstractFontTest::layout,
&AbstractFontTest::layoutNoFont,
@ -162,6 +162,7 @@ void AbstractFontTest::construct() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -187,6 +188,7 @@ void AbstractFontTest::openData() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -218,6 +220,7 @@ void AbstractFontTest::openFileAsData() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -244,6 +247,7 @@ void AbstractFontTest::openFileAsDataNotFound() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -269,6 +273,7 @@ void AbstractFontTest::openFileNotImplemented() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -291,6 +296,7 @@ void AbstractFontTest::openDataNotSupported() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -312,6 +318,7 @@ void AbstractFontTest::openDataNotImplemented() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -334,6 +341,7 @@ void AbstractFontTest::setFileCallback() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -360,6 +368,7 @@ void AbstractFontTest::setFileCallbackTemplate() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -392,6 +401,7 @@ void AbstractFontTest::setFileCallbackTemplateNull() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -417,6 +427,7 @@ void AbstractFontTest::setFileCallbackTemplateConst() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -444,6 +455,7 @@ void AbstractFontTest::setFileCallbackFileOpened() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -466,6 +478,7 @@ void AbstractFontTest::setFileCallbackNotImplemented() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -491,6 +504,7 @@ void AbstractFontTest::setFileCallbackNotSupported() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -526,6 +540,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -568,6 +583,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -622,6 +638,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed()
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -659,6 +676,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -714,6 +732,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -746,6 +765,7 @@ void AbstractFontTest::properties() {
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -771,6 +791,7 @@ void AbstractFontTest::propertiesNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -799,6 +820,7 @@ void AbstractFontTest::glyphId() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t a) override { return a*10; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -817,6 +839,7 @@ void AbstractFontTest::glyphIdNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -829,7 +852,7 @@ void AbstractFontTest::glyphIdNoFont() {
CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphId(): no font opened\n");
}
void AbstractFontTest::glyphAdvance() {
void AbstractFontTest::glyphSizeAdvance() {
struct MyFont: AbstractFont {
FontFeatures doFeatures() const override { return FontFeature::OpenData; }
bool doIsOpened() const override { return _opened; }
@ -840,6 +863,7 @@ void AbstractFontTest::glyphAdvance() {
return {0.0f, 0.0f, 0.0f, 0.0f, 98};
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt a) override { return {a*2.0f, a/3.0f}; }
Vector2 doGlyphAdvance(UnsignedInt a) override { return {a*10.0f, -Float(a)/10.0f}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -850,10 +874,11 @@ void AbstractFontTest::glyphAdvance() {
/* Have to explicitly open in order to make glyphCount() non-zero */
CORRADE_VERIFY(font.openData(nullptr, 0.0f));
CORRADE_COMPARE(font.glyphSize(33), (Vector2{66.0f, 11.0f}));
CORRADE_COMPARE(font.glyphAdvance(97), (Vector2{970.0f, -9.7f}));
}
void AbstractFontTest::glyphAdvanceNoFont() {
void AbstractFontTest::glyphSizeAdvanceNoFont() {
CORRADE_SKIP_IF_NO_ASSERT();
struct MyFont: AbstractFont {
@ -862,6 +887,7 @@ void AbstractFontTest::glyphAdvanceNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -870,11 +896,14 @@ void AbstractFontTest::glyphAdvanceNoFont() {
std::ostringstream out;
Error redirectError{&out};
font.glyphSize(33);
font.glyphAdvance(97);
CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphAdvance(): no font opened\n");
CORRADE_COMPARE(out.str(),
"Text::AbstractFont::glyphSize(): no font opened\n"
"Text::AbstractFont::glyphAdvance(): no font opened\n");
}
void AbstractFontTest::glyphAdvanceOutOfRange() {
void AbstractFontTest::glyphSizeAdvanceOutOfRange() {
CORRADE_SKIP_IF_NO_ASSERT();
struct MyFont: AbstractFont {
@ -887,6 +916,7 @@ void AbstractFontTest::glyphAdvanceOutOfRange() {
return {0.0f, 0.0f, 0.0f, 0.0f, 3};
}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;
@ -900,8 +930,10 @@ void AbstractFontTest::glyphAdvanceOutOfRange() {
std::ostringstream out;
Error redirectError{&out};
font.glyphSize(3);
font.glyphAdvance(3);
CORRADE_COMPARE(out.str(),
"Text::AbstractFont::glyphSize(): index 3 out of range for 3 glyphs\n"
"Text::AbstractFont::glyphAdvance(): index 3 out of range for 3 glyphs\n");
}
@ -924,6 +956,7 @@ void AbstractFontTest::layout() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache& cache, Float size, Containers::StringView str) override {
return Containers::pointer<Layouter>(UnsignedInt(cache.textureSize().x()*str.size()*size));
@ -944,6 +977,7 @@ void AbstractFontTest::layoutNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -962,6 +996,7 @@ void AbstractFontTest::fillGlyphCache() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
@ -991,6 +1026,7 @@ void AbstractFontTest::fillGlyphCacheNotSupported() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1011,6 +1047,7 @@ void AbstractFontTest::fillGlyphCacheNotImplemented() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1031,6 +1068,7 @@ void AbstractFontTest::fillGlyphCacheNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1051,6 +1089,7 @@ void AbstractFontTest::fillGlyphCacheInvalidUtf8() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1069,6 +1108,7 @@ void AbstractFontTest::createGlyphCache() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
@ -1097,6 +1137,7 @@ void AbstractFontTest::createGlyphCacheNotSupported() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1116,6 +1157,7 @@ void AbstractFontTest::createGlyphCacheNotImplemented() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;
@ -1135,6 +1177,7 @@ void AbstractFontTest::createGlyphCacheNoFont() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; }
} font;

2
src/Magnum/Text/Test/RendererGLTest.cpp

@ -77,6 +77,7 @@ class TestFont: public AbstractFont {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return 0; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float size, Containers::StringView text) override {
@ -354,6 +355,7 @@ void RendererGLTest::multiline() {
}
UnsignedInt doGlyphId(char32_t) override { return 0; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView text) override {

30
src/MagnumPlugins/MagnumFont/MagnumFont.cpp

@ -29,6 +29,7 @@
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/Containers/Triple.h>
#include <Corrade/Utility/Configuration.h>
#include <Corrade/Utility/Path.h>
@ -52,18 +53,22 @@ struct MagnumFont::Data {
Containers::Optional<Trade::ImageData2D> image;
Containers::Optional<Containers::String> filePath;
std::unordered_map<char32_t, UnsignedInt> glyphId;
Containers::Array<Vector2> glyphAdvance;
struct Glyph {
Vector2i size;
Vector2 advance;
};
Containers::Array<Glyph> glyphs;
};
namespace {
class MagnumFontLayouter: public AbstractLayouter {
public:
explicit MagnumFontLayouter(Containers::ArrayView<const Vector2> glyphAdvance, const AbstractGlyphCache& cache, Float fontSize, Float textSize, Containers::Array<UnsignedInt>&& glyphs);
explicit MagnumFontLayouter(const Containers::StridedArrayView1D<const Vector2>& glyphAdvance, const AbstractGlyphCache& cache, Float fontSize, Float textSize, Containers::Array<UnsignedInt>&& glyphs);
private:
Containers::Triple<Range2D, Range2D, Vector2> doRenderGlyph(UnsignedInt i) override;
const Containers::ArrayView<const Vector2> glyphAdvance;
const Containers::StridedArrayView1D<const Vector2> glyphAdvance;
const AbstractGlyphCache& cache;
const Float fontSize, textSize;
const Containers::Array<UnsignedInt> glyphs;
@ -119,15 +124,18 @@ auto MagnumFont::doOpenData(const Containers::ArrayView<const char> data, const
/* Glyph advances */
const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph");
_opened->glyphAdvance = Containers::Array<Vector2>{NoInit, glyphs.size()};
_opened->glyphs = Containers::Array<Data::Glyph>{NoInit, glyphs.size()};
for(std::size_t i = 0; i != glyphs.size(); ++i)
_opened->glyphAdvance[i] = glyphs[i]->value<Vector2>("advance");
_opened->glyphs[i] = {
glyphs[i]->value<Range2Di>("rectangle").size(),
glyphs[i]->value<Vector2>("advance")
};
/* Fill character->glyph map */
const std::vector<Utility::ConfigurationGroup*> chars = _opened->conf.groups("char");
for(const Utility::ConfigurationGroup* const c: chars) {
const UnsignedInt glyphId = c->value<UnsignedInt>("glyph");
CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphAdvance.size());
CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphs.size());
_opened->glyphId.emplace(c->value<char32_t>("unicode"), glyphId);
}
@ -150,8 +158,12 @@ UnsignedInt MagnumFont::doGlyphId(const char32_t character) {
return it != _opened->glyphId.end() ? it->second : 0;
}
Vector2 MagnumFont::doGlyphSize(const UnsignedInt glyph) {
return Vector2{_opened->glyphs[glyph].size};
}
Vector2 MagnumFont::doGlyphAdvance(const UnsignedInt glyph) {
return _opened->glyphAdvance[glyph];
return _opened->glyphs[glyph].advance;
}
Containers::Pointer<AbstractGlyphCache> MagnumFont::doCreateGlyphCache() {
@ -181,12 +193,12 @@ Containers::Pointer<AbstractLayouter> MagnumFont::doLayout(const AbstractGlyphCa
i = codepointNext.second();
}
return Containers::pointer<MagnumFontLayouter>(_opened->glyphAdvance, cache, this->size(), size, Utility::move(glyphs));
return Containers::pointer<MagnumFontLayouter>(stridedArrayView(_opened->glyphs).slice(&Data::Glyph::advance), cache, this->size(), size, Utility::move(glyphs));
}
namespace {
MagnumFontLayouter::MagnumFontLayouter(Containers::ArrayView<const Vector2> glyphAdvance, const AbstractGlyphCache& cache, const Float fontSize, const Float textSize, Containers::Array<UnsignedInt>&& glyphs): AbstractLayouter{UnsignedInt(glyphs.size())}, glyphAdvance{glyphAdvance}, cache(cache), fontSize{fontSize}, textSize{textSize}, glyphs{Utility::move(glyphs)} {}
MagnumFontLayouter::MagnumFontLayouter(const Containers::StridedArrayView1D<const Vector2>& glyphAdvance, const AbstractGlyphCache& cache, const Float fontSize, const Float textSize, Containers::Array<UnsignedInt>&& glyphs): AbstractLayouter{UnsignedInt(glyphs.size())}, glyphAdvance{glyphAdvance}, cache(cache), fontSize{fontSize}, textSize{textSize}, glyphs{Utility::move(glyphs)} {}
Containers::Triple<Range2D, Range2D, Vector2> MagnumFontLayouter::doRenderGlyph(const UnsignedInt i) {
/* Position of the texture in the resulting glyph, texture coordinates */

1
src/MagnumPlugins/MagnumFont/MagnumFont.h

@ -177,6 +177,7 @@ class MAGNUM_MAGNUMFONT_EXPORT MagnumFont: public AbstractFont {
MAGNUM_MAGNUMFONT_LOCAL void doClose() override;
MAGNUM_MAGNUMFONT_LOCAL UnsignedInt doGlyphId(char32_t character) override;
MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphSize(UnsignedInt glyph) override;
MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphAdvance(UnsignedInt glyph) override;
MAGNUM_MAGNUMFONT_LOCAL Containers::Pointer<AbstractGlyphCache> doCreateGlyphCache() override;
MAGNUM_MAGNUMFONT_LOCAL Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache& cache, Float size, Containers::StringView text) override;

1
src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp

@ -94,6 +94,7 @@ void MagnumFontTest::properties() {
CORRADE_COMPARE(font->descent(), -10.0f);
CORRADE_COMPARE(font->lineHeight(), 39.7333f);
CORRADE_COMPARE(font->glyphCount(), 3);
CORRADE_COMPARE(font->glyphSize(font->glyphId(U'W')), (Vector2{16.0f, 120.0f}));
CORRADE_COMPARE(font->glyphAdvance(font->glyphId(U'W')), (Vector2{23.0f, 0.0f}));
}

3
src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp

@ -109,6 +109,8 @@ void MagnumFontConverterTest::exportFont() {
return 0;
}
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(const UnsignedInt glyph) override {
switch(glyph) {
case 0: return {8, 0};
@ -166,6 +168,7 @@ void MagnumFontConverterTest::exportFontNoGlyphCacheImageDownload() {
void doClose() override {}
UnsignedInt doGlyphId(char32_t) override { return {}; }
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractLayouter> doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override {
return nullptr;

Loading…
Cancel
Save