summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-25 19:23:52 +0200
committerwm4 <wm4@nowhere>2013-09-26 00:39:13 +0200
commit4f542f2b9d003125c3b04416074078c3d81c0d6c (patch)
tree0cb8817499bd558a08e1d21a514fa9e2c1afa7fb
parent9b48357234806a4fe29ec97eba6c998a26033b5d (diff)
downloadlibass-4f542f2b9d003125c3b04416074078c3d81c0d6c.tar.bz2
libass-4f542f2b9d003125c3b04416074078c3d81c0d6c.tar.xz
Fix Hinting again
Commit 05eb520 missed some duplicated bits in ass_shaper.c. <wm4> oh crap <zgreg> oh crap indeed Instead of duplicating the logic in ass_shaper.c, just change the glyphs before they even get into processing. This way, all code reading the font size etc. is affected. This essentially reverts commit c207000c, because it's not needed anymore.
-rw-r--r--libass/ass_render.c64
-rw-r--r--libass/ass_render.h1
-rw-r--r--libass/ass_shaper.c13
3 files changed, 49 insertions, 29 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 0cf1f16..734dc6c 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -937,8 +937,8 @@ static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info,
{
int i;
int adv = advance.x;
- double scale_y = info->scale_y;
- double scale_x = info->scale_x;
+ double scale_y = info->orig_scale_y;
+ double scale_x = info->orig_scale_x;
// to avoid gaps
sx = FFMAX(64, sx);
@@ -1099,21 +1099,10 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
v.desc = drawing->desc;
key.u.drawing.text = strdup(drawing->text);
} else {
- double ft_size;
- if (priv->settings.hinting == ASS_HINTING_NONE) {
- // arbitrary, not too small to prevent grid fitting rounding effects
- // XXX: this is a rather crude hack
- ft_size = 256.0;
- } else {
- // If hinting is enabled, we want to pass the real font size
- // to freetype. Normalize scale_y to 1.0.
- ft_size = info->scale_y * info->font_size;
- }
- ass_face_set_size(info->font->faces[info->face_index], ft_size);
- ass_font_set_transform(info->font,
- info->scale_x * info->font_size / ft_size,
- info->scale_y * info->font_size / ft_size,
- NULL);
+ ass_face_set_size(info->font->faces[info->face_index],
+ info->font_size);
+ ass_font_set_transform(info->font, info->scale_x,
+ info->scale_y, NULL);
FT_Glyph glyph =
ass_font_get_glyph(priv->fontconfig_priv, info->font,
info->symbol, info->face_index, info->glyph_index,
@@ -1128,8 +1117,8 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
FT_Done_Glyph(glyph);
ass_font_get_asc_desc(info->font, info->symbol,
&v.asc, &v.desc);
- v.asc *= info->scale_y * info->font_size / ft_size;
- v.desc *= info->scale_y * info->font_size / ft_size;
+ v.asc *= info->scale_y;
+ v.desc *= info->scale_y;
}
}
@@ -1682,6 +1671,33 @@ fill_bitmap_hash(ASS_Renderer *priv, GlyphInfo *info,
}
/**
+ * \brief Adjust the glyph's font size and scale factors to ensure smooth
+ * scaling and handle pathological font sizes. The main problem here is
+ * freetype's grid fitting, which destroys animations by font size, or will
+ * result in incorrect final text size if font sizes are very small and
+ * scale factors very large. See Google Code issue #46.
+ * \param priv guess what
+ * \param glyph the glyph to be modified
+ */
+static void
+fix_glyph_scaling(ASS_Renderer *priv, GlyphInfo *glyph)
+{
+ double ft_size;
+ if (priv->settings.hinting == ASS_HINTING_NONE) {
+ // arbitrary, not too small to prevent grid fitting rounding effects
+ // XXX: this is a rather crude hack
+ ft_size = 256.0;
+ } else {
+ // If hinting is enabled, we want to pass the real font size
+ // to freetype. Normalize scale_y to 1.0.
+ ft_size = glyph->scale_y * glyph->font_size;
+ }
+ glyph->scale_x = glyph->scale_x * glyph->font_size / ft_size;
+ glyph->scale_y = glyph->scale_y * glyph->font_size / ft_size;
+ glyph->font_size = ft_size;
+}
+
+/**
* \brief Main ass rendering function, glues everything together
* \param event event to render
* \param event_images struct containing resulting images, will also be initialized
@@ -1808,8 +1824,12 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
glyphs[text_info->length].blur = render_priv->state.blur;
glyphs[text_info->length].shadow_x = render_priv->state.shadow_x;
glyphs[text_info->length].shadow_y = render_priv->state.shadow_y;
- glyphs[text_info->length].scale_x= render_priv->state.scale_x;
- glyphs[text_info->length].scale_y = render_priv->state.scale_y;
+ glyphs[text_info->length].orig_scale_x
+ = glyphs[text_info->length].scale_x
+ = render_priv->state.scale_x;
+ glyphs[text_info->length].orig_scale_y
+ = glyphs[text_info->length].scale_y
+ = render_priv->state.scale_y;
glyphs[text_info->length].border_style = render_priv->state.border_style;
glyphs[text_info->length].border_x= render_priv->state.border_x;
glyphs[text_info->length].border_y = render_priv->state.border_y;
@@ -1827,6 +1847,8 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
if (glyphs[text_info->length].drawing) {
drawing = render_priv->state.drawing =
ass_drawing_new(render_priv->library, render_priv->ftlibrary);
+ } else {
+ fix_glyph_scaling(render_priv, &glyphs[text_info->length]);
}
text_info->length++;
diff --git a/libass/ass_render.h b/libass/ass_render.h
index ecfca61..3a7c6d9 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -143,6 +143,7 @@ typedef struct glyph_info {
double frx, fry, frz; // rotation
double fax, fay; // text shearing
double scale_x, scale_y;
+ double orig_scale_x, orig_scale_y; // scale_x,y before fix_glyph_scaling
int border_style;
double border_x, border_y;
double hspacing;
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 46b11fe..46e6edc 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -392,9 +392,7 @@ static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
font->faces[info->face_index], NULL);
}
- // XXX: this is a rather crude hack
- const double ft_size = 256.0;
- ass_face_set_size(font->faces[info->face_index], ft_size);
+ ass_face_set_size(font->faces[info->face_index], info->font_size);
update_hb_size(hb_fonts[info->face_index], font->faces[info->face_index]);
// update hash key for cached metrics
@@ -525,7 +523,6 @@ static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
hb_buffer_t *buf;
hb_font_t *font;
} runs[MAX_RUNS];
- const double ft_size = 256.0;
for (i = 0; i < len && run < MAX_RUNS; i++, run++) {
// get length and level of the current run
@@ -581,10 +578,10 @@ static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
// set position and advance
info->skip = 0;
info->glyph_index = glyph_info[j].codepoint;
- info->offset.x = pos[j].x_offset * info->scale_x * (info->font_size / ft_size);
- info->offset.y = -pos[j].y_offset * info->scale_y * (info->font_size / ft_size);
- info->advance.x = pos[j].x_advance * info->scale_x * (info->font_size / ft_size);
- info->advance.y = -pos[j].y_advance * info->scale_y * (info->font_size / ft_size);
+ info->offset.x = pos[j].x_offset * info->scale_x;
+ info->offset.y = -pos[j].y_offset * info->scale_y;
+ info->advance.x = pos[j].x_advance * info->scale_x;
+ info->advance.y = -pos[j].y_advance * info->scale_y;
// accumulate advance in the root glyph
root->cluster_advance.x += info->advance.x;