中村 のりつぐ です。

GD-0.6.2 では、1.4.x 系列では怒られてしまうし、
gd-1.7.1 が出てもうすでに完全に png ライブラリに
なってしまったようなので、パッチを作りました。

o 1.4.x 系列に対応
o コンパイルオプションに -DGD_PNG を付けると
  最新の gd ライブラリで使用可
  (もっと良いオプション名があると…)
o libttf 関係は実装していない(環境がないんだ!)
o extconf.rb に対するパッチも作っていない
o gd2 フォーマットとかに対するパッチも作っていない
o 本当は、example.rb, README に対するパッチも必要


--- GD-0.6.2/GD.c	Sat May  8 22:01:05 1999
+++ GD.c	Sat Sep 25 12:32:41 1999
@@ -40,7 +40,11 @@
 }
 
 static VALUE
+#ifdef GD_PNG
+img_from_png(class, f)
+#else
 img_from_gif(class, f)
+#endif
     VALUE class, f;
 {
     VALUE img;
@@ -48,11 +52,15 @@
     gdImagePtr iptr;
 
     Check_Type(f, T_FILE); 
-    io_binmode(f);
+    rb_io_binmode(f);
     GetOpenFile(f, fptr);
-    io_readable(fptr);
+    rb_io_check_readable(fptr);
 
+#ifdef GD_PNG
+    iptr = gdImageCreateFromPng(fptr->f);
+#else
     iptr = gdImageCreateFromGif(fptr->f);
+#endif
     return Data_Wrap_Struct(class,0,free_img,iptr);
 }
 
@@ -65,9 +73,9 @@
     gdImagePtr iptr;
 
     Check_Type(f, T_FILE); 
-    io_binmode(f);
+    rb_io_binmode(f);
     GetOpenFile(f, fptr);
-    io_readable(fptr);
+    rb_io_check_readable(fptr);
 
     iptr = gdImageCreateFromGd(fptr->f);
     return Data_Wrap_Struct(class,0,free_img,iptr);
@@ -82,9 +90,9 @@
     gdImagePtr iptr;
 
     Check_Type(f, T_FILE); 
-    io_binmode(f);
+    rb_io_binmode(f);
     GetOpenFile(f, fptr);
-    io_readable(fptr);
+    rb_io_check_readable(fptr);
 
     iptr = gdImageCreateFromXbm(fptr->f);
     return Data_Wrap_Struct(class,0,free_img,iptr);
@@ -195,18 +203,18 @@
     VALUE img, idx;
 {
     gdImagePtr im;
-    VALUE ary = ary_new2(3);
+    VALUE ary = rb_ary_new2(3);
     int i, c;
 
     Data_Get_Struct(img, gdImage, im);
     i = NUM2INT(idx);
 
     c = gdImageRed(im, i);
-    ary_push(ary, INT2FIX(c));
+    rb_ary_push(ary, INT2FIX(c));
     c = gdImageGreen(im, i);
-    ary_push(ary, INT2FIX(c));
+    rb_ary_push(ary, INT2FIX(c));
     c = gdImageBlue(im, i);
-    ary_push(ary, INT2FIX(c));
+    rb_ary_push(ary, INT2FIX(c));
 
     return ary;
 }
@@ -228,8 +236,8 @@
 image_req(img)
     VALUE img;
 {
-    if (!obj_is_kind_of(img, cImage)) {
-	TypeError("GD::Image required");
+    if (!rb_obj_is_kind_of(img, cImage)) {
+	rb_raise(rb_eTypeError, "GD::Image required");
     }
 }
 
@@ -336,8 +344,8 @@
 poly_req(ply)
     VALUE ply;
 {
-    if (!obj_is_kind_of(ply, cPolygon) || TYPE(ply) != T_ARRAY) {
-	TypeError("GD::Polygon required");
+    if (!rb_obj_is_kind_of(ply, cPolygon) || TYPE(ply) != T_ARRAY) {
+	rb_raise(rb_eTypeError, "GD::Polygon required");
     }
 }
 
@@ -461,8 +469,8 @@
 font_req(fnt)
     VALUE fnt;
 {
-    if (!obj_is_kind_of(fnt, cFont)) {
-	TypeError("GD::Font required");
+    if (!rb_obj_is_kind_of(fnt, cFont)) {
+	rb_raise(rb_eTypeError, "GD::Font required");
     }
 }
 
@@ -514,7 +522,7 @@
 
     if (TYPE(ch) == T_STRING) {
 	if (RSTRING(ch)->len != 1) {
-	    ArgError("string must be 1 byte(%d bytes)", RSTRING(ch)->len);
+	    rb_raise(rb_eTypeError, "string must be 1 byte(%d bytes)", RSTRING(ch)->len);
 	}
 	ci = RSTRING(ch)->ptr[0];
     }
@@ -540,7 +548,7 @@
 
     if (TYPE(ch) == T_STRING) {
 	if (RSTRING(ch)->len != 1) {
-	    ArgError("string must be 1 byte(%d bytes)", RSTRING(ch)->len);
+	    rb_raise(rb_eArgError, "string must be 1 byte(%d bytes)", RSTRING(ch)->len);
 	}
 	ci = RSTRING(ch)->ptr[0];
     }
@@ -560,9 +568,9 @@
 
     Data_Get_Struct(img, gdImage, im);
     if (gdImageGetInterlaced(im)) {
-	return TRUE;
+	return Qtrue;
     }
-    return FALSE;
+    return Qfalse;
 }
 
 static VALUE
@@ -581,14 +589,14 @@
     VALUE img;
 {
     gdImagePtr im;
-    VALUE ary = ary_new2(2);
+    VALUE ary = rb_ary_new2(2);
     int i;
 
     Data_Get_Struct(img, gdImage, im);
     i = gdImageSX(im);
-    ary_push(ary, INT2FIX(i));
+    rb_ary_push(ary, INT2FIX(i));
     i = gdImageSY(im);
-    ary_push(ary, INT2FIX(i));
+    rb_ary_push(ary, INT2FIX(i));
 
     return ary;
 }
@@ -618,7 +626,11 @@
 }
 
 static VALUE
+#ifdef GD_PNG
+img_png(img, out)
+#else
 img_gif(img, out)
+#endif
     VALUE img, out;
 {
     gdImagePtr im;
@@ -627,12 +639,16 @@
 
     Data_Get_Struct(img, gdImage, im);
     Check_Type(out, T_FILE); 
-    io_binmode(out);
+    rb_io_binmode(out);
     GetOpenFile(out, fptr);
-    io_writable(fptr);
+    rb_io_check_writable(fptr);
     f = (fptr->f2) ? fptr->f2 : fptr->f;
 
+#ifdef GD_PNG
+    gdImagePng(im, f);
+#else
     gdImageGif(im, f);
+#endif
 
     return img;
 }
@@ -647,9 +663,9 @@
 
     Data_Get_Struct(img, gdImage, im);
     Check_Type(out, T_FILE); 
-    io_binmode(out);
+    rb_io_binmode(out);
     GetOpenFile(out, fptr);
-    io_writable(fptr);
+    rb_io_check_writable(fptr);
     f = (fptr->f2) ? fptr->f2 : fptr->f;
 
     gdImageGd(im, f);
@@ -665,7 +681,7 @@
 ply_new(klass)
     VALUE klass;
 {
-    VALUE self = ary_new();
+    VALUE self = rb_ary_new();
 
     RBASIC(self)->klass = klass;
     return self;
@@ -679,8 +695,8 @@
     NUM2INT(x);
     NUM2INT(y);
 
-    ary_push(ply, x);
-    ary_push(ply, y);
+    rb_ary_push(ply, x);
+    rb_ary_push(ply, y);
     return ply;
 }
 
@@ -695,10 +711,10 @@
     NUM2INT(dy);
 
     if (RARRAY(ply)->len > 0) {
-        x = ary_entry(ply, RARRAY(ply)->len - 2);
-        y = ary_entry(ply, RARRAY(ply)->len - 1);
-        ary_push(ply, INT2NUM(NUM2INT(x) + NUM2INT(dx)));
-        ary_push(ply, INT2NUM(NUM2INT(y) + NUM2INT(dy)));
+        x = rb_ary_entry(ply, RARRAY(ply)->len - 2);
+        y = rb_ary_entry(ply, RARRAY(ply)->len - 1);
+        rb_ary_push(ply, INT2NUM(NUM2INT(x) + NUM2INT(dx)));
+        rb_ary_push(ply, INT2NUM(NUM2INT(y) + NUM2INT(dy)));
     } else {
         ply_add_pt(ply, dx, dy);
     }
@@ -714,7 +730,7 @@
     if (RARRAY(ply)->len < idx) return Qnil;
     i *= 2;
 
-    return assoc_new(ary_entry(ply, i), ary_entry(ply, i+1));
+    return rb_assoc_new(rb_ary_entry(ply, i), rb_ary_entry(ply, i+1));
 }
 
 static VALUE
@@ -727,8 +743,8 @@
     NUM2INT(x);
     NUM2INT(y);
 
-    ary_store(ply, i,   x);
-    ary_store(ply, i+1, y);
+    rb_ary_store(ply, i,   x);
+    rb_ary_store(ply, i+1, y);
 
     return ply;
 }
@@ -739,8 +755,8 @@
 {
     int i = NUM2INT(idx)*2;
 
-    ary_delete_at(ply, INT2FIX(i));
-    ary_delete_at(ply, INT2FIX(i+1));
+    rb_ary_delete_at(ply, INT2FIX(i));
+    rb_ary_delete_at(ply, INT2FIX(i+1));
 
     return ply;
 }
@@ -757,10 +773,10 @@
     struct RArray *ply;
 {
     int i;
-    VALUE ary = ary_new2(ply->len/2);
+    VALUE ary = rb_ary_new2(ply->len/2);
 
     for (i = 0; i<ply->len; i+=2) {
-	ary_push(ary, assoc_new(ply->ptr[i], ply->ptr[i+1]));
+	rb_ary_push(ary, rb_assoc_new(ply->ptr[i], ply->ptr[i+1]));
     }
     return ary;
 }
@@ -787,7 +803,7 @@
 	if (ny < t) t = ny;
 	if (ny > b) b = ny;
     }
-    return ary_new3(4, INT2FIX(l), INT2FIX(t), INT2FIX(r), INT2FIX(b));
+    return rb_ary_new3(4, INT2FIX(l), INT2FIX(t), INT2FIX(r), INT2FIX(b));
 }
 
 static VALUE
@@ -860,7 +876,7 @@
 	    (double)(NUM2INT(sb) - NUM2INT(st));
     }
     else {
-	ArgError("wrong # of arguments (%d for 4 or 8)", argc);
+	rb_raise(rb_eArgError, "wrong # of arguments (%d for 4 or 8)", argc);
     }
 
     for (i = 0; i<ply->len; i+=2) {
@@ -927,7 +943,7 @@
     if (strcmp(name, "Tiny") == 0) {
 	return fnt_create(gdFontTiny);
     }
-    ArgError("undefined font name `%s'", name);
+    rb_raise(rb_eArgError, "undefined font name `%s'", name);
 }
 
 static VALUE
@@ -983,9 +999,13 @@
 Init_GD()
 {
     mGD = rb_define_module("GD");
-    cImage = rb_define_class_under(mGD, "Image", cObject);
+    cImage = rb_define_class_under(mGD, "Image", rb_cObject);
     rb_define_singleton_method(cImage, "new", img_s_new, 2);
+#ifdef GD_PNG
+    rb_define_singleton_method(cImage, "newFromPng", img_from_png, 1);
+#else
     rb_define_singleton_method(cImage, "newFromGif", img_from_gif, 1);
+#endif
     rb_define_singleton_method(cImage, "newFromXbm", img_from_xbm, 1);
     rb_define_singleton_method(cImage, "newFromGd",  img_from_gd, 1);
     rb_define_method(cImage, "destroy", img_destroy, 0);
@@ -1035,10 +1055,14 @@
     rb_define_method(cImage, "width", img_width, 0);
     rb_define_method(cImage, "height", img_height, 0);
 
+#ifdef GD_PNG
+    rb_define_method(cImage, "png", img_png, 1);
+#else
     rb_define_method(cImage, "gif", img_gif, 1);
+#endif
     rb_define_method(cImage, "gd", img_gd, 1);
 
-    cPolygon = rb_define_class_under(mGD, "Polygon", cObject);
+    cPolygon = rb_define_class_under(mGD, "Polygon", rb_cObject);
     rb_define_singleton_method(cPolygon, "new", ply_new, 0);
 
     rb_define_method(cPolygon, "addPt", ply_add_pt, 2);
@@ -1054,7 +1078,7 @@
     rb_define_method(cPolygon, "transform", ply_transform, 6);
     rb_define_method(cPolygon, "scale", ply_scale, 2);
 
-    cFont = rb_define_class_under(mGD, "Font", cObject);
+    cFont = rb_define_class_under(mGD, "Font", rb_cObject);
     rb_define_singleton_method(cFont, "new", fnt_s_new, 1);
 
     rb_define_const(cFont, "GiantFont", fnt_new("Giant"));


       中村 典嗣  E-mail:     nnakamur / mxq.mesh.ne.jp