--- parser3/src/classes/image.C 2009/07/07 05:47:43 1.129 +++ parser3/src/classes/image.C 2010/07/05 05:54:46 1.134 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_IMAGE_C="$Date: 2009/07/07 05:47:43 $"; +static const char * const IDENT_IMAGE_C="$Date: 2010/07/05 05:54:46 $"; /* jpegsize: gets the width and height (in pixels) of a jpeg file @@ -39,7 +39,7 @@ static const String letter_spacing_name( class MImage: public Methoded { public: // VStateless_class - Value* create_new_value(Pool&, HashStringValue*) { return new VImage(); } + Value* create_new_value(Pool&) { return new VImage(); } public: MImage(); @@ -806,14 +806,18 @@ struct Attrib_info { }; #endif static void append_attrib_pair( - 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) + HashStringValue::key_type key, + HashStringValue::value_type value, + Attrib_info* info) { + // skip user-specified, internal(starting with "line-") attributes and border attribute with empty value + if( + (info->skip && info->skip->get(key)) + || key.pos("line-")==0 + || (key=="border" && !value->is_defined()) + ) return; - // src="a.gif" width=123 ismap[=-1] + // src="a.gif" width="123" ismap[=-1] *info->tag << " " << key; if(value->is_string() || value->as_int()>=0) *info->tag << "=\"" << value->as_string() << "\""; @@ -828,8 +832,7 @@ static void _html(Request& r, MethodPara if(params.count()) { // for backward compatibility: someday was ^html{} - Value& vattribs=r.process_to_value(params[0], - false/*don't intercept string*/); + Value& vattribs=r.process_to_value(params[0], false/*don't intercept string*/); if(!vattribs.is_string()) // allow empty if((attribs=vattribs.get_hash())) { Attrib_info info={&tag, 0}; @@ -1033,13 +1036,23 @@ static void _polybar(Request& r, MethodP // Font class -Font::Font(//, +Font::Font( + Charset& asource_charset, const String& aalphabet, gdImage* aifont, int aheight, int amonospace, int aspacebarspace, int aletterspacing): - height(aheight), monospace(amonospace), spacebarspace(aspacebarspace), + fsource_charset(asource_charset), + height(aheight), + monospace(amonospace), + spacebarspace(aspacebarspace), letterspacing(aletterspacing), ifont(aifont), alphabet(aalphabet) { + + if(fsource_charset.isUTF8()){ + size_t index=0; + for(UTF8_string_iterator i(alphabet); i.has_next(); ) + fletter2index.put_dont_replace(i.next(), index++); + } } /* ******************************** char ********************************** */ @@ -1049,6 +1062,11 @@ size_t Font::index_of(char ch) { return alphabet.pos(ch); } +size_t Font::index_of(XMLCh ch) { + if(ch==' ') return STRING_NOT_FOUND; + return fletter2index.get(ch); +} + int Font::index_width(size_t index) { if(index==STRING_NOT_FOUND) return spacebarspace; @@ -1076,17 +1094,33 @@ int Font::step_width(int index) { int Font::string_width(const String& s){ const char* cstr=s.cstr(); int result=0; - for(const char* current=cstr; *current; current++) - result+=step_width(index_of(*current)); + + if(fsource_charset.isUTF8()){ + for(UTF8_string_iterator i(s); i.has_next(); ) + result+=step_width(index_of(i.next())); + } else { + for(const char* current=cstr; *current; current++) + result+=step_width(index_of(*current)); + } + return result; } void Font::string_display(gdImage& image, int x, int y, const String& s){ const char* cstr=s.cstr(); - for(const char* current=cstr; *current; current++) { - size_t index=index_of(*current); - index_display(image, x, y, index); - x+=step_width(index); + + if(fsource_charset.isUTF8()){ + for(UTF8_string_iterator i(s); i.has_next(); ){ + size_t index=index_of(i.next()); + index_display(image, x, y, index); + x+=step_width(index); + } + } else { + for(const char* current=cstr; *current; current++) { + size_t index=index_of(*current); + index_display(image, x, y, index); + x+=step_width(index); + } } } @@ -1095,7 +1129,8 @@ void Font::string_display(gdImage& image static void _font(Request& r, MethodParams& params) { const String& alphabet=params.as_string(0, "alphabet must not be code"); - if(!alphabet.length()) + size_t alphabet_length=alphabet.length(r.charsets.source()); + if(!alphabet_length) throw Exception(PARSER_RUNTIME, 0, "alphabet must not be empty"); @@ -1128,9 +1163,7 @@ static void _font(Request& r, MethodPara letter_spacing=r.process_to_value(*vletter_spacing).as_int(); } if(valid_options!=options->count()) - throw Exception(PARSER_RUNTIME, - 0, - "called with invalid option"); + throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION); } else { // backward spacebar_width=params.as_int(2, "spacebar_width must be int", r); @@ -1142,16 +1175,17 @@ static void _font(Request& r, MethodPara } } - if(int remainder=image->SY() % alphabet.length()) + if(int remainder=image->SY() % alphabet_length) throw Exception(PARSER_RUNTIME, 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).set_font(new Font( + r.charsets.source(), alphabet, image, - image->SY() / alphabet.length(), monospace_width, spacebar_width, letter_spacing)); + image->SY() / alphabet_length, monospace_width, spacebar_width, letter_spacing)); } static void _text(Request& r, MethodParams& params) { @@ -1213,7 +1247,7 @@ static void _circle(Request& r, MethodPa gdImage& as_image(MethodParams& params, int index, const char* msg) { Value& value=params.as_no_junction(index, msg); - if(Value* vimage=value.as(VIMAGE_TYPE, false)) { + if(Value* vimage=value.as(VIMAGE_TYPE)) { return static_cast(vimage)->image(); } else throw Exception(PARSER_RUNTIME,