summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_coretext.c15
-rw-r--r--libass/ass_directwrite.c20
-rw-r--r--libass/ass_fontconfig.c8
-rw-r--r--libass/ass_fontselect.c44
-rw-r--r--libass/ass_fontselect.h3
-rw-r--r--libass/dwrite_c.h11
6 files changed, 88 insertions, 13 deletions
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index a2cd77f..006547b 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -88,6 +88,19 @@ static void get_name(CTFontDescriptorRef fontd, CFStringRef attr,
}
}
+static bool is_postscript(CTFontDescriptorRef fontd)
+{
+ int format;
+ CFNumberRef cfformat =
+ CTFontDescriptorCopyAttribute(fontd, kCTFontFormatAttribute);
+
+ if (!CFNumberGetValue(cfformat, kCFNumberIntType, &format))
+ return false;
+
+ return format == kCTFontFormatOpenTypePostScript ||
+ format == kCTFontFormatPostScript;
+}
+
static void get_trait(CFDictionaryRef traits, CFStringRef attribute,
float *trait)
{
@@ -192,6 +205,8 @@ static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd)
get_name(fontd, kCTFontNameAttribute, identifiers, &zero);
meta.postscript_name = identifiers[0];
+ meta.is_postscript = is_postscript(fontd);
+
CFCharacterSetRef chset =
CTFontDescriptorCopyAttribute(fontd, kCTFontCharacterSetAttribute);
ass_font_provider_add_font(provider, &meta, path, index, (void*)chset);
diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c
index 6b6b623..8388f1c 100644
--- a/libass/ass_directwrite.c
+++ b/libass/ass_directwrite.c
@@ -483,6 +483,24 @@ static int map_width(enum DWRITE_FONT_STRETCH stretch)
}
}
+static bool is_postscript(IDWriteFont *font)
+{
+ HRESULT hr = S_OK;
+ IDWriteFontFace *face = NULL;
+ DWRITE_FONT_FACE_TYPE type;
+
+ hr = IDWriteFont_CreateFontFace(font, &face);
+ if (FAILED(hr) || !face)
+ return false;
+
+ type = IDWriteFontFace_GetType(face);
+ IDWriteFontFace_Release(face);
+
+ return type == DWRITE_FONT_FACE_TYPE_CFF ||
+ type == DWRITE_FONT_FACE_TYPE_RAW_CFF ||
+ type == DWRITE_FONT_FACE_TYPE_TYPE1;
+}
+
/*
* Scan every system font on the current machine and add it
* to the libass lookup. Stores the FontPrivate as private data
@@ -616,6 +634,8 @@ static void scan_fonts(IDWriteFactory *factory,
}
IDWriteLocalizedStrings_Release(familyNames);
+ meta.is_postscript = is_postscript(font);
+
FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv));
font_priv->font = font;
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index c9bb2f9..8b0824b 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -86,6 +86,7 @@ static void scan_fonts(FcConfig *config, ASS_FontProvider *provider)
FcBool outline;
int index, weight;
char *path;
+ char *format;
char *fullnames[MAX_NAME];
char *families[MAX_NAME];
@@ -138,6 +139,13 @@ static void scan_fonts(FcConfig *config, ASS_FontProvider *provider)
FcPatternGetString(pat, FC_POSTSCRIPT_NAME, 0,
(FcChar8 **)&meta.postscript_name);
+ meta.is_postscript = false;
+ if (FcPatternGetString(pat, FC_FONTFORMAT, 0,
+ (FcChar8 **)&format) == FcResultMatch)
+ meta.is_postscript =
+ !strcmp(format, "Type 1") || !strcmp(format, "Type 42") ||
+ !strcmp(format, "CID Type 1") || !strcmp(format, "CFF");
+
ass_font_provider_add_font(provider, &meta, path, index, (void *)pat);
}
}
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 39d4d5d..2f577f1 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -35,6 +35,7 @@
#include FT_FREETYPE_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
+#include FT_TYPE1_TABLES_H
#include "ass_utils.h"
#include "ass.h"
@@ -66,8 +67,10 @@ struct font_info {
// how to access this face
char *path; // absolute path
int index; // font index inside font collections
+
char *postscript_name; // can be used as an alternative to index to
// identify a font inside a collection
+ bool is_postscript;
// font source
ASS_FontProvider *provider;
@@ -294,21 +297,23 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
// set uid
info->uid = selector->uid++;
- info->slant = slant;
- info->weight = weight;
- info->width = width;
- info->n_fullname = meta->n_fullname;
- info->n_family = meta->n_family;
- info->families = calloc(meta->n_family, sizeof(char *));
+ info->slant = slant;
+ info->weight = weight;
+ info->width = width;
+ info->n_fullname = meta->n_fullname;
+ info->n_family = meta->n_family;
+ info->is_postscript = meta->is_postscript;
+
+ info->families = calloc(meta->n_family, sizeof(char *));
+ if (info->families == NULL)
+ goto error;
+
if (meta->n_fullname) {
info->fullnames = calloc(meta->n_fullname, sizeof(char *));
if (info->fullnames == NULL)
goto error;
}
- if (info->families == NULL)
- goto error;
-
for (i = 0; i < info->n_family; i++) {
info->families[i] = strdup(meta->families[i]);
if (info->families[i] == NULL)
@@ -426,6 +431,18 @@ static bool matches_fullname(ASS_FontInfo *f, const char *fullname)
}
/**
+ * \brief Return whether the given font has the given PostScript name.
+ */
+static bool matches_postscript_name(ASS_FontInfo *f, const char *name)
+{
+ if (f->is_postscript && f->postscript_name) {
+ if (ass_strcasecmp(f->postscript_name, name) == 0)
+ return true;
+ }
+ return false;
+}
+
+/**
* \brief Compare attributes of font (a) against a font request (req). Returns
* a matching score - the lower the better.
* Ignores font names/families!
@@ -510,7 +527,8 @@ find_font(ASS_FontSelector *priv, ASS_Library *library,
// to determine best match in that particular family
score = font_attributes_similarity(font, &req);
*name_match = true;
- } else if (matches_fullname(font, fullname)) {
+ } else if (matches_fullname(font, fullname) ||
+ matches_postscript_name(font, fullname)) {
// If we don't have any match, compare fullnames against request
// if there is a match now, assign lowest score possible. This means
// the font should be chosen instantly, without further search.
@@ -720,6 +738,7 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info)
char *fullnames[MAX_FULLNAME];
char *families[MAX_FULLNAME];
char *postscript_name = NULL;
+ PS_FontInfoRec postscript_info;
// we're only interested in outlines
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
@@ -779,12 +798,13 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info)
info->slant = slant;
info->weight = weight;
info->width = 100; // FIXME, should probably query the OS/2 table
+
info->postscript_name = postscript_name;
- info->families = calloc(sizeof(char *), num_family);
+ info->is_postscript = !FT_Get_PS_Font_Info(face, &postscript_info);
+ info->families = calloc(sizeof(char *), num_family);
if (info->families == NULL)
goto error;
-
memcpy(info->families, &families, sizeof(char *) * num_family);
info->n_family = num_family;
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index f1e2933..09749ad 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -19,6 +19,7 @@
#ifndef LIBASS_FONTCONFIG_H
#define LIBASS_FONTCONFIG_H
+#include <stdbool.h>
#include <stdint.h>
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -171,6 +172,8 @@ struct ass_font_provider_meta_data {
// See FONT_WEIGHT_*
int width; // Font weight in percent, normally 100
// See FONT_WIDTH_*
+
+ bool is_postscript; // Whether the font contains PostScript outlines
};
typedef struct ass_font_stream ASS_FontStream;
diff --git a/libass/dwrite_c.h b/libass/dwrite_c.h
index ac7f4a2..ffdf110 100644
--- a/libass/dwrite_c.h
+++ b/libass/dwrite_c.h
@@ -59,6 +59,15 @@ typedef enum DWRITE_FACTORY_TYPE {
DWRITE_FACTORY_TYPE_ISOLATED
} DWRITE_FACTORY_TYPE;
+typedef enum DWRITE_FONT_FACE_TYPE {
+ DWRITE_FONT_FACE_TYPE_CFF = 0,
+ DWRITE_FONT_FACE_TYPE_TRUETYPE,
+ DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION,
+ DWRITE_FONT_FACE_TYPE_TYPE1,
+ DWRITE_FONT_FACE_TYPE_VECTOR,
+ DWRITE_FONT_FACE_TYPE_BITMAP,
+ DWRITE_FONT_FACE_TYPE_UNKNOWN
+} DWRITE_FONT_FACE_TYPE;
typedef enum DWRITE_FONT_SIMULATIONS {
DWRITE_FONT_SIMULATIONS_NONE = 0x0000,
@@ -319,7 +328,7 @@ DECLARE_INTERFACE_(IDWriteFontFace,IUnknown)
#endif
/* IDWriteFontFace methods */
- STDMETHOD(dummy1)(THIS);
+ STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)(THIS) PURE;
STDMETHOD(GetFiles)(THIS_
UINT32 *numberOfFiles,