Example #1
0
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;
}