From 729484f6de27f719684fbf336ac1abc0f47c6c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 2 Jul 2013 14:23:49 +0200 Subject: [PATCH] Text: implicitly add "Not Found" glyph to GlyphCache. Also added test for GlyphCache functionality. --- src/Text/GlyphCache.cpp | 11 +++- src/Text/GlyphCache.h | 14 +++-- src/Text/Test/CMakeLists.txt | 4 ++ src/Text/Test/GlyphCacheGLTest.cpp | 83 ++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 src/Text/Test/GlyphCacheGLTest.cpp diff --git a/src/Text/GlyphCache.cpp b/src/Text/GlyphCache.cpp index 115e1ece6..cb99aa47a 100644 --- a/src/Text/GlyphCache.cpp +++ b/src/Text/GlyphCache.cpp @@ -55,12 +55,15 @@ GlyphCache::GlyphCache(const Vector2i& size, const Vector2i& padding): _size(siz GlyphCache::~GlyphCache() = default; -/** @todo Delegating constructor when support for GCC 4.6 is dropped */ void GlyphCache::initialize(const TextureFormat internalFormat, const Vector2i& size) { + /* Initialize texture */ _texture.setWrapping(Sampler::Wrapping::ClampToEdge) ->setMinificationFilter(Sampler::Filter::Linear) ->setMagnificationFilter(Sampler::Filter::Linear) ->setStorage(1, internalFormat, size); + + /* Default "Not Found" glyph */ + glyphs.insert({0, {}}); } std::vector GlyphCache::reserve(const std::vector& sizes) { @@ -74,7 +77,11 @@ void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Rectanglei r rectangle.bottomLeft() -= _padding; rectangle.topRight() += _padding; - glyphs.insert({glyph, {position, rectangle}}); + /* Overwriting "Not Found" glyph */ + if(glyph == 0) glyphs[0] = {position, rectangle}; + + /* Inserting new glyph */ + else CORRADE_INTERNAL_ASSERT_OUTPUT(glyphs.insert({glyph, {position, rectangle}}).second); } void GlyphCache::setImage(const Vector2i& offset, const ImageReference2D& image) { diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h index f88ca2318..527617f15 100644 --- a/src/Text/GlyphCache.h +++ b/src/Text/GlyphCache.h @@ -97,8 +97,11 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * @param glyph Glyph ID * * First tuple element is glyph position relative to point on baseline, - * second element is glyph region in texture atlas. If no glyph is - * found, glyph on zero index is returned. + * second element is glyph region in texture atlas. + * + * If no glyph is found, glyph `0` is returned, which is by default on + * zero position and has zero region in texture atlas. You can reset it + * to some meaningful value in insert(). */ std::pair operator[](UnsignedInt glyph) const { auto it = glyphs.find(glyph); @@ -134,8 +137,11 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * @param position Position relative to point on baseline * @param rectangle Region in texture atlas * - * You can obtain unused non-overlapping regions with reserve(). See - * also setImage() to upload glyph image. + * You can obtain unused non-overlapping regions with reserve(). You + * can't overwrite already inserted glyph, however you can reset glyph + * `0` to some meaningful value. + * + * See also setImage() to upload glyph image. */ void insert(UnsignedInt glyph, Vector2i position, Rectanglei rectangle); diff --git a/src/Text/Test/CMakeLists.txt b/src/Text/Test/CMakeLists.txt index ad0affe81..cea16a17b 100644 --- a/src/Text/Test/CMakeLists.txt +++ b/src/Text/Test/CMakeLists.txt @@ -29,3 +29,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) corrade_add_test(TextAbstractFontTest AbstractFontTest.cpp LIBRARIES Magnum MagnumText) corrade_add_test(TextAbstractFontConverterTest AbstractFontConverterTest.cpp LIBRARIES Magnum MagnumText) + +if(BUILD_GL_TESTS) + corrade_add_test(TextGlyphCacheGLTest GlyphCacheGLTest.cpp LIBRARIES MagnumText ${GL_TEST_LIBRARIES}) +endif() diff --git a/src/Text/Test/GlyphCacheGLTest.cpp b/src/Text/Test/GlyphCacheGLTest.cpp new file mode 100644 index 000000000..a46e8f583 --- /dev/null +++ b/src/Text/Test/GlyphCacheGLTest.cpp @@ -0,0 +1,83 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Test/AbstractOpenGLTester.h" +#include "Text/GlyphCache.h" + +namespace Magnum { namespace Text { namespace Test { + +class GlyphCacheGLTest: public Magnum::Test::AbstractOpenGLTester { + public: + explicit GlyphCacheGLTest(); + + void initialize(); + void access(); +}; + +GlyphCacheGLTest::GlyphCacheGLTest() { + addTests({&GlyphCacheGLTest::initialize, + &GlyphCacheGLTest::access}); +} + +void GlyphCacheGLTest::initialize() { + Text::GlyphCache cache({1024, 2048}); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(cache.texture()->imageSize(0), Vector2i(1024, 2048)); +} + +void GlyphCacheGLTest::access() { + Text::GlyphCache cache(Vector2i(236)); + Vector2i position; + Rectanglei rectangle; + + /* Default "Not Found" glyph */ + CORRADE_COMPARE(cache.glyphCount(), 1); + std::tie(position, rectangle) = cache[0]; + CORRADE_COMPARE(position, Vector2i(0, 0)); + CORRADE_COMPARE(rectangle, Rectanglei({0, 0}, {0, 0})); + + /* Overwrite "Not Found" glyph */ + cache.insert(0, {3, 5}, {{10, 10}, {23, 45}}); + CORRADE_COMPARE(cache.glyphCount(), 1); + std::tie(position, rectangle) = cache[0]; + CORRADE_COMPARE(position, Vector2i(3, 5)); + CORRADE_COMPARE(rectangle, Rectanglei({10, 10}, {23, 45})); + + /* Querying available glyph */ + cache.insert(25, {3, 4}, {{15, 30}, {45, 35}}); + CORRADE_COMPARE(cache.glyphCount(), 2); + std::tie(position, rectangle) = cache[25]; + CORRADE_COMPARE(position, Vector2i(3, 4)); + CORRADE_COMPARE(rectangle, Rectanglei({15, 30}, {45, 35})); + + /* Querying not available glyph falls back to "Not Found" */ + std::tie(position, rectangle) = cache[42]; + CORRADE_COMPARE(position, Vector2i(3, 5)); + CORRADE_COMPARE(rectangle, Rectanglei({10, 10}, {23, 45})); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Text::Test::GlyphCacheGLTest)