From 7eef7f52be72edb354851d8f0df0639656addbf8 Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Thu, 16 May 2013 22:03:57 -0700 Subject: [PATCH] More cleanup. --- 3rdparty/freetype/freetype.h | 15 ++ examples/common/font/font_manager.cpp | 128 ++++++----------- examples/common/font/font_manager.h | 33 ++--- examples/common/font/text_buffer_manager.cpp | 144 ++++--------------- examples/common/font/text_buffer_manager.h | 11 +- examples/common/font/utf8.cpp | 57 ++++++++ examples/common/font/utf8.h | 14 ++ 7 files changed, 172 insertions(+), 230 deletions(-) create mode 100644 examples/common/font/utf8.cpp create mode 100644 examples/common/font/utf8.h diff --git a/3rdparty/freetype/freetype.h b/3rdparty/freetype/freetype.h index 74173222c..d71cd8068 100644 --- a/3rdparty/freetype/freetype.h +++ b/3rdparty/freetype/freetype.h @@ -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) diff --git a/examples/common/font/font_manager.cpp b/examples/common/font/font_manager.cpp index 120744a40..705a9cd8b 100644 --- a/examples/common/font/font_manager.cpp +++ b/examples/common/font/font_manager.cpp @@ -4,20 +4,8 @@ */ #include - -#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 -# pragma warning(pop) -#else -# include -#endif // BX_COMPILER_MSVC - -#include +#include +#include #include #include // 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 GlyphHash_t; +typedef stl::unordered_map 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) ) diff --git a/examples/common/font/font_manager.h b/examples/common/font/font_manager.h index 763b1ff70..0724a9d88 100644 --- a/examples/common/font/font_manager.h +++ b/examples/common/font/font_manager.h @@ -6,18 +6,15 @@ #ifndef __FONT_MANAGER_H__ #define __FONT_MANAGER_H__ -#include #include 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() { diff --git a/examples/common/font/text_buffer_manager.cpp b/examples/common/font/text_buffer_manager.cpp index c131f9e55..511fff135 100644 --- a/examples/common/font/text_buffer_manager.cpp +++ b/examples/common/font/text_buffer_manager.cpp @@ -4,11 +4,14 @@ */ #include +#include + #include // offsetof #include // memcpy #include // 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 -// 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"); diff --git a/examples/common/font/text_buffer_manager.h b/examples/common/font/text_buffer_manager.h index 602b51349..5a502bfc2 100644 --- a/examples/common/font/text_buffer_manager.h +++ b/examples/common/font/text_buffer_manager.h @@ -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; diff --git a/examples/common/font/utf8.cpp b/examples/common/font/utf8.cpp new file mode 100644 index 000000000..105a52eec --- /dev/null +++ b/examples/common/font/utf8.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2008-2009 Bjoern Hoehrmann +// 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; +} diff --git a/examples/common/font/utf8.h b/examples/common/font/utf8.h new file mode 100644 index 000000000..04d0aa99b --- /dev/null +++ b/examples/common/font/utf8.h @@ -0,0 +1,14 @@ +// Copyright (c) 2008-2009 Bjoern Hoehrmann +// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + +#ifndef __UTF8_H__ +#define __UTF8_H__ + +#include + +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 1 + +uint32_t utf8_decode(uint32_t* _state, uint32_t* _codep, uint8_t _ch); + +#endif // __UTF8_H_