From d7e9d913730b96a83751863ad896648488296532 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 6 Nov 2010 16:57:33 -0400 Subject: Add pattern framework, impelement checker pattern. --- libdimension/color_map.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 libdimension/color_map.c (limited to 'libdimension/color_map.c') diff --git a/libdimension/color_map.c b/libdimension/color_map.c new file mode 100644 index 0000000..e0ddcd3 --- /dev/null +++ b/libdimension/color_map.c @@ -0,0 +1,120 @@ +/************************************************************************* + * Copyright (C) 2010 Tavian Barnes * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * . * + *************************************************************************/ + +#include "dimension.h" + +/* + * Color-mapped patterned pigments + */ + +typedef struct dmnsn_color_map_entry { + double n; + dmnsn_color color; +} dmnsn_color_map_entry; + +dmnsn_color_map * +dmnsn_new_color_map() +{ + return dmnsn_new_array(sizeof(dmnsn_color_map_entry)); +} + +void +dmnsn_delete_color_map(dmnsn_color_map *map) +{ + dmnsn_delete_array(map); +} + +void +dmnsn_add_color_map_entry(dmnsn_color_map *map, double n, dmnsn_color c) +{ + dmnsn_color_map_entry entry = { .n = n, .color = c }; + + /* Sorted insertion */ + ssize_t i; + dmnsn_color_map_entry *other = dmnsn_array_last(map); + for (i = dmnsn_array_size(map) - 1; i >= 0; --i, --other) { + if (other->n <= n) + break; + } + + dmnsn_array_insert(map, i + 1, &entry); +} + +dmnsn_color +dmnsn_color_map_value(const dmnsn_color_map *map, double n) +{ + dmnsn_color_map_entry *entry = dmnsn_array_first(map); + + double n1, n2 = 0.0; + dmnsn_color c1, c2 = entry->color; + + for (; entry <= (dmnsn_color_map_entry *)dmnsn_array_last(map); ++entry) { + n1 = n2; + c1 = c2; + + n2 = entry->n; + c2 = entry->color; + + if (n < n2) { + return dmnsn_color_gradient(c1, c2, (n - n1)/(n2 - n1)); + } + } + + return c2; +} + +typedef struct dmnsn_color_map_payload { + dmnsn_pattern *pattern; + dmnsn_color_map *map; +} dmnsn_color_map_payload; + +static dmnsn_color +dmnsn_color_map_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v) +{ + const dmnsn_color_map_payload *payload = pigment->ptr; + return dmnsn_color_map_value(payload->map, + dmnsn_pattern_value(payload->pattern, v)); +} + +static void +dmnsn_color_map_init_fn(dmnsn_pigment *pigment) +{ + dmnsn_color_map_payload *payload = pigment->ptr; + payload->pattern->trans = dmnsn_matrix_mul(pigment->trans, + payload->pattern->trans); + dmnsn_pattern_init(payload->pattern); +} + +dmnsn_pigment * +dmnsn_new_color_map_pigment(dmnsn_pattern *pattern, dmnsn_color_map *map) +{ + dmnsn_pigment *pigment = dmnsn_new_pigment(); + + dmnsn_color_map_payload *payload + = dmnsn_malloc(sizeof(dmnsn_color_map_payload)); + payload->pattern = pattern; + payload->map = map; + + pigment->pigment_fn = &dmnsn_color_map_pigment_fn; + pigment->init_fn = &dmnsn_color_map_init_fn; + pigment->free_fn = &dmnsn_free; + pigment->ptr = payload; + return pigment; +} -- cgit v1.2.3