]> granicus.if.org Git - libass/commitdiff
directwrite, coretext: implement substitutions
authorGrigori Goronzy <greg@chown.ath.cx>
Tue, 1 Sep 2015 13:47:40 +0000 (15:47 +0200)
committerGrigori Goronzy <greg@chown.ath.cx>
Wed, 2 Sep 2015 18:24:01 +0000 (20:24 +0200)
This adds simple and sensible substitutions for generic font family
names. A helper function is introduced to reduce code duplication.

libass/ass_coretext.c
libass/ass_directwrite.c
libass/ass_fontselect.h

index 35533248e312728cdf03d33d5d0ef70bcf8e15ff..877018d5ca175fccda82734f25de58403881c25e 100644 (file)
 
 #define SAFE_CFRelease(x) do { if (x) CFRelease(x); } while(0)
 
+static const ASS_FontMapping font_substitutions[] = {
+    {"sans-serif", "Helvetica"},
+    {"serif", "Times"},
+    {"monospace", "Courier"}
+};
+
 static char *cfstr2buf(CFStringRef string)
 {
     const int encoding = kCFStringEncodingUTF8;
@@ -266,10 +272,18 @@ static char *get_fallback(void *priv, const char *family, uint32_t codepoint)
     return res_family;
 }
 
+static void get_substitutions(void *priv, const char *name,
+                              ASS_FontProviderMetaData *meta)
+{
+    const int n = sizeof(font_substitutions) / sizeof(font_substitutions[0]);
+    ass_map_font(font_substitutions, n, name, meta);
+}
+
 static ASS_FontProviderFuncs coretext_callbacks = {
     .check_glyph        = check_glyph,
     .destroy_font       = destroy_font,
     .match_fonts        = match_fonts,
+    .get_substitutions  = get_substitutions,
     .get_fallback       = get_fallback,
 };
 
index 86b0b4b70d39b0fdf06e6bcdf39ac501768680d2..f11deb6f75f08701fb97574831e9ce9514dcc4ed 100644 (file)
 #define NAME_MAX_LENGTH 256
 #define FALLBACK_DEFAULT_FONT L"Arial"
 
+static const ASS_FontMapping font_substitutions[] = {
+    {"sans-serif", "Arial"},
+    {"serif", "Times New Roman"},
+    {"monospace", "Courier New"}
+};
+
 /*
  * The private data stored for every font, detected by this backend.
  */
@@ -624,6 +630,13 @@ static void scan_fonts(IDWriteFactory *factory,
     }
 }
 
+static void get_substitutions(void *priv, const char *name,
+                              ASS_FontProviderMetaData *meta)
+{
+    const int n = sizeof(font_substitutions) / sizeof(font_substitutions[0]);
+    ass_map_font(font_substitutions, n, name, meta);
+}
+
 /*
  * Called by libass when the provider should perform the
  * specified task
@@ -633,6 +646,7 @@ static ASS_FontProviderFuncs directwrite_callbacks = {
     .check_glyph        = check_glyph,
     .destroy_font       = destroy_font,
     .destroy_provider   = destroy_provider,
+    .get_substitutions  = get_substitutions,
     .get_fallback       = get_fallback,
 };
 
index c989e1afe63343f53ea286ad6279dd77a29452ae..1e0959e5a3d932d2c8f39502a255ba1caa80e032 100644 (file)
@@ -177,6 +177,37 @@ struct ass_font_stream {
     void *priv;
 };
 
+
+typedef struct ass_font_mapping ASS_FontMapping;
+
+struct ass_font_mapping {
+    const char *from;
+    const char *to;
+};
+
+/**
+ * Simple font substitution helper. This can be used to implement basic
+ * mappings from one name to another. This is useful for supporting
+ * generic font families in font providers.
+ *
+ * \param map list of mappings
+ * \param len length of list of mappings
+ * \param name font name to map from
+ * \param meta metadata struct, mapped fonts will be stored into this
+ */
+inline void ass_map_font(const ASS_FontMapping *map, int len, const char *name,
+                         ASS_FontProviderMetaData *meta)
+{
+    for (int i = 0; i < len; i++) {
+        if (strcasecmp(map[i].from, name) == 0) {
+            meta->n_fullname = 1;
+            meta->fullnames = calloc(1, sizeof(char *));
+            meta->fullnames[0] = strdup(map[i].to);
+            return;
+        }
+    }
+}
+
 ASS_FontSelector *
 ass_fontselect_init(ASS_Library *library,
                     FT_Library ftlibrary, const char *family,