summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2015-10-21 00:51:34 +0300
committerOleg Oshmyan <chortos@inbox.lv>2015-10-23 02:36:53 +0300
commite00691e8096cc69e5651480155ebc61d9e079290 (patch)
treeb097d3c1b8b560b08b6688330434b5c746d12407
parent018cfe7b2cbbcd10e7860e7903564b5d5a0b1d16 (diff)
downloadlibass-e00691e8096cc69e5651480155ebc61d9e079290.tar.bz2
libass-e00691e8096cc69e5651480155ebc61d9e079290.tar.xz
fontselect: find fonts with PostScript outlines by PostScript name
Fonts without PostScript outlines (such as TrueType fonts) are unaffected, and their PostScript names continue to be ignored when searching for fonts. This matches the behavior of GDI and hence VSFilter.
-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,