bool Font::LoadFromStream(InputStream& stream) { // Cleanup the previous resources Cleanup(); myRefCount = new int(1); // Initialize FreeType // Note: we initialize FreeType for every font instance in order to avoid having a single // global manager that would create a lot of issues regarding creation and destruction order. FT_Library library; if (FT_Init_FreeType(&library) != 0) { Err() << "Failed to load font from stream (failed to initialize FreeType)" << std::endl; return false; } myLibrary = library; // Prepare a wrapper for our stream, that we'll pass to FreeType callbacks FT_StreamRec* rec = new FT_StreamRec; std::memset(rec, 0, sizeof(rec)); rec->base = NULL; rec->size = static_cast<unsigned long>(stream.GetSize()); rec->pos = 0; rec->descriptor.pointer = &stream; rec->read = &Read; rec->close = &Close; // Setup the FreeType callbacks that will read our stream FT_Open_Args args; args.flags = FT_OPEN_STREAM; args.stream = rec; args.driver = 0; // Load the new font face from the specified stream FT_Face face; if (FT_Open_Face(static_cast<FT_Library>(myLibrary), &args, 0, &face) != 0) { Err() << "Failed to load font from stream (failed to create the font face)" << std::endl; return false; } // Select the unicode character map if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) != 0) { Err() << "Failed to load font from stream (failed to set the Unicode character set)" << std::endl; return false; } // Store the loaded font in our ugly void* :) myFace = face; myStreamRec = rec; return true; }