/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2003> David Schleef <ds@schleef.org>
 * Copyright (C) <2009> Young-Ho Cha <ganadist@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */


/**
 * SECTION:element-textrender
 * @title: textrender
 * @see_also: #GstTextOverlay
 *
 * This plugin renders text received on the text sink pad to a video
 * buffer (retaining the alpha channel), so it can later be overlayed
 * on top of video streams using other elements.
 *
 * The text can contain newline characters. (FIXME: What about text
 * wrapping? It does not make sense in this context)
 *
 * ## Example launch lines
 * |[
 * gst-launch-1.0 -v filesrc location=subtitles.srt ! subparse ! textrender ! videoconvert ! autovideosink
 * ]|
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gst/gst.h>
#include <gst/video/video.h>

#include "gsttextrender.h"
#include <string.h>

#if G_BYTE_ORDER == G_LITTLE_ENDIAN
# define CAIRO_ARGB_A 3
# define CAIRO_ARGB_R 2
# define CAIRO_ARGB_G 1
# define CAIRO_ARGB_B 0
#else
# define CAIRO_ARGB_A 0
# define CAIRO_ARGB_R 1
# define CAIRO_ARGB_G 2
# define CAIRO_ARGB_B 3
#endif

GST_DEBUG_CATEGORY_EXTERN (pango_debug);
#define GST_CAT_DEFAULT pango_debug

#define MINIMUM_OUTLINE_OFFSET 1.0

#define DEFAULT_PROP_VALIGNMENT GST_TEXT_RENDER_VALIGN_BASELINE
#define DEFAULT_PROP_HALIGNMENT GST_TEXT_RENDER_HALIGN_CENTER
#define DEFAULT_PROP_LINE_ALIGNMENT GST_TEXT_RENDER_LINE_ALIGN_CENTER
#define DEFAULT_PROP_XPAD       25
#define DEFAULT_PROP_YPAD       25

#define DEFAULT_RENDER_WIDTH 720
#define DEFAULT_RENDER_HEIGHT 576

enum
{
  PROP_0,
  PROP_HALIGNMENT,
  PROP_VALIGNMENT,
  PROP_LINE_ALIGNMENT,
  PROP_XPAD,
  PROP_YPAD,
  PROP_FONT_DESC
};

#define VIDEO_FORMATS "{ AYUV, ARGB } "

static GstStaticPadTemplate src_template_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (VIDEO_FORMATS))
    );

static GstStaticPadTemplate sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("text/x-raw, format = { pango-markup, utf8 }")
    );

#define GST_TYPE_TEXT_RENDER_VALIGN (gst_text_render_valign_get_type())
static GType
gst_text_render_valign_get_type (void)
{
  static GType text_render_valign_type = 0;
  static const GEnumValue text_render_valign[] = {
    {GST_TEXT_RENDER_VALIGN_BASELINE, "baseline", "baseline"},
    {GST_TEXT_RENDER_VALIGN_BOTTOM, "bottom", "bottom"},
    {GST_TEXT_RENDER_VALIGN_TOP, "top", "top"},
    {0, NULL, NULL},
  };

  if (!text_render_valign_type) {
    text_render_valign_type =
        g_enum_register_static ("GstTextRenderVAlign", text_render_valign);
  }
  return text_render_valign_type;
}

#define GST_TYPE_TEXT_RENDER_HALIGN (gst_text_render_halign_get_type())
static GType
gst_text_render_halign_get_type (void)
{
  static GType text_render_halign_type = 0;
  static const GEnumValue text_render_halign[] = {
    {GST_TEXT_RENDER_HALIGN_LEFT, "left", "left"},
    {GST_TEXT_RENDER_HALIGN_CENTER, "center", "center"},
    {GST_TEXT_RENDER_HALIGN_RIGHT, "right", "right"},
    {0, NULL, NULL},
  };

  if (!text_render_halign_type) {
    text_render_halign_type =
        g_enum_register_static ("GstTextRenderHAlign", text_render_halign);
  }
  return text_render_halign_type;
}

#define GST_TYPE_TEXT_RENDER_LINE_ALIGN (gst_text_render_line_align_get_type())
static GType
gst_text_render_line_align_get_type (void)
{
  static GType text_render_line_align_type = 0;
  static const GEnumValue text_render_line_align[] = {
    {GST_TEXT_RENDER_LINE_ALIGN_LEFT, "left", "left"},
    {GST_TEXT_RENDER_LINE_ALIGN_CENTER, "center", "center"},
    {GST_TEXT_RENDER_LINE_ALIGN_RIGHT, "right", "right"},
    {0, NULL, NULL}
  };

  if (!text_render_line_align_type) {
    text_render_line_align_type =
        g_enum_register_static ("GstTextRenderLineAlign",
        text_render_line_align);
  }
  return text_render_line_align_type;
}

static void gst_text_render_adjust_values_with_fontdesc (GstTextRender *
    render, PangoFontDescription * desc);

#define gst_text_render_parent_class parent_class
G_DEFINE_TYPE (GstTextRender, gst_text_render, GST_TYPE_ELEMENT);

static void gst_text_render_finalize (GObject * object);
static void gst_text_render_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_text_render_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static void
gst_text_render_class_init (GstTextRenderClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  PangoFontMap *fontmap;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_text_render_finalize;
  gobject_class->set_property = gst_text_render_set_property;
  gobject_class->get_property = gst_text_render_get_property;

  gst_element_class_add_static_pad_template (gstelement_class,
      &src_template_factory);
  gst_element_class_add_static_pad_template (gstelement_class,
      &sink_template_factory);

  gst_element_class_set_static_metadata (gstelement_class, "Text renderer",
      "Filter/Editor/Video",
      "Renders a text string to an image bitmap",
      "David Schleef <ds@schleef.org>, "
      "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");

  fontmap = pango_cairo_font_map_get_default ();
  klass->pango_context =
      pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
      g_param_spec_string ("font-desc", "font description",
          "Pango font description of font "
          "to be used for rendering. "
          "See documentation of "
          "pango_font_description_from_string"
          " for syntax.", "", G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VALIGNMENT,
      g_param_spec_enum ("valignment", "vertical alignment",
          "Vertical alignment of the text", GST_TYPE_TEXT_RENDER_VALIGN,
          DEFAULT_PROP_VALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HALIGNMENT,
      g_param_spec_enum ("halignment", "horizontal alignment",
          "Horizontal alignment of the text", GST_TYPE_TEXT_RENDER_HALIGN,
          DEFAULT_PROP_HALIGNMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_XPAD,
      g_param_spec_int ("xpad", "horizontal paddding",
          "Horizontal paddding when using left/right alignment", 0, G_MAXINT,
          DEFAULT_PROP_XPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_YPAD,
      g_param_spec_int ("ypad", "vertical padding",
          "Vertical padding when using top/bottom alignment", 0, G_MAXINT,
          DEFAULT_PROP_YPAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LINE_ALIGNMENT,
      g_param_spec_enum ("line-alignment", "line alignment",
          "Alignment of text lines relative to each other.",
          GST_TYPE_TEXT_RENDER_LINE_ALIGN, DEFAULT_PROP_LINE_ALIGNMENT,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_text_render_adjust_values_with_fontdesc (GstTextRender * render,
    PangoFontDescription * desc)
{
  gint font_size = pango_font_description_get_size (desc) / PANGO_SCALE;

  render->shadow_offset = (double) (font_size) / 13.0;
  render->outline_offset = (double) (font_size) / 15.0;
  if (render->outline_offset < MINIMUM_OUTLINE_OFFSET)
    render->outline_offset = MINIMUM_OUTLINE_OFFSET;
}

static void
gst_text_render_render_pangocairo (GstTextRender * render)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  cairo_t *cr_shadow;
  cairo_surface_t *surface_shadow;
  PangoRectangle ink_rect, logical_rect;
  gint width, height;

  pango_layout_get_pixel_extents (render->layout, &ink_rect, &logical_rect);

  width = logical_rect.width + render->shadow_offset;
  height = logical_rect.height + logical_rect.y + render->shadow_offset;

  surface_shadow = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
  cr_shadow = cairo_create (surface_shadow);

  /* clear shadow surface */
  cairo_set_operator (cr_shadow, CAIRO_OPERATOR_CLEAR);
  cairo_paint (cr_shadow);
  cairo_set_operator (cr_shadow, CAIRO_OPERATOR_OVER);

  /* draw shadow text */
  cairo_save (cr_shadow);
  cairo_set_source_rgba (cr_shadow, 0.0, 0.0, 0.0, 0.5);
  cairo_translate (cr_shadow, render->shadow_offset, render->shadow_offset);
  pango_cairo_show_layout (cr_shadow, render->layout);
  cairo_restore (cr_shadow);

  /* draw outline text */
  cairo_save (cr_shadow);
  cairo_set_source_rgb (cr_shadow, 0.0, 0.0, 0.0);
  cairo_set_line_width (cr_shadow, render->outline_offset);
  pango_cairo_layout_path (cr_shadow, render->layout);
  cairo_stroke (cr_shadow);
  cairo_restore (cr_shadow);

  cairo_destroy (cr_shadow);

  render->text_image = g_realloc (render->text_image, 4 * width * height);

  surface = cairo_image_surface_create_for_data (render->text_image,
      CAIRO_FORMAT_ARGB32, width, height, width * 4);
  cr = cairo_create (surface);
  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
  cairo_paint (cr);
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

  /* set default color */
  cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);

  cairo_save (cr);
  /* draw text */
  pango_cairo_show_layout (cr, render->layout);
  cairo_restore (cr);

  /* composite shadow with offset */
  cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
  cairo_set_source_surface (cr, surface_shadow, 0.0, 0.0);
  cairo_paint (cr);

  cairo_destroy (cr);
  cairo_surface_destroy (surface_shadow);
  cairo_surface_destroy (surface);
  render->image_width = width;
  render->image_height = height;
}

static void
gst_text_render_check_argb (GstTextRender * render)
{
  GstCaps *peer_caps;
  peer_caps = gst_pad_get_allowed_caps (render->srcpad);
  if (G_LIKELY (peer_caps)) {
    guint i = 0, n = 0;

    n = gst_caps_get_size (peer_caps);
    GST_DEBUG_OBJECT (render, "peer allowed caps (%u structure(s)) are %"
        GST_PTR_FORMAT, n, peer_caps);

    /* Check if AYUV or ARGB is first */
    for (i = 0; i < n; i++) {
      GstStructure *s;
      GstVideoFormat vformat;
      const GstVideoFormatInfo *info;
      const gchar *fmt;

      s = gst_caps_get_structure (peer_caps, i);
      if (!gst_structure_has_name (s, "video/x-raw"))
        continue;

      fmt = gst_structure_get_string (s, "format");
      if (fmt == NULL)
        continue;

      vformat = gst_video_format_from_string (fmt);
      info = gst_video_format_get_info (vformat);
      if (info == NULL)
        continue;

      render->use_ARGB = GST_VIDEO_FORMAT_INFO_HAS_ALPHA (info);
    }
    gst_caps_unref (peer_caps);
  }
}

static gboolean
gst_text_render_src_setcaps (GstTextRender * render, GstCaps * caps)
{
  GstStructure *structure;
  gboolean ret;
  gint width = 0, height = 0;

  structure = gst_caps_get_structure (caps, 0);
  gst_structure_get_int (structure, "width", &width);
  gst_structure_get_int (structure, "height", &height);

  GST_DEBUG_OBJECT (render, "Got caps %" GST_PTR_FORMAT, caps);

  if (width >= render->image_width && height >= render->image_height) {
    render->width = width;
    render->height = height;
  }

  gst_text_render_check_argb (render);

  ret = gst_pad_set_caps (render->srcpad, caps);

  return ret;
}

static GstCaps *
gst_text_render_fixate_caps (GstTextRender * render, GstCaps * caps)
{
  GstStructure *s;

  caps = gst_caps_truncate (caps);

  caps = gst_caps_make_writable (caps);
  s = gst_caps_get_structure (caps, 0);

  GST_DEBUG ("Fixating caps %" GST_PTR_FORMAT, caps);
  gst_structure_fixate_field_nearest_int (s, "width", MAX (render->image_width,
          DEFAULT_RENDER_WIDTH));
  gst_structure_fixate_field_nearest_int (s, "height",
      MAX (render->image_height + render->ypad, DEFAULT_RENDER_HEIGHT));
  caps = gst_caps_fixate (caps);
  GST_DEBUG ("Fixated to    %" GST_PTR_FORMAT, caps);

  return caps;
}

#define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
  b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
  g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
  r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
} G_STMT_END

static void
gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf,
    int xpos, int ypos, int stride)
{
  int y;                        /* text bitmap coordinates */
  guchar *p, *bitp;
  guchar a, r, g, b;
  int width, height;

  width = render->image_width;
  height = render->image_height;

  for (y = 0; y < height && ypos + y < render->height; y++) {
    int n;
    p = pixbuf + (ypos + y) * stride + xpos * 4;
    bitp = render->text_image + y * width * 4;
    for (n = 0; n < width && n < render->width; n++) {
      b = bitp[CAIRO_ARGB_B];
      g = bitp[CAIRO_ARGB_G];
      r = bitp[CAIRO_ARGB_R];
      a = bitp[CAIRO_ARGB_A];
      bitp += 4;

      /* Cairo uses pre-multiplied ARGB, unpremultiply it */
      CAIRO_UNPREMULTIPLY (a, r, g, b);

      *p++ = a;
      *p++ = CLAMP ((int) (((19595 * r) >> 16) + ((38470 * g) >> 16) +
              ((7471 * b) >> 16)), 0, 255);
      *p++ = CLAMP ((int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) +
              ((32768 * b) >> 16) + 128), 0, 255);
      *p++ = CLAMP ((int) (((32768 * r) >> 16) - ((27439 * g) >> 16) -
              ((5329 * b) >> 16) + 128), 0, 255);
    }
  }
}

static void
gst_text_renderer_image_to_argb (GstTextRender * render, guchar * pixbuf,
    int xpos, int ypos, int stride)
{
  int i, j;
  guchar *p, *bitp;
  int width, height;

  width = render->image_width;
  height = render->image_height;

  for (i = 0; i < height && ypos + i < render->height; i++) {
    p = pixbuf + (ypos + i) * stride + xpos * 4;
    bitp = render->text_image + i * width * 4;
    for (j = 0; j < width && j < render->width; j++) {
      p[0] = bitp[CAIRO_ARGB_A];
      p[1] = bitp[CAIRO_ARGB_R];
      p[2] = bitp[CAIRO_ARGB_G];
      p[3] = bitp[CAIRO_ARGB_B];

      /* Cairo uses pre-multiplied ARGB, unpremultiply it */
      CAIRO_UNPREMULTIPLY (p[0], p[1], p[2], p[3]);

      bitp += 4;
      p += 4;
    }
  }
}

static GstFlowReturn
gst_text_render_chain (GstPad * pad, GstObject * parent, GstBuffer * inbuf)
{
  GstTextRender *render;
  GstFlowReturn ret;
  GstBuffer *outbuf;
  GstCaps *caps = NULL, *padcaps;
  GstMapInfo map;
  guint8 *data;
  gsize size;
  gint n;
  gint xpos, ypos;

  render = GST_TEXT_RENDER (parent);

  gst_buffer_map (inbuf, &map, GST_MAP_READ);
  data = map.data;
  size = map.size;

  /* somehow pango barfs over "\0" buffers... */
  while (size > 0 &&
      (data[size - 1] == '\r' ||
          data[size - 1] == '\n' || data[size - 1] == '\0')) {
    size--;
  }

  /* render text */
  GST_DEBUG ("rendering '%*s'", (gint) size, data);
  pango_layout_set_markup (render->layout, (gchar *) data, size);
  gst_text_render_render_pangocairo (render);
  gst_buffer_unmap (inbuf, &map);

  gst_text_render_check_argb (render);

  padcaps = gst_pad_query_caps (render->srcpad, NULL);
  caps = gst_pad_peer_query_caps (render->srcpad, padcaps);
  gst_caps_unref (padcaps);

  if (!caps || gst_caps_is_empty (caps)) {
    GST_ELEMENT_ERROR (render, CORE, NEGOTIATION, (NULL), (NULL));
    ret = GST_FLOW_ERROR;
    goto done;
  }

  caps = gst_text_render_fixate_caps (render, caps);

  if (!gst_text_render_src_setcaps (render, caps)) {
    GST_ELEMENT_ERROR (render, CORE, NEGOTIATION, (NULL), (NULL));
    ret = GST_FLOW_ERROR;
    goto done;
  }

  if (render->segment_event) {
    gst_pad_push_event (render->srcpad, render->segment_event);
    render->segment_event = NULL;
  }

  GST_DEBUG ("Allocating buffer WxH = %dx%d", render->width, render->height);
  outbuf = gst_buffer_new_and_alloc (render->width * render->height * 4);

  gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1);

  gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
  data = map.data;
  size = map.size;

  if (render->use_ARGB) {
    memset (data, 0, render->width * render->height * 4);
  } else {
    for (n = 0; n < render->width * render->height; n++) {
      data[n * 4] = data[n * 4 + 1] = 0;
      data[n * 4 + 2] = data[n * 4 + 3] = 128;
    }
  }

  switch (render->halign) {
    case GST_TEXT_RENDER_HALIGN_LEFT:
      xpos = render->xpad;
      break;
    case GST_TEXT_RENDER_HALIGN_CENTER:
      xpos = (render->width - render->image_width) / 2;
      break;
    case GST_TEXT_RENDER_HALIGN_RIGHT:
      xpos = render->width - render->image_width - render->xpad;
      break;
    default:
      xpos = 0;
  }

  switch (render->valign) {
    case GST_TEXT_RENDER_VALIGN_BOTTOM:
      ypos = render->height - render->image_height - render->ypad;
      break;
    case GST_TEXT_RENDER_VALIGN_BASELINE:
      ypos = render->height - (render->image_height + render->ypad);
      break;
    case GST_TEXT_RENDER_VALIGN_TOP:
      ypos = render->ypad;
      break;
    default:
      ypos = render->ypad;
      break;
  }

  if (render->text_image) {
    if (render->use_ARGB) {
      gst_text_renderer_image_to_argb (render, data, xpos, ypos,
          render->width * 4);
    } else {
      gst_text_renderer_image_to_ayuv (render, data, xpos, ypos,
          render->width * 4);
    }
  }
  gst_buffer_unmap (outbuf, &map);

  ret = gst_pad_push (render->srcpad, outbuf);

done:
  if (caps)
    gst_caps_unref (caps);
  gst_buffer_unref (inbuf);

  return ret;
}

static gboolean
gst_text_render_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstTextRender *render = GST_TEXT_RENDER (parent);
  gboolean ret = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
    {
      if (gst_pad_has_current_caps (render->srcpad)) {
        ret = gst_pad_push_event (render->srcpad, event);
      } else {
        gst_event_replace (&render->segment_event, event);
        gst_event_unref (event);
      }
      break;
    }
    default:
      ret = gst_pad_push_event (render->srcpad, event);
      break;
  }

  return ret;
}

static void
gst_text_render_finalize (GObject * object)
{
  GstTextRender *render = GST_TEXT_RENDER (object);

  gst_event_replace (&render->segment_event, NULL);

  g_free (render->text_image);

  if (render->layout)
    g_object_unref (render->layout);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_text_render_init (GstTextRender * render)
{
  GstPadTemplate *template;

  /* sink */
  template = gst_static_pad_template_get (&sink_template_factory);
  render->sinkpad = gst_pad_new_from_template (template, "sink");
  gst_object_unref (template);
  gst_pad_set_chain_function (render->sinkpad,
      GST_DEBUG_FUNCPTR (gst_text_render_chain));
  gst_pad_set_event_function (render->sinkpad,
      GST_DEBUG_FUNCPTR (gst_text_render_event));

  gst_element_add_pad (GST_ELEMENT (render), render->sinkpad);

  /* source */
  template = gst_static_pad_template_get (&src_template_factory);
  render->srcpad = gst_pad_new_from_template (template, "src");
  gst_object_unref (template);

  gst_element_add_pad (GST_ELEMENT (render), render->srcpad);

  render->line_align = DEFAULT_PROP_LINE_ALIGNMENT;
  render->layout =
      pango_layout_new (GST_TEXT_RENDER_GET_CLASS (render)->pango_context);
  pango_layout_set_alignment (render->layout,
      (PangoAlignment) render->line_align);

  render->halign = DEFAULT_PROP_HALIGNMENT;
  render->valign = DEFAULT_PROP_VALIGNMENT;
  render->xpad = DEFAULT_PROP_XPAD;
  render->ypad = DEFAULT_PROP_YPAD;

  render->width = DEFAULT_RENDER_WIDTH;
  render->height = DEFAULT_RENDER_HEIGHT;

  render->use_ARGB = FALSE;
}

static void
gst_text_render_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTextRender *render = GST_TEXT_RENDER (object);

  switch (prop_id) {
    case PROP_VALIGNMENT:
      render->valign = g_value_get_enum (value);
      break;
    case PROP_HALIGNMENT:
      render->halign = g_value_get_enum (value);
      break;
    case PROP_LINE_ALIGNMENT:
      render->line_align = g_value_get_enum (value);
      pango_layout_set_alignment (render->layout,
          (PangoAlignment) render->line_align);
      break;
    case PROP_XPAD:
      render->xpad = g_value_get_int (value);
      break;
    case PROP_YPAD:
      render->ypad = g_value_get_int (value);
      break;
    case PROP_FONT_DESC:
    {
      PangoFontDescription *desc;

      desc = pango_font_description_from_string (g_value_get_string (value));
      if (desc) {
        GST_LOG ("font description set: %s", g_value_get_string (value));
        GST_OBJECT_LOCK (render);
        pango_layout_set_font_description (render->layout, desc);
        gst_text_render_adjust_values_with_fontdesc (render, desc);
        pango_font_description_free (desc);
        gst_text_render_render_pangocairo (render);
        GST_OBJECT_UNLOCK (render);
      } else {
        GST_WARNING ("font description parse failed: %s",
            g_value_get_string (value));
      }
      break;
    }

    default:
      break;
  }
}

static void
gst_text_render_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTextRender *render = GST_TEXT_RENDER (object);

  switch (prop_id) {
    case PROP_VALIGNMENT:
      g_value_set_enum (value, render->valign);
      break;
    case PROP_HALIGNMENT:
      g_value_set_enum (value, render->halign);
      break;
    case PROP_LINE_ALIGNMENT:
      g_value_set_enum (value, render->line_align);
      break;
    case PROP_XPAD:
      g_value_set_int (value, render->xpad);
      break;
    case PROP_YPAD:
      g_value_set_int (value, render->ypad);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
