summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
Diffstat (limited to 'libass')
-rw-r--r--libass/Makefile1
-rw-r--r--libass/ass_cache.c48
-rw-r--r--libass/ass_cache.h3
-rw-r--r--libass/ass_font.c139
-rw-r--r--libass/ass_font.h38
-rw-r--r--libass/ass_render.c37
6 files changed, 197 insertions, 69 deletions
diff --git a/libass/Makefile b/libass/Makefile
index 9a7ddde92d..32952a06f5 100644
--- a/libass/Makefile
+++ b/libass/Makefile
@@ -11,6 +11,7 @@ SRCS = ass.c \
ass_mp.c \
ass_bitmap.c \
ass_library.c \
+ ass_font.c \
CFLAGS = -I../libmpcodecs -D_GNU_SOURCE
diff --git a/libass/ass_cache.c b/libass/ass_cache.c
index e4d41e45b0..e3ef630708 100644
--- a/libass/ass_cache.c
+++ b/libass/ass_cache.c
@@ -30,6 +30,7 @@
#include "ass_fontconfig.h"
#include "ass_bitmap.h"
#include "ass_cache.h"
+#include "ass_font.h"
#define MAX_FONT_CACHE_SIZE 100
@@ -49,24 +50,6 @@ static int font_compare(ass_font_desc_t* a, ass_font_desc_t* b) {
}
/**
- * Select Microfost Unicode CharMap, if the font has one.
- * Otherwise, let FreeType decide.
- */
-static void charmap_magic(FT_Face face)
-{
- int i;
- for (i = 0; i < face->num_charmaps; ++i) {
- FT_CharMap cmap = face->charmaps[i];
- unsigned pid = cmap->platform_id;
- unsigned eid = cmap->encoding_id;
- if (pid == 3 /*microsoft*/ && (eid == 1 /*unicode bmp*/ || eid == 10 /*full unicode*/)) {
- FT_Set_Charmap(face, cmap);
- break;
- }
- }
-}
-
-/**
* \brief Get a face object, either from cache or created through FreeType+FontConfig.
* \param library FreeType library object
* \param fontconfig_priv fontconfig private data
@@ -75,12 +58,9 @@ static void charmap_magic(FT_Face face)
*/
ass_font_t* ass_new_font(FT_Library library, void* fontconfig_priv, ass_font_desc_t* desc)
{
- FT_Error error;
int i;
- char* path;
- int index;
ass_font_t* item;
- FT_Face face;
+ int error;
for (i=0; i<font_cache_size; ++i)
if (font_compare(desc, &(font_cache[i].desc)))
@@ -91,24 +71,12 @@ ass_font_t* ass_new_font(FT_Library library, void* fontconfig_priv, ass_font_des
return 0;
}
- path = fontconfig_select(fontconfig_priv, desc->family, desc->bold, desc->italic, &index);
-
- error = FT_New_Face(library, path, index, &face);
- if (error) {
- if (!no_more_font_messages)
- mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index);
- no_more_font_messages = 1;
- return 0;
- }
-
- charmap_magic(face);
-
item = font_cache + font_cache_size;
- item->path = strdup(path);
- item->index = index;
- item->face = face;
- memcpy(&(item->desc), desc, sizeof(ass_font_desc_t));
+ error = ass_font_init(library, fontconfig_priv, item, desc);
+ if (error) // FIXME: mp_msg
+ return 0;
font_cache_size++;
+
return item;
}
@@ -123,9 +91,7 @@ void ass_font_cache_done(void)
int i;
for (i = 0; i < font_cache_size; ++i) {
ass_font_t* item = font_cache + i;
- if (item->face) FT_Done_Face(item->face);
- if (item->path) free(item->path);
- // FIXME: free desc ?
+ ass_font_free(item);
}
free(font_cache);
font_cache_size = 0;
diff --git a/libass/ass_cache.h b/libass/ass_cache.h
index 9609547955..4fd5f79463 100644
--- a/libass/ass_cache.h
+++ b/libass/ass_cache.h
@@ -38,6 +38,9 @@ typedef struct ass_font_s {
char* path;
int index;
FT_Face face;
+ FT_Matrix m; // current transformation
+ FT_Vector v; // current shift
+ int size;
} ass_font_t;
void ass_font_cache_init(void);
diff --git a/libass/ass_font.c b/libass/ass_font.c
new file mode 100644
index 0000000000..5778935d6b
--- /dev/null
+++ b/libass/ass_font.c
@@ -0,0 +1,139 @@
+// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
+// vim:ts=8:sw=8:noet:ai:
+/*
+ Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+
+ 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "config.h"
+
+#include <inttypes.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SYNTHESIS_H
+#include FT_GLYPH_H
+
+#include "ass_font.h"
+#include "ass_fontconfig.h"
+#include "mputils.h"
+
+extern int no_more_font_messages;
+
+/**
+ * Select Microfost Unicode CharMap, if the font has one.
+ * Otherwise, let FreeType decide.
+ */
+static void charmap_magic(FT_Face face)
+{
+ int i;
+ for (i = 0; i < face->num_charmaps; ++i) {
+ FT_CharMap cmap = face->charmaps[i];
+ unsigned pid = cmap->platform_id;
+ unsigned eid = cmap->encoding_id;
+ if (pid == 3 /*microsoft*/ && (eid == 1 /*unicode bmp*/ || eid == 10 /*full unicode*/)) {
+ FT_Set_Charmap(face, cmap);
+ break;
+ }
+ }
+}
+
+int ass_font_init(FT_Library ftlibrary, void* fc_priv, ass_font_t* font, ass_font_desc_t* desc)
+{
+ char* path;
+ int index;
+ FT_Face face;
+ int error;
+
+ path = fontconfig_select(fc_priv, desc->family, desc->bold, desc->italic, &index);
+
+ error = FT_New_Face(ftlibrary, path, index, &face);
+ if (error) {
+ if (!no_more_font_messages)
+ mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningFont, path, index);
+ no_more_font_messages = 1;
+ return 1;
+ }
+
+ charmap_magic(face);
+
+ font->path = strdup(path);
+ font->index = index;
+ font->face = face;
+ font->desc.family = strdup(desc->family);
+ font->desc.bold = desc->bold;
+ font->desc.italic = desc->italic;
+
+ font->m.xx = font->m.yy = (FT_Fixed)0x10000L;
+ font->m.xy = font->m.yy = 0;
+ font->v.x = font->v.y = 0;
+
+ return 0;
+}
+
+void ass_font_set_transform(ass_font_t* font, FT_Matrix* m, FT_Vector* v)
+{
+ font->m.xx = m->xx;
+ font->m.xy = m->xy;
+ font->m.yx = m->yx;
+ font->m.yy = m->yy;
+ font->v.x = v->x;
+ font->v.y = v->y;
+ FT_Set_Transform(font->face, &font->m, &font->v);
+}
+
+void ass_font_set_size(ass_font_t* font, int size)
+{
+ font->size = size;
+ FT_Set_Pixel_Sizes(font->face, 0, size);
+}
+
+FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch)
+{
+ int error;
+ int index;
+ FT_Glyph glyph;
+
+ index = FT_Get_Char_Index(font->face, ch);
+ error = FT_Load_Glyph(font->face, index, FT_LOAD_NO_BITMAP );
+ if (error) {
+ mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
+ return 0;
+ }
+
+#if (FREETYPE_MAJOR > 2) || \
+ ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \
+ ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10))
+// FreeType >= 2.1.10 required
+ if (!(font->face->style_flags & FT_STYLE_FLAG_ITALIC) &&
+ (font->desc.italic > 55)) {
+ FT_GlyphSlot_Oblique(font->face->glyph);
+ }
+#endif
+ error = FT_Get_Glyph(font->face->glyph, &glyph);
+ if (error) {
+ mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
+ return 0;
+ }
+
+ return glyph;
+}
+
+void ass_font_free(ass_font_t* font)
+{
+ if (font->face) FT_Done_Face(font->face);
+ if (font->path) free(font->path);
+ if (font->desc.family) free(font->desc.family);
+}
diff --git a/libass/ass_font.h b/libass/ass_font.h
new file mode 100644
index 0000000000..0e5998ca60
--- /dev/null
+++ b/libass/ass_font.h
@@ -0,0 +1,38 @@
+// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
+// vim:ts=8:sw=8:noet:ai:
+/*
+ Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+
+ 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __ASS_FONT_H__
+#define __ASS_FONT_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_STROKER_H
+#include FT_GLYPH_H
+
+#include "ass_bitmap.h"
+#include "ass_cache.h"
+
+int ass_font_init(FT_Library ftlibrary, void* fc_priv, ass_font_t* font, ass_font_desc_t* desc);
+void ass_font_set_transform(ass_font_t* font, FT_Matrix* m, FT_Vector* v);
+void ass_font_set_size(ass_font_t* font, int size);
+FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch);
+void ass_font_free(ass_font_t* font);
+
+#endif
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 01571d28a5..5175219c98 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -37,6 +37,7 @@
#include "ass_utils.h"
#include "ass_fontconfig.h"
#include "ass_library.h"
+#include "ass_font.h"
#define MAX_GLYPHS 1000
#define MAX_LINES 100
@@ -535,8 +536,8 @@ static void change_font_size(int sz)
size = 1;
else if (size > frame_context.height * 2)
size = frame_context.height * 2;
-
- FT_Set_Pixel_Sizes(render_context.font->face, 0, size);
+
+ ass_font_set_size(render_context.font, size);
render_context.font_size = sz;
}
@@ -1232,27 +1233,10 @@ static int get_glyph(int index, int symbol, glyph_info_t* info, FT_Vector* advan
// not found, get a new outline glyph from face
// mp_msg(MSGT_ASS, MSGL_INFO, "miss, index = %d, symbol = %c, adv = (%d, %d)\n", index, symbol, advance->x, advance->y);
-
- error = FT_Load_Glyph(render_context.font->face, index, FT_LOAD_NO_BITMAP );
- if (error) {
- mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
- return error;
- }
-
-#if (FREETYPE_MAJOR > 2) || \
- ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \
- ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10))
-// FreeType >= 2.1.10 required
- if (!(render_context.font->face->style_flags & FT_STYLE_FLAG_ITALIC) &&
- ((render_context.italic == 1) || (render_context.italic > 55))) {
- FT_GlyphSlot_Oblique(render_context.font->face->glyph);
- }
-#endif
- error = FT_Get_Glyph(render_context.font->face->glyph, &(info->glyph));
- if (error) {
- mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
- return error;
- }
+
+ info->glyph = ass_font_get_glyph(frame_context.ass_priv->fontconfig_priv, render_context.font, symbol);
+ if (!info->glyph)
+ return 0;
info->advance.x = info->glyph->advance.x >> 10;
info->advance.y = info->glyph->advance.y >> 10;
@@ -1633,17 +1617,14 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images)
shift.x = pen.x & 63;
shift.y = pen.y & 63;
- if ((render_context.scale_x != 1.) || (render_context.scale_y != 1.) ||
- (frame_context.font_scale_x != 1.)) {
+ {
FT_Matrix matrix;
matrix.xx = (FT_Fixed)( render_context.scale_x * frame_context.font_scale_x * 0x10000L );
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
matrix.yx = (FT_Fixed)( 0 * 0x10000L );
matrix.yy = (FT_Fixed)( render_context.scale_y * 0x10000L );
- FT_Set_Transform( render_context.font->face, &matrix, &shift );
- } else {
- FT_Set_Transform(render_context.font->face, 0, &shift);
+ ass_font_set_transform(render_context.font, &matrix, &shift );
}
error = get_glyph(glyph_index, code, text_info.glyphs + text_info.length, &shift);