ruby-libgd 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/gd/Makefile +269 -0
- data/ext/gd/arc.c +52 -0
- data/ext/gd/arc.o +0 -0
- data/ext/gd/blit.c +37 -0
- data/ext/gd/blit.o +0 -0
- data/ext/gd/char.c +6 -0
- data/ext/gd/char.o +0 -0
- data/ext/gd/circle.c +39 -0
- data/ext/gd/circle.o +0 -0
- data/ext/gd/clip.c +92 -0
- data/ext/gd/clip.h +7 -0
- data/ext/gd/clip.o +0 -0
- data/ext/gd/color.c +53 -0
- data/ext/gd/color.o +0 -0
- data/ext/gd/draw_line.c +53 -0
- data/ext/gd/draw_line.o +0 -0
- data/ext/gd/ellipse.c +4 -0
- data/ext/gd/ellipse.o +0 -0
- data/ext/gd/encode.c +66 -0
- data/ext/gd/encode.o +0 -0
- data/ext/gd/extconf.rb +5 -0
- data/ext/gd/fill.c +24 -0
- data/ext/gd/fill.o +0 -0
- data/ext/gd/filter.c +70 -0
- data/ext/gd/filter.o +0 -0
- data/ext/gd/gd.c +87 -0
- data/ext/gd/gd.o +0 -0
- data/ext/gd/gd.so +0 -0
- data/ext/gd/image.c +203 -0
- data/ext/gd/image.o +0 -0
- data/ext/gd/join.sh +24 -0
- data/ext/gd/mkmf.log +59 -0
- data/ext/gd/pixel.c +39 -0
- data/ext/gd/pixel.o +0 -0
- data/ext/gd/polygon.c +98 -0
- data/ext/gd/polygon.o +0 -0
- data/ext/gd/rectangle.c +41 -0
- data/ext/gd/rectangle.o +0 -0
- data/ext/gd/ruby_gd.h +38 -0
- data/ext/gd/text.c +48 -0
- data/ext/gd/text.o +0 -0
- data/ext/gd/transform.c +44 -0
- data/ext/gd/transform.o +0 -0
- data/ext/gd/version.c +9 -0
- data/ext/gd/version.o +0 -0
- data/lib/gd.rb +2 -0
- metadata +89 -0
data/ext/gd/polygon.c
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
- [ ] imagefilledpolygon — Draw a filled polygon
|
|
3
|
+
- [ ] imageopenpolygon — Draws an open polygon
|
|
4
|
+
- [ ] imagepolygon — Draws a polygon
|
|
5
|
+
*/
|
|
6
|
+
#include "ruby_gd.h"
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
static gdPointPtr build_points(VALUE points, int *count_out) {
|
|
10
|
+
Check_Type(points, T_ARRAY);
|
|
11
|
+
|
|
12
|
+
long n = RARRAY_LEN(points);
|
|
13
|
+
if (n <= 0) {
|
|
14
|
+
*count_out = 0;
|
|
15
|
+
return NULL;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Primero construimos todos los puntos (como antes)
|
|
19
|
+
gdPoint *raw_pts = ALLOC_N(gdPoint, n);
|
|
20
|
+
for (long i = 0; i < n; i++) {
|
|
21
|
+
VALUE pair = rb_ary_entry(points, i);
|
|
22
|
+
Check_Type(pair, T_ARRAY);
|
|
23
|
+
if (RARRAY_LEN(pair) < 2) {
|
|
24
|
+
xfree(raw_pts);
|
|
25
|
+
rb_raise(rb_eArgError, "each point must be [x, y]");
|
|
26
|
+
}
|
|
27
|
+
raw_pts[i].x = NUM2INT(rb_ary_entry(pair, 0));
|
|
28
|
+
raw_pts[i].y = NUM2INT(rb_ary_entry(pair, 1));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Ahora eliminamos duplicados consecutivos
|
|
32
|
+
long unique_n = 0;
|
|
33
|
+
for (long i = 0; i < n; i++) {
|
|
34
|
+
if (unique_n == 0 ||
|
|
35
|
+
raw_pts[unique_n - 1].x != raw_pts[i].x ||
|
|
36
|
+
raw_pts[unique_n - 1].y != raw_pts[i].y) {
|
|
37
|
+
raw_pts[unique_n++] = raw_pts[i];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
*count_out = (int)unique_n;
|
|
42
|
+
|
|
43
|
+
// Si hay menos de 3 puntos únicos, fallamos
|
|
44
|
+
if (unique_n < 3) {
|
|
45
|
+
xfree(raw_pts);
|
|
46
|
+
*count_out = 0;
|
|
47
|
+
return NULL;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Reasignamos memoria para evitar desperdicio (opcional pero limpio)
|
|
51
|
+
gdPoint *clean_pts = ALLOC_N(gdPoint, unique_n);
|
|
52
|
+
MEMCPY(clean_pts, raw_pts, gdPoint, unique_n);
|
|
53
|
+
xfree(raw_pts);
|
|
54
|
+
|
|
55
|
+
return (gdPointPtr)clean_pts;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static VALUE gd_image_polygon(VALUE self, VALUE points, VALUE color) {
|
|
59
|
+
gd_image_wrapper *wrap;
|
|
60
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
61
|
+
|
|
62
|
+
int count = 0;
|
|
63
|
+
gdPointPtr pts = build_points(points, &count);
|
|
64
|
+
int c = color_to_gd(wrap->img, color);
|
|
65
|
+
|
|
66
|
+
gdImagePolygon(wrap->img, pts, count, c);
|
|
67
|
+
|
|
68
|
+
xfree(pts);
|
|
69
|
+
return self;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static VALUE gd_image_filled_polygon(VALUE self, VALUE points, VALUE color) {
|
|
73
|
+
gd_image_wrapper *wrap;
|
|
74
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
75
|
+
|
|
76
|
+
if (!wrap || !wrap->img) {
|
|
77
|
+
rb_raise(rb_eRuntimeError, "uninitialized GD::Image");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
int count = 0;
|
|
81
|
+
gdPointPtr pts = build_points(points, &count);
|
|
82
|
+
|
|
83
|
+
if (!pts || count < 3) {
|
|
84
|
+
if (pts) xfree(pts);
|
|
85
|
+
rb_raise(rb_eArgError, "points must be an Array of at least 3 [x,y] pairs");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
int c = color_to_gd(wrap->img, color);
|
|
89
|
+
gdImageFilledPolygon(wrap->img, pts, count, c);
|
|
90
|
+
|
|
91
|
+
xfree(pts);
|
|
92
|
+
return self;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
void gd_define_polygon(VALUE cGDImage) {
|
|
96
|
+
rb_define_method(cGDImage, "polygon", gd_image_polygon, 2);
|
|
97
|
+
rb_define_method(cGDImage, "filled_polygon", gd_image_filled_polygon, 2);
|
|
98
|
+
}
|
data/ext/gd/polygon.o
ADDED
|
Binary file
|
data/ext/gd/rectangle.c
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#include "ruby_gd.h"
|
|
2
|
+
/**
|
|
3
|
+
- [ ] imagerectangle — Draw a rectangle
|
|
4
|
+
- [ ] imagefilledrectangle — Draw a filled rectangle
|
|
5
|
+
*/
|
|
6
|
+
static VALUE gd_image_rect(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
|
7
|
+
gd_image_wrapper *wrap;
|
|
8
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
9
|
+
|
|
10
|
+
int r = NUM2INT(rb_ary_entry(color, 0));
|
|
11
|
+
int g = NUM2INT(rb_ary_entry(color, 1));
|
|
12
|
+
int b = NUM2INT(rb_ary_entry(color, 2));
|
|
13
|
+
|
|
14
|
+
int c = gdImageColorAllocate(wrap->img, r, g, b);
|
|
15
|
+
gdImageRectangle(wrap->img,
|
|
16
|
+
NUM2INT(x1), NUM2INT(y1),
|
|
17
|
+
NUM2INT(x2), NUM2INT(y2),
|
|
18
|
+
c);
|
|
19
|
+
return Qnil;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static VALUE gd_image_filled_rect(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
|
23
|
+
gd_image_wrapper *wrap;
|
|
24
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
25
|
+
|
|
26
|
+
int r = NUM2INT(rb_ary_entry(color, 0));
|
|
27
|
+
int g = NUM2INT(rb_ary_entry(color, 1));
|
|
28
|
+
int b = NUM2INT(rb_ary_entry(color, 2));
|
|
29
|
+
|
|
30
|
+
int c = gdImageColorAllocate(wrap->img, r, g, b);
|
|
31
|
+
gdImageFilledRectangle(wrap->img,
|
|
32
|
+
NUM2INT(x1), NUM2INT(y1),
|
|
33
|
+
NUM2INT(x2), NUM2INT(y2),
|
|
34
|
+
c);
|
|
35
|
+
return Qnil;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
void gd_define_rect(VALUE cGDImage) {
|
|
39
|
+
rb_define_method(cGDImage, "rect", gd_image_rect, 5);
|
|
40
|
+
rb_define_method(cGDImage, "filled_rect", gd_image_filled_rect, 5);
|
|
41
|
+
}
|
data/ext/gd/rectangle.o
ADDED
|
Binary file
|
data/ext/gd/ruby_gd.h
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#ifndef RUBY_GD_H
|
|
2
|
+
#define RUBY_GD_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
#include <gd.h>
|
|
6
|
+
|
|
7
|
+
typedef struct {
|
|
8
|
+
gdImagePtr img;
|
|
9
|
+
int owner;
|
|
10
|
+
} gd_image_wrapper;
|
|
11
|
+
|
|
12
|
+
extern const rb_data_type_t gd_image_type;
|
|
13
|
+
|
|
14
|
+
int color_to_gd(gdImagePtr im, VALUE color);
|
|
15
|
+
|
|
16
|
+
/* Image */
|
|
17
|
+
void gd_define_image(VALUE mGD);
|
|
18
|
+
void gd_define_blit(VALUE cGDImage);
|
|
19
|
+
void gd_define_fill(VALUE cGDImage);
|
|
20
|
+
|
|
21
|
+
void gd_define_pixel(VALUE cGDImage);
|
|
22
|
+
void gd_define_line(VALUE cGDImage);
|
|
23
|
+
void gd_define_arc(VALUE cGDImage);
|
|
24
|
+
void gd_define_rect(VALUE cGDImage);
|
|
25
|
+
void gd_define_circle(VALUE cGDImage);
|
|
26
|
+
void gd_define_polygon(VALUE cGDImage);
|
|
27
|
+
|
|
28
|
+
void gd_define_text(VALUE cGDImage);
|
|
29
|
+
|
|
30
|
+
void gd_define_transform(VALUE cGDImage);
|
|
31
|
+
void gd_define_filter(VALUE cGDImage);
|
|
32
|
+
void gd_define_encode(VALUE cGDImage);
|
|
33
|
+
|
|
34
|
+
/* Color */
|
|
35
|
+
void gd_define_color(VALUE mGD);
|
|
36
|
+
void gd_define_version(VALUE mGD);
|
|
37
|
+
|
|
38
|
+
#endif
|
data/ext/gd/text.c
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#include "ruby_gd.h"
|
|
2
|
+
/*
|
|
3
|
+
- [ ] imagefontheight — Get font height
|
|
4
|
+
- [ ] imagefontwidth — Get font width
|
|
5
|
+
- [ ] imageftbbox — Give the bounding box of a text using fonts via freetype2
|
|
6
|
+
- [ ] imagefttext — Write text to the image using fonts using FreeType 2
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
static VALUE gd_image_text(VALUE self, VALUE text, VALUE opts) {
|
|
10
|
+
gd_image_wrapper *wrap;
|
|
11
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
12
|
+
|
|
13
|
+
VALUE x = rb_hash_aref(opts, ID2SYM(rb_intern("x")));
|
|
14
|
+
VALUE y = rb_hash_aref(opts, ID2SYM(rb_intern("y")));
|
|
15
|
+
VALUE size = rb_hash_aref(opts, ID2SYM(rb_intern("size")));
|
|
16
|
+
VALUE color = rb_hash_aref(opts, ID2SYM(rb_intern("color")));
|
|
17
|
+
VALUE font = rb_hash_aref(opts, ID2SYM(rb_intern("font")));
|
|
18
|
+
|
|
19
|
+
if (NIL_P(x) || NIL_P(y) || NIL_P(size) || NIL_P(color) || NIL_P(font))
|
|
20
|
+
rb_raise(rb_eArgError, "missing options");
|
|
21
|
+
|
|
22
|
+
int r = NUM2INT(rb_ary_entry(color,0));
|
|
23
|
+
int g = NUM2INT(rb_ary_entry(color,1));
|
|
24
|
+
int b = NUM2INT(rb_ary_entry(color,2));
|
|
25
|
+
|
|
26
|
+
int fg = gdImageColorAllocate(wrap->img, r, g, b);
|
|
27
|
+
|
|
28
|
+
int brect[8];
|
|
29
|
+
char *err = gdImageStringFT(
|
|
30
|
+
wrap->img,
|
|
31
|
+
brect,
|
|
32
|
+
fg,
|
|
33
|
+
StringValueCStr(font),
|
|
34
|
+
NUM2DBL(size),
|
|
35
|
+
0,
|
|
36
|
+
NUM2INT(x),
|
|
37
|
+
NUM2INT(y),
|
|
38
|
+
StringValueCStr(text)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if (err) rb_raise(rb_eRuntimeError, "%s", err);
|
|
42
|
+
|
|
43
|
+
return Qnil;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void gd_define_text(VALUE cGDImage) {
|
|
47
|
+
rb_define_method(cGDImage, "text", gd_image_text, 2);
|
|
48
|
+
}
|
data/ext/gd/text.o
ADDED
|
Binary file
|
data/ext/gd/transform.c
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#include "ruby_gd.h"
|
|
2
|
+
|
|
3
|
+
static VALUE wrap_new_image(gdImagePtr im, VALUE klass) {
|
|
4
|
+
gd_image_wrapper *w;
|
|
5
|
+
VALUE obj = TypedData_Make_Struct(klass, gd_image_wrapper, &gd_image_type, w);
|
|
6
|
+
w->img = im;
|
|
7
|
+
w->owner = 1;
|
|
8
|
+
return obj;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static VALUE gd_image_crop(VALUE self, VALUE vx, VALUE vy, VALUE vw, VALUE vh) {
|
|
12
|
+
gd_image_wrapper *wrap;
|
|
13
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
14
|
+
|
|
15
|
+
gdRect r;
|
|
16
|
+
r.x = NUM2INT(vx);
|
|
17
|
+
r.y = NUM2INT(vy);
|
|
18
|
+
r.width = NUM2INT(vw);
|
|
19
|
+
r.height = NUM2INT(vh);
|
|
20
|
+
|
|
21
|
+
gdImagePtr out = gdImageCrop(wrap->img, &r);
|
|
22
|
+
if (!out) rb_raise(rb_eRuntimeError, "crop failed");
|
|
23
|
+
|
|
24
|
+
return wrap_new_image(out, CLASS_OF(self));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static VALUE gd_image_scale(VALUE self, VALUE vw, VALUE vh) {
|
|
28
|
+
gd_image_wrapper *wrap;
|
|
29
|
+
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
|
|
30
|
+
|
|
31
|
+
int w = NUM2INT(vw);
|
|
32
|
+
int h = NUM2INT(vh);
|
|
33
|
+
|
|
34
|
+
gdImagePtr out = gdImageScale(wrap->img, w, h);
|
|
35
|
+
if (!out) rb_raise(rb_eRuntimeError, "scale failed");
|
|
36
|
+
|
|
37
|
+
return wrap_new_image(out, CLASS_OF(self));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void gd_define_transform(VALUE cGDImage) {
|
|
41
|
+
rb_define_method(cGDImage, "crop", gd_image_crop, 4);
|
|
42
|
+
rb_define_method(cGDImage, "scale", gd_image_scale, 2);
|
|
43
|
+
rb_define_method(cGDImage, "resize", gd_image_scale, 2);
|
|
44
|
+
}
|
data/ext/gd/transform.o
ADDED
|
Binary file
|
data/ext/gd/version.c
ADDED
data/ext/gd/version.o
ADDED
|
Binary file
|
data/lib/gd.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby-libgd
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Germán Alberto Giménez Silva
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: High-performance native bindings to libgd for image generation
|
|
14
|
+
email:
|
|
15
|
+
- ggerman@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions:
|
|
18
|
+
- ext/gd/extconf.rb
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- ext/gd/Makefile
|
|
22
|
+
- ext/gd/arc.c
|
|
23
|
+
- ext/gd/arc.o
|
|
24
|
+
- ext/gd/blit.c
|
|
25
|
+
- ext/gd/blit.o
|
|
26
|
+
- ext/gd/char.c
|
|
27
|
+
- ext/gd/char.o
|
|
28
|
+
- ext/gd/circle.c
|
|
29
|
+
- ext/gd/circle.o
|
|
30
|
+
- ext/gd/clip.c
|
|
31
|
+
- ext/gd/clip.h
|
|
32
|
+
- ext/gd/clip.o
|
|
33
|
+
- ext/gd/color.c
|
|
34
|
+
- ext/gd/color.o
|
|
35
|
+
- ext/gd/draw_line.c
|
|
36
|
+
- ext/gd/draw_line.o
|
|
37
|
+
- ext/gd/ellipse.c
|
|
38
|
+
- ext/gd/ellipse.o
|
|
39
|
+
- ext/gd/encode.c
|
|
40
|
+
- ext/gd/encode.o
|
|
41
|
+
- ext/gd/extconf.rb
|
|
42
|
+
- ext/gd/fill.c
|
|
43
|
+
- ext/gd/fill.o
|
|
44
|
+
- ext/gd/filter.c
|
|
45
|
+
- ext/gd/filter.o
|
|
46
|
+
- ext/gd/gd.c
|
|
47
|
+
- ext/gd/gd.o
|
|
48
|
+
- ext/gd/gd.so
|
|
49
|
+
- ext/gd/image.c
|
|
50
|
+
- ext/gd/image.o
|
|
51
|
+
- ext/gd/join.sh
|
|
52
|
+
- ext/gd/mkmf.log
|
|
53
|
+
- ext/gd/pixel.c
|
|
54
|
+
- ext/gd/pixel.o
|
|
55
|
+
- ext/gd/polygon.c
|
|
56
|
+
- ext/gd/polygon.o
|
|
57
|
+
- ext/gd/rectangle.c
|
|
58
|
+
- ext/gd/rectangle.o
|
|
59
|
+
- ext/gd/ruby_gd.h
|
|
60
|
+
- ext/gd/text.c
|
|
61
|
+
- ext/gd/text.o
|
|
62
|
+
- ext/gd/transform.c
|
|
63
|
+
- ext/gd/transform.o
|
|
64
|
+
- ext/gd/version.c
|
|
65
|
+
- ext/gd/version.o
|
|
66
|
+
- lib/gd.rb
|
|
67
|
+
homepage:
|
|
68
|
+
licenses: []
|
|
69
|
+
metadata: {}
|
|
70
|
+
post_install_message:
|
|
71
|
+
rdoc_options: []
|
|
72
|
+
require_paths:
|
|
73
|
+
- lib
|
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
requirements: []
|
|
85
|
+
rubygems_version: 3.5.22
|
|
86
|
+
signing_key:
|
|
87
|
+
specification_version: 4
|
|
88
|
+
summary: Native Ruby bindings for libgd
|
|
89
|
+
test_files: []
|