diff options
author | chai <chaifix@163.com> | 2018-10-14 22:52:40 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-10-14 22:52:40 +0800 |
commit | b1bbc998960fff2169dc5a992c47d08723472f9b (patch) | |
tree | 220f3bd5de2266e248884e11161dd715d7632ef2 /src/libjin/Graphics/Font.cpp | |
parent | fbf989f9950a38566e0fb0fc5b6a7aebc9f0fb45 (diff) |
*直接渲染字符串
Diffstat (limited to 'src/libjin/Graphics/Font.cpp')
-rw-r--r-- | src/libjin/Graphics/Font.cpp | 363 |
1 files changed, 0 insertions, 363 deletions
diff --git a/src/libjin/Graphics/Font.cpp b/src/libjin/Graphics/Font.cpp deleted file mode 100644 index 9060961..0000000 --- a/src/libjin/Graphics/Font.cpp +++ /dev/null @@ -1,363 +0,0 @@ -#include "../jin_configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "OpenGL.h" -#include "font.h" -#include <stdio.h> -#include "color.h" -#include "Shader.h" -#include "../Common/Array.hpp" - -namespace jin -{ -namespace graphics -{ - - #include "Shaders/font.shader.h" - - using namespace std; - using namespace jin::math; - - const int Font::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 }; - const int Font::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 }; - - /* utf8 byte string to unicode codepoint */ - static const char* 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 { - if (*(++p) == '\0') { - *res = x; - return p; - } - shift -= 6; - x |= (*p & 0x3f) << shift; - } while (shift); - *res = x; - return p + 1; - } - - /* little endian unicode */ - static const char* unicodeLittleEndian(const char* p, unsigned* res) - { - } - - /*static*/ Font* Font::createFont(FontData* fontData, unsigned int fontSzie) - { - Font* font; - try - { - font = new Font(fontData, fontSzie); - } - catch (...) - { - return nullptr; - } - return font; - } - - Font::Font(FontData* f, unsigned int fontSize) - : cursor(0, 0) - , font(f) - , fontsize(fontSize) - { - font->pushFontsize(fontsize); - font->getVMetrics(&baseline, &descent); - estimateSize(); - font->popFontsize(); - /* create a default texture */ - createAtlas(); - } - - /* estimate the size of atlas texture */ - void Font::estimateSize() - { - for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level) - { - if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level]) - { - textureWidth = TEXTURE_WIDTHS[level]; - textureHeight = TEXTURE_HEIGHTS[level]; - break; - } - } - } - - Font::~Font() - { - map<unsigned int, Glyph*>::iterator it = glyphs.begin(); - for (; it != glyphs.end(); ++it) - { - delete it->second; - } - } - - GLuint Font::createAtlas() - { - GLuint t; - gl.flushError(); - t = gl.genTexture(); - gl.bindTexture(t); - gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE); - if (glGetError() != GL_NO_ERROR) - { - glDeleteTextures(1, &t); - gl.bindTexture(0); - return 0; - } - atlases.push_back(t); - gl.bindTexture(0); - return t; - } - - void Font::print(const char* t, int x, int y, int lineheight, int spacing) - { - Page* page = typeset(t, lineheight, spacing); - print(page, x, y); - delete page; - } - - Page* Font::typeset(const char* text, int lineheight, int spacing) - { - // typesetting, for reducing draw call - const char* t = text; - Page* page = new Page(); - vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - vector<GlyphVertex>& glyphvertices = page->glyphvertices; - Vector2<int> p(0, 0); - Codepoint c; - int texture = -1; - Glyph* glyph = nullptr; - GlyphVertex vertex; - for (int i = 0; *t != NULL; i += 4) - { - t = utf8toCodepoint(t, &c); - if (c == 0x0D) - { - i -= 4; - continue; - } - /* new line */ - if (c == 0x0A) - { - p.y += lineheight; - p.x = 0; - i -= 4; - continue; - } - glyph = findGlyph(c); - if (texture != glyph->atlas) - { - GlyphArrayDrawInfo info; - info.start = i; - info.count = 0; - info.texture = glyph->atlas; - texture = glyph->atlas; - glyphinfolist.push_back(info); - } - glyphinfolist[glyphinfolist.size() - 1].count += 4; - Glyph::Bbox& bbox = glyph->bbox; - // 1 - vertex.x = p.x; vertex.y = p.y; - vertex.u = bbox.x; vertex.v = bbox.y; - glyphvertices.push_back(vertex); - // 2 - vertex.x = p.x; vertex.y = p.y + glyph->height; - vertex.u = bbox.x; vertex.v = bbox.y + bbox.height; - glyphvertices.push_back(vertex); - // 3 - vertex.x = p.x + glyph->width; vertex.y = p.y + glyph->height; - vertex.u = bbox.x + bbox.width; vertex.v = bbox.y + bbox.height; - glyphvertices.push_back(vertex); - // 4 - vertex.x = p.x + glyph->width; vertex.y = p.y; - vertex.u = bbox.x + bbox.width; vertex.v = bbox.y; - glyphvertices.push_back(vertex); - - p.x += glyph->width + spacing; - } - getTextBox(text, &page->width, &page->height, lineheight, spacing); - return page; - } - - void Font::print(const Page* page, int x, int y) - { - Shader* shader = Shader::getCurrentShader(); - const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist; - const vector<GlyphVertex>& glyphvertices = page->glyphvertices; - gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - for (int i = 0; i < glyphinfolist.size(); ++i) - { - const GlyphArrayDrawInfo& info = glyphinfolist[i]; - shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x); - shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u); - gl.bindTexture(info.texture); - gl.drawArrays(GL_QUADS, 0, info.count); - gl.bindTexture(0); - } - } - - int Font::getCharWidth(int c) - { - int adw, lsb; - font->pushFontsize(fontsize); - font->getHMetrics(c, &adw, &lsb); - font->popFontsize(); - return adw; - } - - int Font::getCharHeight(int c) - { - return descent; - } - - int Font::getTextWidth(const char* t, int spacing) - { - font->pushFontsize(fontsize); - int res = 0; - int tmp = 0; - const char *p = t; - while (*p) { - unsigned c; - p = utf8toCodepoint(p, &c); - if (*p == 0x0D) - continue; - if (*p == 0x0A) - { - tmp = 0; - continue; - } - tmp += getCharWidth(c) + spacing; - if (tmp > res) res = tmp; - } - font->popFontsize(); - return res; - } - - int Font::getTextHeight(const char* t, int lineheight) - { - font->pushFontsize(fontsize); - int res = 0; - bool newline = true; - while (*t) - { - unsigned c; - t = utf8toCodepoint(t, &c); - if (*t == 0x0A) - newline = true; - else if (*t == 0x0D); - else if (newline) - { - newline = false; - res += lineheight; - } - } - font->popFontsize(); - return res; - } - - void Font::getTextBox(const char* text, int* w, int* h, int lineheight, int spacing) - { - font->pushFontsize(fontsize); - *w = 0; - *h = 0; - int tmp = 0; - const char* p = text; - const char* pt = nullptr; - bool nl = true; - while (*p) { - unsigned c; - pt = p; - p = utf8toCodepoint(p, &c); - if (*pt == 0x0D) - continue; - if (*pt == 0x0A) - { - tmp = 0; - nl = true; - continue; - } - else if(nl) - { - nl = false; - *h += lineheight; - } - tmp += getCharWidth(c) + spacing; - if (tmp > *w) *w = tmp; - } - font->popFontsize(); - } - - Glyph* Font::bakeGlyph(unsigned int character) - { - Glyph* glyph = (Glyph*)malloc(sizeof(Glyph)); - int w, h, xoff, yoff; - font->pushFontsize(fontsize); - GLuint atlas = atlases.back(); - const Color* bitmap = font->getCodepointBitmap(character, &w, &h, &xoff, &yoff); - int adw, lsb; - { - font->getHMetrics(character, &adw, &lsb); - font->popFontsize(); - if (cursor.x + adw > textureWidth ) - { - cursor.x = 0; - cursor.y += descent; - if (cursor.y + descent * 2 > textureHeight) - { - /* create new atlas */ - atlas = createAtlas(); - cursor.y = 0; - } - } - gl.bindTexture(atlas); - gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); - gl.bindTexture(); - delete[] bitmap; - } - glyph->atlas = atlas; - glyph->bbox.x = cursor.x / (float)textureWidth; - glyph->bbox.y = cursor.y / (float)textureHeight; - glyph->bbox.width = adw / (float)textureWidth; - glyph->bbox.height = descent / (float)textureHeight; - glyph->width = adw; - glyph->height = descent; - glyphs.insert(std::pair<unsigned int, Glyph*>(character, glyph)); - - cursor.x += adw; - return glyph; - } - - Glyph* Font::findGlyph(unsigned int character) - { - map<unsigned int, Glyph*>::iterator it = glyphs.find(character); - if (it != glyphs.end()) - { - return it->second; - } - else - { - Glyph* glyph = bakeGlyph(character); - return glyph; - } - } - -} // graphics -} // jin - -#endif // LIBJIN_MODULES_RENDER
\ No newline at end of file |