summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@chown.ath.cx>2011-08-18 00:15:57 +0200
committerGrigori Goronzy <greg@chown.ath.cx>2015-07-10 10:42:40 +0200
commitc116071fa8d1bbfcf509f1f099ebb789dfd6ae37 (patch)
tree6f62b27d576b380ee8b7160f1a882f2b9a5ce508 /libass
parent38f4a39bdbe6090d39e86b620c772ba5cd88c8a5 (diff)
downloadlibass-c116071fa8d1bbfcf509f1f099ebb789dfd6ae37.tar.bz2
libass-c116071fa8d1bbfcf509f1f099ebb789dfd6ae37.tar.xz
Add glyph coverage map for embedded fonts
Introduce a simple glyph coverage map (created when the font is added) and use it for checking glyph coverage in font selection. This uses a simple linear search at the moment.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_font.c2
-rw-r--r--libass/ass_font.h1
-rw-r--r--libass/ass_fontselect.c85
3 files changed, 83 insertions, 5 deletions
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 16207d3..7170e10 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -39,7 +39,7 @@
* Select a good charmap, prefer Microsoft Unicode charmaps.
* Otherwise, let FreeType decide.
*/
-static void charmap_magic(ASS_Library *library, FT_Face face)
+void charmap_magic(ASS_Library *library, FT_Face face)
{
int i;
int ms_cmap = -1;
diff --git a/libass/ass_font.h b/libass/ass_font.h
index f29e301..693cabf 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -58,6 +58,7 @@ struct ass_font {
double size;
};
+void charmap_magic(ASS_Library *library, FT_Face face);
ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library,
FT_Library ftlibrary, ASS_FontSelector *fontsel,
ASS_FontDesc *desc);
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index e1a57f2..b3702b6 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -92,6 +92,44 @@ struct font_provider {
void *priv;
};
+// simple glyph coverage map
+typedef struct coverage_map CoverageMap;
+struct coverage_map {
+ int n_codepoint;
+ uint32_t *codepoints;
+};
+
+static int check_glyph_ft(void *data, uint32_t codepoint)
+{
+ int i;
+ CoverageMap *coverage = (CoverageMap *)data;
+
+ if (!codepoint)
+ return 1;
+
+ // XXX: sort at map creation and use bsearch here - is this worth it?
+ for (i = 0; i < coverage->n_codepoint; i++)
+ if (coverage->codepoints[i] == codepoint)
+ return 1;
+
+ return 0;
+}
+
+static void coverage_map_destroy(void *data)
+{
+ CoverageMap *coverage = (CoverageMap *)data;
+
+ free(coverage->codepoints);
+ free(coverage);
+}
+
+static ASS_FontProviderFuncs ft_funcs = {
+ NULL,
+ check_glyph_ft,
+ coverage_map_destroy,
+ NULL,
+};
+
ASS_FontProvider *
ass_font_provider_new(ASS_FontSelector *selector, ASS_FontProviderFuncs *funcs,
void *priv)
@@ -417,6 +455,33 @@ static int get_font_info(FT_Library lib, FT_Face face, ASS_FontInfo *info)
return 1;
}
+static CoverageMap *get_coverage_map(FT_Face face)
+{
+ int i = 0;
+ int n_codepoint = 0;
+ uint32_t codepoint;
+ unsigned index;
+ CoverageMap *coverage = calloc(1, sizeof(CoverageMap));
+
+ // determine number of codepoints first
+ codepoint = FT_Get_First_Char(face, &index);
+ while (index) {
+ n_codepoint++;
+ codepoint = FT_Get_Next_Char(face, codepoint, &index);
+ }
+
+ coverage->codepoints = calloc(n_codepoint, sizeof(uint32_t));
+ codepoint = FT_Get_First_Char(face, &index);
+ while (index) {
+ coverage->codepoints[i++] = codepoint;
+ codepoint = FT_Get_Next_Char(face, codepoint, &index);
+ }
+
+ coverage->n_codepoint = n_codepoint;
+
+ return coverage;
+}
+
/**
* \brief Process memory font.
* \param priv private data
@@ -447,6 +512,8 @@ static void process_fontdata(ASS_FontSelector *priv, ASS_Library *library,
}
num_faces = face->num_faces;
+ charmap_magic(library, face);
+
// get font metadata and add to list
ASS_FontInfo info;
memset(&info, 0, sizeof(ASS_FontInfo));
@@ -455,7 +522,17 @@ static void process_fontdata(ASS_FontSelector *priv, ASS_Library *library,
info.index = face_index;
info.path = strdup(name);
- priv->font_infos = realloc(priv->font_infos, sizeof(ASS_FontInfo) * (priv->n_font + 1));
+ info.uid = priv->uid++;
+ info.priv = get_coverage_map(face);
+ info.funcs = ft_funcs;
+
+ // check size
+ if (priv->n_font >= priv->alloc_font) {
+ priv->alloc_font = FFMAX(1, 2 * priv->alloc_font);
+ priv->font_infos = realloc(priv->font_infos,
+ priv->alloc_font * sizeof(ASS_FontInfo));
+ }
+
memcpy(priv->font_infos + priv->n_font, &info, sizeof(ASS_FontInfo));
priv->n_font++;
@@ -484,13 +561,13 @@ ass_fontselect_init(ASS_Library *library,
priv->path_default = path ? strdup(path) : NULL;
priv->index_default = 0;
- // XXX: for now, always add the fontconfig provider
- priv->provider = ass_fontconfig_add_provider(library, priv, NULL);
-
// XXX: use a real font provider for this
for (i = 0; i < library->num_fontdata; ++i)
process_fontdata(priv, library, ftlibrary, i);
+ // XXX: for now, always add the fontconfig provider
+ priv->provider = ass_fontconfig_add_provider(library, priv, NULL);
+
return priv;
}