aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Graphics/Font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/Graphics/Font.cpp')
-rw-r--r--src/libjin/Graphics/Font.cpp217
1 files changed, 81 insertions, 136 deletions
diff --git a/src/libjin/Graphics/Font.cpp b/src/libjin/Graphics/Font.cpp
index b95f78b..bb767db 100644
--- a/src/libjin/Graphics/Font.cpp
+++ b/src/libjin/Graphics/Font.cpp
@@ -12,166 +12,111 @@ namespace jin
namespace graphics
{
+ using namespace std;
using namespace jin::math;
- const int BITMAP_WIDTH = 512;
- const int BITMAP_HEIGHT = 512;
- const int PIXEL_HEIGHT = 32;
+ const int Font::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 };
+ const int Font::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 };
+
+ static const char *ttf_utf8toCodepoint(const char *p, unsigned *res) {
+ unsigned x, mask, shift;
+ switch (*p & 0xf0) {
+ case 0xf0: mask = 0x07; shift = 18; break;
+ case 0xe0: mask = 0x0f; shift = 12; break;
+ case 0xc0:
+ case 0xd0: mask = 0x1f; shift = 6; break;
+ default:
+ *res = *p;
+ return p + 1;
+ }
+ x = (*p & mask) << shift;
+ do {
+ /* Return early if we reach an unexpected NULL */
+ if (*(++p) == '\0') {
+ *res = x;
+ return p;
+ }
+ shift -= 6;
+ x |= (*p & 0x3f) << shift;
+ } while (shift);
+ *res = x;
+ return p + 1;
+ }
- Font::Font():Drawable()
+ /*static*/ Font* Font::createFont(const char* font, size_t size)
{
+
}
- // ttf file read buffer
- static unsigned char ttf_buffer[1 << 20];
+ /*static*/ Font* Font::createFont(const char* file)
+ {
- // bitmap for saving font data
- static unsigned char temp_bitmap[BITMAP_WIDTH * BITMAP_HEIGHT];
+ }
- void Font::loadFile(const char* path)
+ Font::Font()
+ : textureLevel(TEXTURE_SIZE_LEVEL_MAX)
{
- fread(ttf_buffer, 1, 1 << 20, fopen(path, "rb"));
- loadMemory(ttf_buffer);
+
}
- /**
- * load from memory
- */
- void Font::loadMemory(const unsigned char* data)
+ bool Font::createTexture()
{
- if (data == nullptr)
- return;
-
- stbtt_BakeFontBitmap(data, 0, PIXEL_HEIGHT, temp_bitmap, BITMAP_WIDTH, BITMAP_HEIGHT, 32, ASCII_CHARACTER_NUM, asciiData);
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_WIDTH, BITMAP_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLuint t;
+ glGenTextures(1, &t);
+ glBindTexture(GL_TEXTURE_2D, t);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ /*Initialize the texture, attempting smaller sizes if initialization fails.*/
+ bool initialized = false;
+ while (textureLevel >= 0)
+ {
+ /*clear errors before initializing*/
+ while (glGetError() != GL_NO_ERROR);
+ textureWidth = TEXTURE_WIDTHS[textureLevel];
+ textureHeight = TEXTURE_HEIGHTS[textureLevel];
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ initialized = (glGetError() == GL_NO_ERROR);
+ if (initialized || textureLevel <= 0)
+ break;
+ --textureLevel;
+ }
+ if (!initialized)
+ {
+ glDeleteTextures(1, &t);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ return false;
+ }
+ textures.push_back(t);
glBindTexture(GL_TEXTURE_2D, 0);
+ return true;
}
- /**
- * get texture quad
- */
- static Quad getCharQuad(const stbtt_bakedchar* chardata, int pw, int ph, int char_index)
+ void Font::print(const char* text, int x, int y)
{
- float ipw = 1.0f / pw, iph = 1.0f / ph;
- const stbtt_bakedchar *b = chardata + char_index;
- Quad q;
- q.x = b->x0 * ipw;
- q.y = b->y0 * iph;
- q.w = b->x1 * ipw - b->x0 * ipw;
- q.h = b->y1 * iph - b->y0 * iph;
- return q;
+ int len = strlen(text);
+ /* xy and uv list */
+ vector<GlyphVertex> glyphvertices(len*4);
+ /* texture binded along with glyphvertices */
+ vector<GlyphArrayDrawInfo> glyphinfolist;
+ float dx = 0;
+ float dy = 0;
+ //float lineheihgt = ;
}
- void Font::render(
- const char* text,
- float x, float y,
- int fontHeight,
- int spacing,
- int lineHeight)
+ /**
+ * unicodeȾļtextureϣglyphs
+ */
+ Glyph* Font::addGlyph(unsigned int character)
{
- float _x = x,
- _y = y;
+ GLuint texture = textures.back();
- int len = strlen(text);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- // for saving clip quad
- stbtt_aligned_quad q;
-
- // render every given character
- float xc = x;
- float yc = y;
-
- float factor = fontHeight / (float)PIXEL_HEIGHT;
- float texCoord[8];
- float verCoord[8];
- for (int i = 0; i < len; ++i)
- {
- char c = text[i];
- if (c == '\n')
- {
- xc = x;
- yc += lineHeight;
- continue;
- }
-
- // only support ASCII
- Quad q = getCharQuad(asciiData, 512, 512, c - 32);
- float s0 = q.x,
- s1 = q.x + q.w,
- t0 = q.y,
- t1 = q.y + q.h;
-
- // texture quad
- texCoord[0] = s0; texCoord[1] = t1;
- texCoord[2] = s1; texCoord[3] = t1;
- texCoord[4] = s1; texCoord[5] = t0;
- texCoord[6] = s0; texCoord[7] = t0;
-
- // character bound box
- stbtt_bakedchar box = asciiData[c - 32];
-
- float width = factor * (box.x1 - box.x0);
- float height = factor * (box.y1 - box.y0);
- float xoffset = factor * box.xoff;
- // I don't know why add PIXEL_HEIGHT to box.yoff, but
- // it works.
- float yoffset = factor * (box.yoff + PIXEL_HEIGHT);
- float xadvance = factor * box.xadvance;
-
- // render quad
- verCoord[0] = xc + xoffset; verCoord[1] = yc + height + yoffset;
- verCoord[2] = xc + width + xoffset; verCoord[3] = yc + height + yoffset;
- verCoord[4] = xc + width + xoffset; verCoord[5] = yc + yoffset;
- verCoord[6] = xc + xoffset; verCoord[7] = yc + yoffset;
-
- // forward to next character
- xc += xadvance + spacing;
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
- glVertexPointer(2, GL_FLOAT, 0, verCoord);
- glDrawArrays(GL_QUADS, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
}
- void Font::box(const char* text, int fontHeight, int spacing, int lineHeight, int* w, int * h)
+ Glyph* Font::findGlyph(unsigned int character)
{
- int len = strlen(text);
-
- float xc = 0;
- int yc = len ? lineHeight : 0;
- int maxX = 0;
-
- float factor = fontHeight / (float)PIXEL_HEIGHT;
-
- for (int i = 0; i < len; ++i)
- {
- char c = text[i];
- if (c == '\n')
- {
- yc += lineHeight;
- xc = 0;
- continue;
- }
- stbtt_bakedchar box = asciiData[c - 32];
-
- xc += factor * box.xadvance + spacing;
- if (xc > maxX) maxX = xc;
- }
- *w = maxX;
- *h = yc;
}
} // graphics