Пример #1
0
static GtkCssValue *
gtk_css_value_image_transition (GtkCssValue *start,
                                GtkCssValue *end,
                                double       progress)
{
  GtkCssImage *fade;

  fade = _gtk_css_image_cross_fade_new (_gtk_css_image_value_get_image (start),
                                        _gtk_css_image_value_get_image (end),
                                        progress);
      
  return _gtk_css_image_value_new (fade);
}
Пример #2
0
static GtkCssValue *
gtk_css_value_image_transition (GtkCssValue *start,
                                GtkCssValue *end,
                                guint        property_id,
                                double       progress)
{
  GtkCssImage *transition;

  transition = _gtk_css_image_transition (_gtk_css_image_value_get_image (start),
                                          _gtk_css_image_value_get_image (end),
                                          property_id,
                                          progress);
      
  return _gtk_css_image_value_new (transition);
}
Пример #3
0
static GtkCssValue *
gtk_css_value_image_compute (GtkCssValue             *value,
                             guint                    property_id,
                             GtkStyleProviderPrivate *provider,
                             GtkCssComputedValues    *values,
                             GtkCssComputedValues    *parent_values,
                             GtkCssDependencies      *dependencies)
{
  GtkCssImage *image, *computed;
  
  image = _gtk_css_image_value_get_image (value);

  if (image == NULL)
    return _gtk_css_value_ref (value);

  computed = _gtk_css_image_compute (image, property_id, provider, values, parent_values, dependencies);

  if (computed == image)
    {
      g_object_unref (computed);
      return _gtk_css_value_ref (value);
    }

  return _gtk_css_image_value_new (computed);
}
Пример #4
0
static gboolean
gtk_css_value_image_is_dynamic (GtkCssValue *value)
{
  GtkCssImage *image = _gtk_css_image_value_get_image (value);

  if (image == NULL)
    return FALSE;

  return gtk_css_image_is_dynamic (image);
}
Пример #5
0
gboolean
gtk_css_style_render_has_border (GtkCssStyle *style)
{
  if (_gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE)))
    return TRUE;

  return _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100) > 0
      || _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100) > 0
      || _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100) > 0
      || _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100) > 0;
}
Пример #6
0
void
gtk_theming_background_render (GtkStyleContext      *context,
                               cairo_t              *cr,
                               gdouble               x,
                               gdouble               y,
                               gdouble               width,
                               gdouble               height,
                               GtkJunctionSides      junction)
{
  GtkThemingBackground bg;
  gint idx;
  GtkCssValue *background_image;
  GtkCssValue *box_shadow;
  const GdkRGBA *bg_color;

  background_image = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
  bg_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BACKGROUND_COLOR));
  box_shadow = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW);

  /* This is the common default case of no background */
  if (gtk_rgba_is_clear (bg_color) &&
      _gtk_css_array_value_get_n_values (background_image) == 1 &&
      _gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (background_image, 0)) == NULL &&
      _gtk_css_shadows_value_is_none (box_shadow))
    return;

  bg.context = context;
  _gtk_theming_background_init_context (&bg, width, height, junction);

  cairo_save (cr);
  cairo_translate (cr, x, y);

  /* Outset shadows */
  _gtk_css_shadows_value_paint_box (box_shadow,
                                    cr,
                                    &bg.boxes[GTK_CSS_AREA_BORDER_BOX],
                                    FALSE);

  _gtk_theming_background_paint_color (&bg, cr, bg_color, background_image);

  for (idx = _gtk_css_array_value_get_n_values (background_image) - 1; idx >= 0; idx--)
    {
      _gtk_theming_background_paint_layer (&bg, idx, cr);
    }

  /* Inset shadows */
  _gtk_css_shadows_value_paint_box (box_shadow,
                                    cr,
                                    &bg.boxes[GTK_CSS_AREA_PADDING_BOX],
                                    TRUE);

  cairo_restore (cr);
}
Пример #7
0
gboolean
_gtk_theming_background_has_background_image (GtkThemingBackground *bg)
{
  GtkCssImage *image;
  GtkCssValue *value = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);

  if (_gtk_css_array_value_get_n_values (value) == 0)
    return FALSE;

  image = _gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (value, 0));
  return (image != NULL);
}
Пример #8
0
void
gtk_css_style_render_icon (GtkCssStyle            *style,
                           cairo_t                *cr,
                           double                  x,
                           double                  y,
                           double                  width,
                           double                  height,
                           GtkCssImageBuiltinType  builtin_type)
{
  const GtkCssValue *shadows;
  cairo_matrix_t matrix, transform_matrix, saved_matrix;
  GtkCssImage *image;

  g_return_if_fail (GTK_IS_CSS_STYLE (style));
  g_return_if_fail (cr != NULL);

  image = _gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE));
  if (image == NULL)
    return;

  cairo_get_matrix (cr, &saved_matrix);

  shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);

  cairo_translate (cr, x, y);

  if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
    {
      /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
      cairo_matrix_init_translate (&matrix, width / 2, height / 2);
      cairo_matrix_multiply (&matrix, &transform_matrix, &matrix);
      cairo_matrix_translate (&matrix, - width / 2, - height / 2);

      if (_gtk_css_shadows_value_is_none (shadows))
        {
          cairo_transform (cr, &matrix);
          gtk_css_image_builtin_draw (image, cr, width, height, builtin_type);
        }
      else
        {
          cairo_push_group (cr);
          cairo_transform (cr, &matrix);
          gtk_css_image_builtin_draw (image, cr, width, height, builtin_type);
          cairo_pop_group_to_source (cr);
          _gtk_css_shadows_value_paint_icon (shadows, cr);
          cairo_paint (cr);
        }
    }

  cairo_set_matrix (cr, &saved_matrix);
}
Пример #9
0
static gboolean
gtk_border_image_init (GtkBorderImage *image,
                       GtkCssStyle    *style)
{
  image->source = _gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE));
  if (image->source == NULL)
    return FALSE;

  image->slice = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE);
  image->width = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH);
  image->repeat = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT);

  return TRUE;
}
Пример #10
0
static void
_gtk_theming_background_init_layer (GtkThemingBackground *bg,
                                    GtkThemingBackgroundLayer *layer,
                                    GtkCssValue *background_image,
                                    gint idx)
{
  layer->idx = idx;
  layer->clip_box = bg->border_box;

  _gtk_theming_background_layer_apply_clip (bg, layer);
  _gtk_theming_background_layer_apply_origin (bg, layer);

  layer->image = _gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (background_image, layer->idx));
}
Пример #11
0
static GtkCssValue *
gtk_css_value_image_get_dynamic_value (GtkCssValue *value,
                                       gint64       monotonic_time)
{
  GtkCssImage *image, *dynamic;
  
  image = _gtk_css_image_value_get_image (value);
  if (image == NULL)
    return gtk_css_value_ref (value);

  dynamic = gtk_css_image_get_dynamic_image (image, monotonic_time);
  if (dynamic == image)
    {
      g_object_unref (dynamic);
      return gtk_css_value_ref (value);
    }

  return _gtk_css_image_value_new (dynamic);
}
Пример #12
0
static GtkCssValue *
gtk_css_value_image_compute (GtkCssValue      *value,
                             guint             property_id,
                             GtkStyleProvider *provider,
                             GtkCssStyle      *style,
                             GtkCssStyle      *parent_style)
{
  GtkCssImage *image, *computed;
  
  image = _gtk_css_image_value_get_image (value);

  if (image == NULL)
    return _gtk_css_value_ref (value);

  computed = _gtk_css_image_compute (image, property_id, provider, style, parent_style);

  if (computed == image)
    {
      g_object_unref (computed);
      return _gtk_css_value_ref (value);
    }

  return _gtk_css_image_value_new (computed);
}
Пример #13
0
static void
_gtk_theming_background_paint_layer (GtkThemingBackground *bg,
                                     guint                 idx,
                                     cairo_t              *cr)
{
  GtkCssRepeatStyle hrepeat, vrepeat;
  const GtkCssValue *pos, *repeat;
  GtkCssImage *image;
  const GtkRoundedBox *origin;
  double image_width, image_height;
  double width, height;

  pos = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION), idx);
  repeat = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT), idx);
  hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
  vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
  image = _gtk_css_image_value_get_image (
              _gtk_css_array_value_get_nth (
                  _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_IMAGE),
                  idx));
  origin = &bg->boxes[
               _gtk_css_area_value_get (
                   _gtk_css_array_value_get_nth (
                       _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_ORIGIN),
                       idx))];
  width = origin->box.width;
  height = origin->box.height;

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

  _gtk_css_bg_size_value_compute_size (_gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE), idx),
                                       image,
                                       width,
                                       height,
                                       &image_width,
                                       &image_height);

  if (image_width <= 0 || image_height <= 0)
    return;

  /* optimization */
  if (image_width == width)
    hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
  if (image_height == height)
    vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;


  cairo_save (cr);

  _gtk_rounded_box_path (
      &bg->boxes[
          _gtk_css_area_value_get (
              _gtk_css_array_value_get_nth (
                  _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_CLIP),
                  idx))],
      cr);
  cairo_clip (cr);


  cairo_translate (cr, origin->box.x, origin->box.y);

  if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT && vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
    {
      cairo_translate (cr,
                       _gtk_css_position_value_get_x (pos, width - image_width),
                       _gtk_css_position_value_get_y (pos, height - image_height));
      /* shortcut for normal case */
      _gtk_css_image_draw (image, cr, image_width, image_height);
    }
  else
    {
      int surface_width, surface_height;
      cairo_rectangle_t fill_rect;
      cairo_surface_t *surface;
      cairo_t *cr2;

      /* If ‘background-repeat’ is ‘round’ for one (or both) dimensions,
       * there is a second step. The UA must scale the image in that
       * dimension (or both dimensions) so that it fits a whole number of
       * times in the background positioning area. In the case of the width
       * (height is analogous):
       *
       * If X ≠ 0 is the width of the image after step one and W is the width
       * of the background positioning area, then the rounded width
       * X' = W / round(W / X) where round() is a function that returns the
       * nearest natural number (integer greater than zero). 
       *
       * If ‘background-repeat’ is ‘round’ for one dimension only and if
       * ‘background-size’ is ‘auto’ for the other dimension, then there is
       * a third step: that other dimension is scaled so that the original
       * aspect ratio is restored. 
       */
      if (hrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
        {
          double n = round (width / image_width);

          n = MAX (1, n);

          if (vrepeat != GTK_CSS_REPEAT_STYLE_ROUND
              /* && vsize == auto (it is by default) */)
            image_height *= width / (image_width * n);
          image_width = width / n;
        }
      if (vrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
        {
          double n = round (height / image_height);

          n = MAX (1, n);

          if (hrepeat != GTK_CSS_REPEAT_STYLE_ROUND
              /* && hsize == auto (it is by default) */)
            image_width *= height / (image_height * n);
          image_height = height / n;
        }

      /* if hrepeat or vrepeat is 'space', we create a somewhat larger surface
       * to store the extra space. */
      if (hrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
        {
          double n = floor (width / image_width);
          surface_width = n ? round (width / n) : 0;
        }
      else
        surface_width = round (image_width);

      if (vrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
        {
          double n = floor (height / image_height);
          surface_height = n ? round (height / n) : 0;
        }
      else
        surface_height = round (image_height);

      surface = cairo_surface_create_similar (cairo_get_target (cr),
                                              CAIRO_CONTENT_COLOR_ALPHA,
                                              surface_width, surface_height);
      cr2 = cairo_create (surface);
      cairo_translate (cr2,
                       0.5 * (surface_width - image_width),
                       0.5 * (surface_height - image_height));
      _gtk_css_image_draw (image, cr2, image_width, image_height);
      cairo_destroy (cr2);

      cairo_set_source_surface (cr, surface,
                                _gtk_css_position_value_get_x (pos, width - image_width),
                                _gtk_css_position_value_get_y (pos, height - image_height));
      cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
      cairo_surface_destroy (surface);

      if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
        {
          fill_rect.x = _gtk_css_position_value_get_x (pos, width - image_width);
          fill_rect.width = image_width;
        }
      else
        {
          fill_rect.x = 0;
          fill_rect.width = width;
        }

      if (vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
        {
          fill_rect.y = _gtk_css_position_value_get_y (pos, height - image_height);
          fill_rect.height = image_height;
        }
      else
        {
          fill_rect.y = 0;
          fill_rect.height = height;
        }

      cairo_rectangle (cr, fill_rect.x, fill_rect.y,
                       fill_rect.width, fill_rect.height);
      cairo_fill (cr);
    }


  cairo_restore (cr);
}