command-line-formatter: Stop uselessly looping over options
[platform/upstream/gstreamer.git] / ges / ges-text-overlay-clip.c
1 /* GStreamer Editing Services
2  * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
3  *               2009 Nokia Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /**
22  * SECTION:gestextoverlayclip
23  * @title: GESTextOverlayClip
24  * @short_description: Render text onto another stream in a GESLayer
25  *
26  * Renders text onto the next lower priority stream using textrender.
27  */
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "ges-internal.h"
33 #include "ges-text-overlay-clip.h"
34 #include "ges-track-element.h"
35 #include "ges-text-overlay.h"
36 #include <string.h>
37
38
39 #define DEFAULT_PROP_TEXT ""
40 #define DEFAULT_PROP_FONT_DESC "Serif 36"
41 #define DEFAULT_PROP_VALIGNMENT GES_TEXT_VALIGN_BASELINE
42 #define DEFAULT_PROP_HALIGNMENT GES_TEXT_HALIGN_CENTER
43
44 struct _GESTextOverlayClipPrivate
45 {
46   gchar *text;
47   gchar *font_desc;
48   GESTextHAlign halign;
49   GESTextVAlign valign;
50   guint32 color;
51   gdouble xpos;
52   gdouble ypos;
53 };
54
55 enum
56 {
57   PROP_0,
58   PROP_TEXT,
59   PROP_FONT_DESC,
60   PROP_HALIGNMENT,
61   PROP_VALIGNMENT,
62   PROP_COLOR,
63   PROP_XPOS,
64   PROP_YPOS,
65 };
66
67 G_DEFINE_TYPE_WITH_PRIVATE (GESTextOverlayClip, ges_text_overlay_clip,
68     GES_TYPE_OVERLAY_CLIP);
69
70 static GESTrackElement
71     * ges_text_overlay_clip_create_track_element (GESClip * clip,
72     GESTrackType type);
73
74 static void
75 ges_text_overlay_clip_get_property (GObject * object, guint property_id,
76     GValue * value, GParamSpec * pspec)
77 {
78   GESTextOverlayClipPrivate *priv = GES_OVERLAY_TEXT_CLIP (object)->priv;
79
80   switch (property_id) {
81     case PROP_TEXT:
82       g_value_set_string (value, priv->text);
83       break;
84     case PROP_FONT_DESC:
85       g_value_set_string (value, priv->font_desc);
86       break;
87     case PROP_HALIGNMENT:
88       g_value_set_enum (value, priv->halign);
89       break;
90     case PROP_VALIGNMENT:
91       g_value_set_enum (value, priv->valign);
92       break;
93     case PROP_COLOR:
94       g_value_set_uint (value, priv->color);
95       break;
96     case PROP_XPOS:
97       g_value_set_double (value, priv->xpos);
98       break;
99     case PROP_YPOS:
100       g_value_set_double (value, priv->ypos);
101       break;
102     default:
103       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104   }
105 }
106
107 static void
108 ges_text_overlay_clip_set_property (GObject * object, guint property_id,
109     const GValue * value, GParamSpec * pspec)
110 {
111   GESTextOverlayClip *uriclip = GES_OVERLAY_TEXT_CLIP (object);
112
113   switch (property_id) {
114     case PROP_TEXT:
115       ges_text_overlay_clip_set_text (uriclip, g_value_get_string (value));
116       break;
117     case PROP_FONT_DESC:
118       ges_text_overlay_clip_set_font_desc (uriclip, g_value_get_string (value));
119       break;
120     case PROP_HALIGNMENT:
121       ges_text_overlay_clip_set_halign (uriclip, g_value_get_enum (value));
122       break;
123     case PROP_VALIGNMENT:
124       ges_text_overlay_clip_set_valign (uriclip, g_value_get_enum (value));
125       break;
126     case PROP_COLOR:
127       ges_text_overlay_clip_set_color (uriclip, g_value_get_uint (value));
128       break;
129     case PROP_XPOS:
130       ges_text_overlay_clip_set_xpos (uriclip, g_value_get_double (value));
131       break;
132     case PROP_YPOS:
133       ges_text_overlay_clip_set_ypos (uriclip, g_value_get_double (value));
134       break;
135     default:
136       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
137   }
138 }
139
140 static void
141 ges_text_overlay_clip_dispose (GObject * object)
142 {
143   GESTextOverlayClipPrivate *priv = GES_OVERLAY_TEXT_CLIP (object)->priv;
144
145   if (priv->text)
146     g_free (priv->text);
147   if (priv->font_desc)
148     g_free (priv->font_desc);
149
150   G_OBJECT_CLASS (ges_text_overlay_clip_parent_class)->dispose (object);
151 }
152
153 static void
154 ges_text_overlay_clip_class_init (GESTextOverlayClipClass * klass)
155 {
156   GObjectClass *object_class = G_OBJECT_CLASS (klass);
157   GESClipClass *timobj_class = GES_CLIP_CLASS (klass);
158
159   object_class->get_property = ges_text_overlay_clip_get_property;
160   object_class->set_property = ges_text_overlay_clip_set_property;
161   object_class->dispose = ges_text_overlay_clip_dispose;
162
163   /**
164    * GESTextOverlayClip:text:
165    *
166    * The text to diplay
167    */
168
169   g_object_class_install_property (object_class, PROP_TEXT,
170       g_param_spec_string ("text", "Text", "The text to display",
171           DEFAULT_PROP_TEXT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
172
173   /**
174    * GESTextOverlayClip:font-desc:
175    *
176    * Pango font description string
177    */
178
179   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
180       g_param_spec_string ("font-desc", "font description",
181           "Pango font description of font to be used for rendering. "
182           "See documentation of pango_font_description_from_string "
183           "for syntax.", DEFAULT_PROP_FONT_DESC,
184           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
185
186   /**
187    * GESTextOverlayClip:valignment:
188    *
189    * Vertical alignent of the text
190    */
191   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGNMENT,
192       g_param_spec_enum ("valignment", "vertical alignment",
193           "Vertical alignment of the text", GES_TEXT_VALIGN_TYPE,
194           DEFAULT_PROP_VALIGNMENT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
195           G_PARAM_STATIC_STRINGS));
196   /**
197    * GESTextOverlayClip:halignment:
198    *
199    * Horizontal alignment of the text
200    */
201   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGNMENT,
202       g_param_spec_enum ("halignment", "horizontal alignment",
203           "Horizontal alignment of the text",
204           GES_TEXT_HALIGN_TYPE, DEFAULT_PROP_HALIGNMENT,
205           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
206
207   timobj_class->create_track_element =
208       ges_text_overlay_clip_create_track_element;
209
210   /**
211    * GESTextOverlayClip:color:
212    *
213    * The color of the text
214    */
215
216   g_object_class_install_property (object_class, PROP_COLOR,
217       g_param_spec_uint ("color", "Color", "The color of the text",
218           0, G_MAXUINT32, G_MAXUINT32, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
219
220   /**
221    * GESTextOverlayClip:xpos:
222    *
223    * The horizontal position of the text
224    */
225
226   g_object_class_install_property (object_class, PROP_XPOS,
227       g_param_spec_double ("xpos", "Xpos", "The horizontal position",
228           0, 1, 0.5, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
229
230   /**
231    * GESTextOverlayClip:ypos:
232    *
233    * The vertical position of the text
234    */
235
236   g_object_class_install_property (object_class, PROP_YPOS,
237       g_param_spec_double ("ypos", "Ypos", "The vertical position",
238           0, 1, 0.5, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
239 }
240
241 static void
242 ges_text_overlay_clip_init (GESTextOverlayClip * self)
243 {
244   self->priv = ges_text_overlay_clip_get_instance_private (self);
245
246   GES_TIMELINE_ELEMENT (self)->duration = 0;
247   /* Not 100% needed since gobject contents are memzero'd when created */
248   self->priv->text = NULL;
249   self->priv->font_desc = NULL;
250   self->priv->halign = DEFAULT_PROP_HALIGNMENT;
251   self->priv->valign = DEFAULT_PROP_VALIGNMENT;
252   self->priv->color = G_MAXUINT32;
253   self->priv->xpos = 0.5;
254   self->priv->ypos = 0.5;
255 }
256
257 /**
258  * ges_text_overlay_clip_set_text:
259  * @self: the #GESTextOverlayClip* to set text on
260  * @text: the text to render. an internal copy of this text will be
261  * made.
262  *
263  * Sets the text this clip will render.
264  *
265  */
266 void
267 ges_text_overlay_clip_set_text (GESTextOverlayClip * self, const gchar * text)
268 {
269   GList *tmp;
270
271   GST_DEBUG ("self:%p, text:%s", self, text);
272
273   if (self->priv->text)
274     g_free (self->priv->text);
275
276   self->priv->text = g_strdup (text);
277
278   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
279     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
280
281     if (ges_track_element_get_track (trackelement)->type ==
282         GES_TRACK_TYPE_VIDEO)
283       ges_text_overlay_set_text (GES_TEXT_OVERLAY (trackelement),
284           self->priv->text);
285   }
286 }
287
288 /**
289  * ges_text_overlay_clip_set_font_desc:
290  * @self: the #GESTextOverlayClip*
291  * @font_desc: the pango font description
292  *
293  * Sets the pango font description of the text
294  *
295  */
296 void
297 ges_text_overlay_clip_set_font_desc (GESTextOverlayClip * self,
298     const gchar * font_desc)
299 {
300   GList *tmp;
301
302   GST_DEBUG ("self:%p, font_desc:%s", self, font_desc);
303
304   if (self->priv->font_desc)
305     g_free (self->priv->font_desc);
306
307   self->priv->font_desc = g_strdup (font_desc);
308
309   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
310     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
311
312     if (ges_track_element_get_track (trackelement)->type ==
313         GES_TRACK_TYPE_VIDEO)
314       ges_text_overlay_set_font_desc (GES_TEXT_OVERLAY
315           (trackelement), self->priv->font_desc);
316   }
317
318 }
319
320 /**
321  * ges_text_overlay_clip_set_halign:
322  * @self: the #GESTextOverlayClip* to set horizontal alignement of text on
323  * @halign: #GESTextHAlign
324  *
325  * Sets the horizontal aligment of the text.
326  *
327  */
328 void
329 ges_text_overlay_clip_set_halign (GESTextOverlayClip * self,
330     GESTextHAlign halign)
331 {
332   GList *tmp;
333
334   GST_DEBUG ("self:%p, halign:%d", self, halign);
335
336   self->priv->halign = halign;
337
338   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
339     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
340
341     if (ges_track_element_get_track (trackelement)->type ==
342         GES_TRACK_TYPE_VIDEO)
343       ges_text_overlay_set_halignment (GES_TEXT_OVERLAY
344           (trackelement), self->priv->halign);
345   }
346
347 }
348
349 /**
350  * ges_text_overlay_clip_set_valign:
351  * @self: the #GESTextOverlayClip* to set vertical alignement of text on
352  * @valign: #GESTextVAlign
353  *
354  * Sets the vertical aligment of the text.
355  *
356  */
357 void
358 ges_text_overlay_clip_set_valign (GESTextOverlayClip * self,
359     GESTextVAlign valign)
360 {
361   GList *tmp;
362
363   GST_DEBUG ("self:%p, valign:%d", self, valign);
364
365   self->priv->valign = valign;
366
367   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
368     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
369
370     if (ges_track_element_get_track (trackelement)->type ==
371         GES_TRACK_TYPE_VIDEO)
372       ges_text_overlay_set_valignment (GES_TEXT_OVERLAY
373           (trackelement), self->priv->valign);
374   }
375
376 }
377
378 /**
379  * ges_text_overlay_clip_set_color:
380  * @self: the #GESTextOverlayClip* to set
381  * @color: The color @self is being set to
382  *
383  * Sets the color of the text.
384  */
385 void
386 ges_text_overlay_clip_set_color (GESTextOverlayClip * self, guint32 color)
387 {
388   GList *tmp;
389
390   GST_DEBUG ("self:%p, color:%d", self, color);
391
392   self->priv->color = color;
393
394   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
395     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
396
397     if (ges_track_element_get_track (trackelement)->type ==
398         GES_TRACK_TYPE_VIDEO)
399       ges_text_overlay_set_color (GES_TEXT_OVERLAY (trackelement),
400           self->priv->color);
401   }
402 }
403
404 /**
405  * ges_text_overlay_clip_set_xpos:
406  * @self: the #GESTextOverlayClip* to set
407  * @position: The horizontal position @self is being set to
408  *
409  * Sets the horizontal position of the text.
410  */
411 void
412 ges_text_overlay_clip_set_xpos (GESTextOverlayClip * self, gdouble position)
413 {
414   GList *tmp;
415
416   GST_DEBUG ("self:%p, xpos:%f", self, position);
417
418   self->priv->xpos = position;
419
420   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
421     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
422
423     if (ges_track_element_get_track (trackelement)->type ==
424         GES_TRACK_TYPE_VIDEO)
425       ges_text_overlay_set_xpos (GES_TEXT_OVERLAY (trackelement),
426           self->priv->xpos);
427   }
428 }
429
430 /**
431  * ges_text_overlay_clip_set_ypos:
432  * @self: the #GESTextOverlayClip* to set
433  * @position: The vertical position @self is being set to
434  *
435  * Sets the vertical position of the text.
436  */
437 void
438 ges_text_overlay_clip_set_ypos (GESTextOverlayClip * self, gdouble position)
439 {
440   GList *tmp;
441
442   GST_DEBUG ("self:%p, ypos:%f", self, position);
443
444   self->priv->ypos = position;
445
446   for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
447     GESTrackElement *trackelement = (GESTrackElement *) tmp->data;
448
449     if (ges_track_element_get_track (trackelement)->type ==
450         GES_TRACK_TYPE_VIDEO)
451       ges_text_overlay_set_ypos (GES_TEXT_OVERLAY (trackelement),
452           self->priv->ypos);
453   }
454 }
455
456 /**
457  * ges_text_overlay_clip_get_text:
458  * @self: a #GESTextOverlayClip
459  *
460  * Get the text currently set on @self.
461  *
462  * Returns: The text currently set on @self.
463  *
464  */
465 const gchar *
466 ges_text_overlay_clip_get_text (GESTextOverlayClip * self)
467 {
468   return self->priv->text;
469 }
470
471 /**
472  * ges_text_overlay_clip_get_font_desc:
473  * @self: a #GESTextOverlayClip
474  *
475  * Get the pango font description used by @self.
476  *
477  * Returns: The pango font description used by @self.
478  */
479 const char *
480 ges_text_overlay_clip_get_font_desc (GESTextOverlayClip * self)
481 {
482   return self->priv->font_desc;
483 }
484
485 /**
486  * ges_text_overlay_clip_get_halignment:
487  * @self: a #GESTextOverlayClip
488  *
489  * Get the horizontal aligment used by @self.
490  *
491  * Returns: The horizontal aligment used by @self.
492  */
493 GESTextHAlign
494 ges_text_overlay_clip_get_halignment (GESTextOverlayClip * self)
495 {
496   return self->priv->halign;
497 }
498
499 /**
500  * ges_text_overlay_clip_get_valignment:
501  * @self: a #GESTextOverlayClip
502  *
503  * Get the vertical aligment used by @self.
504  *
505  * Returns: The vertical aligment used by @self.
506  */
507 GESTextVAlign
508 ges_text_overlay_clip_get_valignment (GESTextOverlayClip * self)
509 {
510   return self->priv->valign;
511 }
512
513 /**
514  * ges_text_overlay_clip_get_color:
515  * @self: a #GESTextOverlayClip
516  *
517  * Get the color used by @source.
518  *
519  * Returns: The color used by @source.
520  */
521
522 const guint32
523 ges_text_overlay_clip_get_color (GESTextOverlayClip * self)
524 {
525   return self->priv->color;
526 }
527
528 /**
529  * ges_text_overlay_clip_get_xpos:
530  * @self: a #GESTextOverlayClip
531  *
532  * Get the horizontal position used by @source.
533  *
534  * Returns: The horizontal position used by @source.
535  */
536
537 const gdouble
538 ges_text_overlay_clip_get_xpos (GESTextOverlayClip * self)
539 {
540   return self->priv->xpos;
541 }
542
543 /**
544  * ges_text_overlay_clip_get_ypos:
545  * @self: a #GESTextOverlayClip
546  *
547  * Get the vertical position used by @source.
548  *
549  * Returns: The vertical position used by @source.
550  */
551
552 const gdouble
553 ges_text_overlay_clip_get_ypos (GESTextOverlayClip * self)
554 {
555   return self->priv->ypos;
556 }
557
558 static GESTrackElement *
559 ges_text_overlay_clip_create_track_element (GESClip * clip, GESTrackType type)
560 {
561
562   GESTextOverlayClipPrivate *priv = GES_OVERLAY_TEXT_CLIP (clip)->priv;
563   GESTrackElement *res = NULL;
564
565   GST_DEBUG ("Creating a GESTrackOverlay");
566
567   if (type == GES_TRACK_TYPE_VIDEO) {
568     res = (GESTrackElement *) ges_text_overlay_new ();
569     GST_DEBUG ("Setting text property");
570     ges_text_overlay_set_text ((GESTextOverlay *) res, priv->text);
571     ges_text_overlay_set_font_desc ((GESTextOverlay *) res, priv->font_desc);
572     ges_text_overlay_set_halignment ((GESTextOverlay *) res, priv->halign);
573     ges_text_overlay_set_valignment ((GESTextOverlay *) res, priv->valign);
574     ges_text_overlay_set_color ((GESTextOverlay *) res, priv->color);
575     ges_text_overlay_set_xpos ((GESTextOverlay *) res, priv->xpos);
576     ges_text_overlay_set_ypos ((GESTextOverlay *) res, priv->ypos);
577   }
578
579   return res;
580 }
581
582 /**
583  * ges_text_overlay_clip_new:
584  *
585  * Creates a new #GESTextOverlayClip
586  *
587  * Returns: (transfer floating) (nullable): The newly created
588  * #GESTextOverlayClip, or %NULL if there was an error.
589  */
590 GESTextOverlayClip *
591 ges_text_overlay_clip_new (void)
592 {
593   GESTextOverlayClip *new_clip;
594   GESAsset *asset = ges_asset_request (GES_TYPE_OVERLAY_TEXT_CLIP, NULL, NULL);
595
596   new_clip = GES_OVERLAY_TEXT_CLIP (ges_asset_extract (asset, NULL));
597   gst_object_unref (asset);
598
599   return new_clip;
600 }