summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdimension/dimension/pattern.h18
-rw-r--r--libdimension/gradient.c30
-rw-r--r--libdimension/pattern.c22
3 files changed, 47 insertions, 23 deletions
diff --git a/libdimension/dimension/pattern.h b/libdimension/dimension/pattern.h
index c21ca8d..6e8c42f 100644
--- a/libdimension/dimension/pattern.h
+++ b/libdimension/dimension/pattern.h
@@ -1,5 +1,5 @@
/*************************************************************************
- * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
* *
* This file is part of The Dimension Library. *
* *
@@ -35,12 +35,16 @@ typedef struct dmnsn_pattern dmnsn_pattern;
*/
typedef double dmnsn_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v);
+/**
+ * Pattern destruction callback.
+ * @param[in,out] pattern The pattern to destroy.
+ */
+typedef void dmnsn_pattern_free_fn(dmnsn_pattern *pattern);
+
/** A pattern. */
struct dmnsn_pattern {
dmnsn_pattern_fn *pattern_fn; /**< The pattern callback. */
- dmnsn_free_fn *free_fn; /**< The destructor callback. */
-
- void *ptr; /**< Generic pointer. */
+ dmnsn_pattern_free_fn *free_fn; /**< The destructor callback. */
DMNSN_REFCOUNT; /**< Reference count. */
};
@@ -52,6 +56,12 @@ struct dmnsn_pattern {
dmnsn_pattern *dmnsn_new_pattern(void);
/**
+ * Initialize a dmnsn_pattern field.
+ * @param[out] pattern The pattern to initialize.
+ */
+void dmnsn_init_pattern(dmnsn_pattern *pattern);
+
+/**
* Delete a pattern.
* @param[in,out] pattern The pattern to destroy.
*/
diff --git a/libdimension/gradient.c b/libdimension/gradient.c
index 38b460b..bdd6e86 100644
--- a/libdimension/gradient.c
+++ b/libdimension/gradient.c
@@ -25,28 +25,32 @@
#include "dimension.h"
+/** Gradient pattern type. */
+typedef struct dmnns_gradient {
+ dmnsn_pattern pattern;
+ dmnsn_vector orientation;
+} dmnsn_gradient;
+
/** Gradient pattern callback. */
static double
-dmnsn_gradient_pattern_fn(const dmnsn_pattern *gradient, dmnsn_vector v)
+dmnsn_gradient_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v)
{
- dmnsn_vector *orientation = gradient->ptr;
- double n = fmod(dmnsn_vector_dot(*orientation, v), 1.0);
- if (n < -dmnsn_epsilon)
+ const dmnsn_gradient *gradient = (const dmnsn_gradient *)pattern;
+ double n = fmod(dmnsn_vector_dot(gradient->orientation, v), 1.0);
+ if (n < -dmnsn_epsilon) {
n += 1.0;
+ }
return n;
}
dmnsn_pattern *
dmnsn_new_gradient_pattern(dmnsn_vector orientation)
{
- dmnsn_pattern *gradient = dmnsn_new_pattern();
-
- dmnsn_vector *payload = DMNSN_MALLOC(dmnsn_vector);
- *payload = dmnsn_vector_normalized(orientation);
-
- gradient->pattern_fn = dmnsn_gradient_pattern_fn;
- gradient->free_fn = dmnsn_free;
- gradient->ptr = payload;
+ dmnsn_gradient *gradient = DMNSN_MALLOC(dmnsn_gradient);
+ gradient->orientation = dmnsn_vector_normalized(orientation);
- return gradient;
+ dmnsn_pattern *pattern = &gradient->pattern;
+ dmnsn_init_pattern(pattern);
+ pattern->pattern_fn = dmnsn_gradient_pattern_fn;
+ return pattern;
}
diff --git a/libdimension/pattern.c b/libdimension/pattern.c
index 2a7dca6..56c7c48 100644
--- a/libdimension/pattern.c
+++ b/libdimension/pattern.c
@@ -25,25 +25,35 @@
#include "dimension-internal.h"
+static void
+dmnsn_default_pattern_free_fn(dmnsn_pattern *pattern)
+{
+ dmnsn_free(pattern);
+}
+
/* Allocate a dummy pattern */
dmnsn_pattern *
dmnsn_new_pattern(void)
{
dmnsn_pattern *pattern = DMNSN_MALLOC(dmnsn_pattern);
- pattern->free_fn = NULL;
- DMNSN_REFCOUNT_INIT(pattern);
+ dmnsn_init_pattern(pattern);
return pattern;
}
+/* Initialize a pattern */
+void
+dmnsn_init_pattern(dmnsn_pattern *pattern)
+{
+ pattern->free_fn = dmnsn_default_pattern_free_fn;
+ DMNSN_REFCOUNT_INIT(pattern);
+}
+
/* Delete a pattern */
void
dmnsn_delete_pattern(dmnsn_pattern *pattern)
{
if (DMNSN_DECREF(pattern)) {
- if (pattern->free_fn) {
- pattern->free_fn(pattern->ptr);
- }
- dmnsn_free(pattern);
+ pattern->free_fn(pattern);
}
}