Browse Source

MagnumFont: store glyph advance with glyphs, not characters.

Allows to store glyph advance also for notfound glyph, which is exactly
what we want for unknown characters. Also added version information to
allow further extensions.
pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
4725aa6687
  1. 22
      src/Plugins/MagnumFont/MagnumFont.cpp
  2. 8
      src/Plugins/MagnumFont/Test/MagnumFontTest.cpp
  3. 8
      src/Plugins/MagnumFont/Test/font.conf
  4. 5
      src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp

22
src/Plugins/MagnumFont/MagnumFont.cpp

@ -80,6 +80,13 @@ void MagnumFont::doOpenData(const std::vector<std::pair<std::string, Containers:
return; return;
} }
/* Check version */
if(conf.value<UnsignedInt>("version") != 1) {
Error() << "Magnum::Text::MagnumFont::openData(): unsupported file version, expected 1 but got"
<< conf.value<UnsignedInt>("version");
return;
}
/* Check that we have also the image file */ /* Check that we have also the image file */
if(conf.value("image") != data[1].first) { if(conf.value("image") != data[1].first) {
Error() << "Magnum::Text::MagnumFont::openData(): expected file" Error() << "Magnum::Text::MagnumFont::openData(): expected file"
@ -111,6 +118,13 @@ void MagnumFont::doOpenFile(const std::string& filename, Float) {
return; return;
} }
/* Check version */
if(conf.value<UnsignedInt>("version") != 1) {
Error() << "Magnum::Text::MagnumFont::openFile(): unsupported file version, expected 1 but got"
<< conf.value<UnsignedInt>("version");
return;
}
/* Open and load image file */ /* Open and load image file */
const std::string imageFilename = Utility::Directory::join(Utility::Directory::path(filename), conf.value("image")); const std::string imageFilename = Utility::Directory::join(Utility::Directory::path(filename), conf.value("image"));
Trade::TgaImporter importer; Trade::TgaImporter importer;
@ -133,8 +147,11 @@ void MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&
_opened = new Data{std::move(conf), std::move(image), {}, {}}; _opened = new Data{std::move(conf), std::move(image), {}, {}};
_size = _opened->conf.value<Float>("fontSize"); _size = _opened->conf.value<Float>("fontSize");
/* Set glyph advance array to proper size */ /* Glyph advances */
_opened->glyphAdvance.resize(_opened->conf.groupCount("glyph")); const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph");
_opened->glyphAdvance.reserve(glyphs.size());
for(const Utility::ConfigurationGroup* const g: glyphs)
_opened->glyphAdvance.push_back(g->value<Vector2>("advance"));
/* Fill character->glyph map */ /* Fill character->glyph map */
const std::vector<Utility::ConfigurationGroup*> chars = _opened->conf.groups("char"); const std::vector<Utility::ConfigurationGroup*> chars = _opened->conf.groups("char");
@ -142,7 +159,6 @@ void MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&
const UnsignedInt glyphId = c->value<UnsignedInt>("glyph"); const UnsignedInt glyphId = c->value<UnsignedInt>("glyph");
CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphAdvance.size()); CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphAdvance.size());
_opened->glyphId.emplace(c->value<char32_t>("unicode"), glyphId); _opened->glyphId.emplace(c->value<char32_t>("unicode"), glyphId);
_opened->glyphAdvance[glyphId] = c->value<Vector2>("advance");
} }
} }

8
src/Plugins/MagnumFont/Test/MagnumFontTest.cpp

@ -77,17 +77,17 @@ void MagnumFontTest::layout() {
CORRADE_COMPARE(textureCoordinates, Rectangle({0, 0.03125f}, {0.0625f, 0.5f})); CORRADE_COMPARE(textureCoordinates, Rectangle({0, 0.03125f}, {0.0625f, 0.5f}));
CORRADE_COMPARE(advance, Vector2(0.71875f, 0.0f)); CORRADE_COMPARE(advance, Vector2(0.71875f, 0.0f));
/* 'a' (not in cache) */ /* 'a' (not found) */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(1); std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(1);
CORRADE_COMPARE(position, Rectangle()); CORRADE_COMPARE(position, Rectangle());
CORRADE_COMPARE(textureCoordinates, Rectangle()); CORRADE_COMPARE(textureCoordinates, Rectangle());
CORRADE_COMPARE(advance, Vector2(0.34375f, 0.0f)); CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f));
/* 'v' (not in cache) */ /* 'v' (not found) */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(2); std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(2);
CORRADE_COMPARE(position, Rectangle()); CORRADE_COMPARE(position, Rectangle());
CORRADE_COMPARE(textureCoordinates, Rectangle()); CORRADE_COMPARE(textureCoordinates, Rectangle());
CORRADE_COMPARE(advance, Vector2(0.34375f, 0.0f)); CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f));
/* 'e' */ /* 'e' */
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(3); std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(3);

8
src/Plugins/MagnumFont/Test/font.conf

@ -1,29 +1,29 @@
version=1
image=font.tga image=font.tga
originalImageSize=1536 1536 originalImageSize=1536 1536
padding=24 24 padding=24 24
fontSize=16 fontSize=16
[char] [char]
unicode=57 unicode=57
advance=23 0
glyph=2 glyph=2
[char] [char]
unicode=61 unicode=61
advance=11 0
glyph=0 glyph=0
[char] [char]
unicode=65 unicode=65
advance=12 0
glyph=1 glyph=1
[char] [char]
unicode=76 unicode=76
advance=11 0
glyph=0 glyph=0
[glyph] [glyph]
advance=8 0
position=24 24 position=24 24
rectangle=24 24 -24 -24 rectangle=24 24 -24 -24
[glyph] [glyph]
advance=12 0
position=25 12 position=25 12
rectangle=16 4 64 32 rectangle=16 4 64 32
[glyph] [glyph]
advance=23 0
position=25 34 position=25 34
rectangle=0 8 16 128 rectangle=0 8 16 128

5
src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp

@ -46,6 +46,7 @@ auto MagnumFontConverter::doFeatures() const -> Features {
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont* font, GlyphCache* cache, const std::string& filename, const std::u32string& characters) const { std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont* font, GlyphCache* cache, const std::string& filename, const std::u32string& characters) const {
Utility::Configuration configuration; Utility::Configuration configuration;
configuration.setValue("version", 1);
configuration.setValue("image", Utility::Directory::filename(filename) + ".tga"); configuration.setValue("image", Utility::Directory::filename(filename) + ".tga");
configuration.setValue("originalImageSize", cache->textureSize()); configuration.setValue("originalImageSize", cache->textureSize());
configuration.setValue("padding", cache->padding()); configuration.setValue("padding", cache->padding());
@ -66,12 +67,11 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFont
for(const std::pair<UnsignedInt, UnsignedInt>& map: glyphIdMap) for(const std::pair<UnsignedInt, UnsignedInt>& map: glyphIdMap)
inverseGlyphIdMap[map.second] = map.first; inverseGlyphIdMap[map.second] = map.first;
/* Save character properties, map glyph IDs to new ones */ /* Character->glyph map, map glyph IDs to new ones */
for(const char32_t c: characters) { for(const char32_t c: characters) {
Utility::ConfigurationGroup* group = configuration.addGroup("char"); Utility::ConfigurationGroup* group = configuration.addGroup("char");
const UnsignedInt glyphId = font->glyphId(c); const UnsignedInt glyphId = font->glyphId(c);
group->setValue("unicode", c); group->setValue("unicode", c);
group->setValue("advance", font->glyphAdvance(glyphId));
/* Map old glyph ID to new, if not found, map to glyph 0 */ /* Map old glyph ID to new, if not found, map to glyph 0 */
auto found = glyphIdMap.find(glyphId); auto found = glyphIdMap.find(glyphId);
@ -84,6 +84,7 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFont
for(UnsignedInt oldGlyphId: inverseGlyphIdMap) { for(UnsignedInt oldGlyphId: inverseGlyphIdMap) {
std::pair<Vector2i, Rectanglei> glyph = (*cache)[oldGlyphId]; std::pair<Vector2i, Rectanglei> glyph = (*cache)[oldGlyphId];
Utility::ConfigurationGroup* group = configuration.addGroup("glyph"); Utility::ConfigurationGroup* group = configuration.addGroup("glyph");
group->setValue("advance", font->glyphAdvance(oldGlyphId));
group->setValue("position", glyph.first+cache->padding()); group->setValue("position", glyph.first+cache->padding());
group->setValue("rectangle", Rectanglei(glyph.second.bottomLeft()+cache->padding(), group->setValue("rectangle", Rectanglei(glyph.second.bottomLeft()+cache->padding(),
glyph.second.topRight()-cache->padding())); glyph.second.topRight()-cache->padding()));

Loading…
Cancel
Save