summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorfeliwir <stephan.vedder@gmail.com>2015-05-19 11:46:37 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2015-07-10 10:42:40 +0200
commit29fd129671bb66a2e54717ca666b6ccd7f7ee941 (patch)
treed9bf30c9deed976780b923e9655fdd20af59f906 /libass
parentefcb9c17e8da4f09f1aea795f081aebd9a04e8e2 (diff)
downloadlibass-29fd129671bb66a2e54717ca666b6ccd7f7ee941.tar.bz2
libass-29fd129671bb66a2e54717ca666b6ccd7f7ee941.tar.xz
directwrite: add initial fontselect implementation
Incomplete, leaks memory, but capable of rendering something.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass.h1
-rw-r--r--libass/ass_directwrite.cpp248
-rw-r--r--libass/ass_directwrite.h35
-rw-r--r--libass/ass_fontselect.c22
-rw-r--r--libass/ass_utils.h2
5 files changed, 307 insertions, 1 deletions
diff --git a/libass/ass.h b/libass/ass.h
index 1fb2234..5fd11a6 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -190,6 +190,7 @@ typedef enum {
ASS_FONTPROVIDER_AUTODETECT = 1,
ASS_FONTPROVIDER_CORETEXT,
ASS_FONTPROVIDER_FONTCONFIG,
+ ASS_FONTPROVIDER_DIRECTWRITE,
} ASS_DefaultFontProvider;
/**
diff --git a/libass/ass_directwrite.cpp b/libass/ass_directwrite.cpp
new file mode 100644
index 0000000..abf7e67
--- /dev/null
+++ b/libass/ass_directwrite.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2015 Stephan Vedder <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_DIRECTWRITE
+
+#include <dwrite.h>
+
+extern "C"
+{
+#include "ass_directwrite.h"
+#include "ass_utils.h"
+}
+
+static size_t get_data(void * priv, unsigned char* buf, size_t offset, size_t length)
+{
+ HRESULT hr = S_OK;
+ IDWriteFontFace* face = NULL;
+ IDWriteFont* font = (IDWriteFont*)priv;
+ IDWriteFontFile* files = NULL;
+ IDWriteFontFileStream* stream = NULL;
+ IDWriteFontFileLoader* loader = NULL;
+ UINT32 n_files = 0;
+ UINT64 fileSize;
+ const void* fileBuf = NULL;
+
+ hr = font->CreateFontFace(&face);
+ const void* refKey = NULL;
+ UINT32 keySize = 0;
+ void* fragContext = NULL;
+
+ if (FAILED(hr) || !face)
+ return 0;
+
+ hr = face->GetFiles(&n_files, NULL);
+ if (FAILED(hr))
+ return 0;
+
+ hr = face->GetFiles(&n_files, &files);
+ if (FAILED(hr) || !files)
+ return 0;
+
+ hr = files[0].GetReferenceKey(&refKey, &keySize);
+ if (FAILED(hr))
+ return 0;
+
+ hr = files[0].GetLoader(&loader);
+ if (FAILED(hr) || !loader)
+ return 0;
+
+ hr = loader->CreateStreamFromKey(refKey,keySize,&stream);
+ if (FAILED(hr) || !stream)
+ return 0;
+
+ if (buf == NULL)
+ {
+ hr = stream->GetFileSize(&fileSize);
+ if (FAILED(hr))
+ return 0;
+
+ return fileSize;
+ }
+
+ hr = stream->ReadFileFragment(&fileBuf, offset, length, &fragContext);
+ if (FAILED(hr) || !fileBuf)
+ return 0;
+
+ memcpy(buf, fileBuf, length);
+
+ stream->ReleaseFileFragment(fragContext);
+
+ return length;
+}
+
+static int check_glyph(void *priv, uint32_t code)
+{
+ //TODO: use IDWriteFont::HasCharacter method
+ //see: https://msdn.microsoft.com/en-us/library/windows/desktop/dd371165(v=vs.85).aspx
+ HRESULT hr = S_OK;
+ BOOL exists = FALSE;
+
+ ((IDWriteFont*)priv)->HasCharacter(code, &exists);
+
+ if (FAILED(hr))
+ return FALSE;
+
+ return exists;
+}
+
+static void destroy(void* priv)
+{
+ ((IDWriteFactory*)priv)->Release();
+}
+
+static void scan_fonts(IDWriteFactory *factory, ASS_FontProvider *provider)
+{
+ HRESULT hr = S_OK;
+ IDWriteFontCollection* fontCollection = NULL;
+ IDWriteFont* font = NULL;
+ DWRITE_FONT_METRICS metrics;
+ DWRITE_FONT_STYLE style;
+ ASS_FontProviderMetaData meta = ASS_FontProviderMetaData();
+ hr = factory->GetSystemFontCollection(&fontCollection,FALSE);
+ wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
+ int size_needed = 0;
+
+ if(FAILED(hr)||!fontCollection)
+ return;
+
+ UINT32 familyCount = fontCollection->GetFontFamilyCount();
+
+ for (UINT32 i = 0; i < familyCount; ++i)
+ {
+ IDWriteFontFamily* fontFamily = NULL;
+ IDWriteLocalizedStrings* familyNames = NULL;
+ IDWriteLocalizedStrings* fontNames = NULL;
+ IDWriteLocalizedStrings* psNames = NULL;
+ BOOL exists = FALSE;
+ char* psName = NULL;
+
+ // Get the font family.
+ hr = fontCollection->GetFontFamily(i, &fontFamily);
+ if (FAILED(hr))
+ return;
+
+ UINT32 fontCount = fontFamily->GetFontCount();
+ for (UINT32 j = 0; j < fontCount; ++j)
+ {
+ hr = fontFamily->GetFont(j, &font);
+ if (FAILED(hr))
+ return;
+
+ meta.weight = font->GetWeight();
+ font->GetMetrics(&metrics);
+ style = font->GetStyle();
+ meta.slant = (style==DWRITE_FONT_STYLE_NORMAL)? FONT_SLANT_NONE:
+ (style==DWRITE_FONT_STYLE_OBLIQUE)? FONT_SLANT_OBLIQUE:
+ (style==DWRITE_FONT_STYLE_ITALIC)? FONT_SLANT_ITALIC : FONT_SLANT_NONE;
+
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames, &exists);
+ if (FAILED(hr))
+ return;
+
+ if (exists)
+ {
+ hr = psNames->GetString(0, localeName, LOCALE_NAME_MAX_LENGTH + 1);
+ if (FAILED(hr))
+ return;
+
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
+ psName = (char*)ass_aligned_alloc(32, size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, localeName, -1, psName, size_needed, NULL, NULL);
+ }
+
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames, &exists);
+ if (FAILED(hr))
+ return;
+
+ meta.n_fullname = fontNames->GetCount();
+ meta.fullnames = (char **)calloc(meta.n_fullname, sizeof(char *));
+ for (UINT32 k = 0; k < meta.n_fullname; ++k)
+ {
+ hr = fontNames->GetString(k,localeName, LOCALE_NAME_MAX_LENGTH + 1);
+ if (FAILED(hr))
+ return;
+
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
+ char* mbName = (char *)malloc(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
+ meta.fullnames[k] = mbName;
+ }
+
+ hr = fontFamily->GetFamilyNames(&familyNames);
+ if (FAILED(hr))
+ return;
+
+ meta.n_family = familyNames->GetCount();
+ meta.families = (char **)calloc(meta.n_family, sizeof(char *));
+ for (UINT32 k = 0; k < meta.n_family; ++k)
+ {
+ hr = familyNames->GetString(k, localeName, LOCALE_NAME_MAX_LENGTH + 1);
+ if (FAILED(hr))
+ return;
+
+ size_needed = WideCharToMultiByte(CP_UTF8, 0, localeName, -1, NULL, 0, NULL, NULL);
+ char* mbName = (char *)malloc(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, localeName, -1, mbName, size_needed, NULL, NULL);
+ meta.families[k] = mbName;
+ }
+
+ ass_font_provider_add_font(provider, &meta, NULL, j, psName, font);
+ free(meta.fullnames);
+ free(meta.families);
+ }
+ }
+}
+
+static ASS_FontProviderFuncs directwrite_callbacks = {
+ get_data,
+ check_glyph,
+ NULL,
+ destroy,
+ NULL
+};
+
+ASS_FontProvider *
+ass_directwrite_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
+ const char *config)
+{
+ HRESULT hr = S_OK;
+ IDWriteFactory* dwFactory = NULL;
+ ASS_FontProvider *provider = NULL;
+
+ hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ (IUnknown**)(&dwFactory));
+
+ if(FAILED(hr))
+ {
+ ass_msg(lib, MSGL_WARN, "Failed to initialize directwrite.");
+ goto exit;
+ }
+
+
+ provider = ass_font_provider_new(selector, &directwrite_callbacks, dwFactory);
+
+ scan_fonts(dwFactory,provider);
+exit:
+ return provider;
+}
+
+#endif
diff --git a/libass/ass_directwrite.h b/libass/ass_directwrite.h
new file mode 100644
index 0000000..054ea6b
--- /dev/null
+++ b/libass/ass_directwrite.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 Stephan Vedder <stephan.vedder@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_DIRECTWRITE_H
+#define ASS_DIRECTWRITE_H
+
+#ifdef CONFIG_DIRECTWRITE
+
+ASS_FontProvider *
+ass_directwrite_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
+ const char *config);
+
+#endif
+
+#endif
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index bc1dec5..174fe1d 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -38,6 +38,7 @@
#include "ass_fontselect.h"
#include "ass_fontconfig.h"
#include "ass_coretext.h"
+#include "ass_directwrite.h"
#include "ass_font.h"
#define ABS(x) ((x) < 0 ? -(x) : (x))
@@ -236,6 +237,24 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
ASS_FontSelector *selector = provider->parent;
ASS_FontInfo *info;
+#if 0
+ int j;
+ printf("new font:\n");
+ printf(" families: ");
+ for (j = 0; j < meta->n_family; j++)
+ printf("'%s' ", meta->families[j]);
+ printf("\n");
+ printf(" fullnames: ");
+ for (j = 0; j < meta->n_fullname; j++)
+ printf("'%s' ", meta->fullnames[j]);
+ printf("\n");
+ printf(" slant: %d\n", meta->slant);
+ printf(" weight: %d\n", meta->weight);
+ printf(" width: %d\n", meta->width);
+ printf(" path: %s\n", path);
+ printf(" index: %d\n", index);
+#endif
+
weight = meta->weight;
slant = meta->slant;
width = meta->width;
@@ -804,6 +823,9 @@ struct font_constructors font_constructors[] = {
#ifdef CONFIG_FONTCONFIG
{ ASS_FONTPROVIDER_FONTCONFIG, &ass_fontconfig_add_provider },
#endif
+#ifdef CONFIG_DIRECTWRITE
+ { ASS_FONTPROVIDER_DIRECTWRITE, &ass_directwrite_add_provider },
+#endif
{ ASS_FONTPROVIDER_NONE, NULL },
};
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index f249bc9..caff161 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -184,7 +184,7 @@ static inline int rot_key(double a)
static inline unsigned fnv_32a_buf(void *buf, size_t len, unsigned hval)
{
- unsigned char *bp = buf;
+ unsigned char *bp = (unsigned char*)buf;
size_t n = (len + 3) / 4;
switch (len % 4) {