Example #1
0
/**
 * gtk_snapshot_append_color_node:
 * @snapshot: a #GtkSnapshot
 * @color: the #GdkRGBA to draw
 * @bounds: the bounds for the new node
 * @name: (transfer none): a printf() style format string for the name for the new node
 * @...: arguments to insert into the format string
 *
 * Creates a new render node drawing the @color into the given @bounds and appends it
 * to the current render node of @snapshot.
 *
 * You should try to avoid calling this function if @color is transparent.
 **/
void
gtk_snapshot_append_color_node (GtkSnapshot           *snapshot,
                                const GdkRGBA         *color,
                                const graphene_rect_t *bounds,
                                const char            *name,
                                ...)
{
  GskRenderNode *node;
  graphene_rect_t real_bounds;

  g_return_if_fail (snapshot != NULL);
  g_return_if_fail (color != NULL);
  g_return_if_fail (bounds != NULL);

  graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds);
  node = gsk_color_node_new (color, &real_bounds);

  if (name)
    {
      va_list args;
      char *str;

      va_start (args, name);
      str = g_strdup_vprintf (name, args);
      va_end (args);

      gsk_render_node_set_name (node, str);

      g_free (str);
    }

  gtk_snapshot_append_node (snapshot, node);
  gsk_render_node_unref (node);
}
Example #2
0
static GskRenderNode *
gtk_snapshot_collect_rounded_clip (GskRenderNode **nodes,
                                   guint           n_nodes,
                                   const char     *name,
                                   gpointer        bounds)
{
  GskRenderNode *node, *clip_node;

  node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
  if (node == NULL)
    return NULL;

  clip_node = gsk_rounded_clip_node_new (node, bounds);
  gsk_render_node_set_name (clip_node, name);

  gsk_render_node_unref (node);
  g_slice_free (GskRoundedRect, bounds);

  return clip_node;
}
Example #3
0
static GskRenderNode *
gtk_snapshot_collect_opacity (GskRenderNode **nodes,
                              guint           n_nodes,
                              const char     *name,
                              gpointer        opacity)
{
  GskRenderNode *node, *opacity_node;

  node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
  if (node == NULL)
    return NULL;

  opacity_node = gsk_opacity_node_new (node, *(double *) opacity);
  gsk_render_node_set_name (opacity_node, name);

  gsk_render_node_unref (node);
  g_free (opacity);

  return opacity_node;
}
Example #4
0
static GskRenderNode *
gtk_snapshot_collect_transform (GskRenderNode **nodes,
                                guint           n_nodes,
                                const char     *name,
                                gpointer        transform)
{
  GskRenderNode *node, *transform_node;

  node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
  if (node == NULL)
    return NULL;

  transform_node = gsk_transform_node_new (node, transform);
  gsk_render_node_set_name (transform_node, name);

  gsk_render_node_unref (node);
  g_slice_free (graphene_matrix_t, transform);

  return transform_node;
}
Example #5
0
static GskRenderNode *
gtk_snapshot_collect_shadow (GskRenderNode **nodes,
                             guint           n_nodes,
                             const char     *name,
                             gpointer        data)
{
  Shadow *shadow = data;
  GskRenderNode *node, *shadow_node;

  node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
  if (node == NULL)
    return NULL;

  shadow_node = gsk_shadow_node_new (node, shadow->shadows, shadow->n_shadows);
  gsk_render_node_set_name (shadow_node, name);

  gsk_render_node_unref (node);
  g_free (shadow);

  return shadow_node;
}
Example #6
0
/**
 * gtk_snapshot_append_cairo_node:
 * @snapshot: a #GtkSnapshot
 * @bounds: the bounds for the new node
 * @name: (transfer none): a printf() style format string for the name for the new node
 * @...: arguments to insert into the format string
 *
 * Creates a new render node and appends it to the current render
 * node of @snapshot, without changing the current node.
 *
 * Returns: a cairo_t suitable for drawing the contents of the newly
 *     created render node
 *
 * Since: 3.90
 */
cairo_t *
gtk_snapshot_append_cairo_node (GtkSnapshot           *snapshot,
                                const graphene_rect_t *bounds,
                                const char            *name,
                                ...)
{
  GskRenderNode *node;
  graphene_rect_t real_bounds;
  cairo_t *cr;

  g_return_val_if_fail (snapshot != NULL, NULL);
  g_return_val_if_fail (bounds != NULL, NULL);

  graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds);
  node = gsk_cairo_node_new (&real_bounds);

  if (name)
    {
      va_list args;
      char *str;

      va_start (args, name);
      str = g_strdup_vprintf (name, args);
      va_end (args);

      gsk_render_node_set_name (node, str);

      g_free (str);
    }

  gtk_snapshot_append_node (snapshot, node);
  gsk_render_node_unref (node);

  cr = gsk_cairo_node_get_draw_context (node, snapshot->renderer);

  cairo_translate (cr, snapshot->state->translate_x, snapshot->state->translate_y);

  return cr;
}
Example #7
0
static GskRenderNode *
gtk_snapshot_collect_default (GskRenderNode **nodes,
                              guint           n_nodes,
                              const char     *name,
                              gpointer        unused)
{
  GskRenderNode *node;

  if (n_nodes == 0)
    {
      node = NULL;
    }
  else if (n_nodes == 1)
    {
      node = gsk_render_node_ref (nodes[0]);
    }
  else
    {
      node = gsk_container_node_new (nodes, n_nodes);
      gsk_render_node_set_name (node, name);
    }

  return node;
}
Example #8
0
static void
gtk_css_image_linear_snapshot (GtkCssImage        *image,
                               GtkSnapshot        *snapshot,
                               double              width,
                               double              height)
{
  GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
  GskColorStop *stops;
  GskRenderNode *node;
  double off_x, off_y; /* snapshot offset */
  double angle; /* actual angle of the gradiant line in degrees */
  double x, y; /* coordinates of start point */
  double length; /* distance in pixels for 100% */
  double start, end; /* position of first/last point on gradient line - with gradient line being [0, 1] */
  double offset;
  int i, last;
  char *name;

  if (linear->side)
    {
      /* special casing the regular cases here so we don't get rounding errors */
      switch (linear->side)
      {
        case 1 << GTK_CSS_RIGHT:
          angle = 90;
          break;
        case 1 << GTK_CSS_LEFT:
          angle = 270;
          break;
        case 1 << GTK_CSS_TOP:
          angle = 0;
          break;
        case 1 << GTK_CSS_BOTTOM:
          angle = 180;
          break;
        default:
          angle = atan2 (linear->side & 1 << GTK_CSS_TOP ? -width : width,
                         linear->side & 1 << GTK_CSS_LEFT ? -height : height);
          angle = 180 * angle / G_PI + 90;
          break;
      }
    }
  else
    {
      angle = _gtk_css_number_value_get (linear->angle, 100);
    }

  gtk_css_image_linear_compute_start_point (angle,
                                            width, height,
                                            &x, &y);

  length = sqrt (x * x + y * y);
  gtk_css_image_linear_get_start_end (linear, length, &start, &end);

  if (start == end)
    {
      /* repeating gradients with all color stops sharing the same offset
       * get the color of the last color stop */
      GtkCssImageLinearColorStop *stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, linear->stops->len - 1);

      gtk_snapshot_append_color_node (snapshot,
                                      _gtk_css_rgba_value_get_rgba (stop->color),
                                      &GRAPHENE_RECT_INIT (0, 0, width, height),
                                      "RepeatingLinearGradient<degenerate>");
      return;
    }

  offset = start;
  last = -1;
  stops = g_newa (GskColorStop, linear->stops->len);

  for (i = 0; i < linear->stops->len; i++)
    {
      GtkCssImageLinearColorStop *stop;
      double pos, step;
      
      stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);

      if (stop->offset == NULL)
        {
          if (i == 0)
            pos = 0.0;
          else if (i + 1 == linear->stops->len)
            pos = 1.0;
          else
            continue;
        }
      else
        pos = _gtk_css_number_value_get (stop->offset, length) / length;

      pos = MAX (pos, offset);
      step = (pos - offset) / (i - last);
      for (last = last + 1; last <= i; last++)
        {
          stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, last);

          offset += step;

          stops[last].offset = (offset - start) / (end - start);
          stops[last].color = *_gtk_css_rgba_value_get_rgba (stop->color);
        }

      offset = pos;
      last = i;
    }

  gtk_snapshot_get_offset (snapshot, &off_x, &off_y);

  if (linear->repeating)
    {
      node = gsk_repeating_linear_gradient_node_new (
          &GRAPHENE_RECT_INIT (off_x, off_y, width, height),
          &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (start - 0.5), off_y + height / 2 + y * (start - 0.5)),
          &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (end - 0.5),   off_y + height / 2 + y * (end - 0.5)),
          stops,
          linear->stops->len);
    }
  else
    {
      node = gsk_linear_gradient_node_new (
          &GRAPHENE_RECT_INIT (off_x, off_y, width, height),
          &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (start - 0.5), off_y + height / 2 + y * (start - 0.5)),
          &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (end - 0.5),   off_y + height / 2 + y * (end - 0.5)),
          stops,
          linear->stops->len);
    }

  name = g_strdup_printf ("%sLinearGradient<%ustops>", linear->repeating ? "Repeating" : "", linear->stops->len);
  gsk_render_node_set_name (node, name);
  g_free (name);

  gtk_snapshot_append_node (snapshot, node);

  gsk_render_node_unref (node);
}