bool ofxFontStash2::addFont(const string& fontID, const string& fontFile){ int id = fonsAddFont(fs, fontID.c_str(), ofToDataPath(fontFile).c_str()); if(id != FONS_INVALID){ fontIDs[fontID] = id; return true; }else{ ofLogError("ofxFontStash2") << "Could not load font '" << fontFile << "'"; return false; } }
FontID FontContext::addFont(const std::string& _family, const std::string& _weight, const std::string& _style, bool _tryFallback) { unsigned int dataSize = 0; unsigned char* data = nullptr; int font = FONS_INVALID; std::string fontKey = _family + "_" + _weight + "_" + _style; auto it = m_fonts.find(fontKey); if (it != m_fonts.end()) { if (it->second < 0) { goto fallback; } return it->second; } { // Assuming bundled ttf file follows this convention auto bundledFontPath = "fonts/" + _family + "-" + _weight + _style + ".ttf"; if (!(data = bytesFromFile(bundledFontPath.c_str(), PathType::resource, &dataSize)) && !(data = bytesFromFile(bundledFontPath.c_str(), PathType::internal, &dataSize))) { const std::string sysFontPath = systemFontPath(_family, _weight, _style); if ( !(data = bytesFromFile(sysFontPath.c_str(), PathType::absolute, &dataSize)) ) { LOGE("Could not load font file %s", fontKey.c_str()); m_fonts.emplace(std::move(fontKey), INVALID_FONT); goto fallback; } } } font = fonsAddFont(m_fsContext, fontKey.c_str(), data, dataSize); if (font == FONS_INVALID) { LOGE("Could not load font %s", fontKey.c_str()); m_fonts.emplace(std::move(fontKey), INVALID_FONT); goto fallback; } m_fonts.emplace(std::move(fontKey), font); return font; fallback: if (_tryFallback && m_fonts.size() > 0) { return 0; } return INVALID_FONT; }
bool FontContext::addFont(std::string _fontFile, std::string _name) { if (m_fonts.find(_name) != m_fonts.end()) { return true; } unsigned int dataSize; unsigned char* data = bytesFromResource(_fontFile.c_str(), &dataSize); m_font = fonsAddFont(m_fsContext, "droid-serif", data, dataSize); if (m_font == FONS_INVALID) { logMsg("[FontContext] Error loading font file %s\n", _fontFile.c_str()); return false; } m_fonts[_name] = m_font; return true; }
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 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, 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); }
/** * Add and load a new font */ void FontStashAdapter::addFont( const std::string& font_name, const std::string& filename ) { if( fonsAddFont(context, font_name.c_str(), filename.c_str() ) == FONS_INVALID ) throw runtime_error( "Unable to load font: " + filename ); }
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; }