From 7577a2b69f9a77962912753b6768b38db4e3c454 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 15 Apr 2010 23:31:24 -0400 Subject: Initial support for image_maps. --- dimension/common.nonterminals | 1 + dimension/common.rules | 18 ++++++++++++++++ dimension/common.terminals | 4 ++-- dimension/grammar.epilogue | 2 ++ dimension/lexer.l | 2 ++ dimension/parse.h | 2 ++ dimension/realize.c | 49 ++++++++++++++++++++++++++++++++++++++----- 7 files changed, 71 insertions(+), 7 deletions(-) (limited to 'dimension') 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 PIGMENT %type PIGMENT_TYPE %type PIGMENT_MODIFIERS +%type BITMAP_TYPE /* Finishes */ %type 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; -- cgit v1.2.3