summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
Diffstat (limited to 'dimension')
-rw-r--r--dimension/common.nonterminals1
-rw-r--r--dimension/common.rules18
-rw-r--r--dimension/common.terminals4
-rw-r--r--dimension/grammar.epilogue2
-rw-r--r--dimension/lexer.l2
-rw-r--r--dimension/parse.h2
-rw-r--r--dimension/realize.c49
7 files changed, 71 insertions, 7 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals
index 10a7b23..5bd7da6 100644
--- a/dimension/common.nonterminals
+++ b/dimension/common.nonterminals
@@ -61,6 +61,7 @@
%type <astnode> PIGMENT
%type <astnode> PIGMENT_TYPE
%type <astnode> PIGMENT_MODIFIERS
+%type <astnode> BITMAP_TYPE
/* Finishes */
%type <astnode> FINISH
diff --git a/dimension/common.rules b/dimension/common.rules
index 863b288..732a277 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -324,6 +324,24 @@ PIGMENT_TYPE: /* empty */ {
$$ = dmnsn_new_astnode(DMNSN_AST_NONE, @$);
}
| COLOR
+ | "image_map" "{"
+ BITMAP_TYPE STRING
+ "}"
+ {
+ $$ = dmnsn_new_astnode2(DMNSN_AST_IMAGE_MAP, @$, $3, $4);
+ }
+ | "image_map" "{"
+ STRING
+ "}"
+ {
+ dmnsn_astnode type = dmnsn_new_astnode(DMNSN_AST_PNG, @$);
+ $$ = dmnsn_new_astnode2(DMNSN_AST_IMAGE_MAP, @$, type, $3);
+ }
+;
+
+BITMAP_TYPE: "png" {
+ $$ = dmnsn_new_astnode(DMNSN_AST_PNG, @$);
+ }
;
PIGMENT_MODIFIERS: /* empty */ {
diff --git a/dimension/common.terminals b/dimension/common.terminals
index c125489..05ab8b8 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -226,7 +226,7 @@
%token DMNSN_T_HOLLOW
%token DMNSN_T_IFF
%token DMNSN_T_IMAGE_HEIGHT
-%token DMNSN_T_IMAGE_MAP
+%token DMNSN_T_IMAGE_MAP "image_map"
%token DMNSN_T_IMAGE_PATTERN
%token DMNSN_T_IMAGE_WIDTH
%token DMNSN_T_INITIAL_CLOCK
@@ -336,7 +336,7 @@
%token DMNSN_T_PIGMENT_PATTERN
%token DMNSN_T_PLANAR
%token DMNSN_T_PLANE "plane"
-%token DMNSN_T_PNG
+%token DMNSN_T_PNG "png"
%token DMNSN_T_POINT_AT
%token DMNSN_T_POLY
%token DMNSN_T_POLY_WAVE
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index ea1414f..7b004e3 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -147,6 +147,8 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment");
dmnsn_astnode_map(DMNSN_AST_PIGMENT_MODIFIERS, "pigment-modifiers");
+ dmnsn_astnode_map(DMNSN_AST_IMAGE_MAP, "image_map");
+ dmnsn_astnode_map(DMNSN_AST_PNG, "png");
dmnsn_astnode_map(DMNSN_AST_FINISH, "finish");
dmnsn_astnode_map(DMNSN_AST_AMBIENT, "ambient");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 5039bef..18b4202 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -199,6 +199,7 @@ unsigned long wchar;
"gray" RETURN_TOKEN(DMNSN_T_GRAY);
"grey" RETURN_TOKEN(DMNSN_T_GRAY);
"green" RETURN_TOKEN(DMNSN_T_GREEN);
+"image_map" RETURN_TOKEN(DMNSN_T_IMAGE_MAP);
"int" RETURN_TOKEN(DMNSN_T_INT);
"interior" RETURN_TOKEN(DMNSN_T_INTERIOR);
"intersection" RETURN_TOKEN(DMNSN_T_INTERSECTION);
@@ -223,6 +224,7 @@ unsigned long wchar;
"pi" RETURN_TOKEN(DMNSN_T_PI);
"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT);
"plane" RETURN_TOKEN(DMNSN_T_PLANE);
+"png" RETURN_TOKEN(DMNSN_T_PNG);
"pow" RETURN_TOKEN(DMNSN_T_POW);
"radians" RETURN_TOKEN(DMNSN_T_RADIANS);
"red" RETURN_TOKEN(DMNSN_T_RED);
diff --git a/dimension/parse.h b/dimension/parse.h
index 9d9e84f..6e5ef09 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -61,6 +61,8 @@ typedef enum {
DMNSN_AST_PIGMENT,
DMNSN_AST_PIGMENT_MODIFIERS,
+ DMNSN_AST_IMAGE_MAP,
+ DMNSN_AST_PNG,
DMNSN_AST_FINISH,
DMNSN_AST_AMBIENT,
diff --git a/dimension/realize.c b/dimension/realize.c
index 463c27e..a40095a 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -56,6 +56,14 @@ dmnsn_realize_float(dmnsn_astnode astnode)
}
}
+/* dmnsn_realize_string is an API function, so call this dmnsn_realize_str */
+static const char*
+dmnsn_realize_str(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_STRING, "Expected a string.");
+ return astnode.ptr;
+}
+
static dmnsn_vector
dmnsn_realize_vector(dmnsn_astnode astnode)
{
@@ -426,21 +434,52 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
dmnsn_pigment *pigment = NULL;
- dmnsn_astnode color_node;
- dmnsn_array_get(astnode.children, 0, &color_node);
+ dmnsn_astnode type_node;
+ dmnsn_array_get(astnode.children, 0, &type_node);
dmnsn_color color;
- switch (color_node.type) {
+ switch (type_node.type) {
case DMNSN_AST_NONE:
break;
case DMNSN_AST_VECTOR:
- color = dmnsn_realize_color(color_node);
+ color = dmnsn_realize_color(type_node);
pigment = dmnsn_new_solid_pigment(color);
break;
+ case DMNSN_AST_IMAGE_MAP:
+ {
+ dmnsn_astnode filetype, strnode;
+ dmnsn_array_get(type_node.children, 0, &filetype);
+ dmnsn_array_get(type_node.children, 1, &strnode);
+
+ const char *path = dmnsn_realize_str(strnode);
+ FILE *file = fopen(path, "rb");
+ if (!file) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't open image file.");
+ return NULL;
+ }
+
+ dmnsn_canvas *canvas;
+ switch (filetype.type) {
+ case DMNSN_AST_PNG:
+ canvas = dmnsn_png_read_canvas(file);
+ if (!canvas) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Invalid PNG file.");
+ return NULL;
+ }
+ pigment = dmnsn_new_canvas_pigment(canvas);
+ break;
+
+ default:
+ dmnsn_assert(false, "Invalid image_map type.");
+ break;
+ }
+ break;
+ }
+
default:
- dmnsn_assert(false, "Invalid pigment color.");
+ dmnsn_assert(false, "Invalid pigment type.");
}
dmnsn_astnode modifiers;