bool TGLFont::Load(const char* fontname) { char full_filename[512]; sprintf_s(full_filename,sizeof(full_filename),"Data/Fonts/%s", fontname); FT_Face ftFace; FT_Error err_code = FT_New_Face(ftLibrary,full_filename,0,&ftFace); if(err_code == FT_Err_Unknown_File_Format) { LogFile->Write("Bad font file format: "+string(fontname),LT_ERROR); return false; } else if (err_code) { LogFile->Write("Can't load font: "+string(fontname),LT_ERROR); return false; } if (iFontSize > min(ftFace->max_advance_width,ftFace->max_advance_height)) { FT_Done_Face(ftFace); LogFile->Write("Font size greater that supported font: "+string(fontname),LT_ERROR); return false; } if (FT_Set_Char_Size(ftFace, iFontSize*64, iFontSize*64, iHorizDPI, iVertDPI)) { FT_Done_Face(ftFace); LogFile->Write("Can't set font size for font: "+string(fontname),LT_ERROR); return false; } // new code FT_Long glyphs_count = ftFace->num_glyphs; if (glyphs_count == 0) { FT_Done_Face(ftFace); LogFile->Write("No glyphs in font: "+string(fontname),LT_ERROR); return false; } try { PLuint gridsize = GetGridSize(iFontSize); /*sprintf_s(full_filename,sizeof(full_filename),"???%s-%d", fontname, fontsize); pTex = pTextureSpool->CreateFontCashe(full_filename, gridsize*16, gridsize*16);*/ ((Texture::Texture2D&)pTex.GetObj()).LoadFromMem(0, gridsize*16, gridsize*16, Loader::Image::DT_RGBA); pGlyph = new Glyph2D*[MAXBYTE+1]; PLuint xoffset = 2 + iFontSize / 2 + 2; // reverse space for empty glyph PLuint yoffset = 2; PLint max_in_line = 0; for(PLuint i = 0; i <= MAXBYTE; i++) { wchar_t unicode_char = ctowc(i,iCodepage); if ((unicode_char != 0)&&(unicode_char < glyphs_count)) { FT_UInt ch_index = FT_Get_Char_Index(ftFace, unicode_char); if (ch_index) { if (FT_Load_Glyph( ftFace, ch_index, FT_LOAD_DEFAULT )) { pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph continue; } FT_Glyph ftGlyph; if (FT_Get_Glyph( ftFace->glyph, &ftGlyph )) { pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph continue; } if (FT_Glyph_To_Bitmap( &ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1 )) { pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph continue; } FT_BitmapGlyph ftBitmapGlyph = (FT_BitmapGlyph)ftGlyph; FT_Bitmap& bitmap = ftBitmapGlyph->bitmap; if ((bitmap.rows == 0) || (bitmap.width == 0)) { pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph continue; } GLubyte* pExpData = new GLubyte[4*bitmap.width*bitmap.rows]; for (PLint k = 0; k < bitmap.rows; k++) { for(PLint j = 0; j < bitmap.width; j++) { unsigned char buf = bitmap.buffer[j + bitmap.width*k]; pExpData[4*(j+k*bitmap.width)] = 255; pExpData[4*(j+k*bitmap.width)+1] = 255; pExpData[4*(j+k*bitmap.width)+2] = 255; pExpData[4*(j+k*bitmap.width)+3] = buf; } } if (xoffset + bitmap.width >= gridsize*16) { xoffset = 2; yoffset += max_in_line + 2; } if (bitmap.rows > max_in_line) max_in_line = bitmap.rows; ((Texture::Texture2D&)pTex.GetObj()).SetRectFromMem(xoffset,yoffset,pExpData,bitmap.width,bitmap.rows,Loader::Image::DT_RGBA); pGlyph[i] = new Glyph2D(gridsize*16, xoffset, yoffset, bitmap.width, bitmap.rows, ftBitmapGlyph->top-bitmap.rows); delete[] pExpData; xoffset += bitmap.width + 2; } else pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph } else pGlyph[i] = new Glyph2D(gridsize*16, 2, 2, iFontSize / 2, 1, 0); // empty glyph } pTex->SendGPU(false); } catch(...) { delete[] pGlyph; return false; } FT_Done_Face(ftFace); sFontname = fontname; return true; }
//--------------------------------------------------------------------------------------- // WinMain //--------------------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX clas; MSG msg; int style; RECT rect; //need COM for DirectShow CoInitializeEx(NULL, COINIT_MULTITHREADED); //Here we create the Class we named above clas.cbSize = sizeof(WNDCLASSEX); clas.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; clas.lpfnWndProc = WindowProc;//<- tell it where the WindowProc is clas.cbClsExtra = 0; clas.cbWndExtra = 0; clas.hInstance = hInstance; clas.hIcon = NULL; clas.hCursor = NULL; clas.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//<- background colour of window clas.lpszMenuName = NULL; clas.lpszClassName = game_class;//<- the class name clas.hIconSm = 0; //do it! RegisterClassEx(&clas); //style of the window - what boxes do we need (close minimised etc) style = WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX; //create the window game_window = CreateWindowEx(0, game_class, "DirectShow", style, CW_USEDEFAULT, CW_USEDEFAULT, 1,1, NULL, NULL, hInstance, 0); //adjust the window size so that a SCREEN_X x SCREEN_Y window will fit inside its frame rect.left = rect.top = 0; rect.right = SCREEN_X; rect.bottom = SCREEN_Y; AdjustWindowRectEx(&rect, style , FALSE, 0); SetWindowPos(game_window, NULL, 0,0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE|SWP_NOZORDER); //show the window on the desktop ShowWindow(game_window, nCmdShow); char filename[_MAX_PATH]; OPENFILENAME ofn; BOOL res; filename[0] = '\0'; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = NULL; ofn.hInstance = NULL; ofn.lpstrFilter = "AVI Files\0*.avi\0"; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = filename; ofn.nMaxFile = _MAX_PATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = "Select Video File"; ofn.Flags = OFN_FILEMUSTEXIST|OFN_EXPLORER; ofn.nFileOffset=0; ofn.nFileExtension=0; ofn.lpstrDefExt="bin"; ofn.lCustData=0; ofn.lpfnHook=NULL; ofn.lpTemplateName=""; res = GetOpenFileName(&ofn); if (res == 0) return 0; if (init_dshow(ctowc(filename), IN_OWN_WINDOW)==0) { MessageBox(NULL, "A problem occurred creating the DirectShow FilterGraph.\nCheck your video CODECs and " "DirectX version.\nThis demo requires DirectX9.0 or better.", "DirectX Initialisation Error", MB_ICONWARNING|MB_OK); shutdown_dshow(); return 0; } //message processing loop //all Windows programs have one of these. It receives the messages Windows sends to the program and //passes them to the WindowProc in the Class we registered for the window. quit = 0; do { //Are there any messages waiting? while (PeekMessage(&msg, game_window, 0, 0, PM_NOREMOVE)) { //yes! read it. if (GetMessage(&msg, game_window, 0,0) < 0) break; //pass the message to WindowProc TranslateMessage(&msg); DispatchMessage(&msg); } } while (!quit); shutdown_dshow(); CoUninitialize(); return 0; }