summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.c
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-07-04 12:59:11 +0200
committerGrigori Goronzy <greg@blackbox>2011-07-04 12:59:11 +0200
commit53288ab83600d57f6082815183c068ab21959037 (patch)
treead7ab95115d80c3f48f572b0e2c327c82f93086b /libass/ass_render.c
parent0a539d83afef27b64228f5abd8f21c6e15972b0c (diff)
downloadlibass-53288ab83600d57f6082815183c068ab21959037.tar.bz2
libass-53288ab83600d57f6082815183c068ab21959037.tar.xz
Introduce bitmap runs
Prepare for run-based rendering. In the parser, increment a run id according to relevant style changes (color, border, shadow, etc.) to mark the points where a new bitmap needs to be started. Modify the line wrapper to increment the run ids of each glyph after a break. Add functions to calculate the render size of runs for rasterization.
Diffstat (limited to 'libass/ass_render.c')
-rw-r--r--libass/ass_render.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index aaa5778..307b1e8 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -798,6 +798,37 @@ static void compute_string_bbox(TextInfo *info, DBBox *bbox)
}
/**
+ * \brief Compute the size of the target bitmap for a run of outlines.
+ * \param run first outline of the run
+ * \param len run length
+ * \param w returns target width, in pixels
+ * \param h returns target height, in pixels
+ */
+static void compute_run_size(GlyphInfo *run, size_t len, int *w, int *h)
+{
+ int i;
+ FT_BBox bbox;
+ bbox.xMin = bbox.yMin = INT_MAX;
+ bbox.xMax = bbox.yMax = INT_MIN;
+
+ for (i = 0; i < len; i++) {
+ GlyphInfo *info = run + i;
+ if (info->skip || info->symbol == 0 || info->symbol == '\n')
+ continue;
+ bbox.xMin = FFMIN(bbox.xMin, info->pos.x + info->bbox.xMin);
+ bbox.yMin = FFMIN(bbox.yMin, info->pos.y + info->bbox.yMin);
+ bbox.xMax = FFMAX(bbox.xMax, info->pos.x + info->bbox.xMax);
+ bbox.yMax = FFMAX(bbox.yMax, info->pos.y + info->bbox.yMax);
+ }
+ bbox.xMin &= ~63;
+ bbox.yMin &= ~63;
+ bbox.xMax = (bbox.xMax + 63) & ~63;
+ bbox.yMax = (bbox.yMax + 63) & ~63;
+ *w = (bbox.xMax - bbox.xMin) >> 6;
+ *h = (bbox.yMax - bbox.yMin) >> 6;
+}
+
+/**
* \brief partially reset render_context to style values
* Works like {\r}: resets some style overrides
*/
@@ -865,6 +896,7 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event)
render_priv->state.effect_type = EF_NONE;
render_priv->state.effect_timing = 0;
render_priv->state.effect_skip_timing = 0;
+ render_priv->state.bm_run_id = 0;
ass_drawing_free(render_priv->state.drawing);
render_priv->state.drawing = ass_drawing_new(render_priv->library,
render_priv->ftlibrary);
@@ -1416,6 +1448,7 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
double pen_shift_x;
double pen_shift_y;
int cur_line;
+ int run_offset;
TextInfo *text_info = &render_priv->text_info;
last_space = -1;
@@ -1525,6 +1558,7 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
pen_shift_x = 0.;
pen_shift_y = 0.;
cur_line = 1;
+ run_offset = 0;
i = 0;
cur = text_info->glyphs + i;
@@ -1541,12 +1575,14 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width)
text_info->lines[cur_line - 1].desc +
text_info->lines[cur_line].asc;
cur_line++;
+ run_offset++;
pen_shift_x = d6_to_double(-cur->pos.x);
pen_shift_y += height + render_priv->settings.line_spacing;
ass_msg(render_priv->library, MSGL_DBG2,
"shifting from %d to %d by (%f, %f)", i,
text_info->length - 1, pen_shift_x, pen_shift_y);
}
+ cur->bm_run_id += run_offset;
cur->pos.x += double_to_d6(pen_shift_x);
cur->pos.y += double_to_d6(pen_shift_y);
}
@@ -1759,6 +1795,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
glyphs[text_info->length].frz = render_priv->state.frz;
glyphs[text_info->length].fax = render_priv->state.fax;
glyphs[text_info->length].fay = render_priv->state.fay;
+ glyphs[text_info->length].bm_run_id = render_priv->state.bm_run_id;
// fill bitmap hash
glyphs[text_info->length].hash_key.type = BITMAP_OUTLINE;
@@ -2000,6 +2037,31 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
get_bitmap_glyph(render_priv, glyphs + i);
}
+ // Compute runs and their bboxes
+ // XXX: currently does nothing visible/functional
+ for (i = 0; i < text_info->length; i++) {
+ GlyphInfo *g = glyphs + i;
+ OutlineBitmapHashKey *key = &g->hash_key.u.outline;
+ int w, h;
+
+ // skip non-visual glyphs
+ if (g->skip || g->symbol == '\n' || g->symbol == 0)
+ continue;
+
+ // Determine run length and compute run bbox
+ int run_len = 0;
+ int cur_run = g->bm_run_id;
+ while (g->bm_run_id == cur_run && (i + run_len) < text_info->length) {
+ g++;
+ run_len++;
+ }
+ g = glyphs + i;
+ compute_run_size(g, run_len, &w, &h);
+ //printf("run_id %d len %d size %d %d\n", g->bm_run_id, run_len, w, h);
+
+ i += run_len - 1;
+ }
+
memset(event_images, 0, sizeof(*event_images));
event_images->top = device_y - text_info->lines[0].asc;
event_images->height = text_info->height;