/** * Graphics::PNG is PNG library * * text.c includes one class: * Graphics::PNG::Text. * This class is wrapper object for libpng's png_text_struct struct. * It's for the representation of text chunks. * * @author DATE Ken (as Itacchi) / ge6537@i.bekkoame.ne.jp * @code-name Aoi * @see http://www.isc.meiji.ac.jp/~ee77038/ruby/ * $Id: text.c,v 1.1 2000/09/27 17:17:03 date Exp date $ */ #include "libpng.h" VALUE cText; /* * ------------------- * Graphics::PNG::Text * ------------------- * is a wrapper object of the libpng's png_text_struct struct. */ /* =begin = (({Graphics::PNG::Text})) A wrapper object of the libpng's png_text_struct struct. === class method --- Graphics::PNG::Text.new Create PNG text data for text chunk object. === Constant : ((<(({Graphics::PNG::TEXT_COMPRESSION_NONE_WR}))>)) : ((<(({Graphics::PNG::TEXT_COMPRESSION_zTXt_WR}))>)) : ((<(({Graphics::PNG::TEXT_COMPRESSION_NONE}))>)) : ((<(({Graphics::PNG::TEXT_COMPRESSION_zTXt}))>)) : ((<(({Graphics::PNG::ITXT_COMPRESSION_NONE}))>)) : ((<(({Graphics::PNG::ITXT_COMPRESSION_zTXt}))>)) === instance method --- Graphics::PNG::Text#compression Get compression type. Default is Graphics::PNG::TEXT_COMPRESSION_NONE. * ((<(({Graphics::PNG::TEXT_COMPRESSION_NONE_WR}))>)) -3, tEXt, none, wide character * ((<(({Graphics::PNG::TEXT_COMPRESSION_zTXt_WR}))>)) -2, zTXt, deflate, wide character * ((<(({Graphics::PNG::TEXT_COMPRESSION_NONE}))>)) -1, tEXt, none * ((<(({Graphics::PNG::TEXT_COMPRESSION_zTXt}))>)) 0, zTXt, deflate, * ((<(({Graphics::PNG::ITXT_COMPRESSION_NONE}))>)) 1, iTXt, none * ((<(({Graphics::PNG::ITXT_COMPRESSION_zTXt}))>)) 2, iTXt, deflate --- Graphics::PNG::Text#compression=(val) Set compression type. --- Graphics::PNG::Text#key Get keyword (description of "text"). 1-79 character. --- Graphics::PNG::Text#key=(string) Set keyword, 1-79 Latin-1 character. But, don't check character code. This is task for users. --- Graphics::PNG::Text#lang Get language code. --- Graphics::PNG::Text#lang=(str) Set language code, 1-79 characters. `nil' for unknown. But, don't check character code. This is task for users. --- Graphics::PNG::Text#lang_key Get keyword translated UTF-8 string. --- Graphics::PNG::Text#lang_key=(str) Set keyword translated UTF-8 string. But, don't check character code. This is task for users. --- Graphics::PNG::Text#text Get comment. --- Graphics::PNG::Text#text=(str) Set comment. Empty string is also valid. =end */ #ifdef PNG_TEXT_SUPPORTED /* * --------------------- * utility function for * Graphics::PNG::Text * --------------------- */ void libpng_text_check_type(obj) VALUE obj; { if (rb_class_of(obj) != cText){ rb_raise(rb_eTypeError, "wrong argument type %s (expected Graphics::PNG::Text)", rb_class2name(CLASS_OF(obj))); } } static void libpng_text_free(text) png_textp text; { if (text->key) free(text->key); if (text->text) free(text->text); #ifdef PNG_iTXt_SUPPORTED if (text->lang) free(text->lang); if (text->lang_key) free(text->lang_key); #endif /* PNG_iTXt_SUPPORTED */ free(text); } /* * --------------------- * class method of * Graphics::PNG::Text * --------------------- */ static VALUE libpng_text_new(klass) VALUE klass; { VALUE new_obj; png_textp text; new_obj = Data_Make_Struct(klass, png_text, NULL, libpng_text_free, text); text->key = NULL; text->text = NULL; text->compression = PNG_TEXT_COMPRESSION_NONE; #ifdef PNG_iTXt_SUPPORTED text->lang = NULL; text->lang_key = NULL; #endif /* PNG_iTXt_SUPPORTED */ return new_obj; } VALUE libpng_text_new2(klass, png_text_src) VALUE klass; png_textp png_text_src; { VALUE new_obj; png_textp text; new_obj = Data_Make_Struct(klass, png_text, NULL, free, text); if (png_text_src->key != NULL){ text->key = ALLOC_N(char, strlen(png_text_src->key)+1); strcpy(text->key, png_text_src->key); } if (png_text_src->text != NULL){ text->text = ALLOC_N(char, strlen(png_text_src->text)+1); strcpy(text->text, png_text_src->text); } text->compression = png_text_src->compression; #ifdef PNG_iTXt_SUPPORTED if (png_text_src->lang != NULL){ text->lang = ALLOC_N(char, strlen(png_text_src->lang)+1); strcpy(text->lang, png_text_src->lang); } if (png_text_src->lang_key != NULL){ text->lang_key = ALLOC_N(char, strlen(png_text_src->lang_key)+1); strcpy(text->lang_key, png_text_src->lang_key); } #endif /* PNG_iTXt_SUPPORTED */ return new_obj; } /* * --------------------- * instance method of * Graphics::PNG::Text * --------------------- */ static VALUE libpng_text_initialize(obj) VALUE obj; { return Qnil; } static VALUE libpng_text_get_compression(obj) VALUE obj; { png_textp text; Data_Get_Struct(obj, png_text, text); return INT2FIX(text->compression); } static VALUE libpng_text_get_key(obj) VALUE obj; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->key) return rb_str_new2(text->key); return Qnil; } #ifdef PNG_iTXt_SUPPORTED static VALUE libpng_text_get_lang(obj) VALUE obj; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->lang) return rb_str_new2(text->lang); return Qnil; } static VALUE libpng_text_get_lang_key(obj) VALUE obj; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->lang_key) return rb_str_new2(text->lang_key); return Qnil; } #endif /* PNG_iTXt_SUPPORTED */ static VALUE libpng_text_get_text(obj) VALUE obj; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->text) return rb_str_new2(text->text); return Qnil; } static VALUE libpng_text_inspect(obj) VALUE obj; { png_textp text; char *buf; VALUE str; int text_len = 0; Data_Get_Struct(obj, png_text, text); if (text->text) text_len = strlen(text->text); if (text_len < 256) text_len = 256; buf = ALLOCA_N(char, text_len); str = rb_str_new2("#key); rb_str_cat(str, buf, strlen(buf)); sprintf(buf, "@text=\"%s\", ", text->text); rb_str_cat(str, buf, strlen(buf)); switch (text->compression){ case PNG_TEXT_COMPRESSION_NONE_WR: strcpy(buf, "@compression=Graphics::PNG::TEXT_COMPRESSION_NONE_WR"); break; case PNG_TEXT_COMPRESSION_zTXt_WR: strcpy(buf, "@compression=Graphics::PNG::TEXT_COMPRESSION_zTXt_WR"); break; case PNG_TEXT_COMPRESSION_NONE: strcpy(buf, "@compression=Graphics::PNG::TEXT_COMPRESSION_NONE"); break; case PNG_TEXT_COMPRESSION_zTXt: strcpy(buf, "@compression=Graphics::PNG::TEXT_COMPRESSION_zTXt"); break; case PNG_ITXT_COMPRESSION_NONE: strcpy(buf, "@compression=Graphics::PNG::ITXT_COMPRESSION_NONE"); break; case PNG_ITXT_COMPRESSION_zTXt: strcpy(buf, "@compression=Graphics::PNG::ITXT_COMPRESSION_zTXt"); break; default: strcpy(buf, "@compression=unkown type"); } rb_str_cat(str, buf, strlen(buf)); #ifdef PNG_iTXt_SUPPORTED rb_str_cat(str, ", ", 2); if (text->lang) sprintf(buf, "@lang=\"%s\", ", text->lang); else strcpy(buf, "@lang=unknown, "); rb_str_cat(str, buf, strlen(buf)); if (text->lang_key) sprintf(buf, "@lang_key=\"%s\"", text->lang_key); else strcpy(buf, "@lang_key=unknown"); rb_str_cat(str, buf, strlen(buf)); #endif /* PNG_iTXt_SUPPORTED */ rb_str_cat(str, ">", 1); return str; } static VALUE libpng_text_set_compression(obj, val) VALUE obj, val; { png_textp text; int compression_type; FIXNUM_P(val); compression_type = FIX2INT(val); if (compression_type < PNG_TEXT_COMPRESSION_NONE_WR || compression_type >= PNG_TEXT_COMPRESSION_LAST){ rb_raise(ePngError, "invalid value for compression type of text chunk: %d", compression_type); } Data_Get_Struct(obj, png_text, text); text->compression = compression_type; return Qnil; } static VALUE libpng_text_set_key(obj, str) VALUE obj, str; { png_textp text; Check_Type(str, T_STRING); Data_Get_Struct(obj, png_text, text); if (text->key) free(text->key); if (RSTRING(str)->len > 79){ rb_warning("Given string is too long."); text->key = ALLOC_N(char, 80); strncpy(text->key, STR2CSTR(str), 79); } else { text->key = ALLOC_N(char, RSTRING(str)->len+1); strcpy(text->key, STR2CSTR(str)); } return Qnil; } #ifdef PNG_iTXt_SUPPORTED static VALUE libpng_text_set_lang(obj, str) VALUE obj, str; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->lang) free(text->lang); switch (TYPE(str)){ case T_NIL: text->lang = NULL; break; case T_STRING: if (RSTRING(str)->len > 79){ rb_warning("Given string is too long."); text->lang = ALLOC_N(char, 80); strncpy(text->lang, STR2CSTR(str), 79); } else { text->lang = ALLOC_N(char, RSTRING(str)->len+1); strcpy(text->lang, STR2CSTR(str)); } break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected String/nil)", rb_class2name(CLASS_OF(str))); } return Qnil; } static VALUE libpng_text_set_lang_key(obj, str) VALUE obj, str; { png_textp text; Data_Get_Struct(obj, png_text, text); if (text->lang_key) free(text->lang_key); switch (TYPE(str)){ case T_NIL: text->lang_key = NULL; break; case T_STRING: text->lang_key = ALLOC_N(char, RSTRING(str)->len+1); strcpy(text->lang_key, STR2CSTR(str)); break; default: rb_raise(rb_eTypeError, "wrong argument type %s (expected String/nil)", rb_class2name(CLASS_OF(str))); } return Qnil; } #endif /* PNG_iTXt_SUPPORTED */ static VALUE libpng_text_set_text(obj, str) VALUE obj, str; { png_textp text; Check_Type(str, T_STRING); Data_Get_Struct(obj, png_text, text); if (text->text) free(text->text); text->text = ALLOC_N(char, RSTRING(str)->len+1); strcpy(text->text, STR2CSTR(str)); return Qnil; } #endif /* PNG_TEXT_SUPPORTED */ void Init_text() { /* * ------------------- * Graphics::PNG::Text * ------------------- */ #if defined(PNG_TEXT_SUPPORTED) cText = rb_define_class_under(mPng, "Text", rb_cObject); rb_define_const(mPng, "TEXT_COMPRESSION_NONE_WR", INT2FIX(PNG_TEXT_COMPRESSION_NONE_WR)); rb_define_const(mPng, "TEXT_COMPRESSION_zTXt_WR", INT2FIX(PNG_TEXT_COMPRESSION_zTXt_WR)); rb_define_const(mPng, "TEXT_COMPRESSION_NONE", INT2FIX(PNG_TEXT_COMPRESSION_NONE)); rb_define_const(mPng, "TEXT_COMPRESSION_zTXt", INT2FIX(PNG_TEXT_COMPRESSION_zTXt)); rb_define_const(mPng, "ITXT_COMPRESSION_NONE", INT2FIX(PNG_ITXT_COMPRESSION_NONE)); rb_define_const(mPng, "ITXT_COMPRESSION_zTXt", INT2FIX(PNG_ITXT_COMPRESSION_zTXt)); rb_define_singleton_method(cText, "new", libpng_text_new, 0); rb_define_method(cText, "initialize", libpng_text_initialize, -1); rb_define_method(cText, "compression", libpng_text_get_compression, 0); rb_define_method(cText, "key", libpng_text_get_key, 0); #ifdef PNG_iTXt_SUPPORTED rb_define_method(cText, "lang", libpng_text_get_lang, 0); rb_define_method(cText, "lang_key", libpng_text_get_lang_key, 0); #endif /* PNG_iTXt_SUPPORTED */ rb_define_method(cText, "text", libpng_text_get_text, 0); rb_define_method(cText, "inspect", libpng_text_inspect, 0); rb_define_method(cText, "compression=", libpng_text_set_compression, 1); rb_define_method(cText, "key=", libpng_text_set_key, 1); #ifdef PNG_iTXt_SUPPORTED rb_define_method(cText, "lang=", libpng_text_set_lang, 1); rb_define_method(cText, "lang_key=", libpng_text_set_lang_key, 1); #endif /* PNG_iTXt_SUPPORTED */ rb_define_method(cText, "text=", libpng_text_set_text, 1); #endif /* PNG_TEXT_SUPPORTED */ }