From 429bcdb09a443ad5748cfc2da571e49023b4bb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 3 Jul 2013 00:03:58 +0200 Subject: [PATCH] Text: publicize glyph padding in GlyphCache, simplify internals. By publicizing and documenting what "originalSize" and "padding" means whole implementation and understanding is a lot simpler. Yay! --- src/Text/DistanceFieldGlyphCache.cpp | 25 ++++++++-------- src/Text/DistanceFieldGlyphCache.h | 6 ++-- src/Text/GlyphCache.cpp | 16 ++++++----- src/Text/GlyphCache.h | 43 +++++++++++++++++++--------- 4 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/Text/DistanceFieldGlyphCache.cpp b/src/Text/DistanceFieldGlyphCache.cpp index 78ce1b833..d0643d212 100644 --- a/src/Text/DistanceFieldGlyphCache.cpp +++ b/src/Text/DistanceFieldGlyphCache.cpp @@ -34,22 +34,23 @@ namespace Magnum { namespace Text { -DistanceFieldGlyphCache::DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& distanceFieldSize, UnsignedInt radius): GlyphCache(originalSize, Vector2i(radius)), scale(Vector2(distanceFieldSize)/originalSize), radius(radius) { +DistanceFieldGlyphCache::DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& size, const UnsignedInt radius): + #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) + GlyphCache(TextureFormat::R8, originalSize, size, Vector2i(radius)), + #else + GlyphCache(Context::current()->isExtensionSupported() ? + TextureFormat::Red : TextureFormat::RGB, originalSize, size, Vector2i(radius)), + #endif + scale(Vector2(size)/originalSize), radius(radius) +{ #ifndef MAGNUM_TARGET_GLES MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); #endif - #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) - const TextureFormat internalFormat = TextureFormat::R8; - #else - const TextureFormat internalFormat = - Context::current()->isExtensionSupported() ? - TextureFormat::Red : TextureFormat::RGB; - if(internalFormat == TextureFormat::RGB) + #ifdef MAGNUM_TARGET_GLES2 + if(!Context::current()->isExtensionSupported()) Warning() << "Text::DistanceFieldGlyphCache:" << Extensions::GL::EXT::texture_rg::string() << "not supported, using inefficient RGB format for glyph cache texture"; #endif - - initialize(internalFormat, distanceFieldSize); } void DistanceFieldGlyphCache::setImage(const Vector2i& offset, const ImageReference2D& image) { @@ -81,11 +82,11 @@ void DistanceFieldGlyphCache::setImage(const Vector2i& offset, const ImageRefere ->setImage(0, internalFormat, image); /* Create distance field from input texture */ - TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize(offset*scale, image.size()*scale), radius, image.size()); + TextureTools::distanceField(&input, texture(), Rectanglei::fromSize(offset*scale, image.size()*scale), radius, image.size()); } void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image) { - _texture.setSubImage(0, offset, image); + texture()->setSubImage(0, offset, image); } }} diff --git a/src/Text/DistanceFieldGlyphCache.h b/src/Text/DistanceFieldGlyphCache.h index 011d11943..892f20da9 100644 --- a/src/Text/DistanceFieldGlyphCache.h +++ b/src/Text/DistanceFieldGlyphCache.h @@ -57,8 +57,8 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { public: /** * @brief Constructor - * @param originalSize Original cache texture size - * @param distanceFieldSize Size of computed distance field texture + * @param originalSize Unscaled glyph cache texture size + * @param size Actual glyph cache texture size * @param radius Distance field computation radius * * See TextureTools::distanceField() for more information about the @@ -70,7 +70,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * possible to convert the RGB texture to Luminance after it has * been rendered when blitting is not supported to save memory? */ - explicit DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& distanceFieldSize, UnsignedInt radius); + explicit DistanceFieldGlyphCache(const Vector2i& originalSize, const Vector2i& size, UnsignedInt radius); /** * @brief Set cache image diff --git a/src/Text/GlyphCache.cpp b/src/Text/GlyphCache.cpp index cb99aa47a..6fbfc5313 100644 --- a/src/Text/GlyphCache.cpp +++ b/src/Text/GlyphCache.cpp @@ -31,7 +31,15 @@ namespace Magnum { namespace Text { -GlyphCache::GlyphCache(const Vector2i& size): _size(size) { +GlyphCache::GlyphCache(const TextureFormat internalFormat, const Vector2i& originalSize, const Vector2i& size, const Vector2i& padding): _size(originalSize), _padding(padding) { + initialize(internalFormat, size); +} + +GlyphCache::GlyphCache(const TextureFormat internalFormat, const Vector2i& size, const Vector2i& padding): _size(size), _padding(padding) { + initialize(internalFormat, size); +} + +GlyphCache::GlyphCache(const Vector2i& size, const Vector2i& padding): _size(size), _padding(padding) { #ifndef MAGNUM_TARGET_GLES MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); #endif @@ -47,12 +55,6 @@ GlyphCache::GlyphCache(const Vector2i& size): _size(size) { initialize(internalFormat, size); } -GlyphCache::GlyphCache(const Vector2i& size, const TextureFormat internalFormat): _size(size) { - initialize(internalFormat, size); -} - -GlyphCache::GlyphCache(const Vector2i& size, const Vector2i& padding): _size(size), _padding(padding) {} - GlyphCache::~GlyphCache() = default; void GlyphCache::initialize(const TextureFormat internalFormat, const Vector2i& size) { diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h index 527617f15..d790abc51 100644 --- a/src/Text/GlyphCache.h +++ b/src/Text/GlyphCache.h @@ -61,21 +61,33 @@ class MAGNUM_TEXT_EXPORT GlyphCache { public: /** * @brief Constructor - * @param size Glyph cache texture size * @param internalFormat Internal texture format + * @param originalSize Unscaled glyph cache texture size + * @param size Actual glyph cache texture size + * @param padding Padding around every glyph + * + * All glyphs parameters are saved relative to @p originalSize, + * although the actual glyph cache texture has @p size. Glyph + * @p padding can be used to account for e.g. glyph shadows. + */ + explicit GlyphCache(TextureFormat internalFormat, const Vector2i& originalSize, const Vector2i& size, const Vector2i& padding); + + /** + * @brief Constructor + * + * Same as calling the above with @p originalSize and @p size the same. */ - explicit GlyphCache(const Vector2i& size, TextureFormat internalFormat); + explicit GlyphCache(TextureFormat internalFormat, const Vector2i& size, const Vector2i& padding = Vector2i()); /** * @brief Constructor - * @param size Glyph cache texture size * * Sets internal texture format to red channel only. On desktop OpenGL * requires @extension{ARB,texture_rg} (also part of OpenGL ES 3.0), in * ES2 uses @es_extension{EXT,texture_rg}, if available, or * @ref TextureFormat "TextureFormat::Luminance" as fallback. */ - explicit GlyphCache(const Vector2i& size); + explicit GlyphCache(const Vector2i& size, const Vector2i& padding = Vector2i()); virtual ~GlyphCache(); @@ -86,6 +98,9 @@ class MAGNUM_TEXT_EXPORT GlyphCache { */ Vector2i textureSize() const { return _size; } + /** @brief Glyph padding */ + Vector2i padding() const { return _padding; } + /** @brief Count of glyphs in the cache */ std::size_t glyphCount() const { return glyphs.size(); } @@ -99,9 +114,12 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * First tuple element is glyph position relative to point on baseline, * second element is glyph region in texture atlas. * + * Returned values include padding. + * * 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(). + * @see padding() */ std::pair operator[](UnsignedInt glyph) const { auto it = glyphs.find(glyph); @@ -126,8 +144,11 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * was stored there, use insert() to store actual glyph on given * position and setImage() to upload glyph image. * + * Glyph @p sizes are expected to be without padding. + * * @attention Cache size must be large enough to contain all rendered * glyphs. + * @see padding() */ std::vector reserve(const std::vector& sizes); @@ -141,7 +162,10 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * can't overwrite already inserted glyph, however you can reset glyph * `0` to some meaningful value. * + * Glyph parameters are expected to be without padding. + * * See also setImage() to upload glyph image. + * @see padding() */ void insert(UnsignedInt glyph, Vector2i position, Rectanglei rectangle); @@ -153,21 +177,12 @@ class MAGNUM_TEXT_EXPORT GlyphCache { */ virtual void setImage(const Vector2i& offset, const ImageReference2D& image); - #ifdef DOXYGEN_GENERATING_OUTPUT private: - #else - protected: - #endif - /* Used from DistanceFieldGlyphCache */ - explicit MAGNUM_LOCAL GlyphCache(const Vector2i& size, const Vector2i& padding); - void MAGNUM_LOCAL initialize(TextureFormat internalFormat, const Vector2i& size); - const Vector2i _size; + Vector2i _size, _padding; Texture2D _texture; - private: - const Vector2i _padding; std::unordered_map> glyphs; };