Browse Source

Expose font index in AbstractFont

pull/695/head
Andrew Snyder 3 weeks ago
parent
commit
d99b5cfa58
  1. 23
      src/Magnum/Text/AbstractFont.cpp
  2. 68
      src/Magnum/Text/AbstractFont.h
  3. 43
      src/Magnum/Text/Test/AbstractFontTest.cpp

23
src/Magnum/Text/AbstractFont.cpp

@ -108,7 +108,11 @@ void AbstractFont::setFileCallback(Containers::Optional<Containers::ArrayView<co
void AbstractFont::doSetFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {} void AbstractFont::doSetFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {}
bool AbstractFont::openData(Containers::ArrayView<const void> data, const Float size) { bool AbstractFont::openData(const Containers::ArrayView<const void> data, const Float size) {
return openData(data, size, 0);
}
bool AbstractFont::openData(Containers::ArrayView<const void> data, const Float size, const UnsignedInt fontIndex) {
CORRADE_ASSERT(features() & FontFeature::OpenData, CORRADE_ASSERT(features() & FontFeature::OpenData,
"Text::AbstractFont::openData(): feature not supported", false); "Text::AbstractFont::openData(): feature not supported", false);
@ -116,16 +120,19 @@ bool AbstractFont::openData(Containers::ArrayView<const void> data, const Float
the check doesn't be done on the plugin side) because for some file the check doesn't be done on the plugin side) because for some file
formats it could be valid (MagnumFont in particular). */ formats it could be valid (MagnumFont in particular). */
close(); close();
_fontIndex = fontIndex;
const Properties properties = doOpenData(Containers::arrayCast<const char>(data), size); const Properties properties = doOpenData(Containers::arrayCast<const char>(data), size);
/* If opening succeeded, save the returned values. If not, the values were /* If opening succeeded, save the returned values. If not, the values were
set to their default values by close() already. */ set to their default values by close() already. */
if(isOpened()) { if(isOpened()) {
CORRADE_INTERNAL_ASSERT(!properties.fontCount || fontIndex < properties.fontCount);
_size = properties.size; _size = properties.size;
_ascent = properties.ascent; _ascent = properties.ascent;
_descent = properties.descent; _descent = properties.descent;
_lineHeight = properties.lineHeight; _lineHeight = properties.lineHeight;
_glyphCount = properties.glyphCount; _glyphCount = properties.glyphCount;
_fontCount = properties.fontCount ? properties.fontCount : 1;
return true; return true;
} }
@ -137,7 +144,12 @@ auto AbstractFont::doOpenData(Containers::ArrayView<const char>, Float) -> Prope
} }
bool AbstractFont::openFile(const Containers::StringView filename, const Float size) { bool AbstractFont::openFile(const Containers::StringView filename, const Float size) {
return openFile(filename, size, 0);
}
bool AbstractFont::openFile(const Containers::StringView filename, const Float size, const UnsignedInt fontIndex) {
close(); close();
_fontIndex = fontIndex;
Properties properties; Properties properties;
/* If file loading callbacks are not set or the font implementation /* If file loading callbacks are not set or the font implementation
@ -174,11 +186,13 @@ bool AbstractFont::openFile(const Containers::StringView filename, const Float s
/* If opening succeeded, save the returned values. If not, the values were /* If opening succeeded, save the returned values. If not, the values were
set to their default values by close() already. */ set to their default values by close() already. */
if(isOpened()) { if(isOpened()) {
CORRADE_INTERNAL_ASSERT(!properties.fontCount || fontIndex < properties.fontCount);
_size = properties.size; _size = properties.size;
_ascent = properties.ascent; _ascent = properties.ascent;
_descent = properties.descent; _descent = properties.descent;
_lineHeight = properties.lineHeight; _lineHeight = properties.lineHeight;
_glyphCount = properties.glyphCount; _glyphCount = properties.glyphCount;
_fontCount = properties.fontCount ? properties.fontCount : 1;
return true; return true;
} }
@ -228,6 +242,13 @@ void AbstractFont::close() {
_lineHeight = {}; _lineHeight = {};
_descent = {}; _descent = {};
_lineHeight = {}; _lineHeight = {};
_fontIndex = {};
_fontCount = {};
}
UnsignedInt AbstractFont::fontCount() const {
CORRADE_ASSERT(isOpened(), "Text::AbstractFont::fontCount(): no font opened", {});
return _fontCount;
} }
Float AbstractFont::size() const { Float AbstractFont::size() const {

68
src/Magnum/Text/AbstractFont.h

@ -400,28 +400,40 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* @brief Open raw data * @brief Open raw data
* @param data File data * @param data File data
* @param size Font size in points * @param size Font size in points
* @param fontIndex Font index to open
* *
* Closes previous file, if it was opened, and tries to open given * Closes previous file, if it was opened, and tries to open given
* raw data. Available only if @ref FontFeature::OpenData is supported. * raw data. The @p fontIndex is useful for opening a particular font
* On failure prints a message to @relativeref{Magnum,Error} and * from a collection such as TrueType Collection (`*.ttc`) files.
* returns @cpp false @ce. * Available only if @ref FontFeature::OpenData is supported. On
* @see @ref features(), @ref openFile() * failure prints a message to @relativeref{Magnum,Error} and returns
* @cpp false @ce.
* @see @ref features(), @ref openFile(), @ref fontIndex(),
* @ref fontCount()
*/ */
bool openData(Containers::ArrayView<const void> data, Float size, UnsignedInt fontIndex);
/** @overload */
bool openData(Containers::ArrayView<const void> data, Float size); bool openData(Containers::ArrayView<const void> data, Float size);
/** /**
* @brief Open a file * @brief Open a file
* @param filename Font file * @param filename Font file
* @param size Size to open the font in, in points * @param size Size to open the font in, in points
* @param fontIndex Font index to open
* *
* Closes previous file, if it was opened, and tries to open given * Closes previous file, if it was opened, and tries to open given
* file. On failure prints a message to @relativeref{Magnum,Error} and * file. The @p fontIndex is useful for opening a particular font from
* returns @cpp false @ce. If file loading callbacks are set via * a collection such as TrueType Collection (`*.ttc`) files. On
* failure prints a message to @relativeref{Magnum,Error} and returns
* @cpp false @ce. If file loading callbacks are set via
* @ref setFileCallback() and @ref FontFeature::OpenData is supported, * @ref setFileCallback() and @ref FontFeature::OpenData is supported,
* this function uses the callback to load the file and passes the * this function uses the callback to load the file and passes the
* memory view to @ref openData() instead. See @ref setFileCallback() * memory view to @ref openData() instead. See @ref setFileCallback()
* for more information. * for more information.
* @see @ref fontIndex(), @ref fontCount()
*/ */
bool openFile(Containers::StringView filename, Float size, UnsignedInt fontIndex);
/** @overload */
bool openFile(Containers::StringView filename, Float size); bool openFile(Containers::StringView filename, Float size);
/** /**
@ -437,6 +449,28 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
*/ */
void close(); void close();
/**
* @brief Opened font index
* @m_since_latest
*
* Returns the font index passed to @ref openFile() or @ref openData().
* For files containing just one font, this value is @cpp 0 @ce.
* @see @ref fontCount()
*/
UnsignedInt fontIndex() const { return _fontIndex; }
/**
* @brief Count of fonts in the opened file
* @m_since_latest
*
* For files containing just one font, this value is @cpp 1 @ce. For
* font collections such as TrueType Collection (`*.ttc`) files, this
* is the count of fonts in the collection. Expects that a font is
* opened.
* @see @ref fontIndex()
*/
UnsignedInt fontCount() const;
/** /**
* @brief Font size in points * @brief Font size in points
* *
@ -655,11 +689,8 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* Returned from @ref doOpenFile(), @ref doOpenData(). * Returned from @ref doOpenFile(), @ref doOpenData().
*/ */
struct Properties { struct Properties {
#if defined(CORRADE_TARGET_GCC) && !defined(CORRADE_TARGET_CLANG) && __GNUC__ < 5 constexpr /*implicit*/ Properties() noexcept: size{}, ascent{}, descent{}, lineHeight{}, glyphCount{}, fontCount{} {}
/* Otherwise GCC 4.8 loudly complains about missing initializers */ constexpr /*implicit*/ Properties(Float size, Float ascent, Float descent, Float lineHeight, UnsignedInt glyphCount, UnsignedInt fontCount = 0) noexcept: size{size}, ascent{ascent}, descent{descent}, lineHeight{lineHeight}, glyphCount{glyphCount}, fontCount{fontCount} {}
constexpr /*implicit*/ Properties() noexcept: size{}, ascent{}, descent{}, lineHeight{}, glyphCount{} {}
constexpr /*implicit*/ Properties(Float size, Float ascent, Float descent, Float lineHeight, UnsignedInt glyphCount) noexcept: size{size}, ascent{ascent}, descent{descent}, lineHeight{lineHeight}, glyphCount{glyphCount} {}
#endif
/** /**
* Font size in points * Font size in points
@ -691,6 +722,17 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
* @m_since_latest * @m_since_latest
*/ */
UnsignedInt glyphCount; UnsignedInt glyphCount;
/**
* Count of fonts in the opened file
*
* If left at @cpp 0 @ce by an implementation, the public
* @ref fontCount() reports @cpp 1 @ce. Implementations supporting
* font collections should return the real count.
* @see @ref fontCount()
* @m_since_latest
*/
UnsignedInt fontCount;
}; };
protected: protected:
@ -823,7 +865,7 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
#endif #endif
Float _size{}, _ascent{}, _descent{}, _lineHeight{}; Float _size{}, _ascent{}, _descent{}, _lineHeight{};
UnsignedInt _glyphCount{}; UnsignedInt _glyphCount{}, _fontIndex{}, _fontCount{};
}; };
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
@ -917,7 +959,7 @@ updated interface string.
*/ */
/* Silly indentation to make the string appear in pluginInterface() docs */ /* Silly indentation to make the string appear in pluginInterface() docs */
#define MAGNUM_TEXT_ABSTRACTFONT_PLUGIN_INTERFACE /* [interface] */ \ #define MAGNUM_TEXT_ABSTRACTFONT_PLUGIN_INTERFACE /* [interface] */ \
"cz.mosra.magnum.Text.AbstractFont/0.3.7" "cz.mosra.magnum.Text.AbstractFont/0.3.8"
/* [interface] */ /* [interface] */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT

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

@ -57,6 +57,7 @@ struct AbstractFontTest: TestSuite::Tester {
void construct(); void construct();
void openData(); void openData();
void openDataFontIndex();
void openFileAsData(); void openFileAsData();
void openFileAsDataNotFound(); void openFileAsDataNotFound();
@ -131,6 +132,7 @@ AbstractFontTest::AbstractFontTest() {
addTests({&AbstractFontTest::construct, addTests({&AbstractFontTest::construct,
&AbstractFontTest::openData, &AbstractFontTest::openData,
&AbstractFontTest::openDataFontIndex,
&AbstractFontTest::openFileAsData, &AbstractFontTest::openFileAsData,
&AbstractFontTest::openFileAsDataNotFound, &AbstractFontTest::openFileAsDataNotFound,
@ -250,6 +252,41 @@ void AbstractFontTest::openData() {
CORRADE_COMPARE(font.descent(), 2.0f); CORRADE_COMPARE(font.descent(), 2.0f);
CORRADE_COMPARE(font.lineHeight(), 3.0f); CORRADE_COMPARE(font.lineHeight(), 3.0f);
CORRADE_COMPARE(font.glyphCount(), 15); CORRADE_COMPARE(font.glyphCount(), 15);
CORRADE_COMPARE(font.fontIndex(), 0);
CORRADE_COMPARE(font.fontCount(), 1);
}
void AbstractFontTest::openDataFontIndex() {
struct: AbstractFont {
FontFeatures doFeatures() const override { return FontFeature::OpenData; }
bool doIsOpened() const override { return _opened; }
void doClose() override {}
Properties doOpenData(const Containers::ArrayView<const char> data, Float size) override {
CORRADE_COMPARE(fontIndex(), 2);
_opened = (data.size() == 1 && data[0] == '\xa5');
return {size, 1.0f, 2.0f, 3.0f, 15, 3};
}
void doGlyphIdsInto(const Containers::StridedArrayView1D<const char32_t>&, const Containers::StridedArrayView1D<UnsignedInt>&) override {}
Vector2 doGlyphSize(UnsignedInt) override { return {}; }
Vector2 doGlyphAdvance(UnsignedInt) override { return {}; }
Containers::Pointer<AbstractShaper> doCreateShaper() override { return {}; }
bool _opened = false;
} font;
CORRADE_VERIFY(!font.isOpened());
const char a5 = '\xa5';
font.openData({&a5, 1}, 13.0f, 2);
CORRADE_VERIFY(font.isOpened());
CORRADE_COMPARE(font.size(), 13.0f);
CORRADE_COMPARE(font.ascent(), 1.0f);
CORRADE_COMPARE(font.descent(), 2.0f);
CORRADE_COMPARE(font.lineHeight(), 3.0f);
CORRADE_COMPARE(font.glyphCount(), 15);
CORRADE_COMPARE(font.fontIndex(), 2);
CORRADE_COMPARE(font.fontCount(), 3);
} }
void AbstractFontTest::openFileAsData() { void AbstractFontTest::openFileAsData() {
@ -280,6 +317,8 @@ void AbstractFontTest::openFileAsData() {
CORRADE_COMPARE(font.descent(), 2.0f); CORRADE_COMPARE(font.descent(), 2.0f);
CORRADE_COMPARE(font.lineHeight(), 3.0f); CORRADE_COMPARE(font.lineHeight(), 3.0f);
CORRADE_COMPARE(font.glyphCount(), 15); CORRADE_COMPARE(font.glyphCount(), 15);
CORRADE_COMPARE(font.fontIndex(), 0);
CORRADE_COMPARE(font.fontCount(), 1);
} }
void AbstractFontTest::openFileAsDataNotFound() { void AbstractFontTest::openFileAsDataNotFound() {
@ -811,12 +850,14 @@ void AbstractFontTest::propertiesNoFont() {
font.descent(); font.descent();
font.lineHeight(); font.lineHeight();
font.glyphCount(); font.glyphCount();
font.fontCount();
CORRADE_COMPARE(out, CORRADE_COMPARE(out,
"Text::AbstractFont::size(): no font opened\n" "Text::AbstractFont::size(): no font opened\n"
"Text::AbstractFont::ascent(): no font opened\n" "Text::AbstractFont::ascent(): no font opened\n"
"Text::AbstractFont::descent(): no font opened\n" "Text::AbstractFont::descent(): no font opened\n"
"Text::AbstractFont::lineHeight(): no font opened\n" "Text::AbstractFont::lineHeight(): no font opened\n"
"Text::AbstractFont::glyphCount(): no font opened\n"); "Text::AbstractFont::glyphCount(): no font opened\n"
"Text::AbstractFont::fontCount(): no font opened\n");
} }
void AbstractFontTest::glyphId() { void AbstractFontTest::glyphId() {

Loading…
Cancel
Save