mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-04-24 04:53:28 -04:00
Fixed GCC warnings. Cleanup.
This commit is contained in:
parent
75ef4b9d71
commit
9dfe1421d8
6 changed files with 547 additions and 536 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue