Fixed GCC warnings. Cleanup.

This commit is contained in:
bkaradzic 2013-05-15 19:42:39 -07:00
parent 75ef4b9d71
commit 9dfe1421d8
6 changed files with 547 additions and 536 deletions

View file

@ -1,67 +1,76 @@
/*
* Copyright 2013 Jeremie Roy. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
* Copyright 2013 Jeremie Roy. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "cube_atlas.h"
#include <bx/bx.h>
#include <bgfx.h>
#include <limits.h> // INT_MAX
#include <memory.h> // memset
#include <vector>
//********** Rectangle packer implementation ************
#include "cube_atlas.h"
class RectanglePacker
{
public:
RectanglePacker();
RectanglePacker(uint32_t _width, uint32_t _height);
RectanglePacker();
RectanglePacker(uint32_t _width, uint32_t _height);
/// non constructor initialization
void init(uint32_t _width, uint32_t _height);
/// find a suitable position for the given rectangle
/// @return true if the rectangle can be added, false otherwise
bool addRectangle(uint16_t _width, uint16_t _height, uint16_t& _outX, uint16_t& _outY);
/// return the used surface in squared unit
uint32_t getUsedSurface()
{
return m_usedSpace;
}
/// return the total available surface in squared unit
uint32_t getTotalSurface()
{
return m_width * m_height;
}
/// return the usage ratio of the available surface [0:1]
float getUsageRatio();
/// reset to initial state
void clear();
/// non constructor initialization
void init(uint32_t _width, uint32_t _height);
private:
int32_t fit(uint32_t _skylineNodeIndex, uint16_t _width, uint16_t _height);
/// Merges all skyline nodes that are at the same level.
void merge();
/// find a suitable position for the given rectangle
/// @return true if the rectangle can be added, false otherwise
bool addRectangle(uint16_t _width, uint16_t _height, uint16_t& _outX, uint16_t& _outY);
struct Node
{
Node(int16_t _x, int16_t _y, int16_t _width) : m_x(_x), m_y(_y), m_width(_width)
/// return the used surface in squared unit
uint32_t getUsedSurface()
{
return m_usedSpace;
}
/// The starting x-coordinate (leftmost).
int16_t m_x;
/// The y-coordinate of the skyline level line.
int16_t m_y;
/// The line _width. The ending coordinate (inclusive) will be x+width-1.
int32_t m_width; //32bit to avoid padding
};
/// return the total available surface in squared unit
uint32_t getTotalSurface()
{
return m_width * m_height;
}
/// width (in pixels) of the underlying texture
uint32_t m_width;
/// height (in pixels) of the underlying texture
uint32_t m_height;
/// Surface used in squared pixel
uint32_t m_usedSpace;
/// node of the skyline algorithm
std::vector<Node> m_skyline;
/// return the usage ratio of the available surface [0:1]
float getUsageRatio();
/// reset to initial state
void clear();
private:
int32_t fit(uint32_t _skylineNodeIndex, uint16_t _width, uint16_t _height);
/// Merges all skyline nodes that are at the same level.
void merge();
struct Node
{
Node(int16_t _x, int16_t _y, int16_t _width) : m_x(_x), m_y(_y), m_width(_width)
{
}
/// The starting x-coordinate (leftmost).
int16_t m_x;
/// The y-coordinate of the skyline level line.
int16_t m_y;
/// The line _width. The ending coordinate (inclusive) will be x+width-1.
int32_t m_width; // 32bit to avoid padding
};
/// width (in pixels) of the underlying texture
uint32_t m_width;
/// height (in pixels) of the underlying texture
uint32_t m_height;
/// Surface used in squared pixel
uint32_t m_usedSpace;
/// node of the skyline algorithm
std::vector<Node> m_skyline;
};
RectanglePacker::RectanglePacker() : m_width(0), m_height(0), m_usedSpace(0)
@ -110,8 +119,8 @@ bool RectanglePacker::addRectangle(uint16_t _width, uint16_t _height, uint16_t&
{
node = &m_skyline[ii];
if ( ( (y + _height) < best_height)
|| ( ( (y + _height) == best_height)
&& (node->m_width < best_width) ) )
|| ( ( (y + _height) == best_height)
&& (node->m_width < best_width) ) )
{
best_height = y + _height;
best_index = ii;
@ -239,8 +248,6 @@ void RectanglePacker::merge()
}
}
//********** Cube Atlas implementation ************
struct Atlas::PackedLayer
{
RectanglePacker packer;
@ -250,9 +257,9 @@ struct Atlas::PackedLayer
Atlas::Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount)
{
BX_CHECK(_textureSize >= 64
&& _textureSize <= 4096, "suspicious texture size");
&& _textureSize <= 4096, "suspicious texture size");
BX_CHECK(_maxRegionsCount >= 64
&& _maxRegionsCount <= 32000, "suspicious _regions count");
&& _maxRegionsCount <= 32000, "suspicious _regions count");
m_layers = new PackedLayer[24];
for (int ii = 0; ii < 24; ++ii)
{
@ -278,18 +285,18 @@ Atlas::Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount)
//memset(mem->data, 255, mem->size);
const bgfx::Memory* mem = NULL;
m_textureHandle = bgfx::createTextureCube(6
, _textureSize
, 1
, bgfx::TextureFormat::BGRA8
, flags
, mem
);
, _textureSize
, 1
, bgfx::TextureFormat::BGRA8
, flags
, mem
);
}
Atlas::Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _regionCount, const uint8_t* _regionBuffer, uint16_t _maxRegionsCount)
{
BX_CHECK(_regionCount <= 64
&& _maxRegionsCount <= 4096, "suspicious initialization");
&& _maxRegionsCount <= 4096, "suspicious initialization");
//layers are frozen
m_usedLayers = 24;
m_usedFaces = 6;
@ -317,12 +324,12 @@ Atlas::Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _reg
memcpy(m_textureBuffer, _textureBuffer, getTextureBufferSize() );
m_textureHandle = bgfx::createTextureCube(6
, _textureSize
, 1
, bgfx::TextureFormat::BGRA8
, flags
, bgfx::makeRef(m_textureBuffer, getTextureBufferSize() )
);
, _textureSize
, 1
, bgfx::TextureFormat::BGRA8
, flags
, bgfx::makeRef(m_textureBuffer, getTextureBufferSize() )
);
}
Atlas::~Atlas()
@ -360,7 +367,7 @@ uint16_t Atlas::addRegion(uint16_t _width, uint16_t _height, const uint8_t* _bit
{
//do we have still room to add layers ?
if ( (idx + _type) > 24
|| m_usedFaces >= 6)
|| m_usedFaces >= 6)
{
return UINT16_MAX;
}

View file

@ -50,120 +50,121 @@ struct AtlasRegion
class Atlas
{
public:
/// create an empty dynamic atlas (region can be updated and added)
/// @param textureSize an atlas creates a texture cube of 6 faces with size equal to (textureSize*textureSize * sizeof(RGBA))
/// @param maxRegionCount maximum number of region allowed in the atlas
Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount = 4096);
/// create an empty dynamic atlas (region can be updated and added)
/// @param textureSize an atlas creates a texture cube of 6 faces with size equal to (textureSize*textureSize * sizeof(RGBA))
/// @param maxRegionCount maximum number of region allowed in the atlas
Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount = 4096);
/// initialize a static atlas with serialized data (region can be updated but not added)
/// @param textureSize an atlas creates a texture cube of 6 faces with size equal to (textureSize*textureSize * sizeof(RGBA))
/// @param textureBuffer buffer of size 6*textureSize*textureSize*sizeof(uint32_t) (will be copied)
/// @param regionCount number of region in the Atlas
/// @param regionBuffer buffer containing the region (will be copied)
/// @param maxRegionCount maximum number of region allowed in the atlas
Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _regionCount, const uint8_t* _regionBuffer, uint16_t _maxRegionsCount = 4096);
~Atlas();
/// initialize a static atlas with serialized data (region can be updated but not added)
/// @param textureSize an atlas creates a texture cube of 6 faces with size equal to (textureSize*textureSize * sizeof(RGBA))
/// @param textureBuffer buffer of size 6*textureSize*textureSize*sizeof(uint32_t) (will be copied)
/// @param regionCount number of region in the Atlas
/// @param regionBuffer buffer containing the region (will be copied)
/// @param maxRegionCount maximum number of region allowed in the atlas
Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _regionCount, const uint8_t* _regionBuffer, uint16_t _maxRegionsCount = 4096);
~Atlas();
/// add a region to the atlas, and copy the content of mem to the underlying texture
uint16_t addRegion(uint16_t _width, uint16_t _height, const uint8_t* _bitmapBuffer, AtlasRegion::Type _type = AtlasRegion::TYPE_BGRA8, uint16_t outline = 0);
/// add a region to the atlas, and copy the content of mem to the underlying texture
uint16_t addRegion(uint16_t _width, uint16_t _height, const uint8_t* _bitmapBuffer, AtlasRegion::Type _type = AtlasRegion::TYPE_BGRA8, uint16_t outline = 0);
/// update a preallocated region
void updateRegion(const AtlasRegion& _region, const uint8_t* _bitmapBuffer);
/// update a preallocated region
void updateRegion(const AtlasRegion& _region, const uint8_t* _bitmapBuffer);
/// Pack the UV coordinates of the four corners of a region to a vertex buffer using the supplied vertex format.
/// v0 -- v3
/// | | encoded in that order: v0,v1,v2,v3
/// v1 -- v2
/// @remark the UV are four signed short normalized components.
/// @remark the x,y,z components encode cube uv coordinates. The w component encode the color channel if any.
/// @param handle handle to the region we are interested in
/// @param vertexBuffer address of the first vertex we want to update. Must be valid up to vertexBuffer + offset + 3*stride + 4*sizeof(int16_t), which means the buffer must contains at least 4 vertex includind the first.
/// @param offset byte offset to the first uv coordinate of the vertex in the buffer
/// @param stride stride between tho UV coordinates, usually size of a Vertex.
void packUV(uint16_t _regionHandle, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
void packUV(const AtlasRegion& _region, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
/// Pack the UV coordinates of the four corners of a region to a vertex buffer using the supplied vertex format.
/// v0 -- v3
/// | | encoded in that order: v0,v1,v2,v3
/// v1 -- v2
/// @remark the UV are four signed short normalized components.
/// @remark the x,y,z components encode cube uv coordinates. The w component encode the color channel if any.
/// @param handle handle to the region we are interested in
/// @param vertexBuffer address of the first vertex we want to update. Must be valid up to vertexBuffer + offset + 3*stride + 4*sizeof(int16_t), which means the buffer must contains at least 4 vertex includind the first.
/// @param offset byte offset to the first uv coordinate of the vertex in the buffer
/// @param stride stride between tho UV coordinates, usually size of a Vertex.
void packUV(uint16_t _regionHandle, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
void packUV(const AtlasRegion& _region, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
/// Same as packUV but pack a whole face of the atlas cube, mostly used for debugging and visualizing atlas
void packFaceLayerUV(uint32_t _idx, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
/// Same as packUV but pack a whole face of the atlas cube, mostly used for debugging and visualizing atlas
void packFaceLayerUV(uint32_t _idx, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride);
/// Pack the vertex index of the region as 2 quad into an index buffer
void packIndex(uint16_t* _indexBuffer, uint32_t _startIndex, uint32_t _startVertex)
{
_indexBuffer[_startIndex + 0] = _startVertex + 0;
_indexBuffer[_startIndex + 1] = _startVertex + 1;
_indexBuffer[_startIndex + 2] = _startVertex + 2;
_indexBuffer[_startIndex + 3] = _startVertex + 0;
_indexBuffer[_startIndex + 4] = _startVertex + 2;
_indexBuffer[_startIndex + 5] = _startVertex + 3;
}
/// Pack the vertex index of the region as 2 quad into an index buffer
void packIndex(uint16_t* _indexBuffer, uint32_t _startIndex, uint32_t _startVertex)
{
_indexBuffer[_startIndex + 0] = _startVertex + 0;
_indexBuffer[_startIndex + 1] = _startVertex + 1;
_indexBuffer[_startIndex + 2] = _startVertex + 2;
_indexBuffer[_startIndex + 3] = _startVertex + 0;
_indexBuffer[_startIndex + 4] = _startVertex + 2;
_indexBuffer[_startIndex + 5] = _startVertex + 3;
}
/// return the TextureHandle (cube) of the atlas
bgfx::TextureHandle getTextureHandle() const
{
return m_textureHandle;
}
/// return the TextureHandle (cube) of the atlas
bgfx::TextureHandle getTextureHandle() const
{
return m_textureHandle;
}
//retrieve a region info
const AtlasRegion& getRegion(uint16_t _handle) const
{
return m_regions[_handle];
}
//retrieve a region info
const AtlasRegion& getRegion(uint16_t _handle) const
{
return m_regions[_handle];
}
/// retrieve the size of side of a texture in pixels
uint16_t getTextureSize()
{
return m_textureSize;
}
/// retrieve the size of side of a texture in pixels
uint16_t getTextureSize()
{
return m_textureSize;
}
/// retrieve the usage ratio of the atlas
//float getUsageRatio() const { return 0.0f; }
/// retrieve the usage ratio of the atlas
//float getUsageRatio() const { return 0.0f; }
/// retrieve the numbers of region in the atlas
uint16_t getRegionCount() const
{
return m_regionCount;
}
/// retrieve the numbers of region in the atlas
uint16_t getRegionCount() const
{
return m_regionCount;
}
/// retrieve a pointer to the region buffer (in order to serialize it)
const AtlasRegion* getRegionBuffer() const
{
return m_regions;
}
/// retrieve a pointer to the region buffer (in order to serialize it)
const AtlasRegion* getRegionBuffer() const
{
return m_regions;
}
/// retrieve the byte size of the texture
uint32_t getTextureBufferSize() const
{
return 6 * m_textureSize * m_textureSize * 4;
}
/// retrieve the byte size of the texture
uint32_t getTextureBufferSize() const
{
return 6 * m_textureSize * m_textureSize * 4;
}
/// retrieve the mirrored texture buffer (to serialize it)
const uint8_t* getTextureBuffer() const
{
return m_textureBuffer;
}
/// retrieve the mirrored texture buffer (to serialize it)
const uint8_t* getTextureBuffer() const
{
return m_textureBuffer;
}
private:
void writeUV(uint8_t* _vertexBuffer, int16_t _x, int16_t _y, int16_t _z, int16_t _w)
{
( (uint16_t*) _vertexBuffer)[0] = _x;
( (uint16_t*) _vertexBuffer)[1] = _y;
( (uint16_t*) _vertexBuffer)[2] = _z;
( (uint16_t*) _vertexBuffer)[3] = _w;
}
void writeUV(uint8_t* _vertexBuffer, int16_t _x, int16_t _y, int16_t _z, int16_t _w)
{
( (uint16_t*) _vertexBuffer)[0] = _x;
( (uint16_t*) _vertexBuffer)[1] = _y;
( (uint16_t*) _vertexBuffer)[2] = _z;
( (uint16_t*) _vertexBuffer)[3] = _w;
}
struct PackedLayer;
PackedLayer* m_layers;
struct PackedLayer;
PackedLayer* m_layers;
uint32_t m_usedLayers;
uint32_t m_usedFaces;
uint32_t m_usedLayers;
uint32_t m_usedFaces;
bgfx::TextureHandle m_textureHandle;
uint16_t m_textureSize;
bgfx::TextureHandle m_textureHandle;
uint16_t m_textureSize;
uint16_t m_regionCount;
uint16_t m_maxRegionCount;
uint16_t m_regionCount;
uint16_t m_maxRegionCount;
AtlasRegion* m_regions;
uint8_t* m_textureBuffer;
AtlasRegion* m_regions;
uint8_t* m_textureBuffer;
};
#endif // __CUBE_ATLAS_H__

View file

@ -3,8 +3,7 @@
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "font_manager.h"
#include "../cube_atlas.h"
#include <bx/bx.h>
#if BX_COMPILER_MSVC
# pragma warning(push)
@ -20,7 +19,10 @@
#include <edtaa3/edtaa3func.h>
#include <edtaa3/edtaa3func.cpp>
#include <bx/bx.h>
#include <wchar.h> // wcslen
#include "font_manager.h"
#include "../cube_atlas.h"
#if BGFX_CONFIG_USE_TINYSTL
namespace tinystl
@ -39,7 +41,7 @@ namespace stl = tinystl;
# include <unordered_map>
namespace std
{ namespace tr1
{}
{}
}
namespace stl
{
@ -48,43 +50,44 @@ namespace stl
}
#endif // BGFX_CONFIG_USE_TINYSTL
class FontManager::TrueTypeFont
{
public:
TrueTypeFont();
~TrueTypeFont();
/// Initialize from an external buffer
/// @remark The ownership of the buffer is external, and you must ensure it stays valid up to this object lifetime
/// @return true if the initialization succeed
bool init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight);
/// return the font descriptor of the current font
FontInfo getFontInfo();
/// raster a glyph as 8bit alpha to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
bool bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
/// raster a glyph as 32bit subpixel rgba to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(uint32_t)
bool bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
/// raster a glyph as 8bit signed distance to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
bool bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
private:
void* m_font;
};
struct FTHolder
{
FT_Library library;
FT_Face face;
};
class FontManager::TrueTypeFont
{
public:
TrueTypeFont();
~TrueTypeFont();
/// Initialize from an external buffer
/// @remark The ownership of the buffer is external, and you must ensure it stays valid up to this object lifetime
/// @return true if the initialization succeed
bool init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight);
/// return the font descriptor of the current font
FontInfo getFontInfo();
/// raster a glyph as 8bit alpha to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
bool bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
/// raster a glyph as 32bit subpixel rgba to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(uint32_t)
bool bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
/// raster a glyph as 8bit signed distance to a memory buffer
/// update the GlyphInfo according to the raster strategy
/// @ remark buffer min size: glyphInfo.m_width * glyphInfo * height * sizeof(char)
bool bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
private:
FTHolder* m_font;
};
FontManager::TrueTypeFont::TrueTypeFont() : m_font(NULL)
{
}
@ -104,9 +107,9 @@ FontManager::TrueTypeFont::~TrueTypeFont()
bool FontManager::TrueTypeFont::init(const uint8_t* _buffer, uint32_t _bufferSize, int32_t _fontIndex, uint32_t _pixelHeight)
{
BX_CHECK( (_bufferSize > 256
&& _bufferSize < 100000000), "TrueType buffer size is suspicious");
&& _bufferSize < 100000000), "TrueType buffer size is suspicious");
BX_CHECK( (_pixelHeight > 4
&& _pixelHeight < 128), "TrueType buffer size is suspicious");
&& _pixelHeight < 128), "TrueType buffer size is suspicious");
BX_CHECK(m_font == NULL, "TrueTypeFont already initialized");
@ -228,7 +231,7 @@ bool FontManager::TrueTypeFont::bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo
for (int32_t ii = 0; ii < h; ++ii)
{
memcpy(_outBuffer + (ii * w) * charsize * depth,
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
}
FT_Done_Glyph(glyph);
@ -280,7 +283,7 @@ bool FontManager::TrueTypeFont::bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphI
for (int32_t ii = 0; ii < h; ++ii)
{
memcpy(_outBuffer + (ii * w) * charsize * depth,
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
}
FT_Done_Glyph(glyph);
@ -442,7 +445,7 @@ bool FontManager::TrueTypeFont::bakeGlyphDistance(CodePoint_t _codePoint, GlyphI
for (int32_t ii = 0; ii < h; ++ii)
{
memcpy(_outBuffer + (ii * w) * charsize * depth,
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
bitmap->bitmap.buffer + (ii * stride) * charsize, w * charsize * depth);
}
FT_Done_Glyph(glyph);
@ -487,8 +490,6 @@ bool FontManager::TrueTypeFont::bakeGlyphDistance(CodePoint_t _codePoint, GlyphI
return true;
}
//*************************************************************
typedef stl::unordered_map<CodePoint_t, GlyphInfo> GlyphHash_t;
// cache font data
struct FontManager::CachedFont
@ -509,17 +510,21 @@ const uint16_t MAX_OPENED_FILES = 64;
const uint16_t MAX_OPENED_FONT = 64;
const uint32_t MAX_FONT_BUFFER_SIZE = 512 * 512 * 4;
FontManager::FontManager(Atlas* _atlas) : m_filesHandles(MAX_OPENED_FILES), m_fontHandles(MAX_OPENED_FONT)
FontManager::FontManager(Atlas* _atlas)
: m_ownAtlas(false)
, m_atlas(_atlas)
, m_fontHandles(MAX_OPENED_FONT)
, m_filesHandles(MAX_OPENED_FILES)
{
m_atlas = _atlas;
m_ownAtlas = false;
init();
}
FontManager::FontManager(uint32_t _textureSideWidth) : m_filesHandles(MAX_OPENED_FILES), m_fontHandles(MAX_OPENED_FONT)
FontManager::FontManager(uint32_t _textureSideWidth)
: m_ownAtlas(true)
, m_atlas(new Atlas(_textureSideWidth) )
, m_fontHandles(MAX_OPENED_FONT)
, m_filesHandles(MAX_OPENED_FILES)
{
m_atlas = new Atlas(_textureSideWidth);
m_ownAtlas = true;
init();
}
@ -758,9 +763,9 @@ bool FontManager::preloadGlyph(FontHandle _handle, CodePoint_t _codePoint)
font.trueTypeFont->bakeGlyphAlpha(_codePoint, glyphInfo, m_buffer);
break;
//case FONT_TYPE_LCD:
//font.m_trueTypeFont->bakeGlyphSubpixel(codePoint, glyphInfo, m_buffer);
//break;
//case FONT_TYPE_LCD:
//font.m_trueTypeFont->bakeGlyphSubpixel(codePoint, glyphInfo, m_buffer);
//break;
case FONT_TYPE_DISTANCE:
font.trueTypeFont->bakeGlyphDistance(_codePoint, glyphInfo, m_buffer);
break;
@ -842,8 +847,6 @@ bool FontManager::getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, Glyph
return true;
}
// ****************************************************************************
bool FontManager::addBitmap(GlyphInfo& _glyphInfo, const uint8_t* _data)
{
_glyphInfo.regionIndex = m_atlas->addRegion( (uint16_t) ceil(_glyphInfo.width), (uint16_t) ceil(_glyphInfo.height), _data, AtlasRegion::TYPE_GRAY);

View file

@ -115,100 +115,100 @@ BGFX_HANDLE(FontHandle);
class FontManager
{
public:
/// create the font manager using an external cube atlas (doesn't take ownership of the atlas)
FontManager(Atlas* _atlas);
/// create the font manager and create the texture cube as BGRA8 with linear filtering
FontManager(uint32_t _textureSideWidth = 512);
/// create the font manager using an external cube atlas (doesn't take ownership of the atlas)
FontManager(Atlas* _atlas);
/// create the font manager and create the texture cube as BGRA8 with linear filtering
FontManager(uint32_t _textureSideWidth = 512);
~FontManager();
~FontManager();
/// retrieve the atlas used by the font manager (e.g. to add stuff to it)
Atlas* getAtlas()
{
return m_atlas;
}
/// retrieve the atlas used by the font manager (e.g. to add stuff to it)
Atlas* getAtlas()
{
return m_atlas;
}
/// load a TrueType font from a file path
/// @return invalid handle if the loading fail
TrueTypeHandle loadTrueTypeFromFile(const char* _fontPath);
/// load a TrueType font from a file path
/// @return invalid handle if the loading fail
TrueTypeHandle loadTrueTypeFromFile(const char* _fontPath);
/// load a TrueType font from a given buffer.
/// the buffer is copied and thus can be freed or reused after this call
/// @return invalid handle if the loading fail
TrueTypeHandle loadTrueTypeFromMemory(const uint8_t* _buffer, uint32_t _size);
/// load a TrueType font from a given buffer.
/// the buffer is copied and thus can be freed or reused after this call
/// @return invalid handle if the loading fail
TrueTypeHandle loadTrueTypeFromMemory(const uint8_t* _buffer, uint32_t _size);
/// unload a TrueType font (free font memory) but keep loaded glyphs
void unloadTrueType(TrueTypeHandle _handle);
/// unload a TrueType font (free font memory) but keep loaded glyphs
void unloadTrueType(TrueTypeHandle _handle);
/// return a font whose height is a fixed pixel size
FontHandle createFontByPixelSize(TrueTypeHandle _handle, uint32_t _typefaceIndex, uint32_t _pixelSize, FontType _fontType = FONT_TYPE_ALPHA);
/// return a font whose height is a fixed pixel size
FontHandle createFontByPixelSize(TrueTypeHandle _handle, uint32_t _typefaceIndex, uint32_t _pixelSize, FontType _fontType = FONT_TYPE_ALPHA);
/// return a scaled child font whose height is a fixed pixel size
FontHandle createScaledFontToPixelSize(FontHandle _baseFontHandle, uint32_t _pixelSize);
/// return a scaled child font whose height is a fixed pixel size
FontHandle createScaledFontToPixelSize(FontHandle _baseFontHandle, uint32_t _pixelSize);
/// load a baked font (the set of glyph is fixed)
/// @return INVALID_HANDLE if the loading fail
FontHandle loadBakedFontFromFile(const char* _imagePath, const char* _descriptorPath);
/// load a baked font (the set of glyph is fixed)
/// @return INVALID_HANDLE if the loading fail
FontHandle loadBakedFontFromFile(const char* _imagePath, const char* _descriptorPath);
/// load a baked font (the set of glyph is fixed)
/// @return INVALID_HANDLE if the loading fail
FontHandle loadBakedFontFromMemory(const uint8_t* _imageBuffer, uint32_t _imageSize, const uint8_t* _descriptorBuffer, uint32_t _descriptorSize);
/// load a baked font (the set of glyph is fixed)
/// @return INVALID_HANDLE if the loading fail
FontHandle loadBakedFontFromMemory(const uint8_t* _imageBuffer, uint32_t _imageSize, const uint8_t* _descriptorBuffer, uint32_t _descriptorSize);
/// destroy a font (truetype or baked)
void destroyFont(FontHandle _handle);
/// destroy a font (truetype or baked)
void destroyFont(FontHandle _handle);
/// Preload a set of glyphs from a TrueType file
/// @return true if every glyph could be preloaded, false otherwise
/// if the Font is a baked font, this only do validation on the characters
bool preloadGlyph(FontHandle _handle, const wchar_t* _string);
/// Preload a set of glyphs from a TrueType file
/// @return true if every glyph could be preloaded, false otherwise
/// if the Font is a baked font, this only do validation on the characters
bool preloadGlyph(FontHandle _handle, const wchar_t* _string);
/// Preload a single glyph, return true on success
bool preloadGlyph(FontHandle _handle, CodePoint_t _character);
/// Preload a single glyph, return true on success
bool preloadGlyph(FontHandle _handle, CodePoint_t _character);
/// bake a font to disk (the set of preloaded glyph)
/// @return true if the baking succeed, false otherwise
bool saveBakedFont(FontHandle _handle, const char* _fontDirectory, const char* _fontName);
/// bake a font to disk (the set of preloaded glyph)
/// @return true if the baking succeed, false otherwise
bool saveBakedFont(FontHandle _handle, const char* _fontDirectory, const char* _fontName);
/// return the font descriptor of a font
/// @remark the handle is required to be valid
const FontInfo& getFontInfo(FontHandle _handle);
/// return the font descriptor of a font
/// @remark the handle is required to be valid
const FontInfo& getFontInfo(FontHandle _handle);
/// Return the rendering informations about the glyph region
/// Load the glyph from a TrueType font if possible
/// @return true if the Glyph is available
bool getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, GlyphInfo& _outInfo);
/// Return the rendering informations about the glyph region
/// Load the glyph from a TrueType font if possible
/// @return true if the Glyph is available
bool getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, GlyphInfo& _outInfo);
GlyphInfo& getBlackGlyph()
{
return m_blackGlyph;
}
GlyphInfo& getBlackGlyph()
{
return m_blackGlyph;
}
class TrueTypeFont; //public to shut off Intellisense warning
class TrueTypeFont; //public to shut off Intellisense warning
private:
struct CachedFont;
struct CachedFile
{
uint8_t* buffer;
uint32_t bufferSize;
};
struct CachedFont;
struct CachedFile
{
uint8_t* buffer;
uint32_t bufferSize;
};
void init();
bool addBitmap(GlyphInfo& _glyphInfo, const uint8_t* _data);
void init();
bool addBitmap(GlyphInfo& _glyphInfo, const uint8_t* _data);
bool m_ownAtlas;
Atlas* m_atlas;
bool m_ownAtlas;
Atlas* m_atlas;
bx::HandleAlloc m_fontHandles;
CachedFont* m_cachedFonts;
bx::HandleAlloc m_fontHandles;
CachedFont* m_cachedFonts;
bx::HandleAlloc m_filesHandles;
CachedFile* m_cachedFiles;
bx::HandleAlloc m_filesHandles;
CachedFile* m_cachedFiles;
GlyphInfo m_blackGlyph;
GlyphInfo m_blackGlyph;
//temporary buffer to raster glyph
uint8_t* m_buffer;
//temporary buffer to raster glyph
uint8_t* m_buffer;
};
#endif // __FONT_MANAGER_H__

View file

@ -3,12 +3,14 @@
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <bx/bx.h>
#include <stddef.h> // offsetof
#include <memory.h> // memcpy
#include <wchar.h> // wcslen
#include "text_buffer_manager.h"
#include "../cube_atlas.h"
#include <bx/bx.h>
#include <stddef.h> /* offsetof */
#include "vs_font_basic.bin.h"
#include "fs_font_basic.bin.h"
#include "vs_font_distance_field.bin.h"
@ -49,8 +51,8 @@ inline uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte)
uint32_t type = utf8d[byte];
*codep = (*state != UTF8_ACCEPT) ?
(byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte);
(byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte);
*state = utf8d[256 + *state * 16 + type];
return *state;
@ -76,156 +78,156 @@ class TextBuffer
{
public:
/// TextBuffer is bound to a fontManager for glyph retrieval
/// @remark the ownership of the manager is not taken
TextBuffer(FontManager* _fontManager);
~TextBuffer();
/// TextBuffer is bound to a fontManager for glyph retrieval
/// @remark the ownership of the manager is not taken
TextBuffer(FontManager* _fontManager);
~TextBuffer();
void setStyle(uint32_t _flags = STYLE_NORMAL)
{
m_styleFlags = _flags;
}
void setTextColor(uint32_t _rgba = 0x000000FF)
{
m_textColor = toABGR(_rgba);
}
void setBackgroundColor(uint32_t _rgba = 0x000000FF)
{
m_backgroundColor = toABGR(_rgba);
}
void setStyle(uint32_t _flags = STYLE_NORMAL)
{
m_styleFlags = _flags;
}
void setTextColor(uint32_t _rgba = 0x000000FF)
{
m_textColor = toABGR(_rgba);
}
void setBackgroundColor(uint32_t _rgba = 0x000000FF)
{
m_backgroundColor = toABGR(_rgba);
}
void setOverlineColor(uint32_t _rgba = 0x000000FF)
{
m_overlineColor = toABGR(_rgba);
}
void setUnderlineColor(uint32_t _rgba = 0x000000FF)
{
m_underlineColor = toABGR(_rgba);
}
void setStrikeThroughColor(uint32_t _rgba = 0x000000FF)
{
m_strikeThroughColor = toABGR(_rgba);
}
void setOverlineColor(uint32_t _rgba = 0x000000FF)
{
m_overlineColor = toABGR(_rgba);
}
void setUnderlineColor(uint32_t _rgba = 0x000000FF)
{
m_underlineColor = toABGR(_rgba);
}
void setStrikeThroughColor(uint32_t _rgba = 0x000000FF)
{
m_strikeThroughColor = toABGR(_rgba);
}
void setPenPosition(float _x, float _y)
{
m_penX = _x; m_penY = _y;
}
void setPenPosition(float _x, float _y)
{
m_penX = _x; m_penY = _y;
}
/// return the size of the text
//Rectangle measureText(FontHandle _fontHandle, const char * _string);
//Rectangle measureText(FontHandle _fontHandle, const wchar_t * _string);
/// return the size of the text
//Rectangle measureText(FontHandle _fontHandle, const char * _string);
//Rectangle measureText(FontHandle _fontHandle, const wchar_t * _string);
/// append an ASCII/utf-8 string to the buffer using current pen position and color
void appendText(FontHandle _fontHandle, const char* _string);
/// append an ASCII/utf-8 string to the buffer using current pen position and color
void appendText(FontHandle _fontHandle, const char* _string);
/// append a wide char unicode string to the buffer using current pen position and color
void appendText(FontHandle _fontHandle, const wchar_t* _string);
/// append a wide char unicode string to the buffer using current pen position and color
void appendText(FontHandle _fontHandle, const wchar_t* _string);
/// Clear the text buffer and reset its state (pen/color)
void clearTextBuffer();
/// Clear the text buffer and reset its state (pen/color)
void clearTextBuffer();
/// get pointer to the vertex buffer to submit it to the graphic card
const uint8_t* getVertexBuffer()
{
return (uint8_t*) m_vertexBuffer;
}
/// number of vertex in the vertex buffer
uint32_t getVertexCount()
{
return m_vertexCount;
}
/// size in bytes of a vertex
uint32_t getVertexSize()
{
return sizeof(TextVertex);
}
/// get pointer to the vertex buffer to submit it to the graphic card
const uint8_t* getVertexBuffer()
{
return (uint8_t*) m_vertexBuffer;
}
/// number of vertex in the vertex buffer
uint32_t getVertexCount()
{
return m_vertexCount;
}
/// size in bytes of a vertex
uint32_t getVertexSize()
{
return sizeof(TextVertex);
}
/// get a pointer to the index buffer to submit it to the graphic
const uint16_t* getIndexBuffer()
{
return m_indexBuffer;
}
/// number of index in the index buffer
uint32_t getIndexCount()
{
return m_indexCount;
}
/// size in bytes of an index
uint32_t getIndexSize()
{
return sizeof(uint16_t);
}
/// get a pointer to the index buffer to submit it to the graphic
const uint16_t* getIndexBuffer()
{
return m_indexBuffer;
}
/// number of index in the index buffer
uint32_t getIndexCount()
{
return m_indexCount;
}
/// size in bytes of an index
uint32_t getIndexSize()
{
return sizeof(uint16_t);
}
uint32_t getTextColor()
{
return toABGR(m_textColor);
}
uint32_t getTextColor()
{
return toABGR(m_textColor);
}
TextRectangle getRectangle() const
{
return m_rectangle;
}
TextRectangle getRectangle() const
{
return m_rectangle;
}
private:
void appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom);
uint32_t toABGR(uint32_t _rgba)
{
return ( ( (_rgba >> 0) & 0xff) << 24) |
( ( (_rgba >> 8) & 0xff) << 16) |
( ( (_rgba >> 16) & 0xff) << 8) |
( ( (_rgba >> 24) & 0xff) << 0);
}
void appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom);
uint32_t toABGR(uint32_t _rgba)
{
return ( ( (_rgba >> 0) & 0xff) << 24) |
( ( (_rgba >> 8) & 0xff) << 16) |
( ( (_rgba >> 16) & 0xff) << 8) |
( ( (_rgba >> 24) & 0xff) << 0);
}
uint32_t m_styleFlags;
uint32_t m_styleFlags;
// color states
uint32_t m_textColor;
// color states
uint32_t m_textColor;
uint32_t m_backgroundColor;
uint32_t m_overlineColor;
uint32_t m_underlineColor;
uint32_t m_strikeThroughColor;
uint32_t m_backgroundColor;
uint32_t m_overlineColor;
uint32_t m_underlineColor;
uint32_t m_strikeThroughColor;
//position states
float m_penX;
float m_penY;
//position states
float m_penX;
float m_penY;
float m_originX;
float m_originY;
float m_originX;
float m_originY;
float m_lineAscender;
float m_lineDescender;
float m_lineGap;
float m_lineAscender;
float m_lineDescender;
float m_lineGap;
TextRectangle m_rectangle;
TextRectangle m_rectangle;
///
FontManager* m_fontManager;
///
FontManager* m_fontManager;
void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL)
{
m_vertexBuffer[_i].x = _x;
m_vertexBuffer[_i].y = _y;
m_vertexBuffer[_i].rgba = _rgba;
m_styleBuffer[_i] = _style;
}
void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL)
{
m_vertexBuffer[_i].x = _x;
m_vertexBuffer[_i].y = _y;
m_vertexBuffer[_i].rgba = _rgba;
m_styleBuffer[_i] = _style;
}
struct TextVertex
{
float x, y;
int16_t u, v, w, t;
uint32_t rgba;
};
struct TextVertex
{
float x, y;
int16_t u, v, w, t;
uint32_t rgba;
};
TextVertex* m_vertexBuffer;
uint16_t* m_indexBuffer;
uint8_t* m_styleBuffer;
TextVertex* m_vertexBuffer;
uint16_t* m_indexBuffer;
uint8_t* m_styleBuffer;
uint32_t m_vertexCount;
uint32_t m_indexCount;
uint32_t m_lineStartIndex;
uint32_t m_vertexCount;
uint32_t m_indexCount;
uint32_t m_lineStartIndex;
};
TextBuffer::TextBuffer(FontManager* _fontManager)
@ -369,7 +371,7 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
}
if (_font.ascender > m_lineAscender
|| (_font.descender < m_lineDescender) )
|| (_font.descender < m_lineDescender) )
{
if (_font.descender < m_lineDescender)
{
@ -398,7 +400,7 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
GlyphInfo& blackGlyph = m_fontManager->getBlackGlyph();
if (m_styleFlags & STYLE_BACKGROUND
&& m_backgroundColor & 0xFF000000)
&& m_backgroundColor & 0xFF000000)
{
float x0 = (m_penX - kerning);
float y0 = (m_penY - m_lineAscender);
@ -423,7 +425,7 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
}
if (m_styleFlags & STYLE_UNDERLINE
&& m_underlineColor & 0xFF000000)
&& m_underlineColor & 0xFF000000)
{
float x0 = (m_penX - kerning);
float y0 = (m_penY - m_lineDescender / 2);
@ -448,7 +450,7 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
}
if (m_styleFlags & STYLE_OVERLINE
&& m_overlineColor & 0xFF000000)
&& m_overlineColor & 0xFF000000)
{
float x0 = (m_penX - kerning);
float y0 = (m_penY - _font.ascender);
@ -473,7 +475,7 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
}
if (m_styleFlags & STYLE_STRIKE_THROUGH
&& m_strikeThroughColor & 0xFF000000)
&& m_strikeThroughColor & 0xFF000000)
{
float x0 = (m_penX - kerning);
float y0 = (m_penY - _font.ascender / 3);
@ -556,8 +558,6 @@ void TextBuffer::verticalCenterLastLine(float _dy, float _top, float _bottom)
}
}
// ****************************************************************
TextBufferManager::TextBufferManager(FontManager* _fontManager) : m_fontManager(_fontManager), m_textBufferHandles(MAX_TEXT_BUFFER_COUNT)
{
m_textBuffers = new BufferCache[MAX_TEXT_BUFFER_COUNT];
@ -675,16 +675,16 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle)
switch (bc.bufferType)
{
case STATIC:
{
bgfx::IndexBufferHandle ibh;
bgfx::VertexBufferHandle vbh;
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
bgfx::destroyIndexBuffer(ibh);
bgfx::destroyVertexBuffer(vbh);
}
{
bgfx::IndexBufferHandle ibh;
bgfx::VertexBufferHandle vbh;
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
bgfx::destroyIndexBuffer(ibh);
bgfx::destroyVertexBuffer(vbh);
}
break;
break;
case DYNAMIC:
bgfx::DynamicIndexBufferHandle ibh;
@ -735,80 +735,80 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id,
switch (bc.bufferType)
{
case STATIC:
{
bgfx::IndexBufferHandle ibh;
bgfx::VertexBufferHandle vbh;
if (bc.vertexBufferHandle == bgfx::invalidHandle)
{
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
ibh = bgfx::createIndexBuffer(mem);
bgfx::IndexBufferHandle ibh;
bgfx::VertexBufferHandle vbh;
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
vbh = bgfx::createVertexBuffer(mem, m_vertexDecl);
if (bc.vertexBufferHandle == bgfx::invalidHandle)
{
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
ibh = bgfx::createIndexBuffer(mem);
bc.indexBufferHandle = ibh.idx;
bc.vertexBufferHandle = vbh.idx;
}
else
{
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
}
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
vbh = bgfx::createVertexBuffer(mem, m_vertexDecl);
bgfx::setVertexBuffer(vbh, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(ibh, bc.textBuffer->getIndexCount() );
} break;
bc.indexBufferHandle = ibh.idx;
bc.vertexBufferHandle = vbh.idx;
}
else
{
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
}
bgfx::setVertexBuffer(vbh, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(ibh, bc.textBuffer->getIndexCount() );
} break;
case DYNAMIC:
{
bgfx::DynamicIndexBufferHandle ibh;
bgfx::DynamicVertexBufferHandle vbh;
if (bc.vertexBufferHandle == bgfx::invalidHandle)
{
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
ibh = bgfx::createDynamicIndexBuffer(mem);
bgfx::DynamicIndexBufferHandle ibh;
bgfx::DynamicVertexBufferHandle vbh;
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
vbh = bgfx::createDynamicVertexBuffer(mem, m_vertexDecl);
if (bc.vertexBufferHandle == bgfx::invalidHandle)
{
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
ibh = bgfx::createDynamicIndexBuffer(mem);
bc.indexBufferHandle = ibh.idx;
bc.vertexBufferHandle = vbh.idx;
}
else
{
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
vbh = bgfx::createDynamicVertexBuffer(mem, m_vertexDecl);
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
bgfx::updateDynamicIndexBuffer(ibh, mem);
bc.indexBufferHandle = ibh.idx;
bc.vertexBufferHandle = vbh.idx;
}
else
{
ibh.idx = bc.indexBufferHandle;
vbh.idx = bc.vertexBufferHandle;
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
bgfx::updateDynamicVertexBuffer(vbh, mem);
}
mem = bgfx::alloc(indexSize);
memcpy(mem->data, bc.textBuffer->getIndexBuffer(), indexSize);
bgfx::updateDynamicIndexBuffer(ibh, mem);
bgfx::setVertexBuffer(vbh, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(ibh, bc.textBuffer->getIndexCount() );
} break;
mem = bgfx::alloc(vertexSize);
memcpy(mem->data, bc.textBuffer->getVertexBuffer(), vertexSize);
bgfx::updateDynamicVertexBuffer(vbh, mem);
}
bgfx::setVertexBuffer(vbh, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(ibh, bc.textBuffer->getIndexCount() );
} break;
case TRANSIENT:
{
bgfx::TransientIndexBuffer tib;
bgfx::TransientVertexBuffer tvb;
bgfx::allocTransientIndexBuffer(&tib, bc.textBuffer->getIndexCount() );
bgfx::allocTransientVertexBuffer(&tvb, bc.textBuffer->getVertexCount(), m_vertexDecl);
memcpy(tib.data, bc.textBuffer->getIndexBuffer(), indexSize);
memcpy(tvb.data, bc.textBuffer->getVertexBuffer(), vertexSize);
bgfx::setVertexBuffer(&tvb, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(&tib, bc.textBuffer->getIndexCount() );
} break;
{
bgfx::TransientIndexBuffer tib;
bgfx::TransientVertexBuffer tvb;
bgfx::allocTransientIndexBuffer(&tib, bc.textBuffer->getIndexCount() );
bgfx::allocTransientVertexBuffer(&tvb, bc.textBuffer->getVertexCount(), m_vertexDecl);
memcpy(tib.data, bc.textBuffer->getIndexBuffer(), indexSize);
memcpy(tvb.data, bc.textBuffer->getVertexBuffer(), vertexSize);
bgfx::setVertexBuffer(&tvb, bc.textBuffer->getVertexCount() );
bgfx::setIndexBuffer(&tib, bc.textBuffer->getIndexCount() );
} break;
}
bgfx::submit(_id, _depth);

View file

@ -24,8 +24,8 @@ enum TextStyleFlags
STYLE_NORMAL = 0,
STYLE_OVERLINE = 1,
STYLE_UNDERLINE = 1 << 1,
STYLE_STRIKE_THROUGH = 1 << 2,
STYLE_BACKGROUND = 1 << 3,
STYLE_STRIKE_THROUGH = 1 << 2,
STYLE_BACKGROUND = 1 << 3,
};
struct TextRectangle
@ -37,63 +37,63 @@ class TextBuffer;
class TextBufferManager
{
public:
TextBufferManager(FontManager* _fontManager);
~TextBufferManager();
TextBufferManager(FontManager* _fontManager);
~TextBufferManager();
TextBufferHandle createTextBuffer(FontType _type, BufferType _bufferType);
void destroyTextBuffer(TextBufferHandle _handle);
void submitTextBuffer(TextBufferHandle _handle, uint8_t _id, int32_t _depth = 0);
void submitTextBufferMask(TextBufferHandle _handle, uint32_t _viewMask, int32_t _depth = 0);
TextBufferHandle createTextBuffer(FontType _type, BufferType _bufferType);
void destroyTextBuffer(TextBufferHandle _handle);
void submitTextBuffer(TextBufferHandle _handle, uint8_t _id, int32_t _depth = 0);
void submitTextBufferMask(TextBufferHandle _handle, uint32_t _viewMask, int32_t _depth = 0);
void setStyle(TextBufferHandle _handle, uint32_t _flags = STYLE_NORMAL);
void setTextColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setBackgroundColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setStyle(TextBufferHandle _handle, uint32_t _flags = STYLE_NORMAL);
void setTextColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setBackgroundColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setOverlineColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setUnderlineColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setStrikeThroughColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setOverlineColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setUnderlineColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setStrikeThroughColor(TextBufferHandle _handle, uint32_t _rgba = 0x000000FF);
void setPenPosition(TextBufferHandle _handle, float _x, float _y);
void setPenPosition(TextBufferHandle _handle, float _x, float _y);
/// append an ASCII/utf-8 string to the buffer using current pen position and color
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const char* _string);
/// append an ASCII/utf-8 string to the buffer using current pen position and color
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const char* _string);
/// append a wide char unicode string to the buffer using current pen position and color
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const wchar_t* _string);
/// append a wide char unicode string to the buffer using current pen position and color
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const wchar_t* _string);
/// Clear the text buffer and reset its state (pen/color)
void clearTextBuffer(TextBufferHandle _handle);
/// Clear the text buffer and reset its state (pen/color)
void clearTextBuffer(TextBufferHandle _handle);
TextRectangle getRectangle(TextBufferHandle _handle) const;
TextRectangle getRectangle(TextBufferHandle _handle) const;
/// return the size of the text
//Rectangle measureText(FontHandle fontHandle, const char * _string);
//Rectangle measureText(FontHandle fontHandle, const wchar_t * _string);
/// return the size of the text
//Rectangle measureText(FontHandle fontHandle, const char * _string);
//Rectangle measureText(FontHandle fontHandle, const wchar_t * _string);
private:
struct BufferCache
{
uint16_t indexBufferHandle;
uint16_t vertexBufferHandle;
TextBuffer* textBuffer;
BufferType bufferType;
FontType fontType;
};
struct BufferCache
{
uint16_t indexBufferHandle;
uint16_t vertexBufferHandle;
TextBuffer* textBuffer;
BufferType bufferType;
FontType fontType;
};
BufferCache* m_textBuffers;
bx::HandleAlloc m_textBufferHandles;
FontManager* m_fontManager;
bgfx::VertexDecl m_vertexDecl;
bgfx::UniformHandle u_texColor;
bgfx::UniformHandle u_inverse_gamma;
//shaders program
bgfx::ProgramHandle m_basicProgram;
bgfx::ProgramHandle m_distanceProgram;
bgfx::ProgramHandle m_distanceSubpixelProgram;
BufferCache* m_textBuffers;
bx::HandleAlloc m_textBufferHandles;
FontManager* m_fontManager;
bgfx::VertexDecl m_vertexDecl;
bgfx::UniformHandle u_texColor;
bgfx::UniformHandle u_inverse_gamma;
//shaders program
bgfx::ProgramHandle m_basicProgram;
bgfx::ProgramHandle m_distanceProgram;
bgfx::ProgramHandle m_distanceSubpixelProgram;
float m_height;
float m_width;
float m_height;
float m_width;
};
#endif // __TEXT_BUFFER_MANAGER_H__