}
}
+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)
{
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);
}
}
+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
}
IDWriteLocalizedStrings_Release(familyNames);
+ meta.is_postscript = is_postscript(font);
+
FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv));
font_priv->font = font;
FcBool outline;
int index, weight;
char *path;
+ char *format;
char *fullnames[MAX_NAME];
char *families[MAX_NAME];
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);
}
}
#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"
// 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;
// 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)
return false;
}
+/**
+ * \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.
// 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.
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))
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;
#ifndef LIBASS_FONTCONFIG_H
#define LIBASS_FONTCONFIG_H
+#include <stdbool.h>
#include <stdint.h>
#include <ft2build.h>
#include FT_FREETYPE_H
// 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;
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,
#endif
/* IDWriteFontFace methods */
- STDMETHOD(dummy1)(THIS);
+ STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)(THIS) PURE;
STDMETHOD(GetFiles)(THIS_
UINT32 *numberOfFiles,