Ejemplo n.º 1
0
/**
 * graphene_rect_intersection:
 * @a: a #graphene_rect_t
 * @b: a #graphene_rect_t
 * @res: (out caller-allocates) (optional): return location for
 *   a #graphene_rect_t
 *
 * Computes the intersection of the two given rectangles.
 *
 * ![](rectangle-intersection.png)
 *
 * The intersection in the image above is the blue outline.
 *
 * If the two rectangles do not intersect, @res will contain
 * a degenerate rectangle with origin in (0, 0) and a size of 0.
 *
 * Returns: `true` if the two rectangles intersect
 *
 * Since: 1.0
 */
bool
graphene_rect_intersection (const graphene_rect_t *a,
                            const graphene_rect_t *b,
                            graphene_rect_t       *res)
{
  graphene_rect_t ra, rb;
  float x_1, y_1, x_2, y_2;

  ra = *a;
  rb = *b;

  graphene_rect_normalize_in_place (&ra);
  graphene_rect_normalize_in_place (&rb);

  x_1 = MAX (ra.origin.x, rb.origin.x);
  y_1 = MAX (ra.origin.y, rb.origin.y);
  x_2 = MIN (ra.origin.x + ra.size.width, rb.origin.x + rb.size.width);
  y_2 = MIN (ra.origin.y + ra.size.height, rb.origin.x + rb.size.height);

  if (x_1 >= x_2 || y_1 >= y_2)
    {
      if (res != NULL)
        graphene_rect_init (res, 0.0f, 0.0f, 0.0f, 0.0f);

      return false;
    }

  if (res != NULL)
    graphene_rect_init (res, x_1, y_1, x_2 - x_1, y_2 - y_1);

  return true;
}
Ejemplo n.º 2
0
void
graphene_matrix_project_rect_bounds (const graphene_matrix_t *m,
                                     const graphene_rect_t   *r,
                                     graphene_rect_t         *res)
{
  graphene_point_t points[4];
  graphene_point_t ret[4];
  float min_x, min_y;
  float max_x, max_y;
  int i;

  graphene_rect_get_top_left (r, &points[0]);
  graphene_rect_get_top_right (r, &points[1]);
  graphene_rect_get_bottom_left (r, &points[2]);
  graphene_rect_get_bottom_right (r, &points[3]);

  graphene_matrix_project_point (m, &points[0], &ret[0]);
  graphene_matrix_project_point (m, &points[1], &ret[1]);
  graphene_matrix_project_point (m, &points[2], &ret[2]);
  graphene_matrix_project_point (m, &points[3], &ret[3]);

  min_x = max_x = ret[0].x;
  min_y = max_y = ret[0].y;

  for (i = 1; i < 4; i++)
    {
      min_x = MIN (ret[i].x, min_x);
      min_y = MIN (ret[i].y, min_y);

      max_x = MAX (ret[i].x, max_x);
      max_y = MAX (ret[i].y, max_y);
    }

  graphene_rect_init (res, min_x, min_y, max_x - min_x, max_y - min_y);
}
Ejemplo n.º 3
0
void
graphene_matrix_untransform_bounds (const graphene_matrix_t *m,
                                    const graphene_rect_t   *r,
                                    const graphene_rect_t   *bounds,
                                    graphene_rect_t         *res)
{
  graphene_matrix_t inverse;
  graphene_rect_t bounds_t;
  graphene_rect_t rect;

  g_return_if_fail (m != NULL && r != NULL);
  g_return_if_fail (bounds != NULL);
  g_return_if_fail (res != NULL);

  if (graphene_matrix_is_2d (m))
    {
      graphene_matrix_inverse (m, &inverse);
      graphene_matrix_transform_bounds (&inverse, r, res);
      return;
    }

  graphene_matrix_transform_bounds (m, bounds, &bounds_t);
  if (!graphene_rect_intersection (r, &bounds_t, &rect))
    {
      graphene_rect_init (res, 0.f, 0.f, 0.f, 0.f);
      return;
    }

  graphene_matrix_inverse (m, &inverse);
  graphene_matrix_project_rect_bounds (&inverse, &rect, res);
}
Ejemplo n.º 4
0
/**
 * graphene_rect_expand:
 * @r: a #graphene_rect_t
 * @p: a #graphene_point_t
 * @res: (out caller-allocates): return location for the expanded rectangle
 *
 * Expands a #graphene_rect_t to contain the given #graphene_point_t.
 *
 * Since: 1.4
 */
void
graphene_rect_expand (const graphene_rect_t  *r,
                      const graphene_point_t *p,
                      graphene_rect_t        *res)
{
  graphene_rect_t tmp;

  graphene_rect_init (&tmp, p->x, p->y, 0.f, 0.f);
  graphene_rect_union (r, &tmp, res);

  graphene_rect_normalize_in_place (res);
}
Ejemplo n.º 5
0
/**
 * gtk_snapshot_render_layout:
 * @snapshot: a #GtkSnapshot
 * @context: the #GtkStyleContext to use
 * @x: X origin of the rectangle
 * @y: Y origin of the rectangle
 * @layout: the #PangoLayout to render
 *
 * Creates a render node for rendering @layout according to the style
 * information in @context, and appends it to the current node of @snapshot,
 * without changing the current node.
 *
 * Since: 3.90
 */
void
gtk_snapshot_render_layout (GtkSnapshot     *snapshot,
                            GtkStyleContext *context,
                            gdouble          x,
                            gdouble          y,
                            PangoLayout     *layout)
{
  const GdkRGBA *fg_color;
  graphene_rect_t bounds;
  GtkBorder shadow_extents;
  PangoRectangle ink_rect;
  GtkCssValue *shadow;
  cairo_t *cr;

  g_return_if_fail (snapshot != NULL);
  g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
  g_return_if_fail (PANGO_IS_LAYOUT (layout));

  fg_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
  shadow = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_SHADOW);
  pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
  _gtk_css_shadows_value_get_extents (shadow, &shadow_extents);
  graphene_rect_init (&bounds,
                      ink_rect.x - shadow_extents.left,
                      ink_rect.y - shadow_extents.top,
                      ink_rect.width + shadow_extents.left + shadow_extents.right,
                      ink_rect.height + shadow_extents.top + shadow_extents.bottom);

  gtk_snapshot_translate_2d (snapshot, x, y);

  cr = gtk_snapshot_append_cairo_node (snapshot, &bounds, "Text<%dchars>", pango_layout_get_character_count (layout));

  _gtk_css_shadows_value_paint_layout (shadow, cr, layout);

  gdk_cairo_set_source_rgba (cr, fg_color);
  pango_cairo_show_layout (cr, layout);

  cairo_destroy (cr);
  gtk_snapshot_translate_2d (snapshot, -x, -y);
}