summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2015-10-30 01:13:59 +0200
committerOleg Oshmyan <chortos@inbox.lv>2015-10-30 03:50:53 +0200
commit488070876efea2c28ff3e3945c4568c3d831a254 (patch)
treec3f3a8754c1aaadfed063e7dc91ef1fe0e4a8e3b /libass
parent5d7093a54ed23d76f9f6f5638a39a40b4640f90d (diff)
downloadlibass-488070876efea2c28ff3e3945c4568c3d831a254.tar.bz2
libass-488070876efea2c28ff3e3945c4568c3d831a254.tar.xz
directwrite: split out the inner loop of scan_fonts as a separate function
This has the side effect that the ASS_FontProviderMetaData instance is now cleared for every font rather than only once at the start of the search, which fixes some use-after-free scenarios and prevents the creation of chimeric fonts using names left over from other fonts processed earlier. This lays the groundwork for further code simplification and error handling improvements within this function, which will come in a separate commit. This commit is transparent to `git blame -w` except for return statements.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_directwrite.c226
1 files changed, 117 insertions, 109 deletions
diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c
index bf40cfb..be029e6 100644
--- a/libass/ass_directwrite.c
+++ b/libass/ass_directwrite.c
@@ -500,6 +500,122 @@ static bool is_postscript(IDWriteFont *font)
type == DWRITE_FONT_FACE_TYPE_TYPE1;
}
+static void add_font(IDWriteFont *font, IDWriteFontFamily *fontFamily,
+ ASS_FontProvider *provider)
+{
+ HRESULT hr = S_OK;
+ DWRITE_FONT_METRICS metrics;
+ DWRITE_FONT_STYLE style;
+ ASS_FontProviderMetaData meta = {0};
+ wchar_t temp_name[NAME_MAX_LENGTH];
+ int size_needed = 0;
+ IDWriteLocalizedStrings *familyNames = NULL;
+ IDWriteLocalizedStrings *fontNames = NULL;
+ IDWriteLocalizedStrings *psNames = NULL;
+ BOOL exists = FALSE;
+
+ meta.weight = IDWriteFont_GetWeight(font);
+ meta.width = map_width(IDWriteFont_GetStretch(font));
+ IDWriteFont_GetMetrics(font, &metrics);
+ style = IDWriteFont_GetStyle(font);
+ meta.slant = (style == DWRITE_FONT_STYLE_NORMAL) ? FONT_SLANT_NONE :
+ (style == DWRITE_FONT_STYLE_OBLIQUE)? FONT_SLANT_OBLIQUE :
+ (style == DWRITE_FONT_STYLE_ITALIC) ? FONT_SLANT_ITALIC : FONT_SLANT_NONE;
+
+ hr = IDWriteFont_GetInformationalStrings(font,
+ DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames,&exists);
+ if (FAILED(hr)) {
+ IDWriteFont_Release(font);
+ return;
+ }
+
+ if (exists) {
+ hr = IDWriteLocalizedStrings_GetString(psNames, 0, temp_name, NAME_MAX_LENGTH);
+ if (FAILED(hr)) {
+ IDWriteLocalizedStrings_Release(psNames);
+ IDWriteFont_Release(font);
+ return;
+ }
+
+ temp_name[NAME_MAX_LENGTH-1] = 0;
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0,NULL, NULL);
+ char *mbName = (char *) malloc(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
+ meta.postscript_name = mbName;
+
+ IDWriteLocalizedStrings_Release(psNames);
+ }
+
+ hr = IDWriteFont_GetInformationalStrings(font,
+ DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames,&exists);
+ if (FAILED(hr)) {
+ IDWriteFont_Release(font);
+ return;
+ }
+
+ if (exists) {
+ meta.n_fullname = IDWriteLocalizedStrings_GetCount(fontNames);
+ meta.fullnames = (char **) calloc(meta.n_fullname, sizeof(char *));
+ for (UINT32 k = 0; k < meta.n_fullname; ++k) {
+ hr = IDWriteLocalizedStrings_GetString(fontNames, k,
+ temp_name,
+ NAME_MAX_LENGTH);
+ if (FAILED(hr)) {
+ continue;
+ }
+
+ temp_name[NAME_MAX_LENGTH-1] = 0;
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0, NULL, NULL);
+ char *mbName = (char *) malloc(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
+ meta.fullnames[k] = mbName;
+ }
+ IDWriteLocalizedStrings_Release(fontNames);
+ }
+
+ hr = IDWriteFont_GetInformationalStrings(font,
+ DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &familyNames, &exists);
+ if (!exists)
+ hr = IDWriteFontFamily_GetFamilyNames(fontFamily, &familyNames);
+ if (FAILED(hr)) {
+ IDWriteFont_Release(font);
+ return;
+ }
+
+ meta.n_family = IDWriteLocalizedStrings_GetCount(familyNames);
+ meta.families = (char **) calloc(meta.n_family, sizeof(char *));
+ for (UINT32 k = 0; k < meta.n_family; ++k) {
+ hr = IDWriteLocalizedStrings_GetString(familyNames, k,
+ temp_name,
+ NAME_MAX_LENGTH);
+ if (FAILED(hr)) {
+ continue;
+ }
+
+ temp_name[NAME_MAX_LENGTH-1] = 0;
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0,NULL, NULL);
+ char *mbName = (char *) malloc(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
+ meta.families[k] = mbName;
+ }
+ IDWriteLocalizedStrings_Release(familyNames);
+
+ meta.is_postscript = is_postscript(font);
+
+ FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv));
+ font_priv->font = font;
+
+ ass_font_provider_add_font(provider, &meta, NULL, 0, font_priv);
+
+ for (UINT32 k = 0; k < meta.n_family; ++k)
+ free(meta.families[k]);
+ for (UINT32 k = 0; k < meta.n_fullname; ++k)
+ free(meta.fullnames[k]);
+ free(meta.fullnames);
+ free(meta.families);
+ free(meta.postscript_name);
+}
+
/*
* Scan every system font on the current machine and add it
* to the libass lookup. Stores the FontPrivate as private data
@@ -511,12 +627,7 @@ static void scan_fonts(IDWriteFactory *factory,
HRESULT hr = S_OK;
IDWriteFontCollection *fontCollection = NULL;
IDWriteFont *font = NULL;
- DWRITE_FONT_METRICS metrics;
- DWRITE_FONT_STYLE style;
- ASS_FontProviderMetaData meta = {0};
hr = IDWriteFactory_GetSystemFontCollection(factory, &fontCollection, FALSE);
- wchar_t temp_name[NAME_MAX_LENGTH];
- int size_needed = 0;
if (FAILED(hr) || !fontCollection)
return;
@@ -525,10 +636,6 @@ static void scan_fonts(IDWriteFactory *factory,
for (UINT32 i = 0; i < familyCount; ++i) {
IDWriteFontFamily *fontFamily = NULL;
- IDWriteLocalizedStrings *familyNames = NULL;
- IDWriteLocalizedStrings *fontNames = NULL;
- IDWriteLocalizedStrings *psNames = NULL;
- BOOL exists = FALSE;
hr = IDWriteFontCollection_GetFontFamily(fontCollection, i, &fontFamily);
if (FAILED(hr))
@@ -547,106 +654,7 @@ static void scan_fonts(IDWriteFactory *factory,
continue;
}
- meta.weight = IDWriteFont_GetWeight(font);
- meta.width = map_width(IDWriteFont_GetStretch(font));
- IDWriteFont_GetMetrics(font, &metrics);
- style = IDWriteFont_GetStyle(font);
- meta.slant = (style == DWRITE_FONT_STYLE_NORMAL) ? FONT_SLANT_NONE :
- (style == DWRITE_FONT_STYLE_OBLIQUE)? FONT_SLANT_OBLIQUE :
- (style == DWRITE_FONT_STYLE_ITALIC) ? FONT_SLANT_ITALIC : FONT_SLANT_NONE;
-
- hr = IDWriteFont_GetInformationalStrings(font,
- DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames,&exists);
- if (FAILED(hr)) {
- IDWriteFont_Release(font);
- continue;
- }
-
- if (exists) {
- hr = IDWriteLocalizedStrings_GetString(psNames, 0, temp_name, NAME_MAX_LENGTH);
- if (FAILED(hr)) {
- IDWriteLocalizedStrings_Release(psNames);
- IDWriteFont_Release(font);
- continue;
- }
-
- temp_name[NAME_MAX_LENGTH-1] = 0;
- size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0,NULL, NULL);
- char *mbName = (char *) malloc(size_needed);
- WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
- meta.postscript_name = mbName;
-
- IDWriteLocalizedStrings_Release(psNames);
- }
-
- hr = IDWriteFont_GetInformationalStrings(font,
- DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames,&exists);
- if (FAILED(hr)) {
- IDWriteFont_Release(font);
- continue;
- }
-
- if (exists) {
- meta.n_fullname = IDWriteLocalizedStrings_GetCount(fontNames);
- meta.fullnames = (char **) calloc(meta.n_fullname, sizeof(char *));
- for (UINT32 k = 0; k < meta.n_fullname; ++k) {
- hr = IDWriteLocalizedStrings_GetString(fontNames, k,
- temp_name,
- NAME_MAX_LENGTH);
- if (FAILED(hr)) {
- continue;
- }
-
- temp_name[NAME_MAX_LENGTH-1] = 0;
- size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0, NULL, NULL);
- char *mbName = (char *) malloc(size_needed);
- WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
- meta.fullnames[k] = mbName;
- }
- IDWriteLocalizedStrings_Release(fontNames);
- }
-
- hr = IDWriteFont_GetInformationalStrings(font,
- DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &familyNames, &exists);
- if (!exists)
- hr = IDWriteFontFamily_GetFamilyNames(fontFamily, &familyNames);
- if (FAILED(hr)) {
- IDWriteFont_Release(font);
- continue;
- }
-
- meta.n_family = IDWriteLocalizedStrings_GetCount(familyNames);
- meta.families = (char **) calloc(meta.n_family, sizeof(char *));
- for (UINT32 k = 0; k < meta.n_family; ++k) {
- hr = IDWriteLocalizedStrings_GetString(familyNames, k,
- temp_name,
- NAME_MAX_LENGTH);
- if (FAILED(hr)) {
- continue;
- }
-
- temp_name[NAME_MAX_LENGTH-1] = 0;
- size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0,NULL, NULL);
- char *mbName = (char *) malloc(size_needed);
- WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL);
- meta.families[k] = mbName;
- }
- IDWriteLocalizedStrings_Release(familyNames);
-
- meta.is_postscript = is_postscript(font);
-
- FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv));
- font_priv->font = font;
-
- ass_font_provider_add_font(provider, &meta, NULL, 0, font_priv);
-
- for (UINT32 k = 0; k < meta.n_family; ++k)
- free(meta.families[k]);
- for (UINT32 k = 0; k < meta.n_fullname; ++k)
- free(meta.fullnames[k]);
- free(meta.fullnames);
- free(meta.families);
- free(meta.postscript_name);
+ add_font(font, fontFamily, provider);
}
}
}