summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac22
-rw-r--r--libass/Makefile.am4
-rw-r--r--libass/ass_coretext.c217
-rw-r--r--libass/ass_coretext.h34
-rw-r--r--libass/ass_fontselect.c8
5 files changed, 284 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index fce38ef..6cfd823 100644
--- a/configure.ac
+++ b/configure.ac
@@ -151,6 +151,28 @@ PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [
])
fi
+if test x$enable_coretext != xno; then
+OLDLIBS="$LIBS"
+# Linking to CoreText directly only works from Mountain Lion and iOS6. In
+# earlier OS releases CoreText was part of the ApplicationServices umbrella
+# framework.
+LIBS="$LIBS -framework CoreText -framework CoreFoundation -framework CoreGraphics"
+AC_MSG_CHECKING([for CORETEXT])
+AC_LINK_IFELSE([
+ AC_LANG_PROGRAM(
+ [[#include <CoreText/CoreText.h>]],
+ [[CTFontCreateWithFontDescriptor(NULL, 0.0, NULL);]],)
+ ], [
+ AC_DEFINE(CONFIG_CORETEXT, 1, [found CoreText in System library])
+ coretext=true
+ AC_MSG_RESULT([yes])
+ ], [
+ LIBS="$OLDLIBS"
+ coretext=false
+ AC_MSG_RESULT([no])
+ ])
+fi
+
if test x$enable_harfbuzz != xno; then
PKG_CHECK_MODULES([HARFBUZZ], harfbuzz >= 0.9.5, [
CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
diff --git a/libass/Makefile.am b/libass/Makefile.am
index b8659e6..6854768 100644
--- a/libass/Makefile.am
+++ b/libass/Makefile.am
@@ -26,7 +26,9 @@ libass_la_SOURCES = ass.c ass_cache.c ass_font.c ass_fontselect.c ass_render.c \
ass_library.h ass_types.h ass_utils.h ass_drawing.c \
ass_drawing.h ass_cache_template.h ass_render.h \
ass_parse.c ass_parse.h ass_render_api.c ass_shaper.c \
- ass_shaper.h ass_strtod.c ass_fontconfig.c ass_fontconfig.h
+ ass_shaper.h ass_strtod.c ass_fontconfig.c ass_fontconfig.h \
+ ass_coretext.c ass_coretext.h
+
libass_la_LDFLAGS = -no-undefined -version-info $(LIBASS_LT_CURRENT):$(LIBASS_LT_REVISION):$(LIBASS_LT_AGE)
libass_la_LDFLAGS += -export-symbols $(srcdir)/libass.sym
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
new file mode 100644
index 0000000..f970226
--- /dev/null
+++ b/libass/ass_coretext.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
+ *
+ * This file is part of libass.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#ifdef CONFIG_CORETEXT
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreText/CoreText.h>
+
+#include "ass_coretext.h"
+
+static char *cfstr2buf(CFStringRef string)
+{
+ const char *buf_ptr = CFStringGetCStringPtr(string, kCFStringEncodingUTF8);
+ if (buf_ptr) {
+ return strdup(buf_ptr);
+ } else {
+ size_t buf_len = CFStringGetLength(string) + 1;
+ char *buf = calloc(buf_len, sizeof(char));
+ CFStringGetCString(string, buf, buf_len, kCFStringEncodingUTF8);
+ return buf;
+ }
+}
+
+static void destroy_font(void *priv)
+{
+ CFCharacterSetRef set = priv;
+ CFRelease(set);
+}
+
+static int check_glyph(void *priv, uint32_t code)
+{
+ CFCharacterSetRef set = priv;
+
+ if (!set)
+ return 1;
+
+ if (code == 0)
+ return 1;
+
+ return CFCharacterSetIsLongCharacterMember(set, code);
+}
+
+static char *get_font_file(CTFontDescriptorRef fontd)
+{
+ CFURLRef url = CTFontDescriptorCopyAttribute(fontd, kCTFontURLAttribute);
+ CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+ char *buffer = cfstr2buf(path);
+ CFRelease(path);
+ CFRelease(url);
+ return buffer;
+}
+
+static void get_name(CTFontDescriptorRef fontd, CFStringRef attr,
+ char **array, int *idx)
+{
+
+ CFStringRef name = CTFontDescriptorCopyAttribute(fontd, attr);
+ if (name) {
+ array[*idx] = cfstr2buf(name);
+ CFRelease(name);
+ *idx += 1;
+ }
+}
+
+static void get_trait(CFDictionaryRef traits, CFStringRef attribute,
+ float *trait)
+{
+ CFNumberRef cftrait = CFDictionaryGetValue(traits, attribute);
+ if (!CFNumberGetValue(cftrait, kCFNumberFloatType, trait))
+ *trait = 0.0;
+}
+
+static void get_font_traits(CTFontDescriptorRef fontd,
+ ASS_FontProviderMetaData *meta)
+{
+ float weight, slant, width;
+
+ CFDictionaryRef traits =
+ CTFontDescriptorCopyAttribute(fontd, kCTFontTraitsAttribute);
+
+ get_trait(traits, kCTFontWeightTrait, &weight);
+ get_trait(traits, kCTFontSlantTrait, &slant);
+ get_trait(traits, kCTFontWidthTrait, &width);
+
+ CFRelease(traits);
+
+ // Printed all of my system fonts (see if'deffed code below). Here is how
+ // CoreText 'normalized' weights maps to CSS/libass:
+
+ // opentype: 0 100 200 300 400 500 600 700 800 900
+ // css: LIGHT REG MED SBOLD BOLD BLACK EXTRABL
+ // libass: LIGHT MEDIUM BOLD
+ // coretext: -0.4 0.0 0.23 0.3 0.4 0.62
+
+ if (weight >= 0.62)
+ meta->weight = 800;
+ else if (weight >= 0.4)
+ meta->weight = 700;
+ else if (weight >= 0.3)
+ meta->weight = 600;
+ else if (weight >= 0.23)
+ meta->weight = 500;
+ else if (weight >= -0.4)
+ meta->weight = 400;
+ else
+ meta->weight = 200;
+
+ if (slant > 0.03)
+ meta->slant = FONT_SLANT_ITALIC;
+ else
+ meta->slant = FONT_SLANT_NONE;
+
+ if (width <= -0.2)
+ meta->width = FONT_WIDTH_CONDENSED;
+ else if (width >= 0.2)
+ meta->width = FONT_WIDTH_EXPANDED;
+ else
+ meta->width = FONT_WIDTH_NORMAL;
+
+#if 0
+ char *name[1];
+ int idx = 0;
+ get_name(fontd, kCTFontDisplayNameAttribute, name, &idx);
+ char *file = get_font_file(fontd);
+ printf(
+ "Font traits for: %-40s [%-50s] "
+ "<slant: %f, %03d>, <weight: (%f, %03d)>, <width: %f, %03d>\n",
+ name[0], file,
+ slant, meta->slant, weight, meta->weight, width, meta->width);
+ free(name[0]);
+ free(file);
+#endif
+}
+
+static void scan_fonts(ASS_Library *lib, ASS_FontProvider *provider)
+{
+ ASS_FontProviderMetaData meta;
+ char *families[1];
+ char *fullnames[2];
+
+ CTFontCollectionRef coll = CTFontCollectionCreateFromAvailableFonts(NULL);
+ CFArrayRef fontsd = CTFontCollectionCreateMatchingFontDescriptors(coll);
+
+ for (int i = 0; i < CFArrayGetCount(fontsd); i++) {
+ CTFontDescriptorRef fontd = CFArrayGetValueAtIndex(fontsd, i);
+ int index = 0;
+
+ char *path = get_font_file(fontd);
+ if (strcmp("", path) == 0) {
+ // skip the font if the URL field in the font descriptor is empty
+ free(path);
+ continue;
+ }
+
+ memset(&meta, 0, sizeof(meta));
+ get_font_traits(fontd, &meta);
+
+ get_name(fontd, kCTFontFamilyNameAttribute, families, &meta.n_family);
+ meta.families = families;
+
+ get_name(fontd, kCTFontDisplayNameAttribute, fullnames, &meta.n_fullname);
+ get_name(fontd, kCTFontNameAttribute, fullnames, &meta.n_fullname);
+ meta.fullnames = fullnames;
+
+ CFCharacterSetRef chset =
+ CTFontDescriptorCopyAttribute(fontd, kCTFontCharacterSetAttribute);
+ ass_font_provider_add_font(provider, &meta, path, index, (void*)chset);
+
+ for (int j = 0; j < meta.n_family; j++)
+ free(meta.families[j]);
+
+ for (int j = 0; j < meta.n_fullname; j++)
+ free(meta.fullnames[j]);
+
+ free(path);
+ }
+
+ CFRelease(fontsd);
+ CFRelease(coll);
+}
+
+static ASS_FontProviderFuncs coretext_callbacks = {
+ NULL,
+ check_glyph,
+ destroy_font,
+ NULL
+};
+
+ASS_FontProvider *
+ass_coretext_add_provider(ASS_Library *lib, ASS_FontSelector *selector)
+{
+ ASS_FontProvider *provider =
+ ass_font_provider_new(selector, &coretext_callbacks, NULL);
+
+ scan_fonts(lib, provider);
+
+ return provider;
+}
+
+#endif
diff --git a/libass/ass_coretext.h b/libass/ass_coretext.h
new file mode 100644
index 0000000..8d96927
--- /dev/null
+++ b/libass/ass_coretext.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
+ *
+ * This file is part of libass.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "ass_types.h"
+#include "ass_fontselect.h"
+
+#ifndef ASS_CORETEXT_H
+#define ASS_CORETEXT_H
+
+#ifdef CONFIG_CORETEXT
+
+ASS_FontProvider *
+ass_coretext_add_provider(ASS_Library *lib, ASS_FontSelector *selector);
+
+#endif
+
+#endif
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index cf1c088..9ef0ace 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -37,6 +37,7 @@
#include "ass_library.h"
#include "ass_fontselect.h"
#include "ass_fontconfig.h"
+#include "ass_coretext.h"
#include "ass_font.h"
#define ABS(x) ((x) < 0 ? -(x) : (x))
@@ -803,6 +804,13 @@ ass_fontselect_init(ASS_Library *library,
priv->embedded_provider = ass_embedded_fonts_add_provider(library, priv,
ftlibrary);
+#ifdef CONFIG_CORETEXT
+ if (fc != 0) {
+ priv->default_provider = ass_coretext_add_provider(library, priv);
+ return priv;
+ }
+#endif
+
#ifdef CONFIG_FONTCONFIG
if (fc != 0)
priv->default_provider = ass_fontconfig_add_provider(library,