Пример #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);
}
Пример #2
0
/**
 * gtk_snapshot_pop_and_append:
 * @snapshot: a #GtkSnapshot
 *
 * Removes the top element from the stack of render nodes,
 * and appends it to the node underneath it.
 *
 * Since: 3.90
 */
void
gtk_snapshot_pop_and_append (GtkSnapshot *snapshot)
{
  GskRenderNode *node;

  node = gtk_snapshot_pop (snapshot);
  if (node)
    {
      gtk_snapshot_append_node (snapshot, node);
      gsk_render_node_unref (node);
    }
}
Пример #3
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;
}
Пример #4
0
static void
gtk_render_node_paintable_paintable_snapshot (GdkPaintable *paintable,
                                              GdkSnapshot  *snapshot,
                                              double        width,
                                              double        height)
{
  GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
  gboolean needs_transform;

  needs_transform = self->bounds.size.width != width ||
                    self->bounds.size.height != height;

  if (needs_transform)
    {
      graphene_matrix_t transform;

      graphene_matrix_init_scale (&transform,
                                  width / (self->bounds.size.width),
                                  height / (self->bounds.size.height),
                                  1.0);
      gtk_snapshot_push_transform (snapshot,
                                   &transform);
    }

  gtk_snapshot_offset (snapshot, -self->bounds.origin.x, -self->bounds.origin.y);

  gtk_snapshot_push_clip (snapshot, &self->bounds);

  gtk_snapshot_append_node (snapshot, self->node);
  //gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 0, 0, 1 }, &self->bounds);

  gtk_snapshot_pop (snapshot);

  gtk_snapshot_offset (snapshot, self->bounds.origin.x, self->bounds.origin.y);

  if (needs_transform)
    gtk_snapshot_pop (snapshot);
}
Пример #5
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);
}