2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
4 * Copyright (C) <2009> Young-Ho Cha <ganadist@gmail.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
24 * SECTION:element-textrender
25 * @see_also: #GstTextOverlay
27 * This plugin renders text received on the text sink pad to a video
28 * buffer (retaining the alpha channel), so it can later be overlayed
29 * on top of video streams using other elements.
31 * The text can contain newline characters. (FIXME: What about text
32 * wrapping? It does not make sense in this context)
35 * <title>Example launch lines</title>
37 * gst-launch -v filesrc location=subtitles.srt ! subparse ! textrender ! xvimagesink
47 #include <gst/video/video.h>
49 #include "gsttextrender.h"
52 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
53 # define CAIRO_ARGB_A 3
54 # define CAIRO_ARGB_R 2
55 # define CAIRO_ARGB_G 1
56 # define CAIRO_ARGB_B 0
58 # define CAIRO_ARGB_A 0
59 # define CAIRO_ARGB_R 1
60 # define CAIRO_ARGB_G 2
61 # define CAIRO_ARGB_B 3
64 GST_DEBUG_CATEGORY_EXTERN (pango_debug);
65 #define GST_CAT_DEFAULT pango_debug
67 #define MINIMUM_OUTLINE_OFFSET 1.0
69 #define DEFAULT_PROP_VALIGNMENT GST_TEXT_RENDER_VALIGN_BASELINE
70 #define DEFAULT_PROP_HALIGNMENT GST_TEXT_RENDER_HALIGN_CENTER
71 #define DEFAULT_PROP_LINE_ALIGNMENT GST_TEXT_RENDER_LINE_ALIGN_CENTER
72 #define DEFAULT_PROP_XPAD 25
73 #define DEFAULT_PROP_YPAD 25
74 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
75 #define DEFAULT_PROP_RENDER_WIDTH 800
76 #define DEFAULT_PROP_RENDER_HEIGHT 480
77 #define DEFAULT_PROP_RENDER_SILENT FALSE
79 #define DEFAULT_RENDER_WIDTH 720
80 #define DEFAULT_RENDER_HEIGHT 576
91 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
100 static GstStaticPadTemplate src_template_factory =
101 GST_STATIC_PAD_TEMPLATE ("src",
104 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV") ";" GST_VIDEO_CAPS_ARGB)
107 static GstStaticPadTemplate sink_template_factory =
108 GST_STATIC_PAD_TEMPLATE ("sink",
111 GST_STATIC_CAPS ("text/x-pango-markup; text/plain")
114 #define GST_TYPE_TEXT_RENDER_VALIGN (gst_text_render_valign_get_type())
116 gst_text_render_valign_get_type (void)
118 static GType text_render_valign_type = 0;
119 static const GEnumValue text_render_valign[] = {
120 {GST_TEXT_RENDER_VALIGN_BASELINE, "baseline", "baseline"},
121 {GST_TEXT_RENDER_VALIGN_BOTTOM, "bottom", "bottom"},
122 {GST_TEXT_RENDER_VALIGN_TOP, "top", "top"},
126 if (!text_render_valign_type) {
127 text_render_valign_type =
128 g_enum_register_static ("GstTextRenderVAlign", text_render_valign);
130 return text_render_valign_type;
133 #define GST_TYPE_TEXT_RENDER_HALIGN (gst_text_render_halign_get_type())
135 gst_text_render_halign_get_type (void)
137 static GType text_render_halign_type = 0;
138 static const GEnumValue text_render_halign[] = {
139 {GST_TEXT_RENDER_HALIGN_LEFT, "left", "left"},
140 {GST_TEXT_RENDER_HALIGN_CENTER, "center", "center"},
141 {GST_TEXT_RENDER_HALIGN_RIGHT, "right", "right"},
145 if (!text_render_halign_type) {
146 text_render_halign_type =
147 g_enum_register_static ("GstTextRenderHAlign", text_render_halign);
149 return text_render_halign_type;
152 #define GST_TYPE_TEXT_RENDER_LINE_ALIGN (gst_text_render_line_align_get_type())
154 gst_text_render_line_align_get_type (void)
156 static GType text_render_line_align_type = 0;
157 static const GEnumValue text_render_line_align[] = {
158 {GST_TEXT_RENDER_LINE_ALIGN_LEFT, "left", "left"},
159 {GST_TEXT_RENDER_LINE_ALIGN_CENTER, "center", "center"},
160 {GST_TEXT_RENDER_LINE_ALIGN_RIGHT, "right", "right"},
164 if (!text_render_line_align_type) {
165 text_render_line_align_type =
166 g_enum_register_static ("GstTextRenderLineAlign",
167 text_render_line_align);
169 return text_render_line_align_type;
172 static void gst_text_render_adjust_values_with_fontdesc (GstTextRender *
173 render, PangoFontDescription * desc);
175 GST_BOILERPLATE (GstTextRender, gst_text_render, GstElement, GST_TYPE_ELEMENT);
177 static void gst_text_render_finalize (GObject * object);
178 static void gst_text_render_set_property (GObject * object,
179 guint prop_id, const GValue * value, GParamSpec * pspec);
180 static void gst_text_render_get_property (GObject * object,
181 guint prop_id, GValue * value, GParamSpec * pspec);
184 gst_text_render_base_init (gpointer g_class)
186 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
188 gst_element_class_add_pad_template (element_class,
189 gst_static_pad_template_get (&src_template_factory));
190 gst_element_class_add_pad_template (element_class,
191 gst_static_pad_template_get (&sink_template_factory));
193 gst_element_class_set_details_simple (element_class, "Text renderer",
194 "Filter/Editor/Video",
195 "Renders a text string to an image bitmap",
196 "David Schleef <ds@schleef.org>, "
197 "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
201 gst_text_render_class_init (GstTextRenderClass * klass)
203 GObjectClass *gobject_class;
204 PangoFontMap *fontmap;
206 gobject_class = (GObjectClass *) klass;
208 parent_class = g_type_class_peek_parent (klass);
210 gobject_class->finalize = gst_text_render_finalize;
211 gobject_class->set_property = gst_text_render_set_property;
212 gobject_class->get_property = gst_text_render_get_property;
214 fontmap = pango_cairo_font_map_get_default ();
215 klass->pango_context =
216 pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
217 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
218 g_param_spec_string ("font-desc", "font description",
219 "Pango font description of font "
220 "to be used for rendering. "
221 "See documentation of "
222 "pango_font_description_from_string"
223 " for syntax.", "", G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
224 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGNMENT,
225 g_param_spec_enum ("valignment", "vertical alignment",
226 "Vertical alignment of the text", GST_TYPE_TEXT_RENDER_VALIGN,
227 DEFAULT_PROP_VALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
228 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGNMENT,
229 g_param_spec_enum ("halignment", "horizontal alignment",
230 "Horizontal alignment of the text", GST_TYPE_TEXT_RENDER_HALIGN,
231 DEFAULT_PROP_HALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
232 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPAD,
233 g_param_spec_int ("xpad", "horizontal paddding",
234 "Horizontal paddding when using left/right alignment", 0, G_MAXINT,
235 DEFAULT_PROP_XPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
236 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPAD,
237 g_param_spec_int ("ypad", "vertical padding",
238 "Vertical padding when using top/bottom alignment", 0, G_MAXINT,
239 DEFAULT_PROP_YPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
240 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
241 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RENDER_WIDTH,
242 g_param_spec_int ("width", "render width",
243 "Width of rendered video size", 0, G_MAXINT,
244 DEFAULT_PROP_RENDER_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
245 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RENDER_HEIGHT,
246 g_param_spec_int ("height", "render height",
247 "Height of rendered video size", 0, G_MAXINT,
248 DEFAULT_PROP_RENDER_HEIGHT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
249 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RENDER_SILENT,
250 g_param_spec_boolean ("silent", "render silent",
251 "Whether to render the text string",
252 DEFAULT_PROP_RENDER_SILENT, G_PARAM_READWRITE));
254 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LINE_ALIGNMENT,
255 g_param_spec_enum ("line-alignment", "line alignment",
256 "Alignment of text lines relative to each other.",
257 GST_TYPE_TEXT_RENDER_LINE_ALIGN, DEFAULT_PROP_LINE_ALIGNMENT,
258 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
262 gst_text_render_adjust_values_with_fontdesc (GstTextRender * render,
263 PangoFontDescription * desc)
265 gint font_size = pango_font_description_get_size (desc) / PANGO_SCALE;
267 render->shadow_offset = (double) (font_size) / 13.0;
268 render->outline_offset = (double) (font_size) / 15.0;
269 if (render->outline_offset < MINIMUM_OUTLINE_OFFSET)
270 render->outline_offset = MINIMUM_OUTLINE_OFFSET;
274 gst_text_render_render_pangocairo (GstTextRender * render)
277 cairo_surface_t *surface;
279 cairo_surface_t *surface_shadow;
280 PangoRectangle ink_rect, logical_rect;
283 pango_layout_get_pixel_extents (render->layout, &ink_rect, &logical_rect);
285 width = logical_rect.width + render->shadow_offset;
286 height = logical_rect.height + logical_rect.y + render->shadow_offset;
288 surface_shadow = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
289 cr_shadow = cairo_create (surface_shadow);
291 /* clear shadow surface */
292 cairo_set_operator (cr_shadow, CAIRO_OPERATOR_CLEAR);
293 cairo_paint (cr_shadow);
294 cairo_set_operator (cr_shadow, CAIRO_OPERATOR_OVER);
296 /* draw shadow text */
297 cairo_save (cr_shadow);
298 cairo_set_source_rgba (cr_shadow, 0.0, 0.0, 0.0, 0.5);
299 cairo_translate (cr_shadow, render->shadow_offset, render->shadow_offset);
300 pango_cairo_show_layout (cr_shadow, render->layout);
301 cairo_restore (cr_shadow);
303 /* draw outline text */
304 cairo_save (cr_shadow);
305 cairo_set_source_rgb (cr_shadow, 0.0, 0.0, 0.0);
306 cairo_set_line_width (cr_shadow, render->outline_offset);
307 pango_cairo_layout_path (cr_shadow, render->layout);
308 cairo_stroke (cr_shadow);
309 cairo_restore (cr_shadow);
311 cairo_destroy (cr_shadow);
313 render->text_image = g_realloc (render->text_image, 4 * width * height);
315 surface = cairo_image_surface_create_for_data (render->text_image,
316 CAIRO_FORMAT_ARGB32, width, height, width * 4);
317 cr = cairo_create (surface);
318 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
320 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
322 /* set default color */
323 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
327 pango_cairo_show_layout (cr, render->layout);
330 /* composite shadow with offset */
331 cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
332 cairo_set_source_surface (cr, surface_shadow, 0.0, 0.0);
336 cairo_surface_destroy (surface_shadow);
337 cairo_surface_destroy (surface);
338 render->image_width = width;
339 render->image_height = height;
343 gst_text_render_check_argb (GstTextRender * render)
346 peer_caps = gst_pad_get_allowed_caps (render->srcpad);
347 if (G_LIKELY (peer_caps)) {
350 n = gst_caps_get_size (peer_caps);
351 GST_DEBUG_OBJECT (render, "peer allowed caps (%u structure(s)) are %"
352 GST_PTR_FORMAT, n, peer_caps);
354 /* Check if AYUV or ARGB is first */
355 for (i = 0; i < n; i++) {
356 GstStructure *s = gst_caps_get_structure (peer_caps, i);
357 if (gst_structure_has_name (s, "video/x-raw-rgb") &&
358 gst_structure_has_field (s, "alpha_mask")) {
359 render->use_ARGB = TRUE;
361 } else if (gst_structure_has_name (s, "video/x-raw-yuv")) {
363 if (gst_structure_get_fourcc (s, "format", &fourcc) &&
364 fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V')) {
365 render->use_ARGB = FALSE;
370 gst_caps_unref (peer_caps);
375 gst_text_render_setcaps (GstPad * pad, GstCaps * caps)
377 GstTextRender *render = GST_TEXT_RENDER (gst_pad_get_parent (pad));
378 GstStructure *structure;
379 gboolean ret = FALSE;
380 gint width = 0, height = 0;
382 structure = gst_caps_get_structure (caps, 0);
383 gst_structure_get_int (structure, "width", &width);
384 gst_structure_get_int (structure, "height", &height);
386 GST_DEBUG ("Got caps %" GST_PTR_FORMAT, caps);
388 if (width >= render->image_width && height >= render->image_height) {
389 render->width = width;
390 render->height = height;
394 gst_text_render_check_argb (render);
396 gst_object_unref (render);
401 gst_text_render_fixate_caps (GstPad * pad, GstCaps * caps)
403 GstTextRender *render = GST_TEXT_RENDER (gst_pad_get_parent (pad));
404 GstStructure *s = gst_caps_get_structure (caps, 0);
406 GST_DEBUG ("Fixating caps %" GST_PTR_FORMAT, caps);
407 gst_structure_fixate_field_nearest_int (s, "width", render->image_width);
408 gst_structure_fixate_field_nearest_int (s, "height", render->image_height);
409 GST_DEBUG ("Fixated to %" GST_PTR_FORMAT, caps);
411 gst_object_unref (render);
414 #define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
415 b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
416 g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
417 r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
421 gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf,
422 int xpos, int ypos, int stride)
424 int y; /* text bitmap coordinates */
429 width = render->image_width;
430 height = render->image_height;
431 bitp = render->text_image;
433 for (y = 0; y < height; y++) {
435 p = pixbuf + (ypos + y) * stride + xpos * 4;
436 for (n = 0; n < width; n++) {
437 b = bitp[CAIRO_ARGB_B];
438 g = bitp[CAIRO_ARGB_G];
439 r = bitp[CAIRO_ARGB_R];
440 a = bitp[CAIRO_ARGB_A];
443 /* Cairo uses pre-multiplied ARGB, unpremultiply it */
444 CAIRO_UNPREMULTIPLY (a, r, g, b);
447 *p++ = CLAMP ((int) (((19595 * r) >> 16) + ((38470 * g) >> 16) +
448 ((7471 * b) >> 16)), 0, 255);
449 *p++ = CLAMP ((int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) +
450 ((32768 * b) >> 16) + 128), 0, 255);
451 *p++ = CLAMP ((int) (((32768 * r) >> 16) - ((27439 * g) >> 16) -
452 ((5329 * b) >> 16) + 128), 0, 255);
458 gst_text_renderer_image_to_argb (GstTextRender * render, guchar * pixbuf,
459 int xpos, int ypos, int stride)
465 width = render->image_width;
466 height = render->image_height;
467 bitp = render->text_image;
469 for (i = 0; i < height; i++) {
470 p = pixbuf + (ypos + i) * stride + xpos * 4;
471 for (j = 0; j < width; j++) {
472 p[0] = bitp[CAIRO_ARGB_A];
473 p[1] = bitp[CAIRO_ARGB_R];
474 p[2] = bitp[CAIRO_ARGB_G];
475 p[3] = bitp[CAIRO_ARGB_B];
477 /* Cairo uses pre-multiplied ARGB, unpremultiply it */
478 CAIRO_UNPREMULTIPLY (p[0], p[1], p[2], p[3]);
487 gst_text_render_chain (GstPad * pad, GstBuffer * inbuf)
489 GstTextRender *render;
492 GstCaps *caps = NULL;
493 guint8 *data = GST_BUFFER_DATA (inbuf);
494 guint size = GST_BUFFER_SIZE (inbuf);
498 render = GST_TEXT_RENDER (gst_pad_get_parent (pad));
500 /* somehow pango barfs over "\0" buffers... */
502 (data[size - 1] == '\r' ||
503 data[size - 1] == '\n' || data[size - 1] == '\0')) {
508 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
509 if (!render->silent) {
510 GST_DEBUG ("rendering '%*s'", size, data);
511 pango_layout_set_markup (render->layout, (gchar *) data, size);
512 gst_text_render_render_pangocairo (render);
514 GST_DEBUG ("silent mode is on, not rendering '%*s'", size, data);
517 GST_DEBUG ("rendering '%*s'", size, data);
518 pango_layout_set_markup (render->layout, (gchar *) data, size);
519 gst_text_render_render_pangocairo (render);
522 gst_text_render_check_argb (render);
524 if (!render->use_ARGB) {
526 gst_video_format_new_caps (GST_VIDEO_FORMAT_AYUV, render->width,
527 render->height, 1, 1, 1, 1);
530 gst_video_format_new_caps (GST_VIDEO_FORMAT_ARGB, render->width,
531 render->height, 1, 1, 1, 1);
534 if (!gst_pad_set_caps (render->srcpad, caps)) {
535 gst_caps_unref (caps);
536 GST_ELEMENT_ERROR (render, CORE, NEGOTIATION, (NULL), (NULL));
537 ret = GST_FLOW_ERROR;
541 GST_DEBUG ("Allocating buffer WxH = %dx%d", render->width, render->height);
543 gst_pad_alloc_buffer_and_set_caps (render->srcpad, GST_BUFFER_OFFSET_NONE,
544 render->width * render->height * 4, caps, &outbuf);
546 if (ret != GST_FLOW_OK)
549 gst_buffer_copy_metadata (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS);
550 data = GST_BUFFER_DATA (outbuf);
552 if (render->use_ARGB) {
553 memset (data, 0, render->width * render->height * 4);
555 for (n = 0; n < render->width * render->height; n++) {
556 data[n * 4] = data[n * 4 + 1] = 0;
557 data[n * 4 + 2] = data[n * 4 + 3] = 128;
561 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
562 if (render->silent) {
563 ret = gst_pad_push (render->srcpad, outbuf);
568 switch (render->halign) {
569 case GST_TEXT_RENDER_HALIGN_LEFT:
572 case GST_TEXT_RENDER_HALIGN_CENTER:
573 xpos = (render->width - render->image_width) / 2;
575 case GST_TEXT_RENDER_HALIGN_RIGHT:
576 xpos = render->width - render->image_width - render->xpad;
582 switch (render->valign) {
583 case GST_TEXT_RENDER_VALIGN_BOTTOM:
584 ypos = render->height - render->image_height - render->ypad;
586 case GST_TEXT_RENDER_VALIGN_BASELINE:
587 ypos = render->height - (render->image_height + render->ypad);
589 case GST_TEXT_RENDER_VALIGN_TOP:
597 if (render->text_image) {
598 if (render->use_ARGB) {
599 gst_text_renderer_image_to_argb (render, data, xpos, ypos,
602 gst_text_renderer_image_to_ayuv (render, data, xpos, ypos,
607 ret = gst_pad_push (render->srcpad, outbuf);
611 gst_caps_unref (caps);
612 gst_buffer_unref (inbuf);
613 gst_object_unref (render);
618 gst_text_render_finalize (GObject * object)
620 GstTextRender *render = GST_TEXT_RENDER (object);
622 g_free (render->text_image);
625 g_object_unref (render->layout);
627 G_OBJECT_CLASS (parent_class)->finalize (object);
631 gst_text_render_init (GstTextRender * render, GstTextRenderClass * klass)
633 GstPadTemplate *template;
636 template = gst_static_pad_template_get (&sink_template_factory);
637 render->sinkpad = gst_pad_new_from_template (template, "sink");
638 gst_object_unref (template);
639 gst_pad_set_chain_function (render->sinkpad,
640 GST_DEBUG_FUNCPTR (gst_text_render_chain));
641 gst_element_add_pad (GST_ELEMENT (render), render->sinkpad);
644 template = gst_static_pad_template_get (&src_template_factory);
645 render->srcpad = gst_pad_new_from_template (template, "src");
646 gst_object_unref (template);
647 gst_pad_set_fixatecaps_function (render->srcpad,
648 GST_DEBUG_FUNCPTR (gst_text_render_fixate_caps));
649 gst_pad_set_setcaps_function (render->srcpad,
650 GST_DEBUG_FUNCPTR (gst_text_render_setcaps));
652 gst_element_add_pad (GST_ELEMENT (render), render->srcpad);
654 render->line_align = DEFAULT_PROP_LINE_ALIGNMENT;
656 pango_layout_new (GST_TEXT_RENDER_GET_CLASS (render)->pango_context);
657 pango_layout_set_alignment (render->layout,
658 (PangoAlignment) render->line_align);
660 render->halign = DEFAULT_PROP_HALIGNMENT;
661 render->valign = DEFAULT_PROP_VALIGNMENT;
662 render->xpad = DEFAULT_PROP_XPAD;
663 render->ypad = DEFAULT_PROP_YPAD;
665 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
666 render->width = DEFAULT_PROP_RENDER_WIDTH;
667 render->height = DEFAULT_PROP_RENDER_HEIGHT;
668 render->silent = DEFAULT_PROP_RENDER_SILENT;
670 render->width = DEFAULT_RENDER_WIDTH;
671 render->height = DEFAULT_RENDER_HEIGHT;
674 render->use_ARGB = FALSE;
678 gst_text_render_set_property (GObject * object, guint prop_id,
679 const GValue * value, GParamSpec * pspec)
681 GstTextRender *render = GST_TEXT_RENDER (object);
684 case PROP_VALIGNMENT:
685 render->valign = g_value_get_enum (value);
687 case PROP_HALIGNMENT:
688 render->halign = g_value_get_enum (value);
690 case PROP_LINE_ALIGNMENT:
691 render->line_align = g_value_get_enum (value);
692 pango_layout_set_alignment (render->layout,
693 (PangoAlignment) render->line_align);
696 render->xpad = g_value_get_int (value);
699 render->ypad = g_value_get_int (value);
701 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
702 case PROP_RENDER_WIDTH:
703 render->width = g_value_get_int (value);
705 case PROP_RENDER_HEIGHT:
706 render->height = g_value_get_int (value);
708 case PROP_RENDER_SILENT:
709 render->silent = g_value_get_boolean (value);
714 PangoFontDescription *desc;
716 desc = pango_font_description_from_string (g_value_get_string (value));
718 GST_LOG ("font description set: %s", g_value_get_string (value));
719 GST_OBJECT_LOCK (render);
720 pango_layout_set_font_description (render->layout, desc);
721 gst_text_render_adjust_values_with_fontdesc (render, desc);
722 pango_font_description_free (desc);
723 gst_text_render_render_pangocairo (render);
724 GST_OBJECT_UNLOCK (render);
726 GST_WARNING ("font description parse failed: %s",
727 g_value_get_string (value));
738 gst_text_render_get_property (GObject * object, guint prop_id,
739 GValue * value, GParamSpec * pspec)
741 GstTextRender *render = GST_TEXT_RENDER (object);
744 case PROP_VALIGNMENT:
745 g_value_set_enum (value, render->valign);
747 case PROP_HALIGNMENT:
748 g_value_set_enum (value, render->halign);
750 case PROP_LINE_ALIGNMENT:
751 g_value_set_enum (value, render->line_align);
754 g_value_set_int (value, render->xpad);
757 g_value_set_int (value, render->ypad);
759 #ifdef GST_EXT_TEXTRENDER_ENHANCEMENT
760 case PROP_RENDER_WIDTH:
761 g_value_set_int (value, render->width);
763 case PROP_RENDER_HEIGHT:
764 g_value_set_int (value, render->height);
766 case PROP_RENDER_SILENT:
767 g_value_set_boolean (value, render->silent);
771 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);