bool ofxFontStash::setup( string fontFile, float lineHeightPercent , int texDimension /*has to be powerfOfTwo!*/){ if (stash == NULL){ lineHeight = lineHeightPercent; texDimension = ofNextPow2(texDimension); stash = sth_create(texDimension,texDimension); stashFontID = sth_add_font( stash, ofToDataPath( fontFile ).c_str() ); if ( stashFontID != 0){ ofLogNotice("ofxFontStash", "loaded font '%s' in texture (%d x %d)", fontFile.c_str(), texDimension, texDimension ); return true; }else{ ofLogError("ofxFontStash", "Can't load font! '%s'", fontFile.c_str() ); } }else{ ofLogError("ofxFontStash", "don't call setup() more than once! %s", fontFile.c_str() ); } return false; }
sth_stash* initFont(GLPrimitiveRenderer* primRender) { GLint err; struct sth_stash* stash = 0; int datasize; float sx,sy,dx,dy,lh; GLuint texture; renderCallbacks = new OpenGL2RenderCallbacks(primRender); stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512); err = glGetError(); assert(err==GL_NO_ERROR); if (!stash) { fprintf(stderr, "Could not create stash.\n"); return 0; } #ifdef LOAD_FONT_FROM_FILE unsigned char* data=0; const char* fontPaths[]={ "./", "../../bin/", "../bin/", "bin/" }; int numPaths=sizeof(fontPaths)/sizeof(char*); // Load the first truetype font from memory (just because we can). FILE* fp = 0; const char* fontPath ="./"; char fullFontFileName[1024]; for (int i=0;i<numPaths;i++) { fontPath = fontPaths[i]; //sprintf(fullFontFileName,"%s%s",fontPath,"OpenSans.ttf");//"DroidSerif-Regular.ttf"); sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Regular.ttf");//OpenSans.ttf");//"DroidSerif-Regular.ttf"); fp = fopen(fullFontFileName, "rb"); if (fp) break; } err = glGetError(); assert(err==GL_NO_ERROR); assert(fp); if (fp) { fseek(fp, 0, SEEK_END); datasize = (int)ftell(fp); fseek(fp, 0, SEEK_SET); data = (unsigned char*)malloc(datasize); if (data == NULL) { assert(0); return 0; } else fread(data, 1, datasize, fp); fclose(fp); fp = 0; } if (!(droidRegular = sth_add_font_from_memory(stash, data))) { assert(0); return 0; } err = glGetError(); assert(err==GL_NO_ERROR); // Load the remaining truetype fonts directly. sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Italic.ttf"); if (!(droidItalic = sth_add_font(stash,fullFontFileName))) { assert(0); return 0; } sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Bold.ttf"); if (!(droidBold = sth_add_font(stash,fullFontFileName))) { assert(0); return 0; } err = glGetError(); assert(err==GL_NO_ERROR); sprintf(fullFontFileName,"%s%s",fontPath,"DroidSansJapanese.ttf"); if (!(droidJapanese = sth_add_font(stash,fullFontFileName))) { assert(0); return 0; } #else//LOAD_FONT_FROM_FILE char* data2 = OpenSansData; unsigned char* data = (unsigned char*) data2; if (!(droidRegular = sth_add_font_from_memory(stash, data))) { printf("error!\n"); } #endif//LOAD_FONT_FROM_FILE err = glGetError(); assert(err==GL_NO_ERROR); return stash; }
Font *CreateFont(Font *font, const char *path, const Vec2i *size) { font->stash = sth_create(size->x, size->y); font->size = 14.0f; font->ID = sth_add_font(font->stash, path); return font; }
int main(int argc, char *argv[]) { int done; SDL_Event event; int width, height; struct sth_stash* stash = 0; FILE* fp = 0; int datasize; unsigned char* data; float sx,sy,dx,dy,lh; int droidRegular, droidItalic, droidBold, droidJapanese, dejavu; SDL_Surface* surface; GLuint texture; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return -1; } // Init OpenGL SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); #ifdef STH_OPENGL3 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); #endif width = 800; height = 600; SDL_Window* window = SDL_CreateWindow("FontStash Demo", 100, 100, width, height, SDL_WINDOW_OPENGL); if (!window) { fprintf(stderr, "Could not initialise SDL opengl\n"); return -1; } SDL_GLContext context = SDL_GL_CreateContext(window); stash = sth_create(512,512); if (!stash) { fprintf(stderr, "Could not create stash.\n"); return -1; } // Load the first truetype font from memory (just because we can). fp = fopen("DroidSerif-Regular.ttf", "rb"); if (!fp) goto error_add_font; fseek(fp, 0, SEEK_END); datasize = (int)ftell(fp); fseek(fp, 0, SEEK_SET); data = (unsigned char*)malloc(datasize); if (data == NULL) goto error_add_font; fread(data, 1, datasize, fp); fclose(fp); fp = 0; if (!(droidRegular = sth_add_font_from_memory(stash, data))) goto error_add_font; // Load the remaining truetype fonts directly. if (!(droidItalic = sth_add_font(stash,"DroidSerif-Italic.ttf"))) goto error_add_font; if (!(droidBold = sth_add_font(stash,"DroidSerif-Bold.ttf"))) goto error_add_font; if (!(droidJapanese = sth_add_font(stash,"DroidSansJapanese.ttf"))) goto error_add_font; // Load a bitmap font surface = IMG_Load("dejavu-sans_0.png"); if (surface == NULL) { fprintf(stderr, "%s.\n", IMG_GetError()); return -1; } glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, surface->w, surface->h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, surface->pixels); if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); SDL_FreeSurface(surface); dejavu = sth_add_bitmap_font(stash, 17, -4, 2); sth_add_glyph_for_char(stash, dejavu, texture, "T", 18, 14, 363, 331, 10, 11, 0, 3, 10); sth_add_glyph_for_char(stash, dejavu, texture, "h", 18, 14, 225, 382, 8, 11, 1, 3, 10); sth_add_glyph_for_char(stash, dejavu, texture, "i", 18, 14, 478, 377, 2, 11, 1, 3, 4); sth_add_glyph_for_char(stash, dejavu, texture, "s", 18, 14, 199, 455, 7, 8, 1, 6, 9); sth_add_glyph_for_char(stash, dejavu, texture, " ", 18, 14, 66, 185, 1, 1, 0, 14, 5); sth_add_glyph_for_char(stash, dejavu, texture, "a", 18, 14, 18, 459, 8, 8, 1, 6, 10); sth_add_glyph_for_char(stash, dejavu, texture, "b", 18, 14, 198, 383, 8, 11, 1, 3, 10); sth_add_glyph_for_char(stash, dejavu, texture, "t", 18, 14, 436, 377, 5, 11, 1, 3, 6); sth_add_glyph_for_char(stash, dejavu, texture, "m", 18, 14, 494, 429, 12, 8, 2, 6, 16); sth_add_glyph_for_char(stash, dejavu, texture, "p", 18, 14, 436, 353, 8, 11, 1, 6, 10); sth_add_glyph_for_char(stash, dejavu, texture, "f", 18, 14, 442, 377, 5, 11, 1, 3, 7); sth_add_glyph_for_char(stash, dejavu, texture, "o", 18, 14, 483, 438, 8, 8, 1, 6, 10); sth_add_glyph_for_char(stash, dejavu, texture, "n", 18, 14, 0, 459, 8, 8, 1, 6, 10); sth_add_glyph_for_char(stash, dejavu, texture, ".", 18, 14, 285, 476, 2, 3, 1, 11, 6); done = 0; while (!done) { while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEMOTION: break; case SDL_MOUSEBUTTONDOWN: break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) done = 1; break; case SDL_QUIT: done = 1; break; default: break; } } // Update and render glViewport(0, 0, width, height); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); #ifdef STH_OPENGL3 std::cout << "OpenGL3" << std::endl; glm::mat4 proj = glm::ortho(0.0f, (GLfloat) width, 0.0f, (GLfloat) height, -1.0f, 1.0f); sth_projection_matrix(stash, glm::value_ptr(proj)); sth_color(stash, 1.0f, 0.0f, 0.0f, 1.0f); #else std::cout << "Immediate OpenGL" << std::endl; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,width,0,height,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor4ub(255,255,255,255); #endif sx = 100; sy = 250; sth_begin_draw(stash); dx = sx; dy = sy; sth_draw_text(stash, droidRegular, 24.0f, dx, dy, "The quick ", &dx); sth_draw_text(stash, droidItalic, 48.0f, dx, dy, "brown ", &dx); sth_draw_text(stash, droidRegular, 24.0f, dx, dy, "fox ", &dx); sth_vmetrics(stash, droidItalic, 24, NULL, NULL, &lh); dx = sx; dy -= lh*1.2f; sth_draw_text(stash, droidItalic, 24.0f, dx, dy, "jumps over ", &dx); sth_draw_text(stash, droidBold, 24.0f, dx, dy, "the lazy ", &dx); sth_draw_text(stash, droidRegular, 24.0f, dx, dy, "dog.", &dx); dx = sx; dy -= lh*1.2f; sth_draw_text(stash, droidRegular, 12.0f, dx, dy, "Now is the time for all good men to come to the aid of the party.", &dx); sth_vmetrics(stash, droidItalic, 12, NULL, NULL, &lh); dx = sx; dy -= lh*1.2f*2; sth_draw_text(stash, droidItalic, 18.0f, dx, dy, "Ég get etið gler án þess að meiða mig.", &dx); sth_vmetrics(stash, droidItalic, 18, NULL, NULL, &lh); dx = sx; dy -= lh*1.2f; sth_draw_text(stash, droidJapanese, 18.0f, dx, dy, "私はガラスを食べられます。それは私を傷つけません。", &dx); dx = sx; dy -= lh*1.2f*2; sth_draw_text(stash, dejavu, 18.0f, dx, dy, "This is a bitmap font.", &dx); sth_end_draw(stash); SDL_GL_SwapWindow(window); } sth_delete(stash); free(data); SDL_GL_DeleteContext(context); SDL_Quit(); return 0; error_add_font: fprintf(stderr, "Could not add font.\n"); return -1; }
int UnicodeFont::LoadFont(const char* fontFileName) { return sth_add_font(_stash,fontFileName); }
int main(int argc, char* argv[]) { GLint err; b3CommandLineArgs args(argc,argv); if (args.CheckCmdLineFlag("help")) { Usage(); return 0; } args.GetCmdLineArgument("enable_interop", useInterop); printf("useInterop=%d\n",useInterop); args.GetCmdLineArgument("pause_simulation", pauseSimulation); printf("pause_simulation=%d\n",pauseSimulation); char* tmpfile = 0; args.GetCmdLineArgument("load_bulletfile", tmpfile ); if (tmpfile) fileName = tmpfile; printf("load_bulletfile=%s\n",fileName); int width = 700; int height= 512; printf("\n"); b3gDefaultOpenGLWindow* window = new b3gDefaultOpenGLWindow(); window->createWindow(b3gWindowConstructionInfo(width,height)); window->setWindowTitle("font test"); #ifndef __APPLE__ err = glewInit(); #endif window->runMainLoop(); loadShader(); loadBufferData(); initTestTexture(); window->startRendering(); window->endRendering(); err = glGetError(); b3Assert(err==GL_NO_ERROR); // render.InitShaders(); // render.writeTransforms(); window->runMainLoop(); // window->setMouseCallback(b3DefaultMouseCallback); // window->setKeyboardCallback(b3DefaultKeyboardCallback); // window->setWheelCallback(b3DefaultWheelCallback); err = glGetError(); b3Assert(err==GL_NO_ERROR); int done; struct sth_stash* stash = 0; FILE* fp = 0; int datasize; float sx,sy,dx,dy,lh; int droidRegular;//, droidItalic, droidBold, droidJapanese, dejavu; GLuint texture; int fontTextureWidth = 512; int fontTextureHeight = 512; SimpleOpenGL2RenderCallbacks* renderCallbacks = new SimpleOpenGL2RenderCallbacks(&sData); stash = sth_create(fontTextureWidth,fontTextureHeight,renderCallbacks); err = glGetError(); b3Assert(err==GL_NO_ERROR); if (!stash) { fprintf(stderr, "Could not create stash.\n"); return -1; } // Load the first truetype font from memory (just because we can). #ifdef _WIN32 const char* fontPath = "../../bin/"; #else const char* fontPath = "./"; #endif char fullFontFileName[1024]; sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Regular.ttf");//cour.ttf");//times.ttf");//DroidSerif-Regular.ttf"); //sprintf(fullFontFileName,"%s%s",fontPath,"arial.ttf");//cour.ttf");//times.ttf");//DroidSerif-Regular.ttf"); fp = fopen(fullFontFileName, "rb"); #ifdef LOAD_FONT_FROM_FILE unsigned char* data; err = glGetError(); b3Assert(err==GL_NO_ERROR); b3Assert(fp); if (fp) { fseek(fp, 0, SEEK_END); datasize = (int)ftell(fp); fseek(fp, 0, SEEK_SET); data = (unsigned char*)malloc(datasize); if (data == NULL) { b3Assert(0); return -1; } else fread(data, 1, datasize, fp); fclose(fp); fp = 0; } if (!(droidRegular = sth_add_font_from_memory(stash, data))) { b3Assert(0); return -1; } err = glGetError(); b3Assert(err==GL_NO_ERROR); // Load the remaining truetype fonts directly. sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Italic.ttf"); if (!(droidItalic = sth_add_font(stash,fullFontFileName))) { b3Assert(0); return -1; } sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Bold.ttf"); if (!(droidBold = sth_add_font(stash,fullFontFileName))) { b3Assert(0); return -1; } err = glGetError(); b3Assert(err==GL_NO_ERROR); sprintf(fullFontFileName,"%s%s",fontPath,"DroidSansJapanese.ttf"); if (!(droidJapanese = sth_add_font(stash,fullFontFileName))) { b3Assert(0); return -1; } err = glGetError(); b3Assert(err==GL_NO_ERROR); #else//LOAD_FONT_FROM_FILE char* data2 = OpenSansData; unsigned char* data = (unsigned char*) data2; if (!(droidRegular = sth_add_font_from_memory(stash, data))) { printf("error!\n"); } #endif//LOAD_FONT_FROM_FILE while (!window->requestedExit()) { GLint err = glGetError(); b3Assert(err==GL_NO_ERROR); // glClearColor(0.5f,0.5f,0.5f,1.f); err = glGetError(); b3Assert(err==GL_NO_ERROR); window->startRendering(); err = glGetError(); b3Assert(err==GL_NO_ERROR); glClearColor(1,1,1,1);//.4, .4, 0.4, 1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //display(); err = glGetError(); b3Assert(err==GL_NO_ERROR); if (1) { B3_PROFILE("font stash rendering"); // Update and render glEnable(GL_BLEND); err = glGetError(); b3Assert(err==GL_NO_ERROR); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); err = glGetError(); b3Assert(err==GL_NO_ERROR); err = glGetError(); b3Assert(err==GL_NO_ERROR); glDisable(GL_DEPTH_TEST); err = glGetError(); b3Assert(err==GL_NO_ERROR); //glColor4ub(255,0,0,255); err = glGetError(); b3Assert(err==GL_NO_ERROR); glEnable(GL_BLEND); err = glGetError(); b3Assert(err==GL_NO_ERROR); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); err = glGetError(); b3Assert(err==GL_NO_ERROR); sx = 0; sy = height; sth_begin_draw(stash); display(); dx = sx; dy = sy; static int once=0; //sth_draw_text(stash, droidRegular,12.f, dx, dy-50, "How does this OpenGL True Type font look? ", &dx,width,height); int spacing = 512; if (1) for (int i=20;i<=110;i+=12) { char txt[512]; sprintf(txt,"%d. The quick brown fox jumped over the lazy dog. 1234567890",i); sth_draw_text(stash, droidRegular,i, 10, dy-spacing, txt, &dx,width,height); spacing-=i; } err = glGetError(); b3Assert(err==GL_NO_ERROR); if (0) for (int i=0;i<1;i++) { dx = sx; if (once!=1) { //need to save this file as UTF-8 without signature, codepage 650001 in Visual Studio err = glGetError(); b3Assert(err==GL_NO_ERROR); //sth_draw_text(stash, droidJapanese,16.f, dx, dy-36, (const char*) "\xE7\xA7\x81\xE3\x81\xAF\xE3\x82\xAC\xE3\x83\xA9\xE3\x82\xB9\xE3\x82\x92\xE9\xA3\x9F\xE3\x81\xB9\xE3\x82\x89\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99\xE3\x80\x82",&dx, // width,height);//はabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); // sth_draw_text(stash, droidJapanese,32.f, dx, dy, (const char*) "私はガラスを食べられます。それは私を傷つけません。",&dx);//はabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); dx = sx; err = glGetError(); b3Assert(err==GL_NO_ERROR); sth_flush_draw(stash); dx=0; sth_draw_text(stash, droidRegular,14.f, dx, dy-80, "How does this OpenGL True Type font look? ", &dx,width,height); dx=0; dy-=30; //sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "Profile How does this OpenGL True Type font look? ", &dx,width,height); dx=0; dy-=30; sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", &dx,width,height); dx=0; dy-=30; sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "!@#$%^abcdefghijklmnopqrstuvwxyz", &dx,width,height); dx=0; // sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); //sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); sth_flush_draw(stash); err = glGetError(); b3Assert(err==GL_NO_ERROR); } else { dx = sx; dy = height; err = glGetError(); b3Assert(err==GL_NO_ERROR); sth_draw_texture(stash, droidRegular, 16.f, 0, 0,width,height, "a", &dx); err = glGetError(); b3Assert(err==GL_NO_ERROR); dumpTextureToPng(fontTextureWidth, fontTextureHeight,"newPic.png"); } once++; } err = glGetError(); b3Assert(err==GL_NO_ERROR); sth_end_draw(stash); glEnable(GL_DEPTH_TEST); err = glGetError(); b3Assert(err==GL_NO_ERROR); //glFinish(); } err = glGetError(); b3Assert(err==GL_NO_ERROR); window->endRendering(); err = glGetError(); b3Assert(err==GL_NO_ERROR); { glFinish(); } static bool printStats = true; if (printStats && !pauseSimulation) { static int count = 0; count--; if (count<0) { count = 100; // b3ProfileManager::dumpAll(); //printStats = false; } else { // printf("."); } } err = glGetError(); b3Assert(err==GL_NO_ERROR); } #ifdef _WIN32 sth_delete(stash); #ifdef LOAD_FONT_FROM_FILE free(data); #endif //LOAD_FONT_FROM_FILE #endif // render.CleanupShaders(); window->closeWindow(); delete window; return 0; }
void font_load(int i, char *path) { int ret = sth_add_font(stash, path); if(!ret)printf("Failed to load font %d:\"%s\"\n", i, path); }