mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
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
This commit is contained in:
parent
2b0e71f4de
commit
7569a2e932
1 changed files with 37 additions and 30 deletions
|
@ -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;
|
||||
|
||||
/* 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) {
|
||||
PangoRectangle rect;
|
||||
PangoContext *context;
|
||||
PangoMatrix matrix = PANGO_MATRIX_INIT;
|
||||
int tmp;
|
||||
gint 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);
|
||||
/* 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);
|
||||
|
|
Loading…
Reference in a new issue