--- parser3/src/classes/image.C 2001/04/10 14:00:02 1.3 +++ parser3/src/classes/image.C 2001/04/11 17:00:53 1.8 @@ -5,15 +5,19 @@ Author: Alexander Petrosyan (http://design.ru/paf) - $Id: image.C,v 1.3 2001/04/10 14:00:02 paf Exp $ + $Id: image.C,v 1.8 2001/04/11 17:00:53 paf Exp $ */ #include "pa_config_includes.h" +#include + #ifdef WIN32 # include "smtp/smtp.h" #endif +#include "gif.h" + #include "pa_common.h" #include "pa_request.h" #include "pa_vfile.h" @@ -269,22 +273,24 @@ static void _measure(Request& r, const S int width, height; measure(pool, *file_name, reader, width, height); - static_cast(r.self)->set(*file_name, width, height); + static_cast(r.self)->set(file_name, width, height); } +struct Attrib_info { + String *tag; + Hash *skip; +}; static void append_attrib_pair(const Hash::Key& key, Hash::Val *val, void *info) { - String& tag=*static_cast(info); + Attrib_info& ai=*static_cast(info); + + if(ai.skip && ai.skip->get(key)) + return; + Value& value=*static_cast(val); // src="a.gif" width=123 ismap[=-1] - tag << " " << key; - if(value.is_string() || value.as_double()>=0) { - tag << "="; - if(value.is_string()) - tag << "\""; - tag << value.as_string(); - if(value.is_string()) - tag << "\""; - } + *ai.tag << " " << key; + if(value.is_string() || value.as_double()>=0) + *ai.tag << "=\"" << value.as_string() << "\""; } /// ^image.html[] /// ^image.html[hash] @@ -293,11 +299,94 @@ static void _html(Request& r, const Stri String tag(pool); tag << "(r.self)->fields().for_each(append_attrib_pair, &tag); - tag << ">"; + + Hash& fields=static_cast(r.self)->fields(); + Hash *attribs=0; + + if(params) + if(attribs=static_cast(params->get(0))->get_hash()) { + Attrib_info attrib_info={&tag, 0}; + attribs->for_each(append_attrib_pair, &attrib_info); + } else + PTHROW(0, 0, + &method_name, + "attributes must be must be hash"); + + Attrib_info attrib_info={&tag, attribs}; + fields.for_each(append_attrib_pair, &attrib_info); + tag << " />"; r.write_pass_lang(tag); } +/// ^image.load[background.gif] +static void _load(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + Value& vfile_name=*static_cast(params->get(0)); + // forcing [this body type] + r.fail_if_junction_(true, vfile_name, method_name, "file name must not be code"); + const String& file_name=vfile_name.as_string(); + + const char *file_name_cstr=r.absolute(file_name).cstr(String::UL_FILE_NAME); + if(FILE *f=fopen(file_name_cstr, "rb")) { + gdImagePtr image=gdImageCreateFromGif(f); + int width=gdImageSX(image); + int height=gdImageSY(image); + fclose(f); + + static_cast(r.self)->set(&file_name, width, height, image); + } else + PTHROW(0, 0, + &method_name, + "can not open background image '%s'", file_name_cstr); +} + +/// ^image.create[width;height] bgcolor=white +/// ^image.create[width;height;bgcolor] +static void _create(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + int width=(int)r.process(*static_cast(params->get(0))).as_double(); + int height=(int)r.process(*static_cast(params->get(1))).as_double(); + int bgcolor_value=0xffFFff; + if(params->size()>2) + bgcolor_value= + (int)r.process(*static_cast(params->get(2))).as_double(); + gdImage *image=new(pool) gdImage(pool); + image->Create(width, height); + image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value)); + static_cast(r.self)->set(0, width, height, image); +} + +/// ^image.gif[] +/// ^image.gif[user-file-name] +/// @test gdImageDestroy make gd pooled! +static void _gif(Request& r, const String& method_name, Array *params) { + Pool& pool=r.pool(); + + gdImagePtr image=static_cast(r.self)->image; + if(!image) + PTHROW(0, 0, + &method_name, + "does not contain image"); + + char *file_name_cstr=0; + if(params) { + Value& vfile_name=*static_cast(params->get(0)); + // forcing [this body type] + r.fail_if_junction_(true, vfile_name, method_name, "file name must not be code"); + + file_name_cstr=vfile_name.as_string().cstr(String::UL_FILE_NAME); + } + // could _ but don't thing it's wise to use $image.src for vfile.name + + VFile& vfile=*new(pool) VFile(pool); + String& image_gif=*new(pool) String(pool, "image/gif"); + vfile.set(false/*not tainted*/, z, z, file_name_cstr, &image_gif); + + r.write_no_lang(vfile); +} + // initialize void initialize_image_class(Pool& pool, VStateless_class& vclass) { // ^image:measure[DATA] @@ -306,4 +395,15 @@ void initialize_image_class(Pool& pool, /// ^image.html[] /// ^image.html[hash] vclass.add_native_method("html", Method::CT_DYNAMIC, _html, 0, 1); + + /// ^image.load[background.gif] + vclass.add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1); + + /// ^image.create[width;height] bgcolor=white + /// ^image.create[width;height;bgcolor] + vclass.add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3); + + /// ^image.gif[] + /// ^image.gif[user-file-name] + vclass.add_native_method("gif", Method::CT_DYNAMIC, _gif, 0, 1); }