/** * Render the font, called by Renderer.cpp */ void FontStashAdapter::render() { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); glFrontFace( GL_CCW ); shaderLib->bind(); shaderLib->getShader()->setUniform("ortho", orthogonalProjection ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D , textureID ); shaderLib->getShader()->setUniform("font", 0 ); fonsClearState(context); for( auto text_info: texts ){ fonsSetFont ( context, text_info.fontID ); fonsSetSize ( context, text_info.fontSize ); fonsSetColor ( context, text_info.color ); fonsSetSpacing( context, text_info.spacing ); fonsSetBlur ( context, text_info.blur ); fonsDrawText ( context, text_info.x, text_info.y, text_info.text.c_str(), NULL ); } shaderLib->unbind(); }
std::vector<FONSquad>& FontContext::rasterize(const std::string& _text, FontID _fontID, float _fontSize, float _sdf) { m_quadBuffer.clear(); fonsSetSize(m_fsContext, _fontSize); fonsSetFont(m_fsContext, _fontID); if (_sdf > 0){ fonsSetBlur(m_fsContext, _sdf); fonsSetBlurType(m_fsContext, FONS_EFFECT_DISTANCE_FIELD); } else { fonsSetBlurType(m_fsContext, FONS_EFFECT_NONE); } float advance = fonsDrawText(m_fsContext, 0, 0, _text.c_str(), _text.c_str() + _text.length(), 0); if (advance < 0) { m_quadBuffer.clear(); return m_quadBuffer; } return m_quadBuffer; }
void FontContext::setFont(const std::string& _key, int size) { FontID id = getFontID(_key); if (id >= 0) { fonsSetSize(m_fsContext, size); fonsSetFont(m_fsContext, id); } else { LOGW("Could not find font %s", _key.c_str()); } }
void FontContext::setFont(std::string _name, int size) { auto it = m_fonts.find(_name); if (it != m_fonts.end()) { fonsSetSize(m_fsContext, size); fonsSetFont(m_fsContext, it->second); } else { logMsg("[FontContext] Could not find font %s\n", _name.c_str()); } }
bool GLHelper::initFont() { if (myFont == nullptr) { myFont = glfonsCreate(2048, 2048, FONS_ZERO_BOTTOMLEFT); if (myFont != nullptr) { const int fontNormal = fonsAddFontMem(myFont, "medium", data_font_Roboto_Medium_ttf, data_font_Roboto_Medium_ttf_len, 0); fonsSetFont(myFont, fontNormal); fonsSetSize(myFont, (float)myFontSize); } } return myFont != nullptr; }
bool ofxFontStash2::applyStyle(const ofxFontStashStyle & style){ //if(style.fontID.size()){ fonsClearState(fs); int id = getFsID(style.fontID); fonsSetFont(fs, id); fonsSetSize(fs, style.fontSize * pixelDensity * fontScale); fonsSetColor(fs, toFScolor(style.color)); fonsSetAlign(fs, style.alignment); fonsSetBlur(fs, style.blur); return id != FONS_INVALID; //} }
bool CRenderEngine::DrawTextSt(const char* text, DuiRECT& pos,int style,int iFont,DWORD dwTextColor) { if (s_fs == NULL) { s_fs = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT); if (s_fs == NULL) { return false; } s_fontNormal = fonsAddFont(s_fs, "sans", "msyh.ttf"); if (s_fontNormal == FONS_INVALID) { return false; } } float line_height = 15.0f; //¸ù¾Ýstyle×óÓÒÖмä¶ÔÆë¼ÆËã float s_x = pos.left; float s_y = (pos.bottom - pos.top) / 2.f + pos.top; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); unsigned char a = (dwTextColor) >> 24; unsigned char r = (dwTextColor & 0xff0000) >> 16; unsigned char g = (dwTextColor & 0xff00) >> 8; unsigned char b = (dwTextColor & 0xff); unsigned int text_clr = glfonsRGBA(r,g,b,a); fonsClearState(s_fs); fonsSetSize(s_fs, line_height); fonsSetFont(s_fs, s_fontNormal); fonsSetColor(s_fs, text_clr); fonsDrawText(s_fs, s_x, s_y, text, NULL); return true; }
int Asset_TextWidth(AssetHandle assetHandle, const char *string, float scale) { Asset *asset = Asset_Get(ASSET_ANY, assetHandle); assert(asset != nullptr); if (asset->type != ASSET_BITMAPFONT && asset->type != ASSET_FONT) { Con_Errorf(ERR_GAME, "asset %s not font or bmpfont", asset->name); return -1; } int hnd; if (asset->type == ASSET_BITMAPFONT) { BitmapFont_t *fnt = (BitmapFont_t*)asset->resource; hnd = fnt->hnd; } else { TTFFont_t *fnt = (TTFFont_t*)asset->resource; hnd = fnt->hnd; } fonsSetFont(ctx, hnd); fonsSetSize(ctx, scale); return (int) fonsTextBounds(ctx, 0, 0, string, nullptr, nullptr); }
int main() { int fontNormal = FONS_INVALID; int fontItalic = FONS_INVALID; int fontBold = FONS_INVALID; int fontJapanese = FONS_INVALID; GLFWwindow* window; const GLFWvidmode* mode; struct FONSparams params; struct FONScontext* fs = NULL; if (!glfwInit()) return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); memset(¶ms, 0, sizeof(params)); params.width = 512; params.height = 512; params.flags = FONS_ZERO_TOPLEFT; if (glstInit(¶ms) == 0) { printf("Could not create renderer.\n"); return -1; } fs = fonsCreate(¶ms); if (fs == NULL) { printf("Could not create stash.\n"); return -1; } fontNormal = fonsAddFont(fs, "../example/DroidSerif-Regular.ttf"); if (fontNormal == FONS_INVALID) { printf("Could not add font normal.\n"); return -1; } fontItalic = fonsAddFont(fs, "../example/DroidSerif-Italic.ttf"); if (fontItalic == FONS_INVALID) { printf("Could not add font italic.\n"); return -1; } fontBold = fonsAddFont(fs, "../example/DroidSerif-Bold.ttf"); if (fontBold == FONS_INVALID) { printf("Could not add font bold.\n"); return -1; } fontJapanese = fonsAddFont(fs, "../example/DroidSansJapanese.ttf"); if (fontJapanese == FONS_INVALID) { printf("Could not add font japanese.\n"); return -1; } while (!glfwWindowShouldClose(window)) { float sx, sy, dx, dy, lh = 0; int width, height; glfwGetFramebufferSize(window, &width, &height); // Update and render glViewport(0, 0, width, height); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,width,height,0,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glColor4ub(255,255,255,255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); unsigned int white = glstRGBA(255,255,255,255); unsigned int brown = glstRGBA(192,128,0,128); unsigned int blue = glstRGBA(0,192,255,255); sx = 100; sy = 100; dx = sx; dy = sy; dash(dx,dy); fonsSetSize(fs, 124.0f); fonsSetFont(fs, fontNormal); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh; dash(dx,dy); fonsSetSize(fs, 124.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"The quick ",&dx); fonsSetSize(fs, 48.0f); fonsSetFont(fs, fontItalic); fonsSetColor(fs, brown); fonsDrawText(fs, dx,dy,"brown ",&dx); fonsSetSize(fs, 24.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"fox ",&dx); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetFont(fs, fontItalic); fonsDrawText(fs, dx,dy,"jumps over ",&dx); fonsSetFont(fs, fontBold); fonsDrawText(fs, dx,dy,"the lazy ",&dx); fonsSetFont(fs, fontNormal); fonsDrawText(fs, dx,dy,"dog.",&dx); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetSize(fs, 12.0f); fonsSetFont(fs, fontNormal); fonsSetColor(fs, blue); fonsDrawText(fs, dx,dy,"Now is the time for all good men to come to the aid of the party.",&dx); fonsVertMetrics(fs, NULL,NULL,&lh); dx = sx; dy += lh*1.2f*2; dash(dx,dy); fonsSetSize(fs, 18.0f); fonsSetFont(fs, fontItalic); fonsSetColor(fs, white); fonsDrawText(fs, dx,dy,"Ég get etið gler án þess að meiða mig.",&dx); fonsVertMetrics(fs, NULL,NULL,&lh); dx = sx; dy += lh*1.2f; dash(dx,dy); fonsSetFont(fs, fontJapanese); fonsDrawText(fs, dx,dy,"私はガラスを食べられます。それは私を傷つけません。asd",&dx); glEnable(GL_DEPTH_TEST); glfwSwapBuffers(window); glfwPollEvents(); } fonsDelete(fs); glfwTerminate(); return 0; }
void LikertHCI::initializeText(int threadId, FONScontext* fs, int fontNormal, int lineCount, float border, std::shared_ptr<GLSLProgram> shader, float textSize, const std::vector<std::string> &texts, std::string texKey, std::vector<std::vector<std::shared_ptr<Texture> > > &textures, std::vector<std::vector<glm::dvec2> > &sizes) { float sx, sy, lh = 0; unsigned int white = glfonsRGBA(255,255,255,255); unsigned int gray = glfonsRGBA(81, 76, 76, 255); fonsClearState(fs); fonsSetSize(fs, textSize); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsSetAlign(fs, FONS_ALIGN_CENTER | FONS_ALIGN_TOP); fonsVertMetrics(fs, NULL, NULL, &lh); for(int i=0; i < texts.size(); i++) { std::stringstream ss(texts[i]); std::string line; std::vector<std::string> lines; float maxWidth = 0; while(std::getline(ss, line, '\n')){ float width = fonsTextBounds(fs, line.c_str(), NULL, NULL); if (width > maxWidth) { maxWidth = width; } lines.push_back(line); } sx = maxWidth + (1.0f*border); sy = border; if (lineCount > lines.size()) { sy += lh * (lineCount - lines.size()) * 0.5; } float height = lh*lineCount+2.0*border; std::shared_ptr<Texture> depthTexture = Texture::createEmpty("depthTex", sx, height, 1, 1, false, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F); depthTexture->setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); depthTexture->setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); depthTexture->setTexParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); depthTexture->setTexParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture->getID(), 0); textures[threadId][i] = Texture::createEmpty("colorTex", sx, height, 1, 4, false, GL_TEXTURE_2D, GL_RGBA8); textures[threadId][i]->setTexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR); textures[threadId][i]->setTexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); textures[threadId][i]->setTexParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); textures[threadId][i]->setTexParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); textures[threadId][i]->setTexParameterf(GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0); glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textures[threadId][i]->getID(), 0); GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: assert(false); break; case GL_FRAMEBUFFER_UNSUPPORTED: assert(false); break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: assert(false); break; default: break; } assert(status == GL_FRAMEBUFFER_COMPLETE); sizes[threadId].push_back(glm::dvec2(sx, height)); glViewport(0,0, sx, height); glClear(GL_COLOR_BUFFER_BIT); shader->setUniform("projection_mat", glm::ortho(0., (double)sx, (double)height, 0., -1., 1.)); shader->setUniform("view_mat", glm::dmat4(1.0)); shader->setUniform("model_mat", glm::dmat4(1.0)); shader->setUniform("has_lambertian_texture", false); glDisable(GL_DEPTH_TEST); // Draw the darker interior quad so we get a white border around the outside from the clear color float rim = border/4.0f; GLfloat vertices[] = {rim, height-rim, sx-rim, height-rim, rim, rim, sx-rim, rim}; GLfloat texCoords[] = { 0, 1, 1, 1, 1, 0, 0, 0 }; GLfloat colors[] = { 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0, 0.32, 0.3, 0.3, 1.0}; // create the vao GLuint vaoID = 0; glGenVertexArrays(1, &vaoID); glBindVertexArray(vaoID); GLuint quadVBO = 0; glGenBuffers(1, &quadVBO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices)+sizeof(texCoords)+sizeof(colors), 0, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // copy vertices starting from 0 offest glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(texCoords), texCoords); // copy texCoords after vertices glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices)+sizeof(texCoords), sizeof(colors), colors); // copy colours after normals // set up vertex attributes glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)sizeof(vertices)); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(vertices)+sizeof(texCoords))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); glDeleteBuffers(1, &quadVBO); glDeleteVertexArrays(1, &vaoID); shader->setUniform("has_lambertian_texture", true); glActiveTexture(GL_TEXTURE0); shader->setUniform("lambertian_texture", 0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for(int j=0; j < lines.size(); j++) { std::string text = boost::replace_all_copy(lines[j], "_", " "); fonsDrawText(fs, sx/2.0, sy, text.c_str(), NULL); sy += lh; } glDisable(GL_BLEND); textures[threadId][i]->generateMipMaps(); std::string textureKey = texKey + texts[i]; texMan->setTextureEntry(threadId, textureKey, textures[threadId][i]); depthTexture.reset(); } }
int main() { int fontNormal = FONS_INVALID; int fontItalic = FONS_INVALID; int fontBold = FONS_INVALID; int fontJapanese = FONS_INVALID; GLFWwindow* window; const GLFWvidmode* mode; if (!glfwInit()) return -1; mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); window = glfwCreateWindow(mode->width - 40, mode->height - 80, "Font Stash", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwSetKeyCallback(window, key); glfwMakeContextCurrent(window); fs = glfonsCreate(256, 256, FONS_ZERO_TOPLEFT); if (fs == NULL) { printf("Could not create stash.\n"); return -1; } fonsSetErrorCallback(fs, stashError, fs); fontNormal = fonsAddFont(fs, "sans", "../example/DroidSerif-Regular.ttf"); if (fontNormal == FONS_INVALID) { printf("Could not add font normal.\n"); return -1; } fontItalic = fonsAddFont(fs, "sans-italic", "../example/DroidSerif-Italic.ttf"); if (fontItalic == FONS_INVALID) { printf("Could not add font italic.\n"); return -1; } fontBold = fonsAddFont(fs, "sans-bold", "../example/DroidSerif-Bold.ttf"); if (fontBold == FONS_INVALID) { printf("Could not add font bold.\n"); return -1; } fontJapanese = fonsAddFont(fs, "sans-jp", "../example/DroidSansJapanese.ttf"); if (fontJapanese == FONS_INVALID) { printf("Could not add font japanese.\n"); return -1; } while (!glfwWindowShouldClose(window)) { float sx, sy, dx, dy, lh = 0; int width, height; int atlasw, atlash; unsigned int white,black,brown,blue; char msg[64]; glfwGetFramebufferSize(window, &width, &height); // Update and render glViewport(0, 0, width, height); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,width,height,0,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glColor4ub(255,255,255,255); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); white = glfonsRGBA(255,255,255,255); brown = glfonsRGBA(192,128,0,128); blue = glfonsRGBA(0,192,255,255); black = glfonsRGBA(0,0,0,255); sx = 50; sy = 50; dx = sx; dy = sy; dash(dx,dy); fonsClearState(fs); fonsSetSize(fs, size); fonsSetFont(fs, fontNormal); fonsVertMetrics(fs, NULL, NULL, &lh); dx = sx; dy += lh; dash(dx,dy); fonsSetSize(fs, size); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); dx = fonsDrawText(fs, dx,dy,"The quick ",NULL); fonsSetSize(fs, size/2); fonsSetFont(fs, fontItalic); fonsSetColor(fs, brown); dx = fonsDrawText(fs, dx,dy,"brown ",NULL); fonsSetSize(fs, size/3); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); dx = fonsDrawText(fs, dx,dy,"fox ",NULL); fonsSetSize(fs, 14); fonsSetFont(fs, fontNormal); fonsSetColor(fs, white); fonsDrawText(fs, 20, height-20,"Press UP / DOWN keys to change font size and to trigger atlas full callback, R to reset atlas, E to expand atlas.",NULL); fonsGetAtlasSize(fs, &atlasw, &atlash); snprintf(msg, sizeof(msg), "Atlas: %d × %d", atlasw, atlash); fonsDrawText(fs, 20, height-50, msg, NULL); fonsDrawDebug(fs, width - atlasw - 20, 20.0); glEnable(GL_DEPTH_TEST); glfwSwapBuffers(window); glfwPollEvents(); } glfonsDelete(fs); glfwTerminate(); return 0; }