/** * \brief Process memory font. * \param priv private data * \param library library object * \param ftlibrary freetype library object * \param idx index of the processed font in library->fontdata * * Builds a FontInfo with FreeType and some table reading. */ static void process_fontdata(ASS_FontProvider *priv, ASS_Library *library, FT_Library ftlibrary, int idx) { int rc; const char *name = library->fontdata[idx].name; const char *data = library->fontdata[idx].data; int data_size = library->fontdata[idx].size; FT_Face face; int face_index, num_faces = 1; for (face_index = 0; face_index < num_faces; ++face_index) { ASS_FontProviderMetaData info; FontDataFT *ft; rc = FT_New_Memory_Face(ftlibrary, (unsigned char *) data, data_size, face_index, &face); if (rc) { ass_msg(library, MSGL_WARN, "Error opening memory font '%s'", name); continue; } num_faces = face->num_faces; charmap_magic(library, face); memset(&info, 0, sizeof(ASS_FontProviderMetaData)); if (get_font_info(ftlibrary, face, &info)) { ass_msg(library, MSGL_WARN, "Error getting metadata for embedded font '%s'", name); FT_Done_Face(face); continue; } ft = calloc(1, sizeof(FontDataFT)); if (ft == NULL) { free_font_info(&info); FT_Done_Face(face); continue; } ft->lib = library; ft->face = face; ft->idx = idx; if (ass_font_provider_add_font(priv, &info, NULL, face_index, ft)) { ass_msg(library, MSGL_WARN, "Failed to add embedded font '%s'", name); } free_font_info(&info); } }
/** * \brief Select a face with the given charcode and add it to ASS_Font * \return index of the new face in font->faces, -1 if failed */ static int add_face(void *fc_priv, ASS_Font *font, uint32_t ch) { char *path; int index; FT_Face face; int error; int mem_idx; if (font->n_faces == ASS_FONT_MAX_FACES) return -1; path = fontconfig_select(font->library, fc_priv, font->desc.family, font->desc.treat_family_as_pattern, font->desc.bold, font->desc.italic, &index, ch); if (!path) return -1; mem_idx = find_font(font->library, path); if (mem_idx >= 0) { error = FT_New_Memory_Face(font->ftlibrary, (unsigned char *) font->library-> fontdata[mem_idx].data, font->library->fontdata[mem_idx].size, index, &face); if (error) { ass_msg(font->library, MSGL_WARN, "Error opening memory font: '%s'", path); free(path); return -1; } } else { error = FT_New_Face(font->ftlibrary, path, index, &face); if (error) { ass_msg(font->library, MSGL_WARN, "Error opening font: '%s', %d", path, index); free(path); return -1; } } charmap_magic(font->library, face); buggy_font_workaround(face); font->faces[font->n_faces++] = face; ass_face_set_size(face, font->size); free(path); return font->n_faces - 1; }
/** * \brief Select a face with the given charcode and add it to ass_font_t * \return index of the new face in font->faces, -1 if failed */ static int add_face(void* fc_priv, ass_font_t* font, uint32_t ch) { char* path; int index; FT_Face face; int error; int mem_idx; if (font->n_faces == ASS_FONT_MAX_FACES) return -1; path = fontconfig_select(fc_priv, font->desc.family, font->desc.bold, font->desc.italic, &index, ch); mem_idx = find_font(font->library, path); if (mem_idx >= 0) { error = FT_New_Memory_Face(font->ftlibrary, (unsigned char*)font->library->fontdata[mem_idx].data, font->library->fontdata[mem_idx].size, 0, &face); if (error) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, path); return -1; } } else { error = FT_New_Face(font->ftlibrary, path, index, &face); if (error) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index); return -1; } } charmap_magic(face); buggy_font_workaround(face); font->faces[font->n_faces++] = face; update_transform(font); face_set_size(face, font->size); return font->n_faces - 1; }
/** * \brief Select a face with the given charcode and add it to ASS_Font * \return index of the new face in font->faces, -1 if failed */ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch) { char *path; char *postscript_name = NULL; int i, index, uid, error; ASS_FontStream stream = { NULL, NULL }; FT_Face face; if (font->n_faces == ASS_FONT_MAX_FACES) return -1; path = ass_font_select(fontsel, font->library, font , &index, &postscript_name, &uid, &stream, ch); if (!path) return -1; for (i = 0; i < font->n_faces; i++) { if (font->faces_uid[i] == uid) { ass_msg(font->library, MSGL_INFO, "Got a font face that already is available! Skipping."); return i; } } if (stream.func) { FT_Open_Args args; FT_Stream ftstream = calloc(1, sizeof(FT_StreamRec)); ASS_FontStream *fs = calloc(1, sizeof(ASS_FontStream)); *fs = stream; ftstream->size = stream.func(stream.priv, NULL, 0, 0); ftstream->read = read_stream_font; ftstream->close = close_stream_font; ftstream->descriptor.pointer = (void *)fs; memset(&args, 0, sizeof(FT_Open_Args)); args.flags = FT_OPEN_STREAM; args.stream = ftstream; error = FT_Open_Face(font->ftlibrary, &args, index, &face); if (error) { ass_msg(font->library, MSGL_WARN, "Error opening memory font: '%s'", path); return -1; } } else { error = FT_New_Face(font->ftlibrary, path, index, &face); if (error) { ass_msg(font->library, MSGL_WARN, "Error opening font: '%s', %d", path, index); return -1; } if (postscript_name && index < 0 && face->num_faces > 0) { // The font provider gave us a post_script name and is not sure // about the face index.. so use the postscript name to find the // correct face_index in the collection! for (int i = 0; i < face->num_faces; i++) { FT_Done_Face(face); error = FT_New_Face(font->ftlibrary, path, i, &face); if (error) { ass_msg(font->library, MSGL_WARN, "Error opening font: '%s', %d", path, i); return -1; } const char *face_psname = FT_Get_Postscript_Name(face); if (face_psname != NULL && strcmp(face_psname, postscript_name) == 0) break; } } } charmap_magic(font->library, face); buggy_font_workaround(face); font->faces[font->n_faces] = face; font->faces_uid[font->n_faces++] = uid; ass_face_set_size(face, font->size); return font->n_faces - 1; }