initial prototype of ruby interface
[swftools.git] / lib / ruby / gfx.c
1 #include <ruby.h>
2 #include "../gfxdevice.h"
3 #include "../gfxsource.h"
4 #include "../devices/pdf.h"
5 #include "../readers/swf.h"
6 #include "../readers/image.h"
7 #include "../pdf/pdf.h"
8 #include "../types.h"
9
10 #define RUBY_GFX_VERSION  "0.9.0"
11
12 static VALUE GFX;
13 static VALUE Document, DocumentPage, PDFClass, SWFClass, ImageClass, Device;
14 static ID id_doc;
15
16 typedef struct doc_internal {
17     gfxsource_t*driver; // filled by alloc
18     gfxdocument_t*doc;
19 } doc_internal_t;
20
21 typedef struct page_internal {
22     gfxpage_t*page;
23 } page_internal_t;
24
25 static gfxsource_t* pdfdriver = 0;
26 static gfxsource_t* imagedriver = 0;
27 static gfxsource_t* swfdriver = 0;
28
29 #define Get_Doc(doc,cls) doc_internal_t*doc=0;Data_Get_Struct(cls, doc_internal_t, doc);
30 #define Get_Page(page,cls) page_internal_t*page=0;Data_Get_Struct(cls, page_internal_t, page);
31
32 static VALUE doc_allocate(VALUE cls, gfxsource_t*driver);
33 static VALUE page_allocate(VALUE cls);
34
35 // ------------------------ documents ---------------------------------------
36
37 static VALUE doc_initialize(VALUE cls, VALUE _filename)
38 {
39     Check_Type(_filename, T_STRING);
40     Get_Doc(doc,cls);
41     const char*filename = StringValuePtr(_filename);
42     doc->doc = pdfdriver->open(pdfdriver, filename);
43     return cls;
44 }
45
46 static VALUE doc_num_pages(VALUE cls)
47 {
48     Get_Doc(doc,cls)
49     return INT2FIX(doc->doc->num_pages);
50 }
51
52
53 static VALUE doc_get_page(VALUE cls, VALUE _nr)
54 {
55     Check_Type(_nr, T_FIXNUM);
56     int nr = FIX2INT(_nr);
57     Get_Doc(doc,cls);
58
59     VALUE v = page_allocate(DocumentPage);
60     Get_Page(page,v)
61     page->page = doc->doc->getpage(doc->doc, nr);
62     return v;
63 }
64
65 static VALUE doc_each_page(VALUE cls)
66 {
67     Get_Doc(doc,cls);
68     int t;
69     for(t=1;t<=doc->doc->num_pages;t++) {
70         VALUE v = page_allocate(DocumentPage);
71         Get_Page(page,v)
72         page->page = doc->doc->getpage(doc->doc, t);
73         rb_yield(v);
74     }
75     return cls;
76 }
77
78 static void doc_mark(doc_internal_t*doc)
79 {
80     // e.g. rb_gc_mark(z->page);
81 }
82
83 static void doc_free(doc_internal_t*doc)
84 {
85     doc->doc->destroy(doc->doc);
86     free(doc);
87 }
88
89 static VALUE doc_allocate(VALUE cls, gfxsource_t*driver)
90 {
91     doc_internal_t*doc = 0;
92     VALUE v = Data_Make_Struct(cls, doc_internal_t, 0, doc_free, doc);
93     memset(doc, 0, sizeof(doc_internal_t));
94     doc->driver = driver;
95     return v;
96 }
97
98 static VALUE pdf_allocate(VALUE cls) {return doc_allocate(cls, pdfdriver);}
99 static VALUE swf_allocate(VALUE cls) {return doc_allocate(cls, swfdriver);}
100 static VALUE image_allocate(VALUE cls) {return doc_allocate(cls, imagedriver);}
101
102 // ------------------------ doc pages ---------------------------------------
103
104 static VALUE page_free(VALUE cls)
105 {
106     Get_Page(page, cls);
107     page->page->destroy(page->page);
108     free(page);
109     return cls;
110 }
111
112 static VALUE page_allocate(VALUE cls)
113 {
114     page_internal_t*page = 0;
115     VALUE v = Data_Make_Struct(cls, page_internal_t, 0, page_free, page);
116     memset(page, 0, sizeof(page_internal_t));
117     return v;
118 }
119
120 static VALUE page_render(VALUE cls, VALUE device)
121 {
122     Check_Type(device, T_CLASS);
123     Get_Page(page,cls)
124
125     gfxdevice_t dev;
126     dev.internal = (void*)(ptroff_t)device;
127
128     page->page->render(page->page, 0);//device);
129     //rb_yield(v);
130 }
131
132 static VALUE page_nr(VALUE cls)
133 {
134     Get_Page(page,cls)
135     return INT2FIX(page->page->nr);
136 }
137
138 static VALUE page_width(VALUE cls)
139 {
140     Get_Page(page,cls)
141     return INT2FIX(page->page->width);
142 }
143
144 static VALUE page_height(VALUE cls)
145 {
146     Get_Page(page,cls)
147     return INT2FIX(page->page->height);
148 }
149
150 // ------------------------ gfx device --------------------------------------
151
152 static VALUE noop(int argc, VALUE *argv, VALUE obj) {return obj;}
153
154 // --------------------------------------------------------------------------
155
156 void Init_gfx()
157 {
158     initLog(0,0,0,0,0,2);
159     pdfdriver = gfxsource_pdf_create();
160     swfdriver = gfxsource_swf_create();
161     imagedriver = gfxsource_image_create();
162
163     GFX = rb_define_module("GFX");
164     
165     DocumentPage = rb_define_class_under(GFX, "DocumentPage", rb_cObject);
166     rb_define_alloc_func(DocumentPage, page_allocate);
167     rb_define_method(DocumentPage, "width", page_width, 0);
168     rb_define_method(DocumentPage, "height", page_height, 0);
169     rb_define_method(DocumentPage, "nr", page_nr, 0);
170     rb_define_method(DocumentPage, "render", page_render, 0);
171
172     Document = rb_define_class_under(GFX, "Document", rb_cObject);
173     rb_define_method(Document, "initialize", doc_initialize, 1);
174     rb_define_method(Document, "page", doc_get_page, 1);
175     rb_define_method(Document, "each_page", doc_each_page, 0);
176     
177     Device = rb_define_class_under(GFX, "Device", rb_cObject);
178     rb_define_method(Device, "startpage", noop, -1);
179     rb_define_method(Device, "endpage", noop, -1);
180     rb_define_method(Device, "startclip", noop, -1);
181     rb_define_method(Device, "endclip", noop, -1);
182     rb_define_method(Device, "stroke", noop, -1);
183     rb_define_method(Device, "fill", noop, -1);
184     rb_define_method(Device, "fillbitmap", noop, -1);
185     rb_define_method(Device, "fillgradient", noop, -1);
186     rb_define_method(Device, "addfont", noop, -1);
187     rb_define_method(Device, "drawchar", noop, -1);
188     rb_define_method(Device, "drawlink", noop, -1);
189     rb_define_method(Device, "endpage", noop, -1);
190
191     PDFClass = rb_define_class_under(GFX, "PDF", Document);
192     rb_define_alloc_func(PDFClass, pdf_allocate);
193     
194     SWFClass = rb_define_class_under(GFX, "SWF", Document);
195     rb_define_alloc_func(SWFClass, swf_allocate);
196     
197     ImageClass = rb_define_class_under(GFX, "Image", Document);
198     rb_define_alloc_func(ImageClass, image_allocate);
199
200     //id_doc = rb_intern("doc");
201 }
202