summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.nonterminals1
-rw-r--r--dimension/common.rules30
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/directives.declarations2
-rw-r--r--dimension/grammar.declarations2
-rw-r--r--dimension/grammar.epilogue4
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h4
-rw-r--r--dimension/realize.c117
-rw-r--r--libdimension/dimension/array.h8
-rw-r--r--tests/dimension/demo.pov2
-rwxr-xr-xtests/dimension/demo.sh10
12 files changed, 165 insertions, 18 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals
index 08a6141..ddd0efb 100644
--- a/dimension/common.nonterminals
+++ b/dimension/common.nonterminals
@@ -68,6 +68,7 @@
%type <astnode> PIGMENT
%type <astnode> PIGMENT_TYPE
%type <astnode> PIGMENT_MODIFIERS
+%type <astnode> COLOR_LIST2
%type <astnode> BITMAP_TYPE
/* Finishes */
diff --git a/dimension/common.rules b/dimension/common.rules
index dc8d0b3..7abae80 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -506,12 +506,20 @@ PIGMENT: "pigment" "{"
{
$$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $3, $4);
}
+ | "pigment" "{"
+ "checker" COLOR_LIST2
+ PIGMENT_MODIFIERS
+ "}"
+ {
+ dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @3);
+ dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @3,
+ checker);
+ dmnsn_array_push($5.children, &$4);
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $5);
+ }
;
-PIGMENT_TYPE: /* empty */ {
- $$ = dmnsn_new_astnode(DMNSN_AST_NONE, @$);
- }
- | COLOR
+PIGMENT_TYPE: COLOR
| "image_map" "{"
BITMAP_TYPE STRING
"}"
@@ -541,6 +549,20 @@ PIGMENT_MODIFIERS: /* empty */ {
}
;
+COLOR_LIST2: /* empty */ {
+ dmnsn_astnode list = dmnsn_new_astnode(DMNSN_AST_ARRAY, @$);
+ $$ = dmnsn_new_astnode1(DMNSN_AST_COLOR_LIST, @$, list);
+ }
+ | COLOR {
+ dmnsn_astnode list = dmnsn_new_astnode1(DMNSN_AST_ARRAY, @$, $1);
+ $$ = dmnsn_new_astnode1(DMNSN_AST_COLOR_LIST, @$, list);
+ }
+ | COLOR "," COLOR {
+ dmnsn_astnode list = dmnsn_new_astnode2(DMNSN_AST_ARRAY, @$,
+ $1, $3);
+ $$ = dmnsn_new_astnode1(DMNSN_AST_COLOR_LIST, @$, list);
+ }
+
/* Finishes */
FINISH: "finish" "{"
FINISH_ITEMS
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 256474f..84f05eb 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -121,7 +121,7 @@
%token DMNSN_T_CEIL "ceil"
%token DMNSN_T_CELLS
%token DMNSN_T_CHARSET
-%token DMNSN_T_CHECKER
+%token DMNSN_T_CHECKER "checker"
%token DMNSN_T_CHR
%token DMNSN_T_CIRCULAR
%token DMNSN_T_CLIPPED_BY
diff --git a/dimension/directives.declarations b/dimension/directives.declarations
index 541ae41..9562ec3 100644
--- a/dimension/directives.declarations
+++ b/dimension/directives.declarations
@@ -21,7 +21,7 @@
%name-prefix "dmnsn_ld_yy"
-%expect 12
+%expect 14
%expect-rr 6
%parse-param {const char *filename}
diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations
index 3eae498..b31ac26 100644
--- a/dimension/grammar.declarations
+++ b/dimension/grammar.declarations
@@ -23,7 +23,7 @@
%name-prefix "dmnsn_yy"
-%expect 8
+%expect 10
%parse-param {const char *filename}
%parse-param {void *yyscanner}
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index a2bd743..6a8e164 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -147,10 +147,14 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers");
+ dmnsn_astnode_map(DMNSN_AST_PATTERN, "pattern");
+ dmnsn_astnode_map(DMNSN_AST_CHECKER, "checker");
+
dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture");
dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment");
dmnsn_astnode_map(DMNSN_AST_PIGMENT_MODIFIERS, "pigment-modifiers");
+ dmnsn_astnode_map(DMNSN_AST_COLOR_LIST, "color-list");
dmnsn_astnode_map(DMNSN_AST_IMAGE_MAP, "image_map");
dmnsn_astnode_map(DMNSN_AST_PNG, "png");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 58a2dba..511e3df 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -182,6 +182,7 @@ unsigned long wchar;
"blue" RETURN_TOKEN(DMNSN_T_BLUE);
"ceil" RETURN_TOKEN(DMNSN_T_CEIL);
"camera" RETURN_TOKEN(DMNSN_T_CAMERA);
+"checker" RETURN_TOKEN(DMNSN_T_CHECKER);
"color" RETURN_TOKEN(DMNSN_T_COLOR);
"colour" RETURN_TOKEN(DMNSN_T_COLOR);
"cone" RETURN_TOKEN(DMNSN_T_CONE);
diff --git a/dimension/parse.h b/dimension/parse.h
index 482c4ad..6e09302 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -61,10 +61,14 @@ typedef enum {
DMNSN_AST_OBJECT_MODIFIERS,
+ DMNSN_AST_PATTERN,
+ DMNSN_AST_CHECKER,
+
DMNSN_AST_TEXTURE,
DMNSN_AST_PIGMENT,
DMNSN_AST_PIGMENT_MODIFIERS,
+ DMNSN_AST_COLOR_LIST,
DMNSN_AST_IMAGE_MAP,
DMNSN_AST_PNG,
diff --git a/dimension/realize.c b/dimension/realize.c
index 18de230..bac3d7e 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -446,6 +446,99 @@ dmnsn_realize_camera(dmnsn_astnode astnode)
return camera;
}
+static dmnsn_pattern *
+dmnsn_realize_pattern(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_PATTERN, "Expected a pattern.");
+
+ dmnsn_astnode type;
+ dmnsn_array_get(astnode.children, 0, &type);
+
+ dmnsn_pattern *pattern = NULL;
+
+ switch (type.type) {
+ case DMNSN_AST_CHECKER:
+ pattern = dmnsn_new_checker_pattern();
+ break;
+
+ default:
+ dmnsn_assert(false, "Unexpected pattern type.");
+ }
+
+ return pattern;
+}
+
+static dmnsn_color_map *
+dmnsn_realize_color_list(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_COLOR_LIST, "Expected a color list.");
+
+ dmnsn_astnode array;
+ dmnsn_array_get(astnode.children, 0, &array);
+
+ dmnsn_color_map *color_map = dmnsn_new_color_map();
+
+ double n = 0.0, i = 1.0/(dmnsn_array_size(array.children) - 1);
+ DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, array.children) {
+ dmnsn_color color = dmnsn_realize_color(*entry);
+ dmnsn_add_color_map_entry(color_map, n, color);
+ n += i;
+ }
+
+ return color_map;
+}
+
+static dmnsn_pigment *
+dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers)
+{
+ dmnsn_assert(modifiers.type == DMNSN_AST_PIGMENT_MODIFIERS,
+ "Expected pigment modifiers");
+
+ dmnsn_pattern *pattern = dmnsn_realize_pattern(type);
+
+ dmnsn_color_map *color_map = NULL;
+
+ /* Set up the color_map */
+ DMNSN_ARRAY_FOREACH_REVERSE (dmnsn_astnode *, modifier, modifiers.children) {
+ switch (modifier->type) {
+ case DMNSN_AST_COLOR_LIST:
+ color_map = dmnsn_realize_color_list(*modifier);
+ break;
+
+ default:
+ break;
+ }
+
+ if (color_map)
+ break;
+ }
+
+ /* Now add the default values */
+ switch (type.type) {
+ case DMNSN_AST_CHECKER:
+ /* Default checker pattern is blue and green */
+ if (!color_map)
+ color_map = dmnsn_new_color_map();
+ if (dmnsn_array_size(color_map) < 1)
+ dmnsn_add_color_map_entry(color_map, 0.0, dmnsn_blue);
+ if (dmnsn_array_size(color_map) < 2)
+ dmnsn_add_color_map_entry(color_map, 1.0, dmnsn_green);
+ break;
+
+ default:
+ /* Default map is grayscale */
+ if (!color_map) {
+ color_map = dmnsn_new_color_map();
+ dmnsn_add_color_map_entry(color_map, 0.0, dmnsn_black);
+ dmnsn_add_color_map_entry(color_map, 1.0, dmnsn_white);
+ }
+ break;
+ }
+
+ dmnsn_pigment *pigment = dmnsn_new_color_map_pigment(pattern, color_map);
+ return pigment;
+}
+
static void
dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment)
{
@@ -461,6 +554,10 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment)
);
break;
+ case DMNSN_AST_COLOR_LIST:
+ /* Already handled by dmnsn_realize_pattern_pigment() */
+ break;
+
default:
dmnsn_assert(false, "Invalid pigment modifier.");
}
@@ -474,18 +571,26 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
dmnsn_pigment *pigment = NULL;
- dmnsn_astnode type_node;
+ dmnsn_astnode type_node, modifiers;
dmnsn_array_get(astnode.children, 0, &type_node);
+ dmnsn_array_get(astnode.children, 1, &modifiers);
- dmnsn_color color;
switch (type_node.type) {
case DMNSN_AST_NONE:
break;
case DMNSN_AST_VECTOR:
- color = dmnsn_realize_color(type_node);
- pigment = dmnsn_new_solid_pigment(color);
- break;
+ {
+ dmnsn_color color = dmnsn_realize_color(type_node);
+ pigment = dmnsn_new_solid_pigment(color);
+ break;
+ }
+
+ case DMNSN_AST_PATTERN:
+ {
+ pigment = dmnsn_realize_pattern_pigment(type_node, modifiers);
+ break;
+ }
case DMNSN_AST_IMAGE_MAP:
{
@@ -522,8 +627,6 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
dmnsn_assert(false, "Invalid pigment type.");
}
- dmnsn_astnode modifiers;
- dmnsn_array_get(astnode.children, 1, &modifiers);
dmnsn_realize_pigment_modifiers(modifiers, pigment);
return pigment;
diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h
index b718021..fa48ac0 100644
--- a/libdimension/dimension/array.h
+++ b/libdimension/dimension/array.h
@@ -170,10 +170,16 @@ dmnsn_array_remove(dmnsn_array *array, size_t i)
dmnsn_array_resize(array, size - 1);
}
-/* Macro to shorten array iteration */
+/* Macros to shorten array iteration */
+
#define DMNSN_ARRAY_FOREACH(type, i, array) \
for (type i = dmnsn_array_first(array); \
i - (type)dmnsn_array_first(array) < dmnsn_array_size(array); \
++i)
+#define DMNSN_ARRAY_FOREACH_REVERSE(type, i, array) \
+ for (type i = dmnsn_array_last(array); \
+ (type)dmnsn_array_last(array) - i < dmnsn_array_size(array); \
+ --i)
+
#endif /* DIMENSION_ARRAY_H */
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index 3d6a879..544cd10 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -111,6 +111,6 @@ union {
plane {
y, -2
pigment {
- color rgb 1
+ checker color rgb 0, color rgb 1
}
}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 20eebb9..05b01aa 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -134,8 +134,14 @@ demo_exp=$(echo -n \
(integer -2))
(object-modifiers
(pigment
- (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
- pigment-modifiers))))' \
+ (pattern checker)
+ (pigment-modifiers
+ (color-list
+ (array
+ (vector (integer 0) (integer 0) (integer 0)
+ (integer 0) (integer 0))
+ (vector (integer 1) (integer 1) (integer 1)
+ (integer 0) (integer 0)))))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
if [ "$demo" != "$demo_exp" ]; then