summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2010-02-18 05:27:16 +0100
committerGrigori Goronzy <greg@blackbox>2010-04-11 01:59:28 +0200
commit6e9557cd6c54c99f0d6d9c11096a2f38be47493a (patch)
tree9606f9ae65bfa5f8c69d5b1dc608ba01fe555600
parent29167f37cf188f0b4dc6003ff6e733388112d183 (diff)
downloadlibass-6e9557cd6c54c99f0d6d9c11096a2f38be47493a.tar.bz2
libass-6e9557cd6c54c99f0d6d9c11096a2f38be47493a.tar.xz
Basic @font support
Do not skip '@' at the start of a font name in styles; detect '@' at font name start and set a new attribute in ASS_Font accordingly. Rotate affected glyphs after loading and calculate a suitable advance.
-rw-r--r--libass/ass.c6
-rw-r--r--libass/ass_cache.c2
-rw-r--r--libass/ass_font.c33
-rw-r--r--libass/ass_font.h1
-rw-r--r--libass/ass_parse.c12
5 files changed, 40 insertions, 14 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 1411776..2efddcd 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -536,12 +536,6 @@ static int process_style(ASS_Track *track, char *str)
style->Name = strdup("Default");
if (!style->FontName)
style->FontName = strdup("Arial");
- // skip '@' at the start of the font name
- if (*style->FontName == '@') {
- p = style->FontName;
- style->FontName = strdup(p + 1);
- free(p);
- }
free(format);
return 0;
diff --git a/libass/ass_cache.c b/libass/ass_cache.c
index 643d991..0252735 100644
--- a/libass/ass_cache.c
+++ b/libass/ass_cache.c
@@ -156,6 +156,8 @@ static int font_compare(void *key1, void *key2, size_t key_size)
return 0;
if (a->treat_family_as_pattern != b->treat_family_as_pattern)
return 0;
+ if (a->vertical != b->vertical)
+ return 0;
return 1;
}
diff --git a/libass/ass_font.c b/libass/ass_font.c
index bb2b96a..109390f 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -188,6 +188,7 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
font.desc.bold = desc->bold;
font.desc.italic = desc->italic;
+ font.desc.vertical = desc->vertical;
font.scale_x = font.scale_y = 1.;
font.v.x = font.v.y = 0;
@@ -207,11 +208,20 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
void ass_font_set_transform(ASS_Font *font, double scale_x,
double scale_y, FT_Vector *v)
{
- font->scale_x = scale_x;
- font->scale_y = scale_y;
- if (v) {
- font->v.x = v->x;
- font->v.y = v->y;
+ if (font->desc.vertical) {
+ font->scale_x = scale_y;
+ font->scale_y = scale_x;
+ if (v) {
+ font->v.x = v->y;
+ font->v.y = v->x;
+ }
+ } else {
+ font->scale_x = scale_x;
+ font->scale_y = scale_y;
+ if (v) {
+ font->v.x = v->x;
+ font->v.y = v->y;
+ }
}
update_transform(font);
}
@@ -414,6 +424,7 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
FT_Glyph glyph;
FT_Face face = 0;
int flags = 0;
+ int vertical = font->desc.vertical;
if (ch < 0x20)
return 0;
@@ -488,6 +499,15 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
return 0;
}
+ if (vertical) {
+ FT_Matrix m = { 0, double_to_d16(-1.0), double_to_d16(1.0), 0 };
+ FT_Outline_Transform(&((FT_OutlineGlyph) glyph)->outline, &m);
+ FT_Outline_Translate(&((FT_OutlineGlyph) glyph)->outline,
+ face->glyph->metrics.vertAdvance * font->scale_y,
+ 0);
+ glyph->advance.x = face->glyph->linearVertAdvance * font->scale_y;
+ }
+
ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE,
deco & DECO_STRIKETHROUGH);
@@ -502,6 +522,9 @@ FT_Vector ass_font_get_kerning(ASS_Font *font, uint32_t c1, uint32_t c2)
FT_Vector v = { 0, 0 };
int i;
+ if (font->desc.vertical)
+ return v;
+
for (i = 0; i < font->n_faces; ++i) {
FT_Face face = font->faces[i];
int i1 = FT_Get_Char_Index(face, c1);
diff --git a/libass/ass_font.h b/libass/ass_font.h
index ca0c213..b16b987 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -36,6 +36,7 @@ typedef struct {
unsigned bold;
unsigned italic;
int treat_family_as_pattern;
+ int vertical; // @font vertical layout
} ASS_FontDesc;
typedef struct {
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index e5d1b16..ac502e7 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -68,9 +68,15 @@ void update_font(ASS_Renderer *render_priv)
{
unsigned val;
ASS_FontDesc desc;
- desc.family = strdup(render_priv->state.family);
- desc.treat_family_as_pattern =
- render_priv->state.treat_family_as_pattern;
+ desc.treat_family_as_pattern = render_priv->state.treat_family_as_pattern;
+
+ if (render_priv->state.family[0] == '@') {
+ desc.vertical = 1;
+ desc.family = strdup(render_priv->state.family + 1);
+ } else {
+ desc.vertical = 0;
+ desc.family = strdup(render_priv->state.family);
+ }
val = render_priv->state.bold;
// 0 = normal, 1 = bold, >1 = exact weight