// can't unload TTFs, so we'll need to make sure we don't keep reloading them, sadly void* TTF_Load(Asset &asset) { TTFFont_t *fnt = new TTFFont_t(); if (ctx == nullptr) { ctx = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT); } int found = fonsGetFontByName(ctx, asset.name); if (found != FONS_INVALID) { fnt->valid = true; fnt->hnd = found; found++; return fnt; } unsigned char *font; auto sz = FS_ReadFile(asset.path, (void **)&font); if (sz == -1) { Con_Errorf(ERR_GAME, "couldn't load file %s", asset.path); return nullptr; } int hnd = fonsAddFontMem(ctx, asset.name, font, sz, 1); if (hnd < 0) { return nullptr; } fnt->valid = true; fnt->hnd = hnd; return (void*)fnt; }
void FontContext::initFontContext(int _atlasSize) { GLFONSparams params; params.errorCallback = errorCallback; params.createAtlas = createAtlas; params.createTexTransforms = createTexTransforms; params.updateAtlas = updateAtlas; params.updateTransforms = updateTransforms; m_fsContext = glfonsCreate(_atlasSize, _atlasSize, FONS_ZERO_TOPLEFT, params, (void*) this); }
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; }
void ofxFontStash2::setup(int atlasSizePow2){ #ifdef GL_VERSION_3 ofLogNotice("ofxFontStash2") << "creating fontStash GL3"; fs = gl3fonsCreate(atlasSizePow2, atlasSizePow2, FONS_ZERO_TOPLEFT); #else ofLogNotice("ofxFontStash2") << "creating fontStash GL2"; fs = glfonsCreate(atlasSizePow2, atlasSizePow2, FONS_ZERO_TOPLEFT); #endif if (fs == NULL) { ofLogError("ofxFontStash2") << "Could not create stash."; return; } }
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; }
void LikertHCI::initializeText(int threadId, MinVR::WindowRef window) { int fontNormal = FONS_INVALID; struct FONScontext* fs = nullptr; fs = glfonsCreate(512, 512, FONS_ZERO_TOPLEFT); if (fs == NULL) { BOOST_ASSERT_MSG(false, "Could not create stash."); } fontNormal = fonsAddFont(fs, "sans", MinVR::ConfigVal("RegularFontFile", "app/fonts/DroidSansMono.ttf", false).c_str()); if (fontNormal == FONS_INVALID) { BOOST_ASSERT_MSG(false, "Could not add font normal.\n"); } glUseProgram(0); glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); GLuint textFBO; glGenFramebuffers(1, &textFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, textFBO); glDrawBuffer(GL_COLOR_ATTACHMENT0); std::map<std::string, std::string> dummyArgs; std::shared_ptr<GLSLProgram> shader(new GLSLProgram()); shader->compileShader(MinVR::DataFileUtils::findDataFile("textRendering.vert").c_str(), GLSLShader::VERTEX, dummyArgs); shader->compileShader(MinVR::DataFileUtils::findDataFile("textRendering.frag").c_str(), GLSLShader::FRAGMENT, dummyArgs); shader->link(); shader->use(); glClearColor(1.0, 1.0, 1.0, 1.0); initializeText(threadId, fs, fontNormal, _maxNumLinesInQuestions, 20.0f, shader, 72.0f, _questions, "QuestionText_", _questionTextures, _questionSizes); initializeText(threadId, fs, fontNormal, _maxNumLinesInAnswers, 15.0f, shader, 35.0f, _answers, "AnswerText_", _answerTextures, _answerSizes); double windowHeight = window->getHeight(); double windowWidth = window->getWidth(); _padding = 0.05; double numAnswersPerQuestion = 7.0; _availableWidth = glm::length(offAxisCamera->getBottomRight() - offAxisCamera->getBottomLeft()) - (2*_padding); _individualSize = _availableWidth/ (numAnswersPerQuestion); glm::dvec3 start(offAxisCamera->getBottomLeft().x + _padding + _individualSize/2.0, 0.0, 0.5); glm::dvec3 spacing(_individualSize, 0.0, 0.0); for(int i=0; i < _answers.size(); i++) { double texHeight = _answerTextures[0][i]->getHeight(); // all answers are the same dimensions; double texWidth = _answerTextures[0][i]->getWidth(); double quadHeightScreen = texHeight/windowHeight; double quadWidthScreen = texWidth/windowWidth; glm::dvec3 quad = glm::abs(convertScreenToRoomCoordinates(glm::dvec2(quadWidthScreen+0.5, quadHeightScreen+0.5))); _answerHeights.push_back(quad.z); glm::dvec2 size = _answerSizes[threadId][i]; double halfWidth = _answerHeights[i] * size.x / size.y / 2.0f; double halfHeight = _answerHeights[i] / 2.0f; glm::dvec3 centerPt = start+ (double)i*spacing; glm::dvec3 low(-halfWidth, -0.001, -halfHeight); glm::dvec3 high(halfWidth, 0.001, halfHeight); AABox bounds(start + (double)i*spacing + low, start + (double)i*spacing +high); _answerBounds.push_back(bounds); } for(int i=0; i < _questions.size(); i++) { double texHeight = _questionTextures[0][i]->getHeight(); // all answers are the same dimensions; double texWidth = _questionTextures[0][i]->getWidth(); double quadHeightScreen = texHeight/windowHeight; double quadWidthScreen = texWidth/windowWidth; glm::dvec3 quad = glm::abs(convertScreenToRoomCoordinates(glm::dvec2(quadWidthScreen+0.5, quadHeightScreen+0.5))); _questionHeights.push_back(quad.z); } glfonsDelete(fs); glUseProgram(0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &textFBO); glPopAttrib(); // restore viewport and enabled bits glEnable(GL_TEXTURE_2D); // restore the clear color glm::dvec3 clearColor = MinVR::ConfigVal("ClearColor", glm::dvec3(0.1), false); glClearColor(clearColor.r, clearColor.g, clearColor.b, 1.0f); }
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; }