Diff for /parser3/src/classes/image.C between versions 1.90.2.15.2.13 and 1.107

version 1.90.2.15.2.13, 2003/03/24 13:43:39 version 1.107, 2004/02/19 15:38:00
Line 1 Line 1
 /** @file  /** @file
         Parser: @b image parser class.          Parser: @b image parser class.
   
         Copyright(c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
 static const char* IDENT_IMAGE_C="$Date$";  static const char * const IDENT_IMAGE_C="$Date$";
   
 /*  /*
         jpegsize: gets the width and height (in pixels) of a jpeg file          jpegsize: gets the width and height (in pixels) of a jpeg file
Line 33  static const char* IDENT_IMAGE_C="$Date$ Line 33  static const char* IDENT_IMAGE_C="$Date$
   
 class MImage: public Methoded {  class MImage: public Methoded {
 public: // VStateless_class  public: // VStateless_class
         Value* create_new_value() { return new VImage(); }          Value* create_new_value(Pool&) { return new VImage(); }
   
 public:  public:
         MImage();          MImage();
Line 161  public: Line 161  public:
 };  };
   
 class Measure_file_reader: public Measure_reader {  class Measure_file_reader: public Measure_reader {
   
         ;  
         const String& file_name; const char* fname;          const String& file_name; const char* fname;
         int f;          int f;
   
Line 180  public: Line 178  public:
                 if(ssize_t(read_size)<0 || read_size>limit)                  if(ssize_t(read_size)<0 || read_size>limit)
                         throw Exception(0,                          throw Exception(0,
                                 &file_name,                                   &file_name, 
                                 "measure failed: actually read %lu bytes count not in [0..%lu] valid range",                                   "measure failed: actually read %u bytes count not in [0..%u] valid range", 
                         read_size, limit);                          read_size, limit);
   
                 return read_size;                  return read_size;
Line 331  static void measure_gif(const String& or Line 329  static void measure_gif(const String& or
                          Measure_reader& reader, ushort& width, ushort& height) {                           Measure_reader& reader, ushort& width, ushort& height) {
   
         const char* buf;          const char* buf;
         const int head_size=sizeof(GIF_Header);          const size_t head_size=sizeof(GIF_Header);
         if(reader.read(buf, head_size)<head_size)          if(reader.read(buf, head_size)<head_size)
                 throw Exception("image.format",                   throw Exception("image.format", 
                         &origin_string,                           &origin_string, 
Line 394  static Value* parse_IFD_entry_formatted_ Line 392  static Value* parse_IFD_entry_formatted_
 }  }
   
 // date.C  // date.C
 time_t cstr_to_time_t(char *cstr, bool fail_on_error);  tm cstr_to_time_t(char *cstr);
   
 static Value* parse_IFD_entry_formatted_value(  static Value* parse_IFD_entry_formatted_value(bool is_big, ushort format, 
                                                                                           bool is_big, ushort format,                                                 size_t component_size, uint components_count, 
                                                                                           size_t component_size, uint components_count,                                                 const uchar *value) {
                                                                                           const uchar *value) {  
         if(format==2) { // ascii string, exception: the only type with varying size          if(format==2) { // ascii string, exception: the only type with varying size
                 const char* cstr=(const char* )value;                  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                  // 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])                          && isdigit(cstr[0])
                         && cstr[JPEG_EXIF_DATE_CHARS-1]==0) {                          && cstr[length-1]==0) {
                         char cstr_writable[JPEG_EXIF_DATE_CHARS];                           char cstr_writable[JPEG_EXIF_DATE_CHARS]; 
                         strcpy(cstr_writable, cstr);                          strcpy(cstr_writable, cstr);
   
                         time_t t=cstr_to_time_t(cstr_writable,                           try {
                                 0/* do not throw exception, just return bad result */);                                  return new VDate(cstr_to_time_t(cstr_writable));
                         if(t>=0)                          }
                                 return new VDate(t);                          catch(...) { /*ignore bad date times*/ }
                 }                  }
   
                 if(const char* premature_zero_pos=(const char* )memchr(cstr, 0, size))                  if(const char* premature_zero_pos=(const char* )memchr(cstr, 0, length))
                         size=premature_zero_pos-cstr;                          length=premature_zero_pos-cstr;
                 return new VString(*new String(cstr, size, true/*tainted*/));                  return new VString(*new String(cstr, length, true/*tainted*/));
         }          }
   
         if(components_count==1)          if(components_count==1)
Line 428  static Value* parse_IFD_entry_formatted_ Line 425  static Value* parse_IFD_entry_formatted_
         HashStringValue& hash=result->hash();          HashStringValue& hash=result->hash();
         for(uint i=0; i<components_count; i++, value+=component_size) {          for(uint i=0; i<components_count; i++, value+=component_size) {
                 hash.put(                  hash.put(
                         StringBody(pa_format_integer(i)),                          String::Body::Format(i),
                         parse_IFD_entry_formatted_one_value(is_big, format, component_size, value));                          parse_IFD_entry_formatted_one_value(is_big, format, component_size, value));
         }          }
   
Line 513  static void parse_IFD_entry(HashStringVa Line 510  static void parse_IFD_entry(HashStringVa
                   
         if(Value* value=parse_IFD_entry_value(is_big, reader, tiff_base, entry)) {          if(Value* value=parse_IFD_entry_value(is_big, reader, tiff_base, entry)) {
                 if(const char* name=exif_tag_value2name.get(tag))                  if(const char* name=exif_tag_value2name.get(tag))
                         hash.put(StringBody(name), value);                          hash.put(String::Body(name), value);
                 else                  else
                         hash.put(StringBody(pa_format_integer(tag)), value);                          hash.put(String::Body::Format(tag), value);
         }          }
 }  }
   
Line 638  static void measure_png(const String& or Line 635  static void measure_png(const String& or
                          Measure_reader& reader, ushort& width, ushort& height) {                           Measure_reader& reader, ushort& width, ushort& height) {
   
         const char* buf;          const char* buf;
         const int head_size=sizeof(PNG_Header);          const size_t head_size=sizeof(PNG_Header);
         if(reader.read(buf, head_size)<head_size)          if(reader.read(buf, head_size)<head_size)
                 throw Exception("image.format",                   throw Exception("image.format", 
                         &origin_string,                           &origin_string, 
Line 688  struct File_measure_action_info { Line 685  struct File_measure_action_info {
 };  };
 #endif  #endif
 static void file_measure_action(  static void file_measure_action(
                                                                 struct stat& finfo, int f,                                                                   struct stat& /*finfo*/, int f, 
                                                                 const String& file_spec, const char* fname, bool as_text,                                                                  const String& /*file_spec*/, const char* fname, bool /*as_text*/,
                                                                 void *context) {                                                                  void *context) {
         File_measure_action_info& info=*static_cast<File_measure_action_info *>(context);          File_measure_action_info& info=*static_cast<File_measure_action_info *>(context);
   
Line 697  static void file_measure_action( Line 694  static void file_measure_action(
         measure(*info.file_name, reader, *info.width, *info.height, info.exif);          measure(*info.file_name, reader, *info.width, *info.height, info.exif);
 }  }
   
 static void _measure(Request& r, MethodParams* params) {  static void _measure(Request& r, MethodParams& params) {
         Value& data=params->as_no_junction(0, "data must not be code");          Value& data=params.as_no_junction(0, "data must not be code");
   
         ushort width=0;          ushort width=0;
         ushort height=0;          ushort height=0;
         Value* exif=0;          Value* exif=0;
         const String* file_name;          const String* file_name;
         if(file_name=data.get_string()) {          if((file_name=data.get_string())) {
                 File_measure_action_info info;                  File_measure_action_info info={
                 info.width=&width;                          &width, &height,
                 info.height=&height;                          &exif,
                 info.exif=&exif;                          file_name
                 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);                          "measure", file_measure_action, &info);
         } else {          } else {
Line 745  static void append_attrib_pair( Line 742  static void append_attrib_pair(
         if(value->is_string() || value->as_int()>=0)          if(value->is_string() || value->as_int()>=0)
                 *info->tag << "=\"" << value->as_string() << "\"";                  *info->tag << "=\"" << value->as_string() << "\"";
 }  }
 static void _html(Request& r, MethodParams* params) {  static void _html(Request& r, MethodParams& params) {
   
         String tag;          String tag;
         tag << "<img";          tag << "<img";
Line 753  static void _html(Request& r, MethodPara Line 750  static void _html(Request& r, MethodPara
         const HashStringValue& fields=GET_SELF(r, VImage).fields();          const HashStringValue& fields=GET_SELF(r, VImage).fields();
         HashStringValue* attribs=0;          HashStringValue* attribs=0;
   
         if(params->count()) {          if(params.count()) {
                 // for backward compatibility: someday was ^html{}                  // for backward compatibility: someday was ^html{}
                 Value& vattribs=r.process_to_value(*(*params)[0],                  Value& vattribs=r.process_to_value(params[0],
                         /*0/*no name* /,*/  
                         false/*don't intercept string*/);                          false/*don't intercept string*/);
                 if(!vattribs.is_string()) // allow empty                  if(!vattribs.is_string()) // allow empty
                         if(attribs=vattribs.get_hash()) {                          if((attribs=vattribs.get_hash())) {
                                 Attrib_info info={&tag};                                  Attrib_info info={&tag, 0};
                                 attribs->for_each(append_attrib_pair, &info);                                  attribs->for_each(append_attrib_pair, &info);
                         } else                          } else
                                 throw Exception("parser.runtime",                                   throw Exception("parser.runtime", 
Line 779  static void _html(Request& r, MethodPara Line 775  static void _html(Request& r, MethodPara
 /// @test wrap FILE to auto-object  /// @test wrap FILE to auto-object
 static gdImage* load(Request& r,   static gdImage* load(Request& r, 
                                          const String& file_name){                                           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")) {          if(FILE *f=fopen(file_name_cstr, "rb")) {
                 gdImage* image=new gdImage;                  gdImage* image=new gdImage;
Line 794  static gdImage* load(Request& r, Line 789  static gdImage* load(Request& r,
                 throw Exception("file.missing",                   throw Exception("file.missing", 
                         0,                           0, 
                         "can not open '%s'", file_name_cstr);                          "can not open '%s'", file_name_cstr);
                 return 0;  
         }          }
 }  }
   
   
 static void _load(Request& r, 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, file_name);          gdImage* image=load(r, file_name);
         GET_SELF(r, VImage).set(&file_name, image->SX(), image->SY(), image);          GET_SELF(r, VImage).set(&file_name, image->SX(), image->SY(), image);
 }  }
   
 static void _create(Request& r, MethodParams* params) {  static void _create(Request& r, MethodParams& params) {
           int width=params.as_int(0, "width must be int", r);
         int width=params->as_int(0, "width must be int", r);          int height=params.as_int(1, "height must be int", r);
         int height=params->as_int(1, "height must be int", r);  
         int bgcolor_value=0xffFFff;          int bgcolor_value=0xffFFff;
         if(params->count()>2)          if(params.count()>2)
                 bgcolor_value=params->as_int(2, "color must be int", r);                  bgcolor_value=params.as_int(2, "color must be int", r);
         gdImage* image=new gdImage;          gdImage* image=new gdImage;
         image->Create(width, height);          image->Create(width, height);
         image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value));          image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value));
         GET_SELF(r, VImage).set(0, width, height, image);          GET_SELF(r, VImage).set(0, width, height, image);
 }  }
   
 static void _gif(Request& r, MethodParams* params) {  static void _gif(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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=&params.as_string(0, "file name must be string");
   
         String out; image->Gif(out);          gdBuf buf=image->Gif();
                   
         VFile& vfile=*new VFile;          VFile& vfile=*new VFile;
         Value* content_type=new VString(*new String("image/gif"));          Value* content_type=new VString(*new String("image/gif"));
         vfile.set(false/*not tainted*/,           vfile.set(false/*not tainted*/, 
                 out.cstr(), out.length(), 0, content_type);                  (const char*)buf.ptr, buf.size, 
                   file_name? file_name->cstr(String::L_FILE_SPEC): 0, 
                   content_type);
   
         r.write_no_lang(vfile);          r.write_no_lang(vfile);
 }  }
   
 static void _line(Request& r, MethodParams* params) {  static void _line(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 848  static void _line(Request& r, MethodPara Line 843  static void _line(Request& r, MethodPara
                         "does not contain an image");                          "does not contain an image");
   
         image->Line(          image->Line(
                 params->as_int(0, "x0 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(1, "y0 must be int", r), 
                 params->as_int(2, "x1 must be int", r),                   params.as_int(2, "x1 must be int", r), 
                 params->as_int(3, "y1 must be int", r),                   params.as_int(3, "y1 must be int", r), 
                 image->Color(params->as_int(4, "color must be int", r)));                  image->Color(params.as_int(4, "color must be int", r)));
 }  }
   
 static void _fill(Request& r, MethodParams* params) {  static void _fill(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 864  static void _fill(Request& r, MethodPara Line 858  static void _fill(Request& r, MethodPara
                         "does not contain an image");                          "does not contain an image");
   
         image->Fill(          image->Fill(
                 params->as_int(0, "x must be int", r),                   params.as_int(0, "x must be int", r), 
                 params->as_int(1, "y must be int", r),                   params.as_int(1, "y must be int", r), 
                 image->Color(params->as_int(2, "color must be int", r)));                  image->Color(params.as_int(2, "color must be int", r)));
 }  }
   
 static void _rectangle(Request& r, MethodParams* params) {  static void _rectangle(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 878  static void _rectangle(Request& r, Metho Line 871  static void _rectangle(Request& r, Metho
                         "does not contain an image");                          "does not contain an image");
   
         image->Rectangle(          image->Rectangle(
                 params->as_int(0, "x0 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(1, "y0 must be int", r), 
                 params->as_int(2, "x1 must be int", r),                   params.as_int(2, "x1 must be int", r), 
                 params->as_int(3, "y1 must be int", r),                   params.as_int(3, "y1 must be int", r), 
                 image->Color(params->as_int(4, "color must be int", r)));                  image->Color(params.as_int(4, "color must be int", r)));
 }  }
   
 static void _bar(Request& r, MethodParams* params) {  static void _bar(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 894  static void _bar(Request& r, MethodParam Line 886  static void _bar(Request& r, MethodParam
                         "does not contain an image");                          "does not contain an image");
   
         image->FilledRectangle(          image->FilledRectangle(
                 params->as_int(0, "x0 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(1, "y0 must be int", r), 
                 params->as_int(2, "x1 must be int", r),                   params.as_int(2, "x1 must be int", r), 
                 params->as_int(3, "y1 must be int", r),                   params.as_int(3, "y1 must be int", r), 
                 image->Color(params->as_int(4, "color must be int", r)));                  image->Color(params.as_int(4, "color must be int", r)));
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
Line 909  static void add_point(Table::element_typ Line 901  static void add_point(Table::element_typ
         (*p)++;          (*p)++;
 }  }
 #endif  #endif
 static void _replace(Request& r, MethodParams* params) {  static void _replace(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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)           if(!table) 
                 throw Exception(0,                  throw Exception(0,
                         0,                          0,
                         "coordinates must be table");                          "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;              gdImage::Point *add_p=all_p;    
         table->for_each(add_point, &add_p);          table->for_each(add_point, &add_p);
         image->FilledPolygonReplaceColor(all_p, table->count(),           image->FilledPolygonReplaceColor(all_p, table->count(), 
                 image->Color(params->as_int(0, "src 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)));                  image->Color(params.as_int(1, "dest color must be int", r)));
 }  }
   
 static void _polyline(Request& r, MethodParams* params) {  static void _polyline(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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)           if(!table) 
                 throw Exception(0,                  throw Exception(0,
                         0,                          0,
                         "coordinates must be table");                          "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;              gdImage::Point *add_p=all_p;    
         table->for_each(add_point, &add_p);          table->for_each(add_point, &add_p);
         image->Polygon(all_p, table->count(),           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*/);                  false/*not closed*/);
 }  }
   
 static void _polygon(Request& r, MethodParams* params) {  static void _polygon(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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)           if(!table) 
                 throw Exception(0,                  throw Exception(0,
                         0,                          0,
                         "coordinates must be table");                          "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;              gdImage::Point *add_p=all_p;    
         table->for_each(add_point, &add_p);          table->for_each(add_point, &add_p);
         image->Polygon(all_p, table->count(),           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, MethodParams* params) {  static void _polybar(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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)           if(!table) 
                 throw Exception("parser.runtime",                  throw Exception("parser.runtime",
                         0,                          0,
                         "coordinates must be table");                          "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;              gdImage::Point *add_p=all_p;    
         table->for_each(add_point, &add_p);          table->for_each(add_point, &add_p);
         image->FilledPolygon(all_p, table->count(),           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  // font
Line 1006  const int Font::letter_spacing=1; Line 994  const int Font::letter_spacing=1;
 Font::Font(//,   Font::Font(//, 
         const String& aalphabet,           const String& aalphabet, 
         gdImage* aifont, int aheight, int amonospace, int aspacebarspace):          gdImage* aifont, int aheight, int amonospace, int aspacebarspace):
         alphabet(aalphabet),   
         height(aheight), monospace(amonospace),  spacebarspace(aspacebarspace),          height(aheight), monospace(amonospace),  spacebarspace(aspacebarspace),
         ifont(aifont) {          ifont(aifont),
           alphabet(aalphabet)     {
 }  }
   
 /* ******************************** char ********************************** */  /* ******************************** char ********************************** */
   
 int Font::index_of(char ch) {  size_t Font::index_of(char ch) {
         if(ch==' ') return -1;          if(ch==' ') return STRING_NOT_FOUND;
         return alphabet.pos(&ch, 1);          return alphabet.pos(ch);
 }  }
   
 int Font::index_width(int index) {  int Font::index_width(size_t index) {
         if(index<0)          if(index==STRING_NOT_FOUND)
                 return spacebarspace;                  return spacebarspace;
         int tr=ifont->GetTransparent();          int tr=ifont->GetTransparent();
         for(int x=ifont->SX()-1; x>=0; x--) {          for(int x=ifont->SX()-1; x>=0; x--) {
Line 1030  int Font::index_width(int index) { Line 1018  int Font::index_width(int index) {
         return 0;          return 0;
 }  }
   
 void Font::index_display(gdImage* image, int x, int y, int index){  void Font::index_display(gdImage* image, int x, int y, size_t index){
         if(index>=0)           if(index!=STRING_NOT_FOUND) 
                 ifont->Copy(*image, x, y, 0, Y(0), index_width(index), height);                  ifont->Copy(*image, x, y, 0, Y(0), index_width(index), height);
 }  }
   
Line 1053  int Font::string_width(const String& s){ Line 1041  int Font::string_width(const String& s){
 void Font::string_display(gdImage* image, int x, int y, 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++) {          for(const char* current=cstr; *current; current++) {
                 int index=index_of(*current);                  size_t index=index_of(*current);
                 index_display(image, x, y, index);                  index_display(image, x, y, index);
                 x+=step_width(index);                  x+=step_width(index);
         }          }
Line 1062  void Font::string_display(gdImage* image Line 1050  void Font::string_display(gdImage* image
 //  //
   
   
 static void _font(Request& r, MethodParams* params) {  static void _font(Request& r, MethodParams& params) {
           const String& alphabet=params.as_string(0, "alphabet must not be code");
         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"));
         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 spacebar_width=params->as_int(2, "spacebar_width must be int", r);  
         int monospace_width;          int monospace_width;
         if(params->count()>3) {          if(params.count()>3) {
                 monospace_width=params->as_int(3, "monospace_width must be int", r);                  monospace_width=params.as_int(3, "monospace_width must be int", r);
                 if(!monospace_width)                  if(!monospace_width)
                         monospace_width=image->SX();                          monospace_width=image->SX();
         } else          } else
Line 1092  static void _font(Request& r, MethodPara Line 1079  static void _font(Request& r, MethodPara
                 image->SY() / alphabet.length(), monospace_width, spacebar_width);                  image->SY() / alphabet.length(), monospace_width, spacebar_width);
 }  }
   
 static void _text(Request& r, MethodParams* params) {  static void _text(Request& r, MethodParams& params) {
           int x=params.as_int(0, "x must be int", r);
         int x=params->as_int(0, "x must be int", r);          int y=params.as_int(1, "y 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");
         const String& s=params->as_string(2, "text must not be code");  
   
         VImage& vimage=GET_SELF(r, VImage);          VImage& vimage=GET_SELF(r, VImage);
         if(vimage.image)          if(vimage.image)
Line 1112  static void _text(Request& r, MethodPara Line 1098  static void _text(Request& r, MethodPara
                         "does not contain an image");                          "does not contain an image");
 }  }
   
 static void _length(Request& r, MethodParams* params) {  static void _length(Request& r, MethodParams& params) {
           const String& s=params.as_string(0, "text must not be code");
         const String& s=params->as_string(0, "text must not be code");  
   
         VImage& vimage=GET_SELF(r, VImage);          VImage& vimage=GET_SELF(r, VImage);
         if(vimage.image)          if(vimage.image)
Line 1130  static void _length(Request& r, MethodPa Line 1115  static void _length(Request& r, MethodPa
                         "does not contain an image");                          "does not contain an image");
 }  }
   
 static void _arc(Request& r, MethodParams* params) {  static void _arc(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 1139  static void _arc(Request& r, MethodParam Line 1123  static void _arc(Request& r, MethodParam
                         "does not contain an image");                          "does not contain an image");
   
         image->Arc(          image->Arc(
                 params->as_int(0, "center_x 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(1, "center_y must be int", r), 
                 params->as_int(2, "width 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(3, "height must be int", r), 
                 params->as_int(4, "start degrees must be int", r),                   params.as_int(4, "start degrees must be int", r), 
                 params->as_int(5, "end 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)));                  image->Color(params.as_int(6, "cx must be int", r)));
 }  }
   
 static void _sector(Request& r, MethodParams* params) {  static void _sector(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
Line 1157  static void _sector(Request& r, MethodPa Line 1140  static void _sector(Request& r, MethodPa
                         "does not contain an image");                          "does not contain an image");
   
         image->Sector(          image->Sector(
                 params->as_int(0, "center_x 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(1, "center_y must be int", r), 
                 params->as_int(2, "width 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(3, "height must be int", r), 
                 params->as_int(4, "start degrees must be int", r),                   params.as_int(4, "start degrees must be int", r), 
                 params->as_int(5, "end 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)));                  image->Color(params.as_int(6, "color must be int", r)));
 }  }
   
 static void _circle(Request& r, MethodParams* params) {  static void _circle(Request& r, MethodParams& params) {
   
         gdImage* image=GET_SELF(r, VImage).image;          gdImage* image=GET_SELF(r, VImage).image;
         if(!image)          if(!image)
                 throw Exception(0,                   throw Exception(0, 
                         0,                           0, 
                         "does not contain an image");                          "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(          image->Arc(
                 params->as_int(0, "center_x 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(1, "center_y must be int", r), 
                 size, //w                  size, //w
                 size, //h                  size, //h
                 0, //s                  0, //s
                 360, //e                  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_image(MethodParams* params, int index, const char* msg) {  gdImage* as_image(MethodParams& params, int index, const char* msg) {
         gdImage* src=0;          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 *>(vimage)->image;                  src=static_cast<VImage *>(vimage)->image;
Line 1204  gdImage* as_image(MethodParams* params, Line 1186  gdImage* as_image(MethodParams* params,
         return src;          return src;
 }  }
   
 static void _copy(Request& r, MethodParams* params) {  static void _copy(Request& r, MethodParams& params) {
   
         gdImage* dest=GET_SELF(r, VImage).image;          gdImage* dest=GET_SELF(r, VImage).image;
         if(!dest)          if(!dest)
                 throw Exception(0,                   throw Exception(0, 
Line 1214  static void _copy(Request& r, MethodPara Line 1195  static void _copy(Request& r, MethodPara
   
         gdImage* src=as_image(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 sx=params.as_int(1, "src_x must be int", r);
         int sy=params->as_int(2, "src_y 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 sw=params.as_int(3, "src_w must be int", r);
         int sh=params->as_int(4, "src_h 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 dx=params.as_int(5, "dest_x must be int", r);
         int dy=params->as_int(6, "dest_y must be int", r);          int dy=params.as_int(6, "dest_y must be int", r);
         if(params->count()>1+2+2+2) {          if(params.count()>1+2+2+2) {
                 int dw=params->as_int(1+2+2+2, "dest_w must be int", r);                  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?                  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)));                          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?                  int tolerance=params.count()>1+2+2+2+2?
                         params->as_int(1+2+2+2+2, "tolerance must be int", r):150;                          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);                  src->CopyResampled(*dest, dx, dy, sx, sy, dw, dh, sw, sh, tolerance);
         } else          } else
Line 1251  MImage::MImage(): Methoded("image") { Line 1232  MImage::MImage(): Methoded("image") {
         add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3);          add_native_method("create", Method::CT_DYNAMIC, _create, 2, 3);
   
         // ^image.gif[]          // ^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)          // ^image.line(x0;y0;x1;y1;color)
         add_native_method("line", Method::CT_DYNAMIC, _line, 5, 5);          add_native_method("line", Method::CT_DYNAMIC, _line, 5, 5);

Removed from v.1.90.2.15.2.13  
changed lines
  Added in v.1.107


E-mail: