More cleanup.

This commit is contained in:
bkaradzic 2013-05-16 22:03:57 -07:00
parent 63041c5c73
commit 7eef7f52be
7 changed files with 172 additions and 230 deletions

View file

@ -1,4 +1,15 @@
#pragma once
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4100) // DISABLE warning C4100: '' : unreferenced formal parameter
# pragma warning(disable: 4146) // DISABLE warning C4146: unary minus operator applied to unsigned type, result still unsigned
# pragma warning(disable: 4700) // DISABLE warning C4700: uninitialized local variable 'temp' used
# pragma warning(disable: 4701) // DISABLE warning C4701: potentially uninitialized local variable '' used
#elif defined(__GNUC__)
# pragma GCC system_header
#endif // defined(__GNUC__)
/***************************************************************************/
/* */
/* ftsystem.c */
@ -117418,3 +117429,7 @@ FT_END_HEADER
(FT_Module_Requester) af_get_interface )
/* END */
/* END */
#if defined(_MSC_VER)
# pragma warning(pop)
#endif // defined(_MSC_VER)

View file

@ -4,20 +4,8 @@
*/
#include <bx/bx.h>
#if BX_COMPILER_MSVC
# pragma warning(push)
# pragma warning(disable: 4100) // DISABLE warning C4100: '' : unreferenced formal parameter
# pragma warning(disable: 4146) // DISABLE warning C4146: unary minus operator applied to unsigned type, result still unsigned
# pragma warning(disable: 4700) // DISABLE warning C4700: uninitialized local variable 'temp' used
# pragma warning(disable: 4701) // DISABLE warning C4701: potentially uninitialized local variable '' used
# include <freetype/freetype.h>
# pragma warning(pop)
#else
# include <freetype/freetype.h>
#endif // BX_COMPILER_MSVC
#include <edtaa3/edtaa3func.h>
#include <bgfx.h>
#include <freetype/freetype.h>
#include <edtaa3/edtaa3func.cpp>
#include <wchar.h> // wcslen
@ -73,17 +61,17 @@ public:
/// 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);
bool bakeGlyphAlpha(CodePoint _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);
bool bakeGlyphSubpixel(CodePoint _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);
bool bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _outGlyphInfo, uint8_t* _outBuffer);
private:
FTHolder* m_font;
@ -107,10 +95,8 @@ TrueTypeFont::~TrueTypeFont()
bool 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");
BX_CHECK( (_pixelHeight > 4
&& _pixelHeight < 128), "TrueType buffer size is suspicious");
BX_CHECK( (_bufferSize > 256 && _bufferSize < 100000000), "TrueType buffer size is suspicious");
BX_CHECK( (_pixelHeight > 4 && _pixelHeight < 128), "TrueType buffer size is suspicious");
BX_CHECK(m_font == NULL, "TrueTypeFont already initialized");
@ -169,7 +155,6 @@ FontInfo TrueTypeFont::getFontInfo()
BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
FTHolder* holder = (FTHolder*) m_font;
//todo manage unscalable font
BX_CHECK(FT_IS_SCALABLE(holder->face), "Font is unscalable");
FT_Size_Metrics metrics = holder->face->size->metrics;
@ -185,7 +170,7 @@ FontInfo TrueTypeFont::getFontInfo()
return outFontInfo;
}
bool TrueTypeFont::bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
bool TrueTypeFont::bakeGlyphAlpha(CodePoint _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
{
BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
FTHolder* holder = (FTHolder*) m_font;
@ -239,7 +224,7 @@ bool TrueTypeFont::bakeGlyphAlpha(CodePoint_t _codePoint, GlyphInfo& _glyphInfo,
return true;
}
bool TrueTypeFont::bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
bool TrueTypeFont::bakeGlyphSubpixel(CodePoint _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
{
BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
FTHolder* holder = (FTHolder*) m_font;
@ -291,23 +276,22 @@ bool TrueTypeFont::bakeGlyphSubpixel(CodePoint_t _codePoint, GlyphInfo& _glyphIn
return true;
}
//TODO optimize: remove dynamic allocation and convert double to float
void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int width, unsigned int height)
void make_distance_map(uint8_t* _img, uint8_t* _outImg, uint32_t _width, uint32_t _height)
{
short* xdist = (short*) malloc(width * height * sizeof(short) );
short* ydist = (short*) malloc(width * height * sizeof(short) );
double* gx = (double*) calloc(width * height, sizeof(double) );
double* gy = (double*) calloc(width * height, sizeof(double) );
double* data = (double*) calloc(width * height, sizeof(double) );
double* outside = (double*) calloc(width * height, sizeof(double) );
double* inside = (double*) calloc(width * height, sizeof(double) );
int16_t* xdist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
int16_t* ydist = (int16_t*)malloc(_width * _height * sizeof(int16_t) );
double* gx = (double*)calloc(_width * _height, sizeof(double) );
double* gy = (double*)calloc(_width * _height, sizeof(double) );
double* data = (double*)calloc(_width * _height, sizeof(double) );
double* outside = (double*)calloc(_width * _height, sizeof(double) );
double* inside = (double*)calloc(_width * _height, sizeof(double) );
uint32_t ii;
// Convert img into double (data)
double img_min = 255, img_max = -255;
for (ii = 0; ii < width * height; ++ii)
for (ii = 0; ii < _width * _height; ++ii)
{
double v = img[ii];
double v = _img[ii];
data[ii] = v;
if (v > img_max)
{
@ -321,15 +305,15 @@ void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int w
}
// Rescale image levels between 0 and 1
for (ii = 0; ii < width * height; ++ii)
for (ii = 0; ii < _width * _height; ++ii)
{
data[ii] = (img[ii] - img_min) / (img_max - img_min);
data[ii] = (_img[ii] - img_min) / (img_max - img_min);
}
// Compute outside = edtaa3(bitmap); % Transform background (0's)
computegradient(data, width, height, gx, gy);
edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
for (ii = 0; ii < width * height; ++ii)
computegradient(data, _width, _height, gx, gy);
edtaa3(data, gx, gy, _width, _height, xdist, ydist, outside);
for (ii = 0; ii < _width * _height; ++ii)
{
if (outside[ii] < 0)
{
@ -338,16 +322,16 @@ void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int w
}
// Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
memset(gx, 0, sizeof(double) * width * height);
memset(gy, 0, sizeof(double) * width * height);
for (ii = 0; ii < width * height; ++ii)
memset(gx, 0, sizeof(double) * _width * _height);
memset(gy, 0, sizeof(double) * _width * _height);
for (ii = 0; ii < _width * _height; ++ii)
{
data[ii] = 1.0 - data[ii];
}
computegradient(data, width, height, gx, gy);
edtaa3(data, gx, gy, width, height, xdist, ydist, inside);
for (ii = 0; ii < width * height; ++ii)
computegradient(data, _width, _height, gx, gy);
edtaa3(data, gx, gy, _width, _height, xdist, ydist, inside);
for (ii = 0; ii < _width * _height; ++ii)
{
if (inside[ii] < 0)
{
@ -356,22 +340,12 @@ void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int w
}
// distmap = outside - inside; % Bipolar distance field
unsigned char* out = outImg; //(unsigned char *) malloc( width * height * sizeof(unsigned char) );
for (ii = 0; ii < width * height; ++ii)
uint8_t* out = _outImg;
for (ii = 0; ii < _width * _height; ++ii)
{
//out[i] = 127 - outside[i]*8;
//if(out[i]<0) out[i] = 0;
//out[i] += inside[i]*16;
//if(out[i]>255) out[i] = 255;
outside[ii] -= inside[ii];
outside[ii] = 128 + outside[ii] * 16;
//if(outside[i] > 8) outside[i] = 8;
//if(inside[i] > 8) outside[i] = 8;
//outside[i] = 128 - inside[i]*8 + outside[i]*8;
if (outside[ii] < 0)
{
outside[ii] = 0;
@ -382,8 +356,7 @@ void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int w
outside[ii] = 255;
}
out[ii] = 255 - (unsigned char) outside[ii];
//out[i] = (unsigned char) outside[i];
out[ii] = 255 - (uint8_t) outside[ii];
}
free(xdist);
@ -395,7 +368,7 @@ void make_distance_map(unsigned char* img, unsigned char* outImg, unsigned int w
free(inside);
}
bool TrueTypeFont::bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
bool TrueTypeFont::bakeGlyphDistance(CodePoint _codePoint, GlyphInfo& _glyphInfo, uint8_t* _outBuffer)
{
BX_CHECK(m_font != NULL, "TrueTypeFont not initialized");
FTHolder* holder = (FTHolder*) m_font;
@ -491,7 +464,8 @@ bool TrueTypeFont::bakeGlyphDistance(CodePoint_t _codePoint, GlyphInfo& _glyphIn
return true;
}
typedef stl::unordered_map<CodePoint_t, GlyphInfo> GlyphHash_t;
typedef stl::unordered_map<CodePoint, GlyphInfo> GlyphHashMap;
// cache font data
struct FontManager::CachedFont
{
@ -500,7 +474,7 @@ struct FontManager::CachedFont
trueTypeFont = NULL; masterFontHandle.idx = -1;
}
FontInfo fontInfo;
GlyphHash_t cachedGlyphs;
GlyphHashMap cachedGlyphs;
TrueTypeFont* trueTypeFont;
// an handle to a master font in case of sub distance field font
FontHandle masterFontHandle;
@ -610,7 +584,6 @@ TrueTypeHandle FontManager::loadTrueTypeFromFile(const char* _fontPath)
return ret;
}
//TODO validate font
TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
return invalid;
}
@ -623,7 +596,6 @@ TrueTypeHandle FontManager::loadTrueTypeFromMemory(const uint8_t* _buffer, uint3
m_cachedFiles[id].bufferSize = _size;
memcpy(m_cachedFiles[id].buffer, _buffer, _size);
//TODO validate font
TrueTypeHandle ret = {id};
return ret;
}
@ -637,7 +609,7 @@ void FontManager::unloadTrueType(TrueTypeHandle _handle)
m_filesHandles.free(_handle.idx);
}
FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _tt_handle, uint32_t _typefaceIndex, uint32_t _pixelSize, FontType _fontType)
FontHandle FontManager::createFontByPixelSize(TrueTypeHandle _tt_handle, uint32_t _typefaceIndex, uint32_t _pixelSize, uint32_t _fontType)
{
BX_CHECK(bgfx::invalidHandle != _tt_handle.idx, "Invalid handle used");
@ -687,20 +659,6 @@ FontHandle FontManager::createScaledFontToPixelSize(FontHandle _baseFontHandle,
return ret;
}
FontHandle FontManager::loadBakedFontFromFile(const char* /*fontPath*/, const char* /*descriptorPath*/)
{
//assert(false); //TODO implement
FontHandle invalid = BGFX_INVALID_HANDLE;
return invalid;
}
FontHandle FontManager::loadBakedFontFromMemory(const uint8_t* /*imageBuffer*/, uint32_t /*imageSize*/, const uint8_t* /*descriptorBuffer*/, uint32_t /*descriptorSize*/)
{
//assert(false); //TODO implement
FontHandle invalid = BGFX_INVALID_HANDLE;
return invalid;
}
void FontManager::destroyFont(FontHandle _handle)
{
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
@ -727,7 +685,7 @@ bool FontManager::preloadGlyph(FontHandle _handle, const wchar_t* _string)
for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
{
//if glyph cached, continue
CodePoint_t codePoint = _string[ii];
CodePoint codePoint = _string[ii];
if (!preloadGlyph(_handle, codePoint) )
{
return false;
@ -740,13 +698,13 @@ bool FontManager::preloadGlyph(FontHandle _handle, const wchar_t* _string)
return false;
}
bool FontManager::preloadGlyph(FontHandle _handle, CodePoint_t _codePoint)
bool FontManager::preloadGlyph(FontHandle _handle, CodePoint _codePoint)
{
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");
CachedFont& font = m_cachedFonts[_handle.idx];
FontInfo& fontInfo = font.fontInfo;
//check if glyph not already present
GlyphHash_t::iterator iter = font.cachedGlyphs.find(_codePoint);
GlyphHashMap::iterator iter = font.cachedGlyphs.find(_codePoint);
if (iter != font.cachedGlyphs.end() )
{
return true;
@ -829,9 +787,9 @@ const FontInfo& FontManager::getFontInfo(FontHandle _handle)
return m_cachedFonts[_handle.idx].fontInfo;
}
bool FontManager::getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, GlyphInfo& _outInfo)
bool FontManager::getGlyphInfo(FontHandle _handle, CodePoint _codePoint, GlyphInfo& _outInfo)
{
GlyphHash_t::iterator iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint);
GlyphHashMap::iterator iter = m_cachedFonts[_handle.idx].cachedGlyphs.find(_codePoint);
if (iter == m_cachedFonts[_handle.idx].cachedGlyphs.end() )
{
if (preloadGlyph(_handle, _codePoint) )

View file

@ -6,18 +6,15 @@
#ifndef __FONT_MANAGER_H__
#define __FONT_MANAGER_H__
#include <bgfx.h>
#include <bx/handlealloc.h>
class Atlas;
enum FontType
{
FONT_TYPE_ALPHA = 0x00000100, // L8
//FONT_TYPE_LCD = 0x00000200, // BGRA8
//FONT_TYPE_RGBA = 0x00000300, // BGRA8
FONT_TYPE_DISTANCE = 0x00000400, // L8
FONT_TYPE_DISTANCE_SUBPIXEL = 0x00000500 // L8
};
#define FONT_TYPE_ALPHA UINT32_C(0x00000100) // L8
// #define FONT_TYPE_LCD UINT32_C(0x00000200) // BGRA8
// #define FONT_TYPE_RGBA UINT32_C(0x00000300) // BGRA8
#define FONT_TYPE_DISTANCE UINT32_C(0x00000400) // L8
#define FONT_TYPE_DISTANCE_SUBPIXEL UINT32_C(0x00000500) // L8
struct FontInfo
{
@ -73,7 +70,7 @@ struct FontInfo
// |------------- advance_x ---------->|
/// Unicode value of a character
typedef int32_t CodePoint_t;
typedef int32_t CodePoint;
/// A structure that describe a glyph.
struct GlyphInfo
@ -147,21 +144,11 @@ public:
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);
FontHandle createFontByPixelSize(TrueTypeHandle _handle, uint32_t _typefaceIndex, uint32_t _pixelSize, uint32_t _fontType = FONT_TYPE_ALPHA);
/// 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 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);
@ -172,7 +159,7 @@ public:
bool preloadGlyph(FontHandle _handle, const wchar_t* _string);
/// Preload a single glyph, return true on success.
bool preloadGlyph(FontHandle _handle, CodePoint_t _character);
bool preloadGlyph(FontHandle _handle, CodePoint _character);
/// Bake a font to disk (the set of preloaded glyph).
///
@ -188,7 +175,7 @@ public:
/// glyph from a TrueType font if possible
///
/// @return True if the Glyph is available.
bool getGlyphInfo(FontHandle _handle, CodePoint_t _codePoint, GlyphInfo& _outInfo);
bool getGlyphInfo(FontHandle _handle, CodePoint _codePoint, GlyphInfo& _outInfo);
GlyphInfo& getBlackGlyph()
{

View file

@ -4,11 +4,14 @@
*/
#include <bx/bx.h>
#include <bgfx.h>
#include <stddef.h> // offsetof
#include <memory.h> // memcpy
#include <wchar.h> // wcslen
#include "text_buffer_manager.h"
#include "utf8.h"
#include "../cube_atlas.h"
#include "vs_font_basic.bin.h"
@ -21,59 +24,6 @@
#define MAX_TEXT_BUFFER_COUNT 64
#define MAX_BUFFERED_CHARACTERS 8192
// Table from Flexible and Economical UTF-8 Decoder
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
static const uint8_t utf8d[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf
8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3,0x3, // e0..ef
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,0x8, // f0..ff
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1,0x1, // s0..s0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8
};
#define UTF8_ACCEPT 0
#define UTF8_REJECT 1
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);
*state = utf8d[256 + *state * 16 + type];
return *state;
}
inline int utf8_strlen(uint8_t* s, size_t* count)
{
uint32_t codepoint;
uint32_t state = 0;
for (*count = 0; *s; ++s)
{
if (!utf8_decode(&state, &codepoint, *s) )
{
*count += 1;
}
}
return state != UTF8_ACCEPT;
}
class TextBuffer
{
public:
@ -170,7 +120,7 @@ public:
}
private:
void appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
void appendGlyph(CodePoint _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom);
uint32_t toABGR(uint32_t _rgba)
{
@ -231,32 +181,29 @@ private:
};
TextBuffer::TextBuffer(FontManager* _fontManager)
: m_styleFlags(STYLE_NORMAL)
, m_textColor(0xffffffff)
, m_backgroundColor(0xffffffff)
, m_overlineColor(0xffffffff)
, m_underlineColor(0xffffffff)
, m_strikeThroughColor(0xffffffff)
, m_penX(0)
, m_penY(0)
, m_originX(0)
, m_originY(0)
, m_lineAscender(0)
, m_lineDescender(0)
, m_lineGap(0)
, m_fontManager(_fontManager)
, m_vertexBuffer(new TextVertex[MAX_BUFFERED_CHARACTERS * 4])
, m_indexBuffer(new uint16_t[MAX_BUFFERED_CHARACTERS * 6])
, m_styleBuffer(new uint8_t[MAX_BUFFERED_CHARACTERS * 4])
, m_vertexCount(0)
, m_indexCount(0)
, m_lineStartIndex(0)
{
m_styleFlags = STYLE_NORMAL;
//0xAABBGGRR
m_textColor = 0xFFFFFFFF;
m_backgroundColor = 0xFFFFFFFF;
m_backgroundColor = 0xFFFFFFFF;
m_overlineColor = 0xFFFFFFFF;
m_underlineColor = 0xFFFFFFFF;
m_strikeThroughColor = 0xFFFFFFFF;
m_penX = 0;
m_penY = 0;
m_originX = 0;
m_originY = 0;
m_lineAscender = 0;
m_lineDescender = 0;
m_lineGap = 0;
m_fontManager = _fontManager;
m_rectangle.width = 0;
m_rectangle.height = 0;
m_vertexBuffer = new TextVertex[MAX_BUFFERED_CHARACTERS * 4];
m_indexBuffer = new uint16_t[MAX_BUFFERED_CHARACTERS * 6];
m_styleBuffer = new uint8_t[MAX_BUFFERED_CHARACTERS * 4];
m_vertexCount = 0;
m_indexCount = 0;
m_lineStartIndex = 0;
}
TextBuffer::~TextBuffer()
@ -278,7 +225,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string)
m_lineAscender = 0; //font.m_ascender;
}
CodePoint_t codepoint = 0;
CodePoint codepoint = 0;
uint32_t state = 0;
for (; *_string; ++_string)
@ -317,10 +264,8 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string)
m_lineGap = 0;
}
//parse string
for (uint32_t ii = 0, end = wcslen(_string); ii < end; ++ii)
{
//if glyph cached, continue
uint32_t _codePoint = _string[ii];
if (m_fontManager->getGlyphInfo(_fontHandle, _codePoint, glyph) )
{
@ -332,15 +277,6 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string)
}
}
}
/*
TextBuffer::Rectangle TextBuffer::measureText(FontHandle _fontHandle, const char * _string)
{
}
TextBuffer::Rectangle TextBuffer::measureText(FontHandle _fontHandle, const wchar_t * _string)
{
}
*/
void TextBuffer::clearTextBuffer()
{
@ -353,9 +289,8 @@ void TextBuffer::clearTextBuffer()
m_rectangle.height = 0;
}
void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo)
void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo)
{
//handle newlines
if (_codePoint == L'\n')
{
m_penX = m_originX;
@ -385,20 +320,13 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
verticalCenterLastLine( (txtDecals), (m_penY - m_lineAscender), (m_penY - m_lineDescender + m_lineGap) );
}
//handle kerning
float kerning = 0;
/*
if( previous && markup->font->kerning )
{
kerning = texture_glyph_get_kerning( glyph, previous );
}
*/
m_penX += kerning * _font.scale;
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 +351,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 +376,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 +401,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);
@ -497,7 +425,6 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
m_indexCount += 6;
}
//handle glyph
float x0_precise = m_penX + (_glyphInfo.offset_x);
float x0 = (x0_precise);
float y0 = (m_penY + (_glyphInfo.offset_y) );
@ -530,9 +457,6 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons
{
m_rectangle.height = (m_penY - m_lineDescender);
}
//if(x1 > m_rectangle.width) m_rectangle.width = x1;
//if(y1 > m_rectangle.height) m_rectangle.height = y1;
}
void TextBuffer::verticalCenterLastLine(float _dy, float _top, float _bottom)
@ -643,7 +567,7 @@ TextBufferManager::~TextBufferManager()
bgfx::destroyProgram(m_distanceSubpixelProgram);
}
TextBufferHandle TextBufferManager::createTextBuffer(FontType _type, BufferType _bufferType)
TextBufferHandle TextBufferManager::createTextBuffer(uint32_t _type, BufferType _bufferType)
{
uint16_t textIdx = m_textBufferHandles.alloc();
BufferCache& bc = m_textBuffers[textIdx];
@ -814,12 +738,6 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id,
bgfx::submit(_id, _depth);
}
void TextBufferManager::submitTextBufferMask(TextBufferHandle /*_handle*/, uint32_t /*_viewMask*/, int32_t /*_depth*/)
{
//TODO
BX_CHECK(false, "TODO TODO");
}
void TextBufferManager::setStyle(TextBufferHandle _handle, uint32_t _flags)
{
BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used");

View file

@ -40,10 +40,9 @@ public:
TextBufferManager(FontManager* _fontManager);
~TextBufferManager();
TextBufferHandle createTextBuffer(FontType _type, BufferType _bufferType);
TextBufferHandle createTextBuffer(uint32_t _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);
@ -66,19 +65,14 @@ public:
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);
private:
struct BufferCache
{
uint16_t indexBufferHandle;
uint16_t vertexBufferHandle;
TextBuffer* textBuffer;
BufferType bufferType;
FontType fontType;
uint32_t fontType;
};
BufferCache* m_textBuffers;
@ -87,7 +81,6 @@ private:
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;

View file

@ -0,0 +1,57 @@
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "utf8.h"
static const uint8_t s_utf8d[364] =
{
// The first part of the table maps bytes to character classes that
// to reduce the size of the transition table and create bitmasks.
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
// The second part is a transition table that maps a combination
// of a state of the automaton and a character class to a state.
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
12,36,12,12,12,12,12,12,12,12,12,12
};
uint32_t utf8_decode(uint32_t* _state, uint32_t* _codep, uint8_t _ch)
{
uint32_t byte = _ch;
uint32_t type = s_utf8d[byte];
*_codep = (*_state != UTF8_ACCEPT) ?
(byte & 0x3fu) | (*_codep << 6) :
(0xff >> type) & (byte);
*_state = s_utf8d[256 + *_state + type];
return *_state;
}

View file

@ -0,0 +1,14 @@
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
#ifndef __UTF8_H__
#define __UTF8_H__
#include <stdint.h>
#define UTF8_ACCEPT 0
#define UTF8_REJECT 1
uint32_t utf8_decode(uint32_t* _state, uint32_t* _codep, uint8_t _ch);
#endif // __UTF8_H_