summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2017-06-01 11:25:09 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2017-06-01 12:13:52 +0200
commitac052de8f7b6b6976ab89601388a1bd4d421e58b (patch)
treeb9cc2fb26548365f8c9fb4610a6e917f6a6ec434
parent4cf8d6bb3e6b75f8215b69f697b6b5c05b1c1dd2 (diff)
downloadlibass-ac052de8f7b6b6976ab89601388a1bd4d421e58b.tar.bz2
libass-ac052de8f7b6b6976ab89601388a1bd4d421e58b.tar.xz
directwrite: fix font collections
DirectWrite's FontFileStream does not actually use the data of a specific font in a collection, which was an expectation of the existing code. It simply returns a stream to the underlying file, collection or not. So we need to get the index of the font. This needs to be done lazily as this information is only available in a FontFace, which is expensive to initialize. Add a new optional font provider function for lazy initialization of the index and use it. This is similar to the check_postscript callback. Fixes libass#275. v2: fix type of returned value.
-rw-r--r--libass/ass_directwrite.c14
-rw-r--r--libass/ass_fontselect.c5
-rw-r--r--libass/ass_fontselect.h11
-rw-r--r--libass/dwrite_c.h3
4 files changed, 33 insertions, 0 deletions
diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c
index 45d2a2e..d15cbcd 100644
--- a/libass/ass_directwrite.c
+++ b/libass/ass_directwrite.c
@@ -352,6 +352,19 @@ static bool check_postscript(void *data)
}
/*
+ * Lazily return index of font. It requires the FontFace to be present, which is expensive to initialize.
+ */
+static unsigned get_font_index(void *data)
+{
+ FontPrivate *priv = (FontPrivate *)data;
+
+ if (!init_font_private_face(priv))
+ return 0;
+
+ return IDWriteFontFace_GetIndex(priv->face);
+}
+
+/*
* Check if the passed font has a specific unicode character.
*/
static bool check_glyph(void *data, uint32_t code)
@@ -719,6 +732,7 @@ static ASS_FontProviderFuncs directwrite_callbacks = {
.destroy_provider = destroy_provider,
.get_substitutions = get_substitutions,
.get_fallback = get_fallback,
+ .get_font_index = get_font_index,
};
typedef HRESULT (WINAPI *DWriteCreateFactoryFn)(
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 5426b15..8c8882c 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -609,6 +609,11 @@ find_font(ASS_FontSelector *priv, ASS_Library *library,
result = selected->path;
}
+ // set up index, if lazy evaluation function exists
+ if (selected->provider->funcs.get_font_index) {
+ *index = selected->provider->funcs.get_font_index(selected->priv);
+ }
+
return result;
}
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 73d5265..8d6e779 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -71,6 +71,16 @@ typedef bool (*CheckPostscriptFunc)(void *font_priv);
typedef bool (*CheckGlyphFunc)(void *font_priv, uint32_t codepoint);
/**
+* Get index of a font in context of a font collection.
+* This function is optional and may be needed to initialize the font index
+* lazily.
+*
+* \param font_priv font private data
+* \return font index inside the collection, or 0 in case of a single font
+*/
+typedef unsigned (*GetFontIndex)(void *font_priv);
+
+/**
* Destroy a font's private data.
*
* \param font_priv font private data
@@ -150,6 +160,7 @@ typedef struct font_provider_funcs {
MatchFontsFunc match_fonts; /* optional */
SubstituteFontFunc get_substitutions; /* optional */
GetFallbackFunc get_fallback; /* optional */
+ GetFontIndex get_font_index; /* optional */
} ASS_FontProviderFuncs;
/*
diff --git a/libass/dwrite_c.h b/libass/dwrite_c.h
index 93c78a7..c902525 100644
--- a/libass/dwrite_c.h
+++ b/libass/dwrite_c.h
@@ -335,6 +335,8 @@ DECLARE_INTERFACE_(IDWriteFontFace,IUnknown)
UINT32 *numberOfFiles,
IDWriteFontFile **fontFiles) PURE;
+ STDMETHOD_(UINT32, GetIndex)(THIS) PURE;
+
/* rest dropped */
END_INTERFACE
};
@@ -342,6 +344,7 @@ DECLARE_INTERFACE_(IDWriteFontFace,IUnknown)
#define IDWriteFontFace_Release(This) (This)->lpVtbl->Release(This)
#define IDWriteFontFace_GetType(This) (This)->lpVtbl->GetType(This)
#define IDWriteFontFace_GetFiles(This,fontFiles,b) (This)->lpVtbl->GetFiles(This,fontFiles,b)
+#define IDWriteFontFace_GetIndex(This) (This)->lpVtbl->GetIndex(This)
#endif /*COBJMACROS*/
#undef INTERFACE