2011-01-08 06:44:40 +01:00
|
|
|
/*
|
|
|
|
* ld-types.c
|
|
|
|
*
|
|
|
|
* This file is a part of logdiag.
|
|
|
|
* Copyright Přemysl Janouch 2010 - 2011. All rights reserved.
|
|
|
|
*
|
|
|
|
* See the file LICENSE for licensing information.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2011-01-09 04:35:10 +01:00
|
|
|
#include <math.h>
|
|
|
|
|
2011-01-10 11:20:14 +01:00
|
|
|
#include "liblogdiag.h"
|
2011-01-08 06:44:40 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
2011-01-28 17:39:40 +01:00
|
|
|
/**
|
|
|
|
* SECTION:ld-types
|
|
|
|
* @short_description: Simple data types
|
|
|
|
*
|
|
|
|
* #LdPoint defines coordinates of a point.
|
|
|
|
*
|
|
|
|
* #LdPointArray defines an array of points.
|
|
|
|
*
|
|
|
|
* #LdRectangle defines the position and size of a rectangle.
|
|
|
|
*/
|
|
|
|
|
2011-01-08 06:44:40 +01:00
|
|
|
#define DEFINE_BOXED_TYPE(TypeName, type_name) \
|
|
|
|
GType \
|
|
|
|
type_name ## _get_type (void) \
|
|
|
|
{ \
|
|
|
|
static GType our_type = 0; \
|
|
|
|
if (our_type == 0) \
|
|
|
|
our_type = g_boxed_type_register_static \
|
|
|
|
(g_intern_static_string (#TypeName), \
|
|
|
|
(GBoxedCopyFunc) type_name ## _copy, \
|
|
|
|
(GBoxedFreeFunc) type_name ## _free); \
|
|
|
|
return our_type; \
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_BOXED_TYPE (LdPoint, ld_point)
|
|
|
|
DEFINE_BOXED_TYPE (LdPointArray, ld_point_array)
|
|
|
|
DEFINE_BOXED_TYPE (LdRectangle, ld_rectangle)
|
|
|
|
|
|
|
|
#define DEFINE_BOXED_TRIVIAL_COPY(TypeName, type_name) \
|
|
|
|
TypeName * \
|
|
|
|
type_name ## _copy (const TypeName *self) \
|
|
|
|
{ \
|
|
|
|
TypeName *new_copy; \
|
|
|
|
g_return_val_if_fail (self != NULL, NULL); \
|
|
|
|
new_copy = g_slice_new (TypeName); \
|
|
|
|
*new_copy = *self; \
|
|
|
|
return new_copy; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DEFINE_BOXED_TRIVIAL_FREE(TypeName, type_name) \
|
|
|
|
void \
|
|
|
|
type_name ## _free (TypeName *self) \
|
|
|
|
{ \
|
|
|
|
g_return_if_fail (self != NULL); \
|
|
|
|
g_slice_free (TypeName, self); \
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_point_copy:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdPoint structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Makes a copy of the structure.
|
|
|
|
* The result must be freed by ld_point_free().
|
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: a copy of @self.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
DEFINE_BOXED_TRIVIAL_COPY (LdPoint, ld_point)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_point_free:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdPoint structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Frees the structure created with ld_point_copy().
|
|
|
|
*/
|
|
|
|
DEFINE_BOXED_TRIVIAL_FREE (LdPoint, ld_point)
|
|
|
|
|
2011-01-09 04:35:10 +01:00
|
|
|
/**
|
|
|
|
* ld_point_distance:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdPoint structure.
|
|
|
|
* @x: the X coordinate of the second point.
|
|
|
|
* @y: the Y coordinate of the second point.
|
2011-01-09 04:35:10 +01:00
|
|
|
*
|
|
|
|
* Compute the distance between two points.
|
|
|
|
*/
|
|
|
|
gdouble
|
|
|
|
ld_point_distance (LdPoint *self, gdouble x, gdouble y)
|
|
|
|
{
|
|
|
|
gdouble dx, dy;
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, -1);
|
|
|
|
|
|
|
|
dx = self->x - x;
|
|
|
|
dy = self->y - y;
|
|
|
|
return sqrt (dx * dx + dy * dy);
|
|
|
|
}
|
|
|
|
|
2011-01-08 06:44:40 +01:00
|
|
|
/**
|
|
|
|
* ld_point_array_new:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @num_points: the number of points the array can store.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Create a new array of points and initialize.
|
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: an #LdPointArray structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
LdPointArray *
|
|
|
|
ld_point_array_new (gint num_points)
|
|
|
|
{
|
|
|
|
LdPointArray *new_array;
|
|
|
|
|
|
|
|
g_return_val_if_fail (num_points >= 1, NULL);
|
|
|
|
|
|
|
|
new_array = g_slice_new (LdPointArray);
|
|
|
|
new_array->num_points = num_points;
|
|
|
|
new_array->points = g_malloc0 (num_points * sizeof (LdPoint));
|
|
|
|
return new_array;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_point_array_copy:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdPointArray structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Makes a copy of the structure.
|
|
|
|
* The result must be freed by ld_point_array_free().
|
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: a copy of @self.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
LdPointArray *
|
|
|
|
ld_point_array_copy (const LdPointArray *self)
|
|
|
|
{
|
|
|
|
LdPointArray *new_array;
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
new_array = g_slice_new (LdPointArray);
|
|
|
|
new_array->num_points = self->num_points;
|
|
|
|
new_array->points = g_memdup (self->points,
|
|
|
|
self->num_points * sizeof (LdPoint));
|
|
|
|
return new_array;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_point_array_free:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdPointArray structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Frees the structure created with ld_point_array_copy().
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ld_point_array_free (LdPointArray *self)
|
|
|
|
{
|
|
|
|
g_return_if_fail (self != NULL);
|
|
|
|
|
|
|
|
g_free (self->points);
|
|
|
|
g_slice_free (LdPointArray, self);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_rectangle_copy:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdRectangle structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Makes a copy of the structure.
|
|
|
|
* The result must be freed by ld_rectangle_free().
|
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: a copy of @self.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
DEFINE_BOXED_TRIVIAL_COPY (LdRectangle, ld_rectangle)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_rectangle_free:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdRectangle structure.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Frees the structure created with ld_rectangle_copy().
|
|
|
|
*/
|
|
|
|
DEFINE_BOXED_TRIVIAL_FREE (LdRectangle, ld_rectangle)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_rectangle_contains:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdRectangle structure.
|
|
|
|
* @x: the X coordinate of the point to be checked.
|
|
|
|
* @y: the Y coordinate of the point to be checked.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: %TRUE if the rectangle contains the specified point.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
ld_rectangle_contains (LdRectangle *self, gdouble x, gdouble y)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
return (x >= self->x && x <= self->x + self->width
|
|
|
|
&& y >= self->y && y <= self->y + self->height);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_rectangle_intersects:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdRectangle structure.
|
|
|
|
* @rect: an #LdRectangle to be checked for intersection.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
2011-01-28 17:39:40 +01:00
|
|
|
* Return value: %TRUE if the two rectangles intersect.
|
2011-01-08 06:44:40 +01:00
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
ld_rectangle_intersects (LdRectangle *self, LdRectangle *rect)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (rect != NULL, FALSE);
|
|
|
|
|
|
|
|
return !(self->x > rect->x + rect->width
|
|
|
|
|| self->y > rect->y + rect->height
|
|
|
|
|| self->x + self->width < rect->x
|
|
|
|
|| self->y + self->height < rect->y);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ld_rectangle_extend:
|
2011-01-28 17:39:40 +01:00
|
|
|
* @self: an #LdRectangle structure.
|
|
|
|
* @border: the border by which the rectangle should be extended.
|
2011-01-08 06:44:40 +01:00
|
|
|
*
|
|
|
|
* Extend a rectangle on all sides.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ld_rectangle_extend (LdRectangle *self, gdouble border)
|
|
|
|
{
|
|
|
|
g_return_if_fail (self != NULL);
|
|
|
|
|
|
|
|
self->x -= border;
|
|
|
|
self->y -= border;
|
|
|
|
self->width += 2 * border;
|
|
|
|
self->height += 2 * border;
|
|
|
|
}
|