--- parser3/src/classes/image.C 2003/03/21 14:27:50 1.90.2.15.2.9 +++ parser3/src/classes/image.C 2003/11/07 13:59:21 1.97 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_IMAGE_C="$Date: 2003/03/21 14:27:50 $"; +static const char* IDENT_IMAGE_C="$Date: 2003/11/07 13:59:21 $"; /* jpegsize: gets the width and height (in pixels) of a jpeg file @@ -33,7 +33,7 @@ static const char* IDENT_IMAGE_C="$Date: class MImage: public Methoded { public: // VStateless_class - Value* create_new_value() { return Value*(new VImage()); } + Value* create_new_value(Pool& apool) { return new VImage(); } public: MImage(); @@ -175,11 +175,11 @@ public: if(limit==0) return 0; - char* lbuf=new char[limit]; + char* lbuf=new(PointerFreeGC) char[limit]; size_t read_size=(size_t)::read(f, lbuf, limit); abuf=lbuf; if(ssize_t(read_size)<0 || read_size>limit) throw Exception(0, - file_name, + &file_name, "measure failed: actually read %lu bytes count not in [0..%lu] valid range", read_size, limit); @@ -189,7 +189,7 @@ public: override void seek(long value, int whence) { if(lseek(f, value, whence)<0) throw Exception("image.format", - file_name, + &file_name, "seek(value=%ld, whence=%d) failed: %s (%d), actual filename '%s'", value, whence, strerror(errno), errno, fname); } @@ -231,7 +231,7 @@ public: if((ssize_t)new_offset<0 || new_offset>size) throw Exception("image.format", - file_name, + &file_name, "seek(value=%l, whence=%d) failed: out of buffer, new_offset>size (%l>%l) or new_offset<0", value, whence, new_offset, size); offset=new_offset; @@ -327,20 +327,20 @@ inline uint endian_to_uint(bool is_big, x_endian_to_uint(b[0], b[1], b[2], b[3]); } -static void measure_gifconst String* origin_string, +static void measure_gif(const String& origin_string, Measure_reader& reader, ushort& width, ushort& height) { const char* buf; const int head_size=sizeof(GIF_Header); if(reader.read(buf, head_size)signature, "GIF", 3)!=0) throw Exception("image.format", - origin_string, + &origin_string, "not GIF file - wrong signature"); width=endian_to_ushort(false, head->width); @@ -354,33 +354,33 @@ static Value* parse_IFD_entry_formatted_ const uchar *value) { switch(format) { case 1: // unsigned byte - return Value*(new VInt((uchar)value[0])); + return new VInt((uchar)value[0]); case 3: // unsigned short - return Value*(new VInt(endian_to_ushort(is_big, value))); + return new VInt(endian_to_ushort(is_big, value)); case 4: // unsigned long // 'double' because parser's Int is signed - return Value*(new VDouble(endian_to_uint(is_big, value))); + return new VDouble(endian_to_uint(is_big, value)); case 5: // unsigned rational { uint numerator=endian_to_uint(is_big, value); value+=component_size/2; uint denominator=endian_to_uint(is_big, value); if(!denominator) return 0; - return Value*(new VDouble(((double)numerator)/denominator)); + return new VDouble(((double)numerator)/denominator); } case 6: // signed byte - return Value*(new VInt((signed char)value[0])); + return new VInt((signed char)value[0]); case 8: // signed short - return Value*(new VInt((signed short)endian_to_ushort(is_big, value))); + return new VInt((signed short)endian_to_ushort(is_big, value)); case 9: // signed long - return Value*(new VInt((signed int)endian_to_uint(is_big, value))); + return new VInt((signed int)endian_to_uint(is_big, value)); case 10: // signed rational { signed int numerator=(signed int)endian_to_uint(is_big, value); value+=component_size/2; uint denominator=endian_to_uint(is_big, value); if(!denominator) return 0; - return Value*(new VDouble(numerator/denominator)); + return new VDouble(numerator/denominator); } /* case 11: // single float @@ -394,42 +394,40 @@ static Value* parse_IFD_entry_formatted_ } // date.C -time_t cstr_to_time_t(char *cstr, const String& report_error_origin); +time_t cstr_to_time_t(char *cstr, bool fail_on_error); -static Value* parse_IFD_entry_formatted_value( - bool is_big, ushort format, - size_t component_size, uint components_count, - const uchar *value) { +static Value* parse_IFD_entry_formatted_value(bool is_big, ushort format, + size_t component_size, uint components_count, + const uchar *value) { if(format==2) { // ascii string, exception: the only type with varying size const char* cstr=(const char* )value; - size_t size=components_count; + size_t length=components_count; // Data format is "YYYY:MM:DD HH:MM:SS"+0x00, total 20bytes - if(size==JPEG_EXIF_DATE_CHARS + if(length==JPEG_EXIF_DATE_CHARS && isdigit(cstr[0]) - && cstr[JPEG_EXIF_DATE_CHARS-1]==0) { + && cstr[length-1]==0) { char cstr_writable[JPEG_EXIF_DATE_CHARS]; strcpy(cstr_writable, cstr); time_t t=cstr_to_time_t(cstr_writable, - 0/* do not throw exception, just return bad result */); + false/* do not throw exception, just return bad result */); if(t>=0) - return Value*(new VDate(t)); + return new VDate(t); } - if(const char* premature_zero_pos=(const char* )memchr(cstr, 0, size)) - size=premature_zero_pos-cstr; - return Value*(new VString(String* (new String(cstr, size, true/*tainted*/)))); + if(const char* premature_zero_pos=(const char* )memchr(cstr, 0, length)) + length=premature_zero_pos-cstr; + return new VString(*new String(cstr, length, true/*tainted*/)); } if(components_count==1) return parse_IFD_entry_formatted_one_value(is_big, format, component_size, value); - VHash* result(new VHash); - HashStringValue& hash=result->hash(0); + VHash* result=new VHash; + HashStringValue& hash=result->hash(); for(uint i=0; ifirst_IFD_offset); reader.seek(tiff_base+first_IFD_offset, SEEK_SET); - VHash* vhash(new VHash); + VHash* vhash=new VHash; // IFD - parse_IFD(vhash->hash(0), is_big, reader, tiff_base); + parse_IFD(vhash->hash(), is_big, reader, tiff_base); return vhash; } -static void measure_jpegconst String* origin_string, +static void measure_jpeg(const String& origin_string, Measure_reader& reader, ushort& width, ushort& height, Value** exif) { // JFIF format markers const uchar MARKER=0xFF; @@ -586,13 +579,13 @@ static void measure_jpegconst String* or const size_t prefix_size=2; if(reader.read(buf, prefix_size)marker!=MARKER) throw Exception("image.format", - origin_string, + &origin_string, "not JPEG file - marker not found"); switch(head->code) { @@ -622,7 +615,7 @@ static void measure_jpegconst String* or // Segments that contain size info if(reader.read(buf, sizeof(JPG_Size_segment_body))signature, "IHDR", 4)!=0) throw Exception("image.format", - origin_string, + &origin_string, "not PNG file - wrong signature"); width=endian_to_ushort(true, head->width); @@ -662,9 +655,9 @@ static void measure_pngconst String* ori // measure center -static void measureconst String& file_name, +static void measure(const String& file_name, Measure_reader& reader, ushort& width, ushort& height, Value** exif) { - const char* file_name_cstr=file_name->cstr(String::L_FILE_SPEC); + const char* file_name_cstr=file_name.cstr(String::L_FILE_SPEC); if(const char* cext=strrchr(file_name_cstr, '.')) { cext++; if(strcasecmp(cext, "GIF")==0) @@ -675,11 +668,11 @@ static void measureconst String& file_na measure_png(file_name, reader, width, height); else throw Exception("image.format", - file_name, + &file_name, "unhandled image file name extension '%s'", cext); } else throw Exception("image.format", - file_name, + &file_name, "can not determine image type - no file name extension"); } @@ -690,7 +683,7 @@ struct File_measure_action_info { ushort* width; ushort* height; Value** exif; - const String& file_name; + const String* file_name; }; #endif static void file_measure_action( @@ -699,61 +692,59 @@ static void file_measure_action( void *context) { File_measure_action_info& info=*static_cast(context); - Measure_file_reader reader(f, info.file_name, fname); - measure(info.file_name, reader, *info.width, *info.height, info.exif); + Measure_file_reader reader(f, *info.file_name, fname); + measure(*info.file_name, reader, *info.width, *info.height, info.exif); } -static void _measure(Request& r, const String& method_name, MethodParams* params) { - - Value* data=params->as_no_junction(0, "data must not be code"); +static void _measure(Request& r, MethodParams& params) { + Value& data=params.as_no_junction(0, "data must not be code"); ushort width=0; ushort height=0; - Value* exif(0); - const String& file_name; - if(file_name=data->get_string()) { - File_measure_action_info info; + Value* exif=0; + const String* file_name; + if(file_name=data.get_string()) { + File_measure_action_info info={0}; info.width=&width; info.height=&height; info.exif=&exif; info.file_name=file_name; - file_read_action_under_lock(r.absolute(file_name), + file_read_action_under_lock(r.absolute(*file_name), "measure", file_measure_action, &info); } else { - VFile* vfile=data->as_vfile(); - file_name=vfile->fields().get(name_name)->as_string(); + VFile* vfile=data.as_vfile(); + file_name=&vfile->fields().get(name_name)->as_string(); Measure_buf_reader reader( vfile->value_ptr(), vfile->value_size(), - file_name + *file_name ); - measure(file_name, reader, width, height, &exif); + measure(*file_name, reader, width, height, &exif); } - GET_SELF(r, VImage).set(file_name, width, height, gdImage*(0), exif); + GET_SELF(r, VImage).set(file_name, width, height, 0, exif); } #ifndef DOXYGEN struct Attrib_info { - ; String* tag; ///< html tag being constructed HashStringValue* skip; ///< tag attributes not to append to tag string [to skip] }; #endif static void append_attrib_pair( - HashStringValue::key_type key, - HashStringValue::value_type value, - Attrib_info* info) { + HashStringValue::key_type key, + HashStringValue::value_type value, + Attrib_info* info) { // skip user-specified and internal(starting with "line-") attributes - if(info->skip && info->skip->get(key) || key->pos("line-")==0) + if(info->skip && info->skip->get(key) || key.pos("line-")==0) return; // src="a.gif" width=123 ismap[=-1] *info->tag << " " << key; if(value->is_string() || value->as_int()>=0) - *info->tag << "=\"" << value->as_string(info->pool) << "\""; + *info->tag << "=\"" << value->as_string() << "\""; } -static void _html(Request& r, const String& method_name, MethodParams* params) { +static void _html(Request& r, MethodParams& params) { String tag; tag << "count()) { + if(params.count()) { // for backward compatibility: someday was ^html{} - Value* vattribs=r.process_to_value(params->get(0), + Value& vattribs=r.process_to_value(params[0], /*0/*no name* /,*/ false/*don't intercept string*/); - if(!vattribs->is_string()) // allow empty - if(attribs=vattribs->get_hash(method_name)) { - Attrib_info info={&&tag}; + if(!vattribs.is_string()) // allow empty + if(attribs=vattribs.get_hash()) { + Attrib_info info={&tag}; attribs->for_each(append_attrib_pair, &info); } else throw Exception("parser.runtime", - method_name, + 0, "attributes must be hash"); } { - Attrib_info info={&&tag, attribs}; + Attrib_info info={&tag, attribs}; fields.for_each(append_attrib_pair, &info); } tag << " />"; @@ -785,129 +776,125 @@ static void _html(Request& r, const Stri } /// @test wrap FILE to auto-object -static gdImage* load(Request& r, const String& method_name, +static gdImage* load(Request& r, const String& file_name){ - - const char* file_name_cstr=r.absolute(file_name)->cstr(String::L_FILE_SPEC); + const char* file_name_cstr=r.absolute(file_name).cstr(String::L_FILE_SPEC); if(FILE *f=fopen(file_name_cstr, "rb")) { - gdImage* image(new gdImage); + gdImage* image=new gdImage; bool ok=image->CreateFromGif(f); fclose(f); if(!ok) throw Exception("image.format", - file_name, + &file_name, "is not in GIF format"); return image; } else { throw Exception("file.missing", - method_name, - "can not open '%s'", file_name_cstr.get()); - return gdImage*(0); + 0, + "can not open '%s'", file_name_cstr); + return 0; } } -static void _load(Request& r, const String& method_name, MethodParams* params) { +static void _load(Request& r, MethodParams& params) { + const String& file_name=params.as_string(0, "file name must not be code"); - const String& file_name=params->as_string(0, "file name must not be code"); - - gdImage* image=load(r, method_name, file_name); - GET_SELF(r, VImage).set(file_name, image->SX(), image->SY(), image); + gdImage* image=load(r, file_name); + GET_SELF(r, VImage).set(&file_name, image->SX(), image->SY(), image); } -static void _create(Request& r, const String& method_name, MethodParams* params) { - - int width=params->as_int(0, "width must be int", r); - int height=params->as_int(1, "height must be int", r); +static void _create(Request& r, MethodParams& params) { + int width=params.as_int(0, "width must be int", r); + int height=params.as_int(1, "height must be int", r); int bgcolor_value=0xffFFff; - if(params->count()>2) - bgcolor_value=params->as_int(2, "color must be int", r); - gdImage* image(new gdImage); + if(params.count()>2) + bgcolor_value=params.as_int(2, "color must be int", r); + gdImage* image=new gdImage; image->Create(width, height); image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value)); GET_SELF(r, VImage).set(0, width, height, image); } -static void _gif(Request& r, const String& method_name, MethodParams* params) { - +static void _gif(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - // could _ but don't thing it's wise to use $image.src for vfile.name + const String *file_name=0; + if(params.count()>0) + file_name=¶ms.as_string(0, "file name must be string"); - String out; image->Gif(out); + gdBuf buf=image->Gif(); - VFile* vfile(new VFile); - Value* content_type(new VString(String* (new String("image/gif")))); - vfile->set(false/*not tainted*/, - out.cstr(), out.length(), 0, content_type); + VFile& vfile=*new VFile; + Value* content_type=new VString(*new String("image/gif")); + vfile.set(false/*not tainted*/, + (const char*)buf.ptr, buf.size, + file_name? file_name->cstr(String::L_FILE_SPEC): 0, + content_type); r.write_no_lang(vfile); } -static void _line(Request& r, const String& method_name, MethodParams* params) { - +static void _line(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->Line( - params->as_int(0, "x0 must be int", r), - params->as_int(1, "y0 must be int", r), - params->as_int(2, "x1 must be int", r), - params->as_int(3, "y1 must be int", r), - image->Color(params->as_int(4, "color must be int", r))); + params.as_int(0, "x0 must be int", r), + params.as_int(1, "y0 must be int", r), + params.as_int(2, "x1 must be int", r), + params.as_int(3, "y1 must be int", r), + image->Color(params.as_int(4, "color must be int", r))); } -static void _fill(Request& r, const String& method_name, MethodParams* params) { - +static void _fill(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->Fill( - params->as_int(0, "x must be int", r), - params->as_int(1, "y must be int", r), - image->Color(params->as_int(2, "color must be int", r))); + params.as_int(0, "x must be int", r), + params.as_int(1, "y must be int", r), + image->Color(params.as_int(2, "color must be int", r))); } -static void _rectangle(Request& r, const String& method_name, MethodParams* params) { - +static void _rectangle(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->Rectangle( - params->as_int(0, "x0 must be int", r), - params->as_int(1, "y0 must be int", r), - params->as_int(2, "x1 must be int", r), - params->as_int(3, "y1 must be int", r), - image->Color(params->as_int(4, "color must be int", r))); + params.as_int(0, "x0 must be int", r), + params.as_int(1, "y0 must be int", r), + params.as_int(2, "x1 must be int", r), + params.as_int(3, "y1 must be int", r), + image->Color(params.as_int(4, "color must be int", r))); } -static void _bar(Request& r, const String& method_name, MethodParams* params) { - +static void _bar(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->FilledRectangle( - params->as_int(0, "x0 must be int", r), - params->as_int(1, "y0 must be int", r), - params->as_int(2, "x1 must be int", r), - params->as_int(3, "y1 must be int", r), - image->Color(params->as_int(4, "color must be int", r))); + params.as_int(0, "x0 must be int", r), + params.as_int(1, "y0 must be int", r), + params.as_int(2, "x1 must be int", r), + params.as_int(3, "y1 must be int", r), + image->Color(params.as_int(4, "color must be int", r))); } #ifndef DOXYGEN @@ -918,90 +905,86 @@ static void add_point(Table::element_typ (*p)++; } #endif -static void _replace(Request& r, const String& method_name, MethodParams* params) { - +static void _replace(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - Table* table=params->as_no_junction(2, "coordinates must not be code")->get_table(); + Table* table=params.as_no_junction(2, "coordinates must not be code").get_table(); if(!table) throw Exception(0, - method_name, + 0, "coordinates must be table"); - gdImage::Point *all_p=new gdImage::Point[table->count()]; + gdImage::Point *all_p=new(PointerFreeGC) gdImage::Point[table->count()]; gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->FilledPolygonReplaceColor(all_p, table->count(), - image->Color(params->as_int(0, "src color must be int", r)), - image->Color(params->as_int(1, "dest color must be int", r))); + image->Color(params.as_int(0, "src color must be int", r)), + image->Color(params.as_int(1, "dest color must be int", r))); } -static void _polyline(Request& r, const String& method_name, MethodParams* params) { - +static void _polyline(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params.as_no_junction(1, "coordinates must not be code").get_table(); if(!table) throw Exception(0, - method_name, + 0, "coordinates must be table"); - gdImage::Point* all_p=new gdImage::Point[table->count()]; + gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()]; gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->Polygon(all_p, table->count(), - image->Color(params->as_int(0, "color must be int", r)), + image->Color(params.as_int(0, "color must be int", r)), false/*not closed*/); } -static void _polygon(Request& r, const String& method_name, MethodParams* params) { - +static void _polygon(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params.as_no_junction(1, "coordinates must not be code").get_table(); if(!table) throw Exception(0, - method_name, + 0, "coordinates must be table"); - gdImage::Point* all_p=new gdImage::Point[table->count()]; + gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()]; gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->Polygon(all_p, table->count(), - image->Color(params->as_int(0, "color must be int", r))); + image->Color(params.as_int(0, "color must be int", r))); } -static void _polybar(Request& r, const String& method_name, MethodParams* params) { - +static void _polybar(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params.as_no_junction(1, "coordinates must not be code").get_table(); if(!table) throw Exception("parser.runtime", - method_name, + 0, "coordinates must be table"); - gdImage::Point* all_p=new gdImage::Point[table->count()]; + gdImage::Point* all_p=new(PointerFreeGC) gdImage::Point[table->count()]; gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->FilledPolygon(all_p, table->count(), - image->Color(params->as_int(0, "color must be int", r))); + image->Color(params.as_int(0, "color must be int", r))); } // font @@ -1022,13 +1005,13 @@ Font::Font(//, /* ******************************** char ********************************** */ -int Font::index_of(char ch) { - if(ch==' ') return -1; - return alphabet->pos(&ch, 1); +size_t Font::index_of(char ch) { + if(ch==' ') return STRING_NOT_FOUND; + return alphabet.pos(ch); } -int Font::index_width(int index) { - if(index<0) +int Font::index_width(size_t index) { + if(index==STRING_NOT_FOUND) return spacebarspace; int tr=ifont->GetTransparent(); for(int x=ifont->SX()-1; x>=0; x--) { @@ -1039,8 +1022,8 @@ int Font::index_width(int index) { return 0; } -void Font::index_display(gdImage* image, int x, int y, int index){ - if(index>=0) +void Font::index_display(gdImage* image, int x, int y, size_t index){ + if(index!=STRING_NOT_FOUND) ifont->Copy(*image, x, y, 0, Y(0), index_width(index), height); } @@ -1052,7 +1035,7 @@ int Font::step_width(int index) { // counts trailing letter_spacing, consider this OK. useful for contiuations int Font::string_width(const String& s){ - const char* cstr=s->cstr(); + const char* cstr=s.cstr(); int result=0; for(const char* current=cstr; *current; current++) result+=step_width(index_of(*current)); @@ -1060,9 +1043,9 @@ int Font::string_width(const String& s){ } void Font::string_display(gdImage* image, int x, int y, const String& s){ - const char* cstr=s->cstr(); + const char* cstr=s.cstr(); for(const char* current=cstr; *current; current++) { - int index=index_of(*current); + size_t index=index_of(*current); index_display(image, x, y, index); x+=step_width(index); } @@ -1071,41 +1054,39 @@ void Font::string_display(gdImage* image // -static void _font(Request& r, const String& method_name, MethodParams* params) { - - const String& alphabet=params->as_string(0, "alphabet must not be code"); - gdImage* image=load(r, method_name, params->as_string(1, "file_name must not be code")); - int spacebar_width=params->as_int(2, "spacebar_width must be int", r); +static void _font(Request& r, MethodParams& params) { + const String& alphabet=params.as_string(0, "alphabet must not be code"); + gdImage* image=load(r, params.as_string(1, "file_name must not be code")); + int spacebar_width=params.as_int(2, "spacebar_width must be int", r); int monospace_width; - if(params->count()>3) { - monospace_width=params->as_int(3, "monospace_width must be int", r); + if(params.count()>3) { + monospace_width=params.as_int(3, "monospace_width must be int", r); if(!monospace_width) monospace_width=image->SX(); } else monospace_width=0; - if(!alphabet->length()) + if(!alphabet.length()) throw Exception("parser.runtime", - method_name, + 0, "alphabet must not be empty"); - if(int remainder=image->SY() % alphabet->length()) + if(int remainder=image->SY() % alphabet.length()) throw Exception("parser.runtime", - method_name, + 0, "font-file height(%d) not divisable by alphabet size(%d), remainder=%d", - image->SY(), alphabet->length(), remainder); + image->SY(), alphabet.length(), remainder); - GET_SELF(r, VImage).font=Font*(new Font(// + GET_SELF(r, VImage).font=new Font( alphabet, image, - image->SY() / alphabet->length(), monospace_width, spacebar_width)); + image->SY() / alphabet.length(), monospace_width, spacebar_width); } -static void _text(Request& r, const String& method_name, MethodParams* params) { - - int x=params->as_int(0, "x must be int", r); - int y=params->as_int(1, "y must be int", r); - const String& s=params->as_string(2, "text must not be code"); +static void _text(Request& r, MethodParams& params) { + int x=params.as_int(0, "x must be int", r); + int y=params.as_int(1, "y must be int", r); + const String& s=params.as_string(2, "text must not be code"); VImage& vimage=GET_SELF(r, VImage); if(vimage.image) @@ -1113,129 +1094,123 @@ static void _text(Request& r, const Stri vimage.font->string_display(vimage.image, x, y, s); else throw Exception("parser.runtime", - method_name, + 0, "set the font first"); else throw Exception(0, - method_name, + 0, "does not contain an image"); } -static void _length(Request& r, const String& method_name, MethodParams* params) { - - const const String& s=params->as_string(0, "text must not be code"); +static void _length(Request& r, MethodParams& params) { + const String& s=params.as_string(0, "text must not be code"); VImage& vimage=GET_SELF(r, VImage); if(vimage.image) if(vimage.font) { - r.write_no_lang(Value*(new VInt(vimage.font->string_width(s)))); + r.write_no_lang(*new VInt(vimage.font->string_width(s))); } else throw Exception("parser.runtime", - method_name, + 0, "set the font first"); else throw Exception(0, - method_name, + 0, "does not contain an image"); } -static void _arc(Request& r, const String& method_name, MethodParams* params) { - +static void _arc(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->Arc( - params->as_int(0, "center_x must be int", r), - params->as_int(1, "center_y must be int", r), - params->as_int(2, "width must be int", r), - params->as_int(3, "height must be int", r), - params->as_int(4, "start degrees must be int", r), - params->as_int(5, "end degrees must be int", r), - image->Color(params->as_int(6, "cx must be int", r))); + params.as_int(0, "center_x must be int", r), + params.as_int(1, "center_y must be int", r), + params.as_int(2, "width must be int", r), + params.as_int(3, "height must be int", r), + params.as_int(4, "start degrees must be int", r), + params.as_int(5, "end degrees must be int", r), + image->Color(params.as_int(6, "cx must be int", r))); } -static void _sector(Request& r, const String& method_name, MethodParams* params) { - +static void _sector(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); image->Sector( - params->as_int(0, "center_x must be int", r), - params->as_int(1, "center_y must be int", r), - params->as_int(2, "width must be int", r), - params->as_int(3, "height must be int", r), - params->as_int(4, "start degrees must be int", r), - params->as_int(5, "end degrees must be int", r), - image->Color(params->as_int(6, "color must be int", r))); + params.as_int(0, "center_x must be int", r), + params.as_int(1, "center_y must be int", r), + params.as_int(2, "width must be int", r), + params.as_int(3, "height must be int", r), + params.as_int(4, "start degrees must be int", r), + params.as_int(5, "end degrees must be int", r), + image->Color(params.as_int(6, "color must be int", r))); } -static void _circle(Request& r, const String& method_name, MethodParams* params) { - +static void _circle(Request& r, MethodParams& params) { gdImage* image=GET_SELF(r, VImage).image; if(!image) throw Exception(0, - method_name, + 0, "does not contain an image"); - int size=params->as_int(2, "radius must be int", r)*2; + int size=params.as_int(2, "radius must be int", r)*2; image->Arc( - params->as_int(0, "center_x must be int", r), - params->as_int(1, "center_y must be int", r), + params.as_int(0, "center_x must be int", r), + params.as_int(1, "center_y must be int", r), size, //w size, //h 0, //s 360, //e - image->Color(params->as_int(3, "color must be int", r))); + image->Color(params.as_int(3, "color must be int", r))); } -gdImage* as_imageconst String& method_name, MethodParams* params, - int index, const char* msg) { - gdImage* src(0); +gdImage* as_image(MethodParams& params, int index, const char* msg) { + gdImage* src=0; - Value* value=params->as_no_junction(index, msg); + Value& value=params.as_no_junction(index, msg); - if(Value* vimage=value->as(VIMAGE_TYPE, false)) { + if(Value* vimage=value.as(VIMAGE_TYPE, false)) { src=static_cast(vimage)->image; if(!src) throw Exception("parser.runtime", - method_name, + 0, msg); } else throw Exception("parser.runtime", - method_name, + 0, msg); return src; } -static void _copy(Request& r, const String& method_name, MethodParams* params) { - +static void _copy(Request& r, MethodParams& params) { gdImage* dest=GET_SELF(r, VImage).image; if(!dest) throw Exception(0, - method_name, + 0, "self does not contain an image"); - gdImage* src=as_image(method_name, params, 0, "src must be image"); + gdImage* src=as_image(params, 0, "src must be image"); - int sx=params->as_int(1, "src_x must be int", r); - int sy=params->as_int(2, "src_y must be int", r); - int sw=params->as_int(3, "src_w must be int", r); - int sh=params->as_int(4, "src_h must be int", r); - int dx=params->as_int(5, "dest_x must be int", r); - int dy=params->as_int(6, "dest_y must be int", r); - if(params->count()>1+2+2+2) { - int dw=params->as_int(1+2+2+2, "dest_w must be int", r); - int dh=(int)(params->count()>1+2+2+2+1? - params->as_int(1+2+2+2+1, "dest_h must be int", r):sh*(((double)dw)/((double)sw))); - int tolerance=params->count()>1+2+2+2+2? - params->as_int(1+2+2+2+2, "tolerance must be int", r):150; + int sx=params.as_int(1, "src_x must be int", r); + int sy=params.as_int(2, "src_y must be int", r); + int sw=params.as_int(3, "src_w must be int", r); + int sh=params.as_int(4, "src_h must be int", r); + int dx=params.as_int(5, "dest_x must be int", r); + int dy=params.as_int(6, "dest_y must be int", r); + if(params.count()>1+2+2+2) { + int dw=params.as_int(1+2+2+2, "dest_w must be int", r); + int dh=(int)(params.count()>1+2+2+2+1? + params.as_int(1+2+2+2+1, "dest_h must be int", r):sh*(((double)dw)/((double)sw))); + int tolerance=params.count()>1+2+2+2+2? + params.as_int(1+2+2+2+2, "tolerance must be int", r):150; src->CopyResampled(*dest, dx, dy, sx, sy, dw, dh, sw, sh, tolerance); } else @@ -1261,7 +1236,7 @@ MImage::MImage(): Methoded("image") { add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3); // ^image.gif[] - add_native_method("gif", Method::CT_DYNAMIC, _gif, 0, 0); + add_native_method("gif", Method::CT_DYNAMIC, _gif, 0, 1); // ^image.line(x0;y0;x1;y1;color) add_native_method("line", Method::CT_DYNAMIC, _line, 5, 5);