mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-04-01 01:51:46 -04:00
More cleanup.
This commit is contained in:
parent
63041c5c73
commit
7eef7f52be
7 changed files with 172 additions and 230 deletions
3rdparty/freetype
examples/common/font
15
3rdparty/freetype/freetype.h
vendored
15
3rdparty/freetype/freetype.h
vendored
|
@ -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)
|
||||
|
|
|
@ -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) )
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
57
examples/common/font/utf8.cpp
Normal file
57
examples/common/font/utf8.cpp
Normal 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;
|
||||
}
|
14
examples/common/font/utf8.h
Normal file
14
examples/common/font/utf8.h
Normal 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_
|
Loading…
Add table
Reference in a new issue