This commit is contained in:
bkaradzic 2013-05-22 21:34:21 -07:00
parent e49810bc29
commit 4a2bfcfbeb
5 changed files with 123 additions and 62 deletions

View File

@ -72,7 +72,7 @@ char* loadText(const char* _textFile)
fseek(pFile, 0L, SEEK_SET);
// Read the entire file into memory.
uint32_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile);
size_t newLen = fread( (void*)buffer, sizeof(char), bufsize, pFile);
if (newLen == 0)
{
fclose(pFile);

View File

@ -37,10 +37,12 @@ public:
{
m_styleFlags = _flags;
}
void setTextColor(uint32_t _rgba = 0x000000FF)
{
m_textColor = toABGR(_rgba);
}
void setBackgroundColor(uint32_t _rgba = 0x000000FF)
{
m_backgroundColor = toABGR(_rgba);
@ -50,10 +52,12 @@ public:
{
m_overlineColor = toABGR(_rgba);
}
void setUnderlineColor(uint32_t _rgba = 0x000000FF)
{
m_underlineColor = toABGR(_rgba);
}
void setStrikeThroughColor(uint32_t _rgba = 0x000000FF)
{
m_strikeThroughColor = toABGR(_rgba);
@ -64,51 +68,58 @@ public:
m_penX = _x; m_penY = _y;
}
/// append an ASCII/utf-8 string to the buffer using current pen position and color
/// Append an ASCII/utf-8 string to the buffer using current pen
/// position and color.
void appendText(FontHandle _fontHandle, const char* _string, const char* _end = NULL);
/// append a wide char unicode string to the buffer using current pen position and color
/// Append a wide char unicode string to the buffer using current pen
/// position and color.
void appendText(FontHandle _fontHandle, const wchar_t* _string, const wchar_t* _end = NULL);
/// append a whole face of the atlas cube, mostly used for debugging and visualizing atlas
/// Append a whole face of the atlas cube, mostly used for debugging
/// and visualizing atlas.
void appendAtlasFace(uint16_t _faceIndex);
/// Clear the text buffer and reset its state (pen/color)
void clearTextBuffer();
/// get pointer to the vertex buffer to submit it to the graphic card
/// Get pointer to the vertex buffer to submit it to the graphic card.
const uint8_t* getVertexBuffer()
{
return (uint8_t*) m_vertexBuffer;
}
/// number of vertex in the vertex buffer
uint32_t getVertexCount()
/// Number of vertex in the vertex buffer.
uint32_t getVertexCount() const
{
return m_vertexCount;
}
/// size in bytes of a vertex
uint32_t getVertexSize()
/// Size in bytes of a vertex.
uint32_t getVertexSize() const
{
return sizeof(TextVertex);
}
/// get a pointer to the index buffer to submit it to the graphic
const uint16_t* getIndexBuffer()
const uint16_t* getIndexBuffer() const
{
return m_indexBuffer;
}
/// number of index in the index buffer
uint32_t getIndexCount()
uint32_t getIndexCount() const
{
return m_indexCount;
}
/// size in bytes of an index
uint32_t getIndexSize()
/// Size in bytes of an index.
uint32_t getIndexSize() const
{
return sizeof(uint16_t);
}
uint32_t getTextColor()
uint32_t getTextColor() const
{
return toABGR(m_textColor);
}
@ -121,12 +132,14 @@ public:
private:
void appendGlyph(CodePoint _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo);
void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom);
uint32_t toABGR(uint32_t _rgba)
static uint32_t toABGR(uint32_t _rgba)
{
return ( ( (_rgba >> 0) & 0xff) << 24) |
( ( (_rgba >> 8) & 0xff) << 16) |
( ( (_rgba >> 16) & 0xff) << 8) |
( ( (_rgba >> 24) & 0xff) << 0);
return ( ( (_rgba >> 0) & 0xff) << 24)
| ( ( (_rgba >> 8) & 0xff) << 16)
| ( ( (_rgba >> 16) & 0xff) << 8)
| ( ( (_rgba >> 24) & 0xff) << 0)
;
}
uint32_t m_styleFlags;
@ -151,8 +164,6 @@ private:
float m_lineGap;
TextRectangle m_rectangle;
///
FontManager* m_fontManager;
void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL)
@ -259,7 +270,8 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string, cons
m_lineAscender = 0;
m_lineGap = 0;
}
if( _end == NULL)
if (_end == NULL)
{
_end = _string + (uint32_t) wcslen(_string);
}
@ -291,7 +303,11 @@ void TextBuffer::appendAtlasFace(uint16_t _faceIndex)
float x1 = x0 + (float)m_fontManager->getAtlas()->getTextureSize();
float y1 = y0 + (float)m_fontManager->getAtlas()->getTextureSize();
m_fontManager->getAtlas()->packFaceLayerUV(_faceIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packFaceLayerUV(_faceIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_backgroundColor);
setVertex(m_vertexCount + 1, x0, y1, m_backgroundColor);
@ -372,7 +388,11 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const
float x1 = ( (float)x0 + (_glyphInfo.advance_x) );
float y1 = (m_penY + m_lineAscender - m_lineDescender + m_lineGap);
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_backgroundColor, STYLE_BACKGROUND);
setVertex(m_vertexCount + 1, x0, y1, m_backgroundColor, STYLE_BACKGROUND);
@ -397,7 +417,11 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const
float x1 = ( (float)x0 + (_glyphInfo.advance_x) );
float y1 = y0 + _font.underlineThickness;
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_underlineColor, STYLE_UNDERLINE);
setVertex(m_vertexCount + 1, x0, y1, m_underlineColor, STYLE_UNDERLINE);
@ -422,7 +446,11 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const
float x1 = ( (float)x0 + (_glyphInfo.advance_x) );
float y1 = y0 + _font.underlineThickness;
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_overlineColor, STYLE_OVERLINE);
setVertex(m_vertexCount + 1, x0, y1, m_overlineColor, STYLE_OVERLINE);
@ -447,7 +475,11 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const
float x1 = ( (float)x0 + (_glyphInfo.advance_x) );
float y1 = y0 + _font.underlineThickness;
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packUV(blackGlyph.regionIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_strikeThroughColor, STYLE_STRIKE_THROUGH);
setVertex(m_vertexCount + 1, x0, y1, m_strikeThroughColor, STYLE_STRIKE_THROUGH);
@ -469,7 +501,11 @@ void TextBuffer::appendGlyph(CodePoint _codePoint, const FontInfo& _font, const
float x1 = (x0 + _glyphInfo.width);
float y1 = (y0 + _glyphInfo.height);
m_fontManager->getAtlas()->packUV(_glyphInfo.regionIndex, (uint8_t*)m_vertexBuffer, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u), sizeof(TextVertex) );
m_fontManager->getAtlas()->packUV(_glyphInfo.regionIndex
, (uint8_t*)m_vertexBuffer
, sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u)
, sizeof(TextVertex)
);
setVertex(m_vertexCount + 0, x0, y0, m_textColor);
setVertex(m_vertexCount + 1, x0, y1, m_textColor);
@ -680,17 +716,27 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id,
{
case FONT_TYPE_ALPHA:
bgfx::setProgram(m_basicProgram);
bgfx::setState(BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) );
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
);
break;
case FONT_TYPE_DISTANCE:
bgfx::setProgram(m_distanceProgram);
bgfx::setState(BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) );
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
);
break;
case FONT_TYPE_DISTANCE_SUBPIXEL:
bgfx::setProgram(m_distanceSubpixelProgram);
bgfx::setState(BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_INV_SRC_COLOR), bc.textBuffer->getTextColor() );
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_INV_SRC_COLOR)
, bc.textBuffer->getTextColor()
);
break;
}

View File

@ -54,19 +54,19 @@ public:
void setPenPosition(TextBufferHandle _handle, float _x, float _y);
/// append an ASCII/utf-8 string to the buffer using current pen position and color
/// Append an ASCII/utf-8 string to the buffer using current pen position and color.
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const char* _string, const char* _end = NULL);
/// append a wide char unicode string to the buffer using current pen position and color
/// Append a wide char unicode string to the buffer using current pen position and color.
void appendText(TextBufferHandle _handle, FontHandle _fontHandle, const wchar_t* _string, const wchar_t* _end = NULL);
/// append a whole face of the atlas cube, mostly used for debugging and visualizing atlas
/// Append a whole face of the atlas cube, mostly used for debugging and visualizing atlas.
void appendAtlasFace(TextBufferHandle _handle, uint16_t _faceIndex);
/// Clear the text buffer and reset its state (pen/color)
/// Clear the text buffer and reset its state (pen/color).
void clearTextBuffer(TextBufferHandle _handle);
/// Return the rectangular size of the current text buffer (including all its content)
/// Return the rectangular size of the current text buffer (including all its content).
TextRectangle getRectangle(TextBufferHandle _handle) const;
private:

View File

@ -2,11 +2,19 @@
* Copyright 2013 Jeremie Roy. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <wchar.h> // wcslen
#include "text_metrics.h"
#include <wchar.h> // wcslen
#include "utf8.h"
TextMetrics::TextMetrics(FontManager* _fontManager): m_fontManager(_fontManager), m_width(0), m_height(0), m_x(0), m_lineHeight(0), m_lineGap(0)
TextMetrics::TextMetrics(FontManager* _fontManager)
: m_fontManager(_fontManager)
, m_width(0)
, m_height(0)
, m_x(0)
, m_lineHeight(0)
, m_lineGap(0)
{
}
@ -15,12 +23,12 @@ void TextMetrics::appendText(FontHandle _fontHandle, const char* _string)
GlyphInfo glyph;
const FontInfo& font = m_fontManager->getFontInfo(_fontHandle);
if(font.lineGap > m_lineGap)
if (font.lineGap > m_lineGap)
{
m_lineGap = font.lineGap;
}
if( (font.ascender - font.descender) > m_lineHeight)
if ( (font.ascender - font.descender) > m_lineHeight)
{
m_height -= m_lineHeight;
m_lineHeight = font.ascender - font.descender;
@ -66,12 +74,12 @@ void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string)
GlyphInfo glyph;
const FontInfo& font = m_fontManager->getFontInfo(_fontHandle);
if(font.lineGap > m_lineGap)
if (font.lineGap > m_lineGap)
{
m_lineGap = font.lineGap;
}
if( (font.ascender - font.descender) > m_lineHeight)
if ( (font.ascender - font.descender) > m_lineHeight)
{
m_height -= m_lineHeight;
m_lineHeight = font.ascender - font.descender;
@ -91,7 +99,7 @@ void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string)
m_x = 0;
break;
}
//TODO handle kerning
m_x += glyph.advance_x;
if(m_x > m_width)
{
@ -105,7 +113,7 @@ void TextMetrics::appendText(FontHandle _fontHandle, const wchar_t* _string)
}
}
TextLineMetrics::TextLineMetrics(FontManager* _fontManager, FontHandle _fontHandle )
TextLineMetrics::TextLineMetrics(FontManager* _fontManager, FontHandle _fontHandle)
{
const FontInfo& font = _fontManager->getFontInfo(_fontHandle);
m_lineHeight = font.ascender - font.descender + font.lineGap;
@ -118,7 +126,7 @@ uint32_t TextLineMetrics::getLineCount(const char* _string) const
uint32_t lineCount = 1;
for (; *_string; ++_string)
{
if(utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT)
{
if(codepoint == L'\n')
{
@ -126,6 +134,7 @@ uint32_t TextLineMetrics::getLineCount(const char* _string) const
}
}
}
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
return lineCount;
}
@ -165,6 +174,7 @@ void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint3
}
}
}
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
_begin = _string;
@ -183,6 +193,7 @@ void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint3
}
}
}
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
_end = _string;
}
@ -190,7 +201,7 @@ void TextLineMetrics::getSubText(const char* _string, uint32_t _firstLine, uint3
void TextLineMetrics::getSubText(const wchar_t* _string, uint32_t _firstLine, uint32_t _lastLine, const wchar_t*& _begin, const wchar_t*& _end)
{
uint32_t currentLine = 0;
while((*_string != L'\0') && (currentLine < _firstLine))
while ( (*_string != L'\0') && (currentLine < _firstLine) )
{
for ( ;*_string != L'\0'; ++_string)
{
@ -204,7 +215,7 @@ void TextLineMetrics::getSubText(const wchar_t* _string, uint32_t _firstLine, ui
}
_begin = _string;
while((*_string != L'\0') && (currentLine < _lastLine) )
while ( (*_string != L'\0') && (currentLine < _lastLine) )
{
for ( ;*_string != L'\0'; ++_string)
{
@ -225,7 +236,7 @@ void TextLineMetrics::getVisibleText(const char* _string, float _top, float _bot
uint32_t state = 0;
// y is bottom of a text line
float y = m_lineHeight;
while(*_string && (y < _top))
while (*_string && (y < _top) )
{
for (; *_string; ++_string)
{
@ -240,12 +251,13 @@ void TextLineMetrics::getVisibleText(const char* _string, float _top, float _bot
}
}
}
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
_begin = _string;
// y is now top of a text line
y -= m_lineHeight;
while((*_string) && (y < _bottom) )
while ( (*_string) && (y < _bottom) )
{
for (; *_string; ++_string)
{
@ -260,6 +272,7 @@ void TextLineMetrics::getVisibleText(const char* _string, float _top, float _bot
}
}
}
BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed");
_end = _string;
}
@ -271,7 +284,7 @@ void TextLineMetrics::getVisibleText(const wchar_t* _string, float _top, float _
const wchar_t* _textEnd = _string + wcslen(_string);
while(y < _top)
while (y < _top)
{
for (const wchar_t* _current = _string; _current < _textEnd; ++_current)
{
@ -287,7 +300,7 @@ void TextLineMetrics::getVisibleText(const wchar_t* _string, float _top, float _
// y is now top of a text line
y -= m_lineHeight;
while(y < _bottom )
while (y < _bottom )
{
for (const wchar_t* _current = _string; _current < _textEnd; ++_current)
{

View File

@ -13,16 +13,16 @@ class TextMetrics
public:
TextMetrics(FontManager* _fontManager);
/// Append an ASCII/utf-8 string to the metrics helper
/// Append an ASCII/utf-8 string to the metrics helper.
void appendText(FontHandle _fontHandle, const char* _string);
/// Append a wide char string to the metrics helper
/// Append a wide char string to the metrics helper.
void appendText(FontHandle _fontHandle, const wchar_t* _string);
/// return the width of the measured text
/// Return the width of the measured text.
float getWidth() const { return m_width; }
/// return the height of the measured text
/// Return the height of the measured text.
float getHeight() const { return m_height; }
private:
@ -34,27 +34,30 @@ private:
float m_lineGap;
};
/// Compute text crop area for text using a single font
/// Compute text crop area for text using a single font.
class TextLineMetrics
{
public:
TextLineMetrics(FontManager* _fontManager, FontHandle _fontHandle);
/// Return the height of a line of text using the given font
/// Return the height of a line of text using the given font.
float getLineHeight() const { return m_lineHeight; }
/// Return the number of text line in the given text
/// Return the number of text line in the given text.
uint32_t getLineCount(const char* _string) const;
/// Return the number of text line in the given text
/// Return the number of text line in the given text.
uint32_t getLineCount(const wchar_t* _string) const;
/// Return the first and last character visible in the [_firstLine, _lastLine[ range
/// Return the first and last character visible in the [_firstLine, _lastLine] range.
void getSubText(const char* _string, uint32_t _firstLine, uint32_t _lastLine, const char*& _begin, const char*& _end);
/// Return the first and last character visible in the [_firstLine, _lastLine[ range
/// Return the first and last character visible in the [_firstLine, _lastLine] range.
void getSubText(const wchar_t* _string, uint32_t _firstLine, uint32_t _lastLine, const wchar_t*& _begin, const wchar_t*& _end);
/// Return the first and last character visible in the [_top, _bottom] range,
void getVisibleText(const char* _string, float _top, float _bottom, const char*& _begin, const char*& _end);
/// Return the first and last character visible in the [_top, _bottom] range,
void getVisibleText(const wchar_t* _string, float _top, float _bottom, const wchar_t*& _begin, const wchar_t*& _end);
@ -63,5 +66,4 @@ private:
float m_lineHeight;
};
#endif // __TEXT_METRICS_H__