]> granicus.if.org Git - libass/commitdiff
directwrite: fix font collections dw-collections
authorGrigori Goronzy <greg@chown.ath.cx>
Thu, 1 Jun 2017 09:25:09 +0000 (11:25 +0200)
committerGrigori Goronzy <greg@chown.ath.cx>
Thu, 1 Jun 2017 10:13:52 +0000 (12:13 +0200)
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.

libass/ass_directwrite.c
libass/ass_fontselect.c
libass/ass_fontselect.h
libass/dwrite_c.h

index 45d2a2e0822308447b9256792c3366cfbc320068..d15cbcd5b6e651bcfbd4efa47ccd19af7eb29209 100644 (file)
@@ -351,6 +351,19 @@ static bool check_postscript(void *data)
            type == DWRITE_FONT_FACE_TYPE_TYPE1;
 }
 
+/*
+ * 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.
  */
@@ -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)(
index 5426b156ca826e3aa430cf100d7faa272f1ad065..8c8882c30dfc2d970e16bca60a453e1d86599ea4 100644 (file)
@@ -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;
 }
 
index 73d526580e9986a485cd104bc15b542c429ece68..8d6e779eb06c1f88d50bafb0b1330e2c143a768e 100644 (file)
@@ -70,6 +70,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.
  *
@@ -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;
 
 /*
index 93c78a7d68a021e93354bf13ee1bc8648d0570e7..c902525b8fe97e86b913c59a7a05355dec302ee1 100644 (file)
@@ -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