Browse Source

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!
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
429bcdb09a
  1. 25
      src/Text/DistanceFieldGlyphCache.cpp
  2. 6
      src/Text/DistanceFieldGlyphCache.h
  3. 16
      src/Text/GlyphCache.cpp
  4. 43
      src/Text/GlyphCache.h

25
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<Extensions::GL::EXT::texture_rg>() ?
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<Extensions::GL::EXT::texture_rg>() ?
TextureFormat::Red : TextureFormat::RGB;
if(internalFormat == TextureFormat::RGB)
#ifdef MAGNUM_TARGET_GLES2
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>())
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);
}
}}

6
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

16
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) {

43
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<Vector2i, Rectanglei> 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<Rectanglei> reserve(const std::vector<Vector2i>& 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<UnsignedInt, std::pair<Vector2i, Rectanglei>> glyphs;
};

Loading…
Cancel
Save