示例#1
0
文件: st-icon.c 项目: Ak-/Cinnamon
static void
st_icon_paint (ClutterActor *actor)
{
  StIconPrivate *priv = ST_ICON (actor)->priv;

  /* Chain up to paint background */
  CLUTTER_ACTOR_CLASS (st_icon_parent_class)->paint (actor);

  if (priv->icon_texture)
    {
      if (priv->shadow_material)
        {
          ClutterActorBox allocation;
          float width, height;

          clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
          clutter_actor_box_get_size (&allocation, &width, &height);

          allocation.x1 = (width - priv->shadow_width) / 2;
          allocation.y1 = (height - priv->shadow_height) / 2;
          allocation.x2 = allocation.x1 + priv->shadow_width;
          allocation.y2 = allocation.y1 + priv->shadow_height;

          _st_paint_shadow_with_opacity (priv->shadow_spec,
                                         priv->shadow_material,
                                         &allocation,
                                         clutter_actor_get_paint_opacity (priv->icon_texture));
        }

      clutter_actor_paint (priv->icon_texture);
    }
}
示例#2
0
static void
clutter_box_real_paint (ClutterActor *actor)
{
  ClutterBoxPrivate *priv = CLUTTER_BOX (actor)->priv;

  if (priv->color_set)
    {
      ClutterActorBox box = { 0, };
      gfloat width, height;
      guint8 tmp_alpha;

      clutter_actor_get_allocation_box (actor, &box);
      clutter_actor_box_get_size (&box, &width, &height);

      tmp_alpha = clutter_actor_get_paint_opacity (actor)
                * priv->color.alpha
                / 255;

      cogl_set_source_color4ub (priv->color.red,
                                priv->color.green,
                                priv->color.blue,
                                tmp_alpha);

      cogl_rectangle (0, 0, width, height);
    }

  g_list_foreach (priv->children, (GFunc) clutter_actor_paint, NULL);
}
示例#3
0
static void
empathy_rounded_effect_paint (ClutterEffect *effect,
    ClutterEffectPaintFlags flags)
{
  EmpathyRoundedEffect *self = EMPATHY_ROUNDED_EFFECT (effect);
  ClutterActor *actor;
  ClutterActorBox allocation = { 0, };
  gfloat width, height;

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (self));
  clutter_actor_get_allocation_box (actor, &allocation);
  clutter_actor_box_get_size (&allocation, &width, &height);

  cogl_path_new ();

  /* Create and store a path describing a rounded rectangle. The small
   * size of the preview window makes the radius of the rounded corners
   * very small too, so we can safely use a very coarse angle step
   * without loosing rendering accuracy. It also significantly reduces
   * the time spent in the underlying internal cogl path functions */
  cogl_path_round_rectangle (0, 0, width, height, height / 16., 15);

  cogl_clip_push_from_path ();

  /* Flip */
  cogl_push_matrix ();
  cogl_translate (width, 0, 0);
  cogl_scale (-1, 1, 1);

  clutter_actor_continue_paint (actor);

  cogl_pop_matrix ();
  cogl_clip_pop ();
}
示例#4
0
void clarity_cover_set_album_item (ClarityCover *self, AlbumItem *item) {
    g_return_if_fail(CLARITY_IS_COVER(self));

    ClarityCoverPrivate *priv = CLARITY_COVER_GET_PRIVATE (self);
    g_return_if_fail(priv);

    GError *error = NULL;
    gint y_offset;

    if (!priv->texture) {
        priv->texture = gtk_clutter_texture_new();
        clutter_container_add_actor(CLUTTER_CONTAINER(self), priv->texture);
    }

    // Set cover artwork
    gtk_clutter_texture_set_from_pixbuf (GTK_CLUTTER_TEXTURE(priv->texture), item->albumart, &error);
    if (error) {
        g_warning("%s", error->message);
        g_error_free(error);
        return;
    }

    // Add reflection
    if (! priv->reflection) {
        y_offset = clutter_actor_get_height (priv->texture) + V_PADDING;

        priv->reflection = clutter_clone_new (priv->texture);
        clutter_actor_add_constraint (priv->reflection, clutter_bind_constraint_new (priv->texture, CLUTTER_BIND_X, 0.0));
        clutter_actor_add_constraint (priv->reflection, clutter_bind_constraint_new (priv->texture, CLUTTER_BIND_Y, y_offset));
        clutter_actor_add_constraint (priv->reflection, clutter_bind_constraint_new (priv->texture, CLUTTER_BIND_WIDTH, 0.0));
        clutter_actor_add_constraint (priv->reflection, clutter_bind_constraint_new (priv->texture, CLUTTER_BIND_HEIGHT, 0.0));
        g_signal_connect (priv->reflection,
                       "paint",
                       G_CALLBACK (_clone_paint_cb),
                       NULL);

        clutter_container_add_actor(CLUTTER_CONTAINER(self), priv->reflection);
    }

    ClutterActorBox box;
    gfloat w, h;
    clutter_actor_get_allocation_box (priv->texture, &box);
    clutter_actor_box_get_size (&box, &w, &h);

    if( h > DEFAULT_IMG_SIZE) {
        gfloat temp = w * DEFAULT_IMG_SIZE / h;
        clutter_actor_set_size(priv->texture, temp, DEFAULT_IMG_SIZE);
    }

    // Add title / artist data
    if (priv->title)
        g_free(priv->title);

    priv->title = g_strdup(item->albumname);

    if (priv->artist)
            g_free(priv->artist);

    priv->artist = g_strdup(item->artist);
}
示例#5
0
static void
clutter_path_constraint_update_allocation (ClutterConstraint *constraint,
                                           ClutterActor      *actor,
                                           ClutterActorBox   *allocation)
{
  ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (constraint);
  gfloat width, height;
  ClutterKnot position;
  guint knot_id;

  if (self->path == NULL)
    return;

  knot_id = clutter_path_get_position (self->path, self->offset, &position);
  clutter_actor_box_get_size (allocation, &width, &height);
  allocation->x1 = position.x;
  allocation->y1 = position.y;
  allocation->x2 = allocation->x1 + width;
  allocation->y2 = allocation->y1 + height;

  if (knot_id != self->current_node)
    {
      self->current_node = knot_id;
      g_signal_emit (self, path_signals[NODE_REACHED], 0,
                     self->actor,
                     self->current_node);
    }
}
示例#6
0
static void
st_icon_paint (ClutterActor *actor)
{
  StIconPrivate *priv = ST_ICON (actor)->priv;

  st_widget_paint_background (ST_WIDGET (actor));

  if (priv->icon_texture)
    {
      if (priv->shadow_material)
        {
          ClutterActorBox allocation;
          float width, height;

          clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
          clutter_actor_box_get_size (&allocation, &width, &height);

          _st_paint_shadow_with_opacity (priv->shadow_spec,
                                         priv->shadow_material,
                                         &allocation,
                                         clutter_actor_get_paint_opacity (priv->icon_texture));
        }

      clutter_actor_paint (priv->icon_texture);
    }
}
示例#7
0
CoglHandle
_st_create_shadow_material_from_actor (StShadow     *shadow_spec,
                                       ClutterActor *actor)
{
  CoglHandle shadow_material = COGL_INVALID_HANDLE;

  if (CLUTTER_IS_TEXTURE (actor))
    {
      CoglHandle texture;

      texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));
      shadow_material = _st_create_shadow_material (shadow_spec, texture);
    }
  else
    {
      CoglHandle buffer, offscreen;
      ClutterActorBox box;
      CoglColor clear_color;
      float width, height;

      clutter_actor_get_allocation_box (actor, &box);
      clutter_actor_box_get_size (&box, &width, &height);

      if (width == 0 || height == 0)
        return COGL_INVALID_HANDLE;

      buffer = st_cogl_texture_new_with_size_wrapper (width, height,
                                                      COGL_TEXTURE_NO_SLICING,
                                                      COGL_PIXEL_FORMAT_ANY);

      if (buffer == COGL_INVALID_HANDLE)
        return COGL_INVALID_HANDLE;

      offscreen = cogl_offscreen_new_to_texture (buffer);

      if (offscreen == COGL_INVALID_HANDLE)
        {
          cogl_handle_unref (buffer);
          return COGL_INVALID_HANDLE;
        }

      cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
      cogl_push_framebuffer (offscreen);
      cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
      cogl_translate (-box.x1, -box.y1, 0);
      cogl_ortho (0, width, height, 0, 0, 1.0);
      clutter_actor_paint (actor);
      cogl_pop_framebuffer ();
      cogl_handle_unref (offscreen);

      shadow_material = _st_create_shadow_material (shadow_spec, buffer);

      cogl_handle_unref (buffer);
    }

  return shadow_material;
}
示例#8
0
/* Allocate position and size of actor and its children */
static void _xfdashboard_live_workspace_allocate(ClutterActor *self,
												const ClutterActorBox *inBox,
												ClutterAllocationFlags inFlags)
{
	XfdashboardLiveWorkspacePrivate		*priv=XFDASHBOARD_LIVE_WORKSPACE(self)->priv;
	gfloat								availableWidth, availableHeight;
	gfloat								workspaceWidth, workspaceHeight;
	ClutterContent						*content;
	XfdashboardWindowTrackerWindow		*window;
	gint								x, y, w, h;
	ClutterActor						*child;
	ClutterActorIter					iter;
	ClutterActorBox						childAllocation={ 0, };

	/* Chain up to store the allocation of the actor */
	CLUTTER_ACTOR_CLASS(xfdashboard_live_workspace_parent_class)->allocate(self, inBox, inFlags);

	/* If we handle no workspace to not set allocation of children */
	if(!priv->workspace) return;

	/* Get size of workspace and this allocation as it is needed
	 * to calculate translated position and size
	 */
	clutter_actor_box_get_size(inBox, &availableWidth, &availableHeight);

	workspaceWidth=(gfloat)xfdashboard_window_tracker_workspace_get_width(priv->workspace);
	workspaceHeight=(gfloat)xfdashboard_window_tracker_workspace_get_height(priv->workspace);

	/* Iterate through window actors, calculate translated allocation of
	 * position and size to available size of this actor
	 */
	clutter_actor_iter_init(&iter, self);
	while(clutter_actor_iter_next(&iter, &child))
	{
		/* Get window actor */
		if(!CLUTTER_IS_ACTOR(child)) continue;

		/* Get associated window */
		content=clutter_actor_get_content(child);
		if(!content || !XFDASHBOARD_IS_WINDOW_CONTENT(content)) continue;

		window=xfdashboard_window_content_get_window(XFDASHBOARD_WINDOW_CONTENT(content));
		if(!window) continue;

		/* Get real size of child */
		xfdashboard_window_tracker_window_get_position_size(window, &x, &y, &w, &h);

		/* Calculate translated position and size of child */
		childAllocation.x1=ceil((x/workspaceWidth)*availableWidth);
		childAllocation.y1=ceil((y/workspaceHeight)*availableHeight);
		childAllocation.x2=childAllocation.x1+ceil((w/workspaceWidth)*availableWidth);
		childAllocation.y2=childAllocation.y1+ceil((h/workspaceHeight)*availableHeight);

		/* Set allocation of child */
		clutter_actor_allocate(child, &childAllocation, inFlags);
	}
}
示例#9
0
static void
st_box_layout_allocate (ClutterActor          *actor,
                        const ClutterActorBox *box,
                        ClutterAllocationFlags flags)
{
  StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (actor)->priv;
  StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
  ClutterLayoutManager *layout = clutter_actor_get_layout_manager (actor);
  ClutterActorBox content_box;
  gfloat avail_width, avail_height, min_width, natural_width, min_height, natural_height;

  CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->allocate (actor, box, flags);

  st_theme_node_get_content_box (theme_node, box, &content_box);
  clutter_actor_box_get_size (&content_box, &avail_width, &avail_height);

  clutter_layout_manager_get_preferred_width (layout, CLUTTER_CONTAINER (actor),
                                              avail_height,
                                              &min_width, &natural_width);
  clutter_layout_manager_get_preferred_height (layout, CLUTTER_CONTAINER (actor),
                                               MAX (avail_width, min_width),
                                               &min_height, &natural_height);


  /* update adjustments for scrolling */
  if (priv->vadjustment)
    {
      gdouble prev_value;

      g_object_set (G_OBJECT (priv->vadjustment),
                    "lower", 0.0,
                    "upper", MAX (min_height, avail_height),
                    "page-size", avail_height,
                    "step-increment", avail_height / 6,
                    "page-increment", avail_height - avail_height / 6,
                    NULL);

      prev_value = st_adjustment_get_value (priv->vadjustment);
      st_adjustment_set_value (priv->vadjustment, prev_value);
    }

  if (priv->hadjustment)
    {
      gdouble prev_value;

      g_object_set (G_OBJECT (priv->hadjustment),
                    "lower", 0.0,
                    "upper", MAX (min_width, avail_width),
                    "page-size", avail_width,
                    "step-increment", avail_width / 6,
                    "page-increment", avail_width - avail_width / 6,
                    NULL);

      prev_value = st_adjustment_get_value (priv->hadjustment);
      st_adjustment_set_value (priv->hadjustment, prev_value);
    }
}
示例#10
0
static void
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
                                           ClutterActor      *actor,
                                           ClutterActorBox   *allocation)
{
  ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
  gfloat source_width, source_height;
  gfloat actor_width, actor_height;
  ClutterVertex source_position = { 0., };

  if (bind->source == NULL)
    return;

  source_position.x = clutter_actor_get_x (bind->source);
  source_position.y = clutter_actor_get_y (bind->source);
  clutter_actor_get_size (bind->source, &source_width, &source_height);

  clutter_actor_box_get_size (allocation, &actor_width, &actor_height);

  switch (bind->coordinate)
    {
    case CLUTTER_BIND_X:
      allocation->x1 = source_position.x + bind->offset;
      allocation->x2 = allocation->x1 + actor_width;
      break;

    case CLUTTER_BIND_Y:
      allocation->y1 = source_position.y + bind->offset;
      allocation->y2 = allocation->y1 + actor_height;
      break;

    case CLUTTER_BIND_POSITION:
      allocation->x1 = source_position.x + bind->offset;
      allocation->y1 = source_position.y + bind->offset;
      allocation->x2 = allocation->x1 + actor_width;
      allocation->y2 = allocation->y1 + actor_height;
      break;

    case CLUTTER_BIND_WIDTH:
      allocation->x2 = allocation->x1 + source_width + bind->offset;
      break;

    case CLUTTER_BIND_HEIGHT:
      allocation->y2 = allocation->y1 + source_height + bind->offset;
      break;

    case CLUTTER_BIND_SIZE:
      allocation->x2 = allocation->x1 + source_width + bind->offset;
      allocation->y2 = allocation->y1 + source_height + bind->offset;
      break;

    default:
      g_assert_not_reached ();
      break;
    }
}
示例#11
0
static void
stage_allocation_changed_cb (ClutterActor           *stage,
                             const ClutterActorBox  *allocation,
                             ClutterAllocationFlags  flags,
                             ClutterActor           *box)
{
    gfloat width, height;

    clutter_actor_box_get_size (allocation, &width, &height);

    clutter_actor_set_size (box, width, height);
}
示例#12
0
/* Allocate position and size of actor and its children */
static void _xfdashboard_workspace_selector_allocate(ClutterActor *inActor,
														const ClutterActorBox *inBox,
														ClutterAllocationFlags inFlags)
{
	XfdashboardWorkspaceSelector			*self=XFDASHBOARD_WORKSPACE_SELECTOR(inActor);
	XfdashboardWorkspaceSelectorPrivate		*priv=self->priv;
	gfloat									availableWidth, availableHeight;
	gfloat									childWidth, childHeight;
	ClutterActor							*child;
	ClutterActorIter						iter;
	ClutterActorBox							childAllocation={ 0, };

	/* Chain up to store the allocation of the actor */
	CLUTTER_ACTOR_CLASS(xfdashboard_workspace_selector_parent_class)->allocate(inActor, inBox, inFlags);

	/* Get available size */
	clutter_actor_box_get_size(inBox, &availableWidth, &availableHeight);

	/* Calculate new position and size of visible children */
	childAllocation.x1=childAllocation.y1=priv->spacing;
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(inActor));
	while(clutter_actor_iter_next(&iter, &child))
	{
		/* Is child visible? */
		if(!CLUTTER_ACTOR_IS_VISIBLE(child)) continue;

		/* Calculate new position and size of child */
		if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL)
		{
			childHeight=availableHeight-(2*priv->spacing);
			clutter_actor_get_preferred_width(child, childHeight, NULL, &childWidth);

			childAllocation.y1=ceil(MAX(((availableHeight-childHeight))/2.0f, priv->spacing));
			childAllocation.y2=floor(childAllocation.y1+childHeight);
			childAllocation.x2=floor(childAllocation.x1+childWidth);
		}
			else
			{
				childWidth=availableWidth-(2*priv->spacing);
				clutter_actor_get_preferred_height(child, childWidth, NULL, &childHeight);

				childAllocation.x1=ceil(MAX(((availableWidth-childWidth))/2.0f, priv->spacing));
				childAllocation.x2=floor(childAllocation.x1+childWidth);
				childAllocation.y2=floor(childAllocation.y1+childHeight);
			}

		clutter_actor_allocate(child, &childAllocation, inFlags);

		/* Set up for next child */
		if(priv->orientation==CLUTTER_ORIENTATION_HORIZONTAL) childAllocation.x1=floor(childAllocation.x1+childWidth+priv->spacing);
			else childAllocation.y1=floor(childAllocation.y1+childHeight+priv->spacing);
	}
}
static void
clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
                                            ClutterActor      *actor,
                                            ClutterActorBox   *allocation)
{
  ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
  gfloat source_width, source_height;
  gfloat actor_width, actor_height;
  gfloat source_x, source_y;

  if (align->source == NULL)
    return;

  clutter_actor_box_get_size (allocation, &actor_width, &actor_height);

  clutter_actor_get_position (align->source, &source_x, &source_y);
  clutter_actor_get_size (align->source, &source_width, &source_height);

  switch (align->align_axis)
    {
    case CLUTTER_ALIGN_X_AXIS:
      allocation->x1 = ((source_width - actor_width) * align->factor)
                     + source_x;
      allocation->x1 = floorf (allocation->x1 + 0.5);
      allocation->x2 = allocation->x1 + actor_width;
      break;

    case CLUTTER_ALIGN_Y_AXIS:
      allocation->y1 = ((source_height - actor_height) * align->factor)
                     + source_y;
      allocation->y1 = floorf (allocation->y1 + 0.5);
      allocation->y2 = allocation->y1 + actor_height;
      break;

    case CLUTTER_ALIGN_BOTH:
      allocation->x1 = ((source_width - actor_width) * align->factor)
                     + source_x;
      allocation->y1 = ((source_height - actor_height) * align->factor)
                     + source_y;
      allocation->x1 = floorf (allocation->x1 + 0.5f);
      allocation->y1 = floorf (allocation->y1 + 0.5f);
      allocation->x2 = allocation->x1 + actor_width;
      allocation->y2 = allocation->y1 + actor_height;
      break;

    default:
      g_assert_not_reached ();
      break;
    }
}
示例#14
0
static void
on_box_allocation_changed (ClutterActor           *box,
                           const ClutterActorBox  *allocation,
                           ClutterAllocationFlags  flags,
                           ClutterActor           *background)
{
  gfloat new_width, new_height;

  clutter_actor_box_get_size (allocation, &new_width, &new_height);
  clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (background),
                                          new_width,
                                          new_height);

  update_background (background, &bg_color, new_width, new_height);
}
示例#15
0
/**
 * st_shadow_helper_paint:
 * @helper: a #StShadowHelper
 * @actor_box: the bounding box of the shadow
 * @paint_opacity: the opacity at which the shadow is painted
 *
 * Paints the shadow associated with @helper This must only
 * be called from the implementation of ClutterActor::paint().
 */
void
st_shadow_helper_paint (StShadowHelper  *helper,
                        ClutterActorBox *actor_box,
                        guint8           paint_opacity)
{
  ClutterActorBox allocation;
  float width, height;

  clutter_actor_box_get_size (actor_box, &width, &height);

  _st_paint_shadow_with_opacity (helper->shadow,
                                 helper->material,
                                 &allocation,
                                 paint_opacity);
}
示例#16
0
/* These are needed since the layout manager allocates {0, 0, 0, 0} for
 * children it can't lay out.
 */
static void
_paint_foreach_cb (ClutterActor *actor,
                   gpointer      data)
{
  ClutterActorBox actor_box;
  gfloat w, h;

  clutter_actor_get_allocation_box (actor, &actor_box);

  clutter_actor_box_get_size (&actor_box, &w, &h);

  if (w > 0 && h > 0)
  {
    clutter_actor_paint (actor);
  }
}
void
allocation_changed_cb (ClutterActor           *actor,
                       const ClutterActorBox  *allocation,
                       ClutterAllocationFlags  flags,
                       gpointer                user_data)
{
  ClutterActor *overlay = CLUTTER_ACTOR (user_data);

  gfloat width, height, x, y;
  clutter_actor_box_get_size (allocation, &width, &height);
  clutter_actor_box_get_origin (allocation, &x, &y);

  clutter_actor_set_size (overlay,
                          width * OVERLAY_FACTOR,
                          height * OVERLAY_FACTOR);

  clutter_actor_set_position (overlay,
                              x - ((OVERLAY_FACTOR - 1) * width * 0.5),
                              y - ((OVERLAY_FACTOR - 1) * width * 0.5));
}
示例#18
0
static void
empathy_rounded_actor_paint (ClutterActor *actor)
{
  EmpathyRoundedActor *self = EMPATHY_ROUNDED_ACTOR (actor);
  ClutterActorBox allocation = { 0, };
  gfloat width, height;

  clutter_actor_get_allocation_box (actor, &allocation);
  clutter_actor_box_get_size (&allocation, &width, &height);

  cogl_path_new ();

  /* create and store a path describing a rounded rectangle */
  cogl_path_round_rectangle (0, 0, width, height,
      height / self->priv->round_factor, 0.1);

  cogl_clip_push_from_path ();

  CLUTTER_ACTOR_CLASS (empathy_rounded_actor_parent_class)->paint (actor);

  cogl_clip_pop ();
}
示例#19
0
static void
gmc_button_allocate (ClutterActor           *actor,
                    const ClutterActorBox  *box,
                    ClutterAllocationFlags  flags)
{
  GmcButtonPrivate *priv;
  ClutterActorBox *actor_box;
  gfloat width, height;
  gfloat icon_w_min = 0, icon_h_min = 0, icon_w_nat = 0, icon_h_nat = 0;
  gfloat label_w_min = 0, label_h_min = 0, label_w_nat = 0, label_h_nat = 0;
  gfloat spacing = 0;

  priv = GMC_BUTTON_GET_PRIVATE (actor);
  CLUTTER_ACTOR_CLASS (gmc_button_parent_class)->allocate (actor, box, flags);

  clutter_actor_box_get_size (box,
                              &width,
                              &height);

  // TODO if icon_h < label_h, center icon
  //      if icon_h > label_h, center label
  if (priv->icon) {
    clutter_actor_get_preferred_width (priv->icon, height, &icon_w_min, &icon_w_nat);
    clutter_actor_get_preferred_height (priv->icon, width, &icon_h_min, &icon_h_nat);
    actor_box = clutter_actor_box_new (0, 0, icon_w_min, icon_h_min);
    clutter_actor_allocate (priv->icon, actor_box, flags);
    clutter_actor_box_free (actor_box);
    spacing = priv->spacing;
  }
  if (priv->label) {
    clutter_actor_get_preferred_width (priv->label, height, &label_w_min, &label_w_nat);
    clutter_actor_get_preferred_height (priv->label, width, &label_h_min, &label_h_nat);
    actor_box = clutter_actor_box_new (icon_w_min + spacing, 0, label_w_min, 25);
    clutter_actor_allocate (priv->label, actor_box, flags);
    clutter_actor_box_free (actor_box);
  }
}
示例#20
0
static void _clone_paint_cb (ClutterActor *actor) {
    ClutterActor *source;
    ClutterActorBox box;
    CoglHandle material;
    gfloat width, height;
    guint8 opacity;
    CoglColor color_1, color_2;
    CoglTextureVertex vertices[4];

    /* if we don't have a source actor, don't paint */
    source = clutter_clone_get_source (CLUTTER_CLONE (actor));
    if (source == NULL)
        goto out;

    /* if the source texture does not have any content, don't paint */
    material = clutter_texture_get_cogl_material (CLUTTER_TEXTURE (source));
    if (material == NULL)
        goto out;

    /* get the size of the reflection */
    clutter_actor_get_allocation_box (actor, &box);
    clutter_actor_box_get_size (&box, &width, &height);

    /* get the composite opacity of the actor */
    opacity = clutter_actor_get_paint_opacity (actor);

    /* figure out the two colors for the reflection: the first is
     * full color and the second is the same, but at 0 opacity
     */
    cogl_color_init_from_4f (&color_1, 1.0, 1.0, 1.0, opacity / 255.0);
    cogl_color_premultiply (&color_1);
    cogl_color_init_from_4f (&color_2, 1.0, 1.0, 1.0, 0.0);
    cogl_color_premultiply (&color_2);

    /* now describe the four vertices of the quad; since it has
     * to be a reflection, we need to invert it as well
     */
    vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0;
    vertices[0].tx = 0.0; vertices[0].ty = 1.0;
    vertices[0].color = color_1;

    vertices[1].x = width; vertices[1].y = 0; vertices[1].z = 0;
    vertices[1].tx = 1.0; vertices[1].ty = 1.0;
    vertices[1].color = color_1;

    vertices[2].x = width; vertices[2].y = height; vertices[2].z = 0;
    vertices[2].tx = 1.0; vertices[2].ty = 0.0;
    vertices[2].color = color_2;

    vertices[3].x = 0; vertices[3].y = height; vertices[3].z = 0;
    vertices[3].tx = 0.0; vertices[3].ty = 0.0;
    vertices[3].color = color_2;

    /* paint the same texture but with a different geometry */
    cogl_set_source (material);
    cogl_polygon (vertices, 4, TRUE);

    out:
      /* prevent the default clone handler from running */
      g_signal_stop_emission_by_name (actor, "paint");
}
示例#21
0
static void
clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
                              ClutterContainer       *container,
                              const ClutterActorBox  *allocation,
                              ClutterAllocationFlags  flags)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  ClutterActor *actor, *child;
  ClutterActorIter iter;
  gfloat x_off, y_off;
  gfloat avail_width, avail_height;
  gfloat item_x, item_y;
  gint line_item_count;
  gint items_per_line;
  gint line_index;

  actor = CLUTTER_ACTOR (container);
  if (clutter_actor_get_n_children (actor) == 0)
    return;

  clutter_actor_box_get_origin (allocation, &x_off, &y_off);
  clutter_actor_box_get_size (allocation, &avail_width, &avail_height);

  /* blow the cached preferred size and re-compute with the given
   * available size in case the FlowLayout wasn't given the exact
   * size it requested
   */
  if ((priv->req_width >= 0 && avail_width != priv->req_width) ||
      (priv->req_height >= 0 && avail_height != priv->req_height))
    {
      clutter_flow_layout_get_preferred_width (manager, container,
                                               avail_height,
                                               NULL, NULL);
      clutter_flow_layout_get_preferred_height (manager, container,
                                                avail_width,
                                                NULL, NULL);
    }

  items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager),
                                  avail_width, avail_height);

  item_x = x_off;
  item_y = y_off;

  line_item_count = 0;
  line_index = 0;

  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      ClutterActorBox child_alloc;
      gfloat item_width, item_height;
      gfloat new_x, new_y;
      gfloat child_min, child_natural;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      new_x = new_y = 0;

      if (!priv->snap_to_grid)
        clutter_actor_get_preferred_size (child,
                                          NULL, NULL,
                                          &item_width,
                                          &item_height);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        {
          if ((priv->snap_to_grid &&
               line_item_count == items_per_line && line_item_count > 0) ||
              (!priv->snap_to_grid && item_x + item_width > avail_width))
            {
              item_y += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_y += priv->row_spacing;

              line_item_count = 0;
              line_index += 1;

              item_x = x_off;
            }

          if (priv->snap_to_grid)
            {
              new_x = x_off + ((line_item_count + 1) * (avail_width + priv->col_spacing))
                    / items_per_line;
              item_width = new_x - item_x - priv->col_spacing;
            }
          else
            {
              new_x = item_x + item_width + priv->col_spacing;
            }

          item_height = g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

        }
      else
        {
          if ((priv->snap_to_grid &&
               line_item_count == items_per_line && line_item_count > 0) ||
              (!priv->snap_to_grid && item_y + item_height > avail_height))
            {
              item_x += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_x += priv->col_spacing;

              line_item_count = 0;
              line_index += 1;

              item_y = y_off;
            }

          if (priv->snap_to_grid)
            {
              new_y = y_off + ((line_item_count + 1) * (avail_height + priv->row_spacing))
                    / items_per_line;
              item_height = new_y - item_y - priv->row_spacing;
            }
          else
            {
              new_y = item_y + item_height + priv->row_spacing;
            }

          item_width = g_array_index (priv->line_natural,
                                      gfloat,
                                      line_index);
        }

      if (!priv->is_homogeneous &&
          !clutter_actor_needs_expand (child,
                                       CLUTTER_ORIENTATION_HORIZONTAL))
        {
          clutter_actor_get_preferred_width (child, item_height,
                                             &child_min,
                                             &child_natural);
          item_width = MIN (item_width, child_natural);
        }

      if (!priv->is_homogeneous &&
          !clutter_actor_needs_expand (child,
                                       CLUTTER_ORIENTATION_VERTICAL))
        {
          clutter_actor_get_preferred_height (child, item_width,
                                              &child_min,
                                              &child_natural);
          item_height = MIN (item_height, child_natural);
        }

      CLUTTER_NOTE (LAYOUT,
                    "flow[line:%d, item:%d/%d] ="
                    "{ %.2f, %.2f, %.2f, %.2f }",
                    line_index, line_item_count + 1, items_per_line,
                    item_x, item_y, item_width, item_height);

      child_alloc.x1 = ceil (item_x);
      child_alloc.y1 = ceil (item_y);
      child_alloc.x2 = ceil (child_alloc.x1 + item_width);
      child_alloc.y2 = ceil (child_alloc.y1 + item_height);
      clutter_actor_allocate (child, &child_alloc, flags);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        item_x = new_x;
      else
        item_y = new_y;

      line_item_count += 1;
    }
}
示例#22
0
static void
clutter_bin_layout_allocate (ClutterLayoutManager   *manager,
                             ClutterContainer       *container,
                             const ClutterActorBox  *allocation,
                             ClutterAllocationFlags  flags)
{
  gfloat allocation_x, allocation_y;
  gfloat available_w, available_h;
  ClutterActor *actor, *child;
  ClutterActorIter iter;

  clutter_actor_box_get_origin (allocation, &allocation_x, &allocation_y);
  clutter_actor_box_get_size (allocation, &available_w, &available_h);

  actor = CLUTTER_ACTOR (container);

  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      ClutterLayoutMeta *meta;
      ClutterBinLayer *layer;
      ClutterActorBox child_alloc = { 0, };
      gdouble x_align, y_align;
      gboolean x_fill, y_fill, is_fixed_position_set;
      float fixed_x, fixed_y;

      if (!clutter_actor_is_visible (child))
        continue;

      meta = clutter_layout_manager_get_child_meta (manager,
                                                    container,
                                                    child);
      layer = CLUTTER_BIN_LAYER (meta);

      fixed_x = fixed_y = 0.f;
      g_object_get (child,
                    "fixed-position-set", &is_fixed_position_set,
                    "fixed-x", &fixed_x,
                    "fixed-y", &fixed_y,
                    NULL);

      /* XXX:2.0 - remove the FIXED alignment, and just use the fixed position
       * of the actor if one is set
       */
      if (is_fixed_position_set ||
          layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
	{
          if (is_fixed_position_set)
            child_alloc.x1 = fixed_x;
          else
            child_alloc.x1 = clutter_actor_get_x (child);
	}
      else
        child_alloc.x1 = allocation_x;

      if (is_fixed_position_set ||
          layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
	{
	  if (is_fixed_position_set)
            child_alloc.y1 = fixed_y;
          else
	    child_alloc.y1 = clutter_actor_get_y (child);
	}
      else
        child_alloc.y1 = allocation_y;

      child_alloc.x2 = allocation_x + available_w;
      child_alloc.y2 = allocation_y + available_h;

      if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL))
        {
          ClutterActorAlign align;

          align = clutter_actor_get_x_align (child);
          x_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
          x_align = get_actor_align_factor (align);
        }
      else
        {
          ClutterTextDirection text_dir;

          x_fill = (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL);

          text_dir = clutter_actor_get_text_direction (child);

          if (!is_fixed_position_set)
            x_align = get_bin_alignment_factor (layer->x_align, text_dir);
          else
            x_align = 0.0;
        }

      if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL))
        {
          ClutterActorAlign align;

          align = clutter_actor_get_y_align (child);
          y_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
          y_align = get_actor_align_factor (align);
        }
      else
        {
          y_fill = (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL);

          if (!is_fixed_position_set)
            y_align = get_bin_alignment_factor (layer->y_align,
                                                CLUTTER_TEXT_DIRECTION_LTR);
          else
            y_align = 0.0;
        }

      clutter_actor_allocate_align_fill (child, &child_alloc,
                                         x_align, y_align,
                                         x_fill, y_fill,
                                         flags);
    }
}
static void
clutter_bin_layout_allocate (ClutterLayoutManager   *manager,
                             ClutterContainer       *container,
                             const ClutterActorBox  *allocation,
                             ClutterAllocationFlags  flags)
{
  gfloat allocation_x, allocation_y;
  gfloat available_w, available_h;
  ClutterActor *actor, *child;
  ClutterActorIter iter;
  gboolean use_animations;
  ClutterAnimationMode easing_mode;
  guint easing_duration, easing_delay;

  clutter_actor_box_get_origin (allocation, &allocation_x, &allocation_y);
  clutter_actor_box_get_size (allocation, &available_w, &available_h);

  actor = CLUTTER_ACTOR (container);

  use_animations = clutter_layout_manager_get_easing_state (manager,
                                                            &easing_mode,
                                                            &easing_duration,
                                                            &easing_delay);
  clutter_actor_iter_init (&iter, actor);
  while (clutter_actor_iter_next (&iter, &child))
    {
      ClutterLayoutMeta *meta;
      ClutterBinLayer *layer;
      ClutterActorBox child_alloc = { 0, };
      gdouble x_align, y_align;
      gboolean x_fill, y_fill;

      meta = clutter_layout_manager_get_child_meta (manager,
                                                    container,
                                                    child);
      layer = CLUTTER_BIN_LAYER (meta);

      if (layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
        child_alloc.x1 = clutter_actor_get_x (child);
      else
        child_alloc.x1 = allocation_x;

      if (layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
        child_alloc.y1 = clutter_actor_get_y (child);
      else
        child_alloc.y1 = allocation_y;

      child_alloc.x2 = available_w;
      child_alloc.y2 = available_h;

      if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL))
        {
          ClutterActorAlign align;

          align = _clutter_actor_get_effective_x_align (child);
          x_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
          x_align = get_actor_align_factor (align);
        }
      else
        {
          x_fill = (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL);
          x_align = get_bin_alignment_factor (layer->x_align);
        }

      if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL))
        {
          ClutterActorAlign align;

          align = clutter_actor_get_y_align (child);
          y_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
          y_align = get_actor_align_factor (align);
        }
      else
        {
          y_fill = (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL);
          y_align = get_bin_alignment_factor (layer->y_align);
        }

      if (use_animations)
        {
          clutter_actor_save_easing_state (child);
          clutter_actor_set_easing_mode (child, easing_mode);
          clutter_actor_set_easing_duration (child, easing_duration);
          clutter_actor_set_easing_delay (child, easing_delay);
        }

      clutter_actor_allocate_align_fill (child, &child_alloc,
                                         x_align, y_align,
                                         x_fill, y_fill,
                                         flags);

      if (use_animations)
        clutter_actor_restore_easing_state (child);
    }
}
示例#24
0
CoglPipeline *
_st_create_shadow_pipeline_from_actor (StShadow     *shadow_spec,
                                       ClutterActor *actor)
{
    CoglPipeline *shadow_pipeline = NULL;

    if (CLUTTER_IS_TEXTURE (actor))
    {
        CoglTexture *texture;

        texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));
        shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture);
    }
    else
    {
        CoglTexture *buffer;
        CoglOffscreen *offscreen;
        CoglFramebuffer *fb;
        ClutterActorBox box;
        CoglColor clear_color;
        float width, height;
        CoglError *catch_error = NULL;

        clutter_actor_get_allocation_box (actor, &box);
        clutter_actor_box_get_size (&box, &width, &height);

        if (width == 0 || height == 0)
            return NULL;

        buffer = cogl_texture_new_with_size (width,
                                             height,
                                             COGL_TEXTURE_NO_SLICING,
                                             COGL_PIXEL_FORMAT_ANY);

        if (buffer == NULL)
            return NULL;

        offscreen = cogl_offscreen_new_with_texture (buffer);
        fb = COGL_FRAMEBUFFER (offscreen);

        if (!cogl_framebuffer_allocate (fb, &catch_error))
        {
            cogl_error_free (catch_error);
            cogl_object_unref (buffer);
            return NULL;
        }

        cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);

        /* XXX: There's no way to render a ClutterActor to an offscreen
         * as it uses the implicit API. */
        G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
        cogl_push_framebuffer (fb);
        G_GNUC_END_IGNORE_DEPRECATIONS;

        cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
        cogl_framebuffer_translate (fb, -box.x1, -box.y1, 0);
        cogl_framebuffer_orthographic (fb, 0, 0, width, height, 0, 1.0);

        clutter_actor_set_opacity_override (actor, 255);
        clutter_actor_paint (actor);
        clutter_actor_set_opacity_override (actor, -1);

        G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
        cogl_pop_framebuffer ();
        G_GNUC_END_IGNORE_DEPRECATIONS;

        cogl_object_unref (fb);

        shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, buffer);

        cogl_object_unref (buffer);
    }

    return shadow_pipeline;
}
示例#25
0
static void
clutter_snap_constraint_update_allocation (ClutterConstraint *constraint,
                                           ClutterActor      *actor,
                                           ClutterActorBox   *allocation)
{
  ClutterSnapConstraint *self = CLUTTER_SNAP_CONSTRAINT (constraint);
  gfloat source_width, source_height;
  gfloat source_x, source_y;
  gfloat actor_width, actor_height;

  if (self->source == NULL)
    return;

  clutter_actor_get_position (self->source, &source_x, &source_y);
  clutter_actor_get_size (self->source, &source_width, &source_height);

  clutter_actor_box_get_size (allocation, &actor_width, &actor_height);

  switch (self->to_edge)
    {
    case CLUTTER_SNAP_EDGE_LEFT:
      if (self->from_edge == CLUTTER_SNAP_EDGE_LEFT)
        allocation->x1 = source_x + self->offset;
      else if (self->from_edge == CLUTTER_SNAP_EDGE_RIGHT)
        allocation->x2 = source_x + self->offset;
      else
        warn_horizontal_edge ("left", self->actor, self->source);
      break;

    case CLUTTER_SNAP_EDGE_RIGHT:
      if (self->from_edge == CLUTTER_SNAP_EDGE_RIGHT)
        allocation->x2 = source_x + source_width + self->offset;
      else if (self->from_edge == CLUTTER_SNAP_EDGE_LEFT)
        allocation->x1 = source_x + source_width + self->offset;
      else
        warn_horizontal_edge ("right", self->actor, self->source);
      break;

      break;

    case CLUTTER_SNAP_EDGE_TOP:
      if (self->from_edge == CLUTTER_SNAP_EDGE_TOP)
        allocation->y1 = source_y + self->offset;
      else if (self->from_edge == CLUTTER_SNAP_EDGE_BOTTOM)
        allocation->y2 = source_y + self->offset;
      else
        warn_vertical_edge ("top", self->actor, self->source);
      break;

    case CLUTTER_SNAP_EDGE_BOTTOM:
      if (self->from_edge == CLUTTER_SNAP_EDGE_BOTTOM)
        allocation->y2 = source_y + source_height + self->offset;
      else if (self->from_edge == CLUTTER_SNAP_EDGE_TOP)
        allocation->y1 = source_y + source_height + self->offset;
      else
        warn_vertical_edge ("bottom", self->actor, self->source);
      break;

    default:
      g_assert_not_reached ();
      break;
    }

  if (allocation->x2 - allocation->x1 < 0)
    allocation->x2 = allocation->x1;

  if (allocation->y2 - allocation->y1 < 0)
    allocation->y2 = allocation->y1;
}
示例#26
0
static void
clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
                              ClutterContainer       *container,
                              const ClutterActorBox  *allocation,
                              ClutterAllocationFlags  flags)
{
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
  GList *l, *children = clutter_container_get_children (container);
  gfloat avail_width, avail_height;
  gfloat item_x, item_y;
  gint line_item_count;
  gint items_per_line;
  gint line_index;

  if (children == NULL)
    return;

  clutter_actor_box_get_size (allocation, &avail_width, &avail_height);

  items_per_line = compute_lines (CLUTTER_FLOW_LAYOUT (manager),
                                  avail_width, avail_height);

  item_x = item_y = 0;

  line_item_count = 0;
  line_index = 0;

  for (l = children; l != NULL; l = l->next)
    {
      ClutterActor *child = l->data;
      ClutterActorBox child_alloc;
      gfloat item_width, item_height;
      gfloat new_x, new_y;

      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
        continue;

      new_x = new_y = 0;

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        {
          if (line_item_count == items_per_line && line_item_count > 0)
            {
              item_y += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_y += priv->row_spacing;

              line_item_count = 0;
              line_index += 1;

              item_x = 0;
            }

          new_x = ((line_item_count + 1) * (avail_width + priv->col_spacing))
                / items_per_line;
          item_width = new_x - item_x - priv->col_spacing;
          item_height = g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

          if (!priv->is_homogeneous)
            {
              gfloat child_min, child_natural;

              clutter_actor_get_preferred_width (child, item_height,
                                                 &child_min,
                                                 &child_natural);
              item_width = MIN (item_width, child_natural);

              clutter_actor_get_preferred_height (child, item_width,
                                                  &child_min,
                                                  &child_natural);
              item_height = MIN (item_height, child_natural);
            }
        }
      else
        {
          if (line_item_count == items_per_line && line_item_count > 0)
            {
              item_x += g_array_index (priv->line_natural,
                                       gfloat,
                                       line_index);

              if (line_index >= 0)
                item_x += priv->col_spacing;

              line_item_count = 0;
              line_index += 1;

              item_y = 0;
            }

          new_y = ((line_item_count + 1) * (avail_height + priv->row_spacing))
                / items_per_line;
          item_height = new_y - item_y - priv->row_spacing;
          item_width = g_array_index (priv->line_natural,
                                      gfloat,
                                      line_index);

          if (!priv->is_homogeneous)
            {
              gfloat child_min, child_natural;

              clutter_actor_get_preferred_width (child, item_height,
                                                 &child_min,
                                                 &child_natural);
              item_width = MIN (item_width, child_natural);

              clutter_actor_get_preferred_height (child, item_width,
                                                  &child_min,
                                                  &child_natural);
              item_height = MIN (item_height, child_natural);
            }
        }

      CLUTTER_NOTE (LAYOUT,
                    "flow[line:%d, item:%d/%d] ="
                    "{ %.2f, %.2f, %.2f, %.2f }",
                    line_index, line_item_count + 1, items_per_line,
                    item_x, item_y, item_width, item_height);

      child_alloc.x1 = ceil (item_x);
      child_alloc.y1 = ceil (item_y);
      child_alloc.x2 = ceil (child_alloc.x1 + item_width);
      child_alloc.y2 = ceil (child_alloc.y1 + item_height);
      clutter_actor_allocate (child, &child_alloc, flags);

      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
        item_x = new_x;
      else
        item_y = new_y;

      line_item_count += 1;
    }

  g_list_free (children);
}
示例#27
0
static gboolean
cd_icc_effect_pre_paint (ClutterEffect *effect)
{
  CdIccEffect *self = CD_ICC_EFFECT (effect);
  ClutterEffectClass *parent_class;
  ClutterActorBox allocation;
  gfloat width, height;

  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
    return FALSE;

  self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  if (self->actor == NULL)
    return FALSE;

  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
    {
      /* if we don't have support for GLSL shaders then we
       * forcibly disable the ActorMeta
       */
      g_warning ("Unable to use the ShaderEffect: the graphics hardware "
                 "or the current GL driver does not implement support "
                 "for the GLSL shading language.");
      clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
      return FALSE;
    }

  clutter_actor_get_allocation_box (self->actor, &allocation);
  clutter_actor_box_get_size (&allocation, &width, &height);

  if (self->shader == COGL_INVALID_HANDLE)
    {
      self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT);
      cogl_shader_source (self->shader, glsl_shader);

      self->is_compiled = FALSE;
      self->main_texture_uniform = -1;
      self->indirect_texture_uniform = -1;
      self->color_data1_uniform = -1;
      self->color_data2_uniform = -1;
    }

  if (self->program == COGL_INVALID_HANDLE)
    self->program = cogl_create_program ();

  if (!self->is_compiled)
    {
      g_assert (self->shader != COGL_INVALID_HANDLE);
      g_assert (self->program != COGL_INVALID_HANDLE);

      cogl_shader_compile (self->shader);
      if (!cogl_shader_is_compiled (self->shader))
        {
          gchar *log_buf = cogl_shader_get_info_log (self->shader);

          g_warning (G_STRLOC ": Unable to compile the icc shader: %s",
                     log_buf);
          g_free (log_buf);

          cogl_handle_unref (self->shader);
          cogl_handle_unref (self->program);

          self->shader = COGL_INVALID_HANDLE;
          self->program = COGL_INVALID_HANDLE;
        }
      else
        {
          cogl_program_attach_shader (self->program, self->shader);
          cogl_program_link (self->program);

          cogl_handle_unref (self->shader);

          self->is_compiled = TRUE;

          self->main_texture_uniform =
            cogl_program_get_uniform_location (self->program, "main_texture");
          self->indirect_texture_uniform =
            cogl_program_get_uniform_location (self->program, "indirect_texture");
          self->color_data1_uniform =
            cogl_program_get_uniform_location (self->program, "color_data1");
          self->color_data2_uniform =
            cogl_program_get_uniform_location (self->program, "color_data2");
        }
    }

  parent_class = CLUTTER_EFFECT_CLASS (cd_icc_effect_parent_class);
  return parent_class->pre_paint (effect);
}