はじめまして。能條といいます。

Ruby の拡張モジュール作成の練習を兼ねて、 GD のパッチ作成しました。
このパッチは、8つメソッドを追加します。

GD::Image.newFromGd2(file)                 ... gd2 ファイルから読み込む
GD::Image.newFromGd2Part(file, x, y, w, h) ... gd2 ファイルの一部分から読み込む
GD::Image.newFromXpm(file)                 ... xpm ファイルから読み込む
im.paletteCopy(im)                         ... パレットのコピー
im.stringTTF(fontcolor, fontname, ptsize, angle, x, y, string) ... TrueType font で文字を書く
im.boundsSafe                              ... 範囲内か否か
im.getTransparent                          ... 透明色を得る
im.gd2(file, cs, fmt)                      ... gd2 で出力

です。あと、extconf.rbも作成しました(ほかの環境でも動くかわかりませんが)。
----
require 'mkmf'

have_library('Xpm')
have_library('ttf')

if have_library('z') and have_library('png') and have_library('gd')
  have_func('gdImagePng')
  have_func('gdImageCreateFromXpm')
  have_func('gdImageStringTTF')

  create_makefile('GD')
end
----

以下のパッチの当てる前に、まず[ruby-list:18412]のパッチをあててください。

--- GD.c.orig	Thu Jan 20 20:25:10 2000
+++ GD.c	Thu Jan 20 23:00:52 2000
@@ -82,6 +82,39 @@
 }
 
 static VALUE
+img_from_gd2(class, f)
+    VALUE class, f;
+{
+    OpenFile *fptr;
+    gdImagePtr iptr;
+
+    Check_Type(f, T_FILE);
+    rb_io_binmode(f);
+    GetOpenFile(f, fptr);
+    rb_io_check_readable(fptr);
+
+    iptr = gdImageCreateFromGd2(fptr->f);
+    return Data_Wrap_Struct(class,0,free_img,iptr);
+}
+
+static VALUE
+img_from_gd2_part(class, f, srcx, srcy, w, h)
+    VALUE class, f, srcx, srcy, w, h;
+{
+    OpenFile *fptr;
+    gdImagePtr iptr;
+
+    Check_Type(f, T_FILE);
+    rb_io_binmode(f);
+    GetOpenFile(f, fptr);
+    rb_io_check_readable(fptr);
+
+    iptr = gdImageCreateFromGd2Part(fptr->f, NUM2INT(srcx),
+				    NUM2INT(srcy), NUM2INT(w), NUM2INT(h));
+    return Data_Wrap_Struct(class,0,free_img,iptr);
+}
+
+static VALUE
 img_from_xbm(class, f)
     VALUE class, f;
 {
@@ -98,6 +131,24 @@
     return Data_Wrap_Struct(class,0,free_img,iptr);
 }
 
+#ifdef HAVE_GDIMAGECREATEFROMXPM
+static VALUE
+img_from_xpm(class, f)
+    VALUE class, f;
+{
+    OpenFile *fptr;
+    gdImagePtr iptr;
+
+    Check_Type(f, T_FILE);
+    rb_io_binmode(f);
+    GetOpenFile(f, fptr);
+    rb_io_check_readable(fptr);
+
+    iptr = (gdImagePtr)gdImageCreateFromXpm(fptr->path);
+    return Data_Wrap_Struct(class,0,free_img,iptr);
+}
+#endif
+
 static VALUE
 img_destroy(img)
     struct RData *img;
@@ -465,6 +516,20 @@
     return img;
 }
 
+static VALUE
+img_palette_copy(img, img2)
+    VALUE img, img2;
+{
+    gdImagePtr im, im2;
+
+    image_req(img2);
+    Data_Get_Struct(img, gdImage, im);
+    Data_Get_Struct(img2, gdImage, im2);
+    gdImagePaletteCopy(im, im2);
+
+    return img;
+}
+
 static void
 font_req(fnt)
     VALUE fnt;
@@ -508,6 +573,40 @@
     return img;
 }
 
+#ifdef HAVE_GDIMAGESTRINGTTF
+static VALUE
+img_string_ttf(img, fgcolor, fontname, ptsize, angle, x, y, string)
+    VALUE img, fgcolor, fontname, ptsize, angle, x, y, string;
+{
+    gdImagePtr im;
+    int brect[8], i;
+    char *msg;
+    VALUE ary = rb_ary_new2(8);
+    VALUE ary_w;
+
+    Check_Type(fontname, T_STRING);
+    Check_Type(string, T_STRING);
+    Data_Get_Struct(img, gdImage, im);
+    msg = gdImageStringTTF(im,
+			   &brect[0],
+			   NUM2INT(fgcolor),
+			   RSTRING(fontname)->ptr,
+			   NUM2DBL(ptsize),
+			   NUM2DBL(angle),
+			   NUM2INT(x),
+			   NUM2INT(y),
+			   RSTRING(string)->ptr);
+    for (i=0; i<8; i++) {
+	rb_ary_push(ary, INT2FIX(brect[i]));
+    }
+    if (msg) {
+	return rb_ary_new3(2, rb_str_new2(msg), ary);
+    } else {
+	return rb_ary_new3(2, Qnil, ary);
+    }
+}
+#endif
+
 static VALUE
 img_char(img, fnt, x, y, ch, c)
     VALUE img, fnt, x, y, ch, c;
@@ -602,6 +701,30 @@
 }
 
 static VALUE
+img_bounds_safe(img, x, y)
+    VALUE img, x, y;
+{
+    gdImagePtr im;
+
+    Data_Get_Struct(img, gdImage, im);
+    if ( gdImageBoundsSafe(im, NUM2INT(x), NUM2INT(y)) ) {
+	return Qtrue;
+    } else {
+	return Qfalse;
+    }
+}
+
+static VALUE
+img_get_transparent(img)
+    VALUE img;
+{
+    gdImagePtr im;
+
+    Data_Get_Struct(img, gdImage, im);
+    return INT2NUM(gdImageGetTransparent(im));
+}
+
+static VALUE
 img_width(img)
     VALUE img;
 {
@@ -673,6 +796,26 @@
     return img;
 }
 
+static VALUE
+img_gd2(img, out, cs, fmt)
+    VALUE img, out, cs, fmt;
+{
+    OpenFile *fptr;
+    gdImagePtr im;
+    FILE *f;
+
+    Check_Type(out, T_FILE);
+    rb_io_binmode(out);
+    GetOpenFile(out, fptr);
+    rb_io_check_writable(fptr);
+    f = (fptr->f2) ? fptr->f2 : fptr->f;
+
+    Data_Get_Struct(img, gdImage, im);
+    gdImageGd2(im, f, NUM2INT(cs), NUM2INT(fmt));
+
+    return img;
+}
+
 
 /* ======================================================================= */
 /* 1999/04/23 modify (replace `class' with `klass') */
@@ -1007,7 +1150,12 @@
     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);
+#ifdef HAVE_GDIMAGECREATEFROMXPM
+    rb_define_singleton_method(cImage, "newFromXpm", img_from_xpm, 1);
+#endif
+    rb_define_singleton_method(cImage, "newFromGd",  img_from_gd,  1);
+    rb_define_singleton_method(cImage, "newFromGd2", img_from_gd2, 1);
+    rb_define_singleton_method(cImage, "newFromGd2Part", img_from_gd2_part, 5);
     rb_define_method(cImage, "destroy", img_destroy, 0);
 
     rb_define_method(cImage, "colorAllocate", img_color_allocate, 3);
@@ -1042,16 +1190,22 @@
 
     rb_define_method(cImage, "copy", img_copy, 7);
     rb_define_method(cImage, "copyResized", img_copy_resized, 9);
+    rb_define_method(cImage, "paletteCopy", img_palette_copy, 1);
 
     rb_define_method(cImage, "string", img_string, 5);
     rb_define_method(cImage, "stringUp", img_string_up, 5);
+#ifdef HAVE_GDIMAGESTRINGTTF
+    rb_define_method(cImage, "stringTTF", img_string_ttf, 7);
+#endif
     rb_define_method(cImage, "char", img_char, 5);
     rb_define_method(cImage, "charUp", img_char_up, 5);
 
     rb_define_method(cImage, "interlace",  img_get_interlace, 0);
     rb_define_method(cImage, "interlace=", img_set_interlace, 1);
+    rb_define_method(cImage, "getTransparent", img_get_transparent, 0);
 
     rb_define_method(cImage, "bounds", img_bounds, 0);
+    rb_define_method(cImage, "boundsSafe", img_bounds_safe, 2);
     rb_define_method(cImage, "width", img_width, 0);
     rb_define_method(cImage, "height", img_height, 0);
 
@@ -1061,6 +1215,7 @@
     rb_define_method(cImage, "gif", img_gif, 1);
 #endif
     rb_define_method(cImage, "gd", img_gd, 1);
+    rb_define_method(cImage, "gd2", img_gd2, 3);
 
     cPolygon = rb_define_class_under(mGD, "Polygon", rb_cObject);
     rb_define_singleton_method(cPolygon, "new", ply_new, 0);

----
能條 聡史 / のうじょう さとし
<s_nojo / geocities.co.jp>
or <nojo / t-samukawa.or.jp>
ruby 1.5.2 (2000-01-18) [i586-cygwin]
<http://www.geocities.co.jp/SiliconValley-PaloAlto/1409/banner/get_ruby.png>