Commit 7569a2e9 authored by Nicolas Dufresne's avatar Nicolas Dufresne

basetextoverlay: Fix clipping issues

This patch uses the ink rectangle in order to compute the size
of the surface require to render. It also correctly compute the
transformation matrix as the ink_rect position might not be at
0, 0. Additionally, shadow_offset and outline_offset (which is
in fact the diameter of a dot, not a really an offset) is now
taken into account. Redundant matrix operation has been removed
for the vertical rendering.

Take note that the matrix operation in cairo are excuted in
reverse order.

https://bugzilla.gnome.org/show_bug.cgi?id=728636
parent 2b0e71f4
......@@ -1566,9 +1566,12 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
cairo_surface_t *surface;
PangoRectangle ink_rect, logical_rect;
cairo_matrix_t cairo_matrix;
int width, height;
gint unscaled_width, unscaled_height;
gint width, height;
double scalef = 1.0;
double a, r, g, b;
gdouble shadow_offset = 0.0;
gdouble outline_offset = 0.0;
GstBuffer *buffer;
GstMapInfo map;
......@@ -1579,6 +1582,14 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
scalef = (double) (overlay->width) / DEFAULT_SCALE_BASIS;
}
if (overlay->draw_shadow)
shadow_offset = overlay->shadow_offset;
/* This value is uses as cairo line width, which is the diameter of a pen
* that is circular. That's why only half of it is used to offset */
if (overlay->draw_outline)
outline_offset = overlay->outline_offset;
pango_layout_set_width (overlay->layout, -1);
/* set text on pango layout */
pango_layout_set_markup (overlay->layout, string, textlen);
......@@ -1586,7 +1597,8 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
/* get subtitle image size */
pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
width = ceil ((logical_rect.width + overlay->shadow_offset) * scalef);
unscaled_width = ink_rect.width + shadow_offset + outline_offset;
width = ceil (unscaled_width * scalef);
if (width + overlay->deltax >
(overlay->use_vertical_render ? overlay->height : overlay->width)) {
......@@ -1596,11 +1608,13 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
*/
gst_base_text_overlay_update_wrap_mode (overlay);
pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
unscaled_width = ink_rect.width + shadow_offset + outline_offset;
width = overlay->width;
}
height = ceil (
(logical_rect.height + logical_rect.y + overlay->shadow_offset) * scalef);
unscaled_height = ink_rect.height + shadow_offset + outline_offset;
height = ceil (unscaled_height * scalef);
if (height > overlay->height) {
height = overlay->height;
}
......@@ -1610,40 +1624,33 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
height = ceil (height * overlay->render_scale);
scalef *= overlay->render_scale;
if (overlay->use_vertical_render) {
PangoRectangle rect;
PangoContext *context;
PangoMatrix matrix = PANGO_MATRIX_INIT;
int tmp;
context = pango_layout_get_context (overlay->layout);
pango_matrix_rotate (&matrix, -90);
rect.x = rect.y = 0;
rect.width = width;
rect.height = height;
pango_matrix_transform_pixel_rectangle (&matrix, &rect);
matrix.x0 = -rect.x;
matrix.y0 = -rect.y;
pango_context_set_matrix (context, &matrix);
cairo_matrix.xx = matrix.xx;
cairo_matrix.yx = matrix.yx;
cairo_matrix.xy = matrix.xy;
cairo_matrix.yy = matrix.yy;
cairo_matrix.x0 = matrix.x0;
cairo_matrix.y0 = matrix.y0;
cairo_matrix_scale (&cairo_matrix, scalef, scalef);
/* Prepare the transformation matrix. Note that the transformation happens
* in reverse order. So for horizontal text, we will translate and then
* scale. This is important to understand which scale shall be used. */
cairo_matrix_init_scale (&cairo_matrix, scalef, scalef);
if (overlay->use_vertical_render) {
gint tmp;
/* tranlate to the center of the image, rotate, and tranlate the rotated
* image back to the right place */
cairo_matrix_translate (&cairo_matrix, unscaled_height / 2.0l,
unscaled_width / 2.0l);
/* 90 degree clockwise rotation which is PI / 2 in radiants */
cairo_matrix_rotate (&cairo_matrix, G_PI_2);
cairo_matrix_translate (&cairo_matrix, -(unscaled_width / 2.0l),
-(unscaled_height / 2.0l));
/* Swap width and height */
tmp = height;
height = width;
width = tmp;
} else {
cairo_matrix_init_scale (&cairo_matrix, scalef, scalef);
}
cairo_matrix_translate (&cairo_matrix,
ceil (outline_offset / 2.0l) - ink_rect.x,
ceil (outline_offset / 2.0l) - ink_rect.y);
/* reallocate overlay buffer */
buffer = gst_buffer_new_and_alloc (4 * width * height);
gst_buffer_replace (&overlay->text_image, buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment