Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- commit d0bfd1267bbef621c1fdd771dd5c8f523f558c92
- Author: Grigori Goronzy <greg@blackbox>
- Date: Mon Aug 22 01:07:12 2011 +0200
- libass: Windows GDI font provider
- Add a simple GDI-based font provider to use system fonts without any
- help from fontconfig.
- There are some limitations: doesn't get all localized fullnames;
- TrueType font collections are not properly supported (only the first
- font); fonts are buffered in memory (needs RAM, sometimes slow).
- diff --git a/configure.ac b/configure.ac
- index fb53386..ff0afc1 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -3397,7 +3397,7 @@ AC_ARG_ENABLE(wingdi,
- if test "${enable_wingdi}" != "no"; then
- if test "${SYS}" = "mingw32"; then
- VLC_ADD_PLUGIN([wingdi])
- - VLC_ADD_LIBS([wingdi],[-lgdi32 -lole32])
- + VLC_ADD_LIBS([wingdi libass],[-lgdi32 -lole32])
- fi
- if test "${SYS}" = "mingwce"; then
- VLC_ADD_PLUGIN([wingdi wingapi])
- diff --git a/modules/codec/Modules.am b/modules/codec/Modules.am
- index 10ca915..33b5f96 100644
- --- a/modules/codec/Modules.am
- +++ b/modules/codec/Modules.am
- @@ -31,7 +31,7 @@ SOURCES_fluidsynth = fluidsynth.c
- SOURCES_cc = cc.c cc.h substext.h
- SOURCES_kate = kate.c
- SOURCES_schroedinger = schroedinger.c
- -SOURCES_libass = libass.c
- +SOURCES_libass = libass.c libass_win32.c
- SOURCES_aes3 = aes3.c
- SOURCES_subsdec = subsdec.c substext.h
- SOURCES_subsusf = subsusf.c
- diff --git a/modules/codec/libass.c b/modules/codec/libass.c
- index 829e1fe..5f8d9ef 100644
- --- a/modules/codec/libass.c
- +++ b/modules/codec/libass.c
- @@ -44,8 +44,10 @@
- #if defined(WIN32)
- # include <vlc_charset.h>
- +ASS_FontProvider *gdi_fonts_add_provider(ASS_Renderer *renderer);
- #endif
- +
- /*****************************************************************************
- * Module descriptor
- *****************************************************************************/
- @@ -78,6 +80,7 @@ struct decoder_sys_t
- /* */
- ASS_Library *p_library;
- ASS_Renderer *p_renderer;
- + ASS_FontProvider *p_provider;
- video_format_t fmt;
- /* */
- @@ -231,6 +234,7 @@ static int Create( vlc_object_t *p_this )
- #endif
- ass_set_fonts( p_renderer, psz_font, psz_family, true, NULL, 1 ); // setup default font/family
- #ifdef WIN32
- + p_sys->p_provider = gdi_fonts_add_provider( p_renderer );
- if( p_dialog )
- {
- dialog_ProgressSet( p_dialog, NULL, 1.0 );
- @@ -242,6 +246,8 @@ static int Create( vlc_object_t *p_this )
- ass_set_fonts( p_renderer, psz_font, psz_family, false, NULL, 1 );
- #endif
- +
- +
- /* Add a track */
- ASS_Track *p_track = p_sys->p_track = ass_new_track( p_sys->p_library );
- if( !p_track )
- @@ -288,6 +294,8 @@ static void DecSysRelease( decoder_sys_t *p_sys )
- if( p_sys->p_track )
- ass_free_track( p_sys->p_track );
- + if( p_sys->p_provider )
- + ass_font_provider_free( p_sys->p_provider );
- if( p_sys->p_renderer )
- ass_renderer_done( p_sys->p_renderer );
- if( p_sys->p_library )
- diff --git a/modules/codec/libass_win32.c b/modules/codec/libass_win32.c
- new file mode 100644
- index 0000000..6925358
- --- /dev/null
- +++ b/modules/codec/libass_win32.c
- @@ -0,0 +1,251 @@
- +/*****************************************************************************
- + * libass Windows GDI font support
- + *****************************************************************************
- + * Copyright (C) 2011 the VideoLAN team
- + * $Id$
- + *
- + * Authors: Grigori Goronzy <greg@chown.ath.cx
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + *
- + * You should have received a copy of the GNU General Public License
- + * along with this program; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- + *****************************************************************************/
- +
- +#ifdef HAVE_CONFIG_H
- +# include "config.h"
- +#endif
- +
- +#ifdef WIN32
- +
- +#define WINVER 0x0501
- +#include <windows.h>
- +#include <wingdi.h>
- +#include <stdio.h>
- +#include <conio.h>
- +#include <shlobj.h>
- +
- +#include <ass/ass.h>
- +
- +#define TTCF_TAG 0x66637474
- +
- +ASS_FontProvider *gdi_fonts_add_provider(ASS_Renderer *renderer);
- +
- +typedef struct enumerate_families EnumerateFamilies;
- +struct enumerate_families {
- + char **names;
- + int n_family;
- + int n_alloc;
- +};
- +
- +typedef struct enumerate_family_faces EnumerateFamilyFaces;
- +struct enumerate_family_faces {
- + HDC hdc;
- + ASS_FontProvider *provider;
- +};
- +
- +typedef struct font_data_gdi FontDataGDI;
- +struct font_data_gdi {
- + HDC hdc;
- + HFONT hf; // caching this seems to be very effective
- + LOGFONT lf;
- + GLYPHSET *gs;
- +
- + void *buf;
- + size_t len;
- +};
- +
- +static int CALLBACK
- +font_family_cb(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
- + int type, LPARAM lparam)
- +{
- + EnumerateFamilies *families = (EnumerateFamilies *)lparam;
- +
- + if (type != TRUETYPE_FONTTYPE)
- + return 1;
- +
- + // skip duplicate pseudo-vertical variants
- + if (lpelfe->elfLogFont.lfFaceName[0] == '@')
- + return 1;
- +
- + // check allocation
- + if (families->n_family >= families->n_alloc) {
- + families->n_alloc = !families->n_alloc ? 1 : families->n_alloc * 2;
- + families->names = realloc(families->names,
- + families->n_alloc * sizeof(char *));
- + }
- +
- + // add to list
- + families->names[families->n_family] = strdup(lpelfe->elfLogFont.lfFaceName);
- + families->n_family++;
- +
- + return 1;
- +}
- +
- +static int CALLBACK
- +font_info_cb(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
- + int type, LPARAM lparam)
- +{
- + char *fnp;
- + EnumerateFamilyFaces *data = (EnumerateFamilyFaces *)lparam;
- + LOGFONT *lf = &lpelfe->elfLogFont;
- + ASS_FontProviderMetaData meta;
- + FontDataGDI *gdi;
- +
- + if (type != TRUETYPE_FONTTYPE)
- + return 1;
- +
- + meta.family = lf->lfFaceName;
- + meta.fullnames = &fnp;
- + meta.fullnames[0] = (char *)lpelfe->elfFullName;
- + meta.n_fullname = 1;
- + meta.weight = lf->lfWeight;
- + meta.slant = !!lf->lfItalic * 110;
- +
- + gdi = calloc(1, sizeof(FontDataGDI));
- + gdi->hdc = data->hdc;
- + gdi->lf = *lf;
- +
- + // FIXME: what about the glyph index of TrueType collections?
- +
- + ass_font_provider_add_font(data->provider, &meta, NULL, 0, gdi);
- +
- + return 1;
- +}
- +
- +static int check_glyph_gdi(void *data, uint32_t codepoint)
- +{
- + int i;
- + FontDataGDI *fd = (FontDataGDI *)data;
- +
- + if (codepoint == 0)
- + return 1;
- +
- + // create GLYPHSET if we don't have a cached copy already
- + if (!fd->gs) {
- + if (!fd->hf)
- + fd->hf = CreateFontIndirect(&fd->lf);
- + //HFONT hf = CreateFontIndirect(&fd->lf);
- + HGDIOBJ old = SelectObject(fd->hdc, fd->hf);
- + int gs_alloc;
- +
- + gs_alloc = GetFontUnicodeRanges(fd->hdc, NULL);
- + fd->gs = malloc(gs_alloc);
- + GetFontUnicodeRanges(fd->hdc, fd->gs);
- +
- + //SelectObject(fd->hdc, old);
- + //DeleteObject(hf);
- + }
- +
- + for (i = 0; i < (int)fd->gs->cRanges; i++) {
- + unsigned low = fd->gs->ranges[i].wcLow;
- + unsigned high = low + fd->gs->ranges[i].cGlyphs - 1;
- + if (low <= codepoint && high >= codepoint)
- + return 1;
- + if (low > codepoint)
- + break;
- + }
- +
- + return 0;
- +}
- +
- +static void destroy_font_gdi(void *data)
- +{
- + FontDataGDI *gdi = (FontDataGDI *)data;
- +
- + DeleteObject(gdi->hf);
- + free(gdi->buf);
- + free(gdi->gs);
- + free(gdi);
- +}
- +
- +static void destroy_provider_gdi(void *data)
- +{
- + HDC hdc = (HDC)data;
- +
- + ReleaseDC(NULL, hdc);
- +}
- +
- +static void *get_face_gdi(void *data, size_t *len)
- +{
- + FontDataGDI *fd = (FontDataGDI *)data;
- +
- + if (!fd->buf) {
- + if (!fd->hf)
- + fd->hf = CreateFontIndirect(&fd->lf);
- + //HFONT hf = CreateFontIndirect(&fd->lf);
- + HGDIOBJ old = SelectObject(fd->hdc, fd->hf);
- + uint32_t tag = TTCF_TAG;
- +
- + // first try to open it as a font collection
- + // if that fails, it must be a normal font
- + fd->len = GetFontData(fd->hdc, TTCF_TAG, 0, NULL, 0);
- + if (fd->len == GDI_ERROR) {
- + fd->len = GetFontData(fd->hdc, 0, 0, NULL, 0);
- + tag = 0;
- + }
- +
- + fd->buf = malloc(fd->len);
- + GetFontData(fd->hdc, tag, 0, fd->buf, fd->len);
- +
- + //SelectObject(fd->hdc, old);
- + //DeleteObject(hf);
- + }
- +
- + *len = fd->len;
- + return fd->buf;
- +}
- +
- +static ASS_FontProviderFuncs gdi_funcs = {
- + get_face_gdi,
- + check_glyph_gdi,
- + destroy_font_gdi,
- + destroy_provider_gdi
- +};
- +
- +ASS_FontProvider *gdi_fonts_add_provider(ASS_Renderer *renderer)
- +{
- + int i;
- + HDC hDC = GetDC(NULL);
- + LOGFONT lf;
- + ASS_FontProvider *provider;
- + EnumerateFamilies families;
- + EnumerateFamilyFaces info_data;
- +
- + // initialize font provider
- + provider = ass_create_font_provider(renderer, &gdi_funcs, hDC);
- +
- + // first iteration
- + // get all unique family names
- + memset(&families, 0, sizeof(EnumerateFamilies));
- + lf.lfFaceName[0] = '\0';
- + lf.lfCharSet = ANSI_CHARSET; // use a specific charset. if we do not specify
- + // one, e.g. use DEFAULT_CHARSET, families are
- + // enumerated multiple times!
- + lf.lfPitchAndFamily = 0;
- + EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)font_family_cb, (LPARAM)&families, 0);
- +
- + // second iteration
- + // iterate over all families to get detailed info about all styles
- + info_data.hdc = hDC;
- + info_data.provider = provider;
- + for (i = 0; i < families.n_family; i++) {
- + strcpy(&lf.lfFaceName[0], families.names[i]);
- + EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)font_info_cb, (LPARAM)&info_data, 0);
- + free(families.names[i]);
- + }
- + free(families.names);
- +
- + return provider;
- +}
- +
- +#endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement