rays 0.1.1
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.
- data/ChangeLog +8 -0
- data/README +4 -0
- data/Rakefile +72 -0
- data/VERSION +1 -0
- data/ext/rays/bitmap.cpp +322 -0
- data/ext/rays/extconf.rb +61 -0
- data/ext/rays/font.cpp +125 -0
- data/ext/rays/image.cpp +166 -0
- data/ext/rays/native.cpp +24 -0
- data/ext/rays/painter.cpp +573 -0
- data/ext/rays/rays.cpp +61 -0
- data/ext/rays/rays.h +39 -0
- data/ext/rays/texture.cpp +130 -0
- data/include/rays.h +20 -0
- data/include/rays/bitmap.h +80 -0
- data/include/rays/colorspace.h +101 -0
- data/include/rays/defs.h +33 -0
- data/include/rays/font.h +49 -0
- data/include/rays/helpers.h +37 -0
- data/include/rays/image.h +68 -0
- data/include/rays/opengl.h +15 -0
- data/include/rays/painter.h +179 -0
- data/include/rays/rays.h +19 -0
- data/include/rays/ruby.h +15 -0
- data/include/rays/ruby/bitmap.h +39 -0
- data/include/rays/ruby/font.h +39 -0
- data/include/rays/ruby/image.h +39 -0
- data/include/rays/ruby/painter.h +39 -0
- data/include/rays/ruby/rays.h +21 -0
- data/include/rays/ruby/texture.h +39 -0
- data/include/rays/texture.h +56 -0
- data/include/rays/transform.h +35 -0
- data/lib/rays.rb +9 -0
- data/lib/rays/autoinit.rb +10 -0
- data/lib/rays/bitmap.rb +25 -0
- data/lib/rays/image.rb +15 -0
- data/lib/rays/module.rb +30 -0
- data/lib/rays/painter.rb +99 -0
- data/lib/rays/texture.rb +15 -0
- data/rays.gemspec +54 -0
- data/src/cocoa/bitmap.mm +286 -0
- data/src/cocoa/font.mm +193 -0
- data/src/cocoa/helpers.h +26 -0
- data/src/cocoa/helpers.mm +25 -0
- data/src/cocoa/rays.mm +40 -0
- data/src/colorspace.cpp +183 -0
- data/src/helpers.cpp +22 -0
- data/src/image.cpp +133 -0
- data/src/painter.cpp +769 -0
- data/src/texture.cpp +360 -0
- data/src/transform.cpp +88 -0
- data/src/win32/bitmap.cpp +212 -0
- data/src/win32/font.cpp +99 -0
- data/src/win32/gdi.cpp +771 -0
- data/src/win32/gdi.h +226 -0
- data/src/win32/rays.cpp +36 -0
- data/support.rb +58 -0
- data/task/ext.rake +41 -0
- data/task/gem.rake +33 -0
- data/task/git.rake +22 -0
- data/task/lib.rake +54 -0
- data/test/helpers.rb +15 -0
- data/test/test_painter.rb +11 -0
- data/test/test_rays.rb +19 -0
- data/test/test_texture.rb +11 -0
- metadata +153 -0
data/rays.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
|
3
|
+
|
4
|
+
$: << File.join(File.dirname(__FILE__), 'lib')
|
5
|
+
|
6
|
+
require 'rake'
|
7
|
+
require 'rays/module'
|
8
|
+
|
9
|
+
|
10
|
+
FILES = FileList[*%w[
|
11
|
+
ChangeLog
|
12
|
+
README
|
13
|
+
Rakefile
|
14
|
+
support.rb
|
15
|
+
rays.gemspec
|
16
|
+
VERSION
|
17
|
+
task/**/*.rake
|
18
|
+
ext/**/*.rb
|
19
|
+
ext/**/*.h
|
20
|
+
ext/**/*.cpp
|
21
|
+
include/**/*.h
|
22
|
+
lib/**/*.rb
|
23
|
+
src/**/*.h
|
24
|
+
src/**/*.cpp
|
25
|
+
src/**/*.mm
|
26
|
+
test/**/*.rb
|
27
|
+
]]
|
28
|
+
|
29
|
+
Gem::Specification.new do |s|
|
30
|
+
s.name = 'rays'
|
31
|
+
s.summary = 'A Drawing Engine using OpenGL.'
|
32
|
+
s.description = 'This library helps you to develop graphics application with OpenGL.'
|
33
|
+
s.version = Rays.version
|
34
|
+
|
35
|
+
s.authors = %w[snori]
|
36
|
+
s.email = 'snori@xord.org'
|
37
|
+
s.homepage = 'http://blog.xord.org/'
|
38
|
+
|
39
|
+
s.platform = Gem::Platform::RUBY
|
40
|
+
s.required_ruby_version = '>=1.9.0'
|
41
|
+
s.require_paths << 'ext'
|
42
|
+
|
43
|
+
s.add_runtime_dependency 'rucy'
|
44
|
+
s.add_development_dependency 'rake'
|
45
|
+
s.add_development_dependency 'gemcutter'
|
46
|
+
|
47
|
+
s.files = FILES.to_a
|
48
|
+
s.test_files = FileList['test/**/test_*.rb'].to_a
|
49
|
+
|
50
|
+
s.has_rdoc = true
|
51
|
+
s.extra_rdoc_files = ['README']
|
52
|
+
|
53
|
+
s.extensions << 'Rakefile'
|
54
|
+
end
|
data/src/cocoa/bitmap.mm
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
// -*- objc -*-
|
2
|
+
#import <rays/bitmap.h>
|
3
|
+
|
4
|
+
|
5
|
+
#include <assert.h>
|
6
|
+
#import <Cocoa/Cocoa.h>
|
7
|
+
#include "helpers.h"
|
8
|
+
|
9
|
+
|
10
|
+
namespace Rays
|
11
|
+
{
|
12
|
+
|
13
|
+
|
14
|
+
static CGBitmapInfo
|
15
|
+
make_bitmapinfo (const ColorSpace& cs)
|
16
|
+
{
|
17
|
+
CGBitmapInfo info = 0;
|
18
|
+
|
19
|
+
if (cs.is_alpha_first())
|
20
|
+
{
|
21
|
+
info |= cs.is_premult()
|
22
|
+
? kCGImageAlphaPremultipliedFirst
|
23
|
+
: kCGImageAlphaFirst;
|
24
|
+
}
|
25
|
+
else if (cs.is_alpha_last())
|
26
|
+
{
|
27
|
+
info |= cs.is_premult()
|
28
|
+
? kCGImageAlphaPremultipliedLast
|
29
|
+
: kCGImageAlphaLast;
|
30
|
+
}
|
31
|
+
else if (cs.is_skip_first())
|
32
|
+
info |= kCGImageAlphaNoneSkipFirst;
|
33
|
+
else if (cs.is_skip_last())
|
34
|
+
info |= kCGImageAlphaNoneSkipLast;
|
35
|
+
else
|
36
|
+
info |= kCGImageAlphaNone;
|
37
|
+
|
38
|
+
if (cs.is_rgb()) info |= kCGBitmapByteOrder32Big;
|
39
|
+
else if (cs.is_bgr()) info |= kCGBitmapByteOrder32Little;
|
40
|
+
else return false;
|
41
|
+
|
42
|
+
if (cs.is_float()) info |= kCGBitmapFloatComponents;
|
43
|
+
|
44
|
+
return info;
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
struct Bitmap::Data
|
49
|
+
{
|
50
|
+
|
51
|
+
int width, height;
|
52
|
+
|
53
|
+
ColorSpace colorspace;
|
54
|
+
|
55
|
+
void* pixels;
|
56
|
+
|
57
|
+
CGContextRef context;
|
58
|
+
|
59
|
+
bool dirty;
|
60
|
+
|
61
|
+
Data ()
|
62
|
+
: width(0), height(0), pixels(NULL), context(NULL), dirty(true)
|
63
|
+
{
|
64
|
+
}
|
65
|
+
|
66
|
+
~Data ()
|
67
|
+
{
|
68
|
+
clear();
|
69
|
+
}
|
70
|
+
|
71
|
+
bool setup (int w, int h, const ColorSpace& cs)
|
72
|
+
{
|
73
|
+
if (w <= 0 || h <= 0 || !cs) return false;
|
74
|
+
|
75
|
+
clear();
|
76
|
+
|
77
|
+
width = w;
|
78
|
+
height = h;
|
79
|
+
colorspace = cs;
|
80
|
+
|
81
|
+
size_t size = w * h * cs.Bpp();
|
82
|
+
pixels = new uchar[size];
|
83
|
+
memset(pixels, 0, size);
|
84
|
+
|
85
|
+
return true;
|
86
|
+
}
|
87
|
+
|
88
|
+
CGContextRef get_context ()
|
89
|
+
{
|
90
|
+
if (context) return context;
|
91
|
+
|
92
|
+
int bpc = colorspace.bpc();
|
93
|
+
int pitch = width * colorspace.Bpp();
|
94
|
+
if (bpc <= 0 || pitch <= 0) return NULL;
|
95
|
+
|
96
|
+
CGColorSpaceRef cgcs = NULL;
|
97
|
+
if (colorspace.is_gray())
|
98
|
+
cgcs = CGColorSpaceCreateDeviceGray();
|
99
|
+
else if (colorspace.is_rgb() || colorspace.is_bgr())
|
100
|
+
cgcs = CGColorSpaceCreateDeviceRGB();
|
101
|
+
else
|
102
|
+
return NULL;
|
103
|
+
|
104
|
+
context = CGBitmapContextCreate(
|
105
|
+
pixels, width, height, bpc, pitch, cgcs, make_bitmapinfo(colorspace));
|
106
|
+
CGColorSpaceRelease(cgcs);
|
107
|
+
return context;
|
108
|
+
}
|
109
|
+
|
110
|
+
CGImageRef get_image ()
|
111
|
+
{
|
112
|
+
CGContextRef c = get_context();
|
113
|
+
if (!c) return NULL;
|
114
|
+
return CGBitmapContextCreateImage(c);
|
115
|
+
}
|
116
|
+
|
117
|
+
void clear ()
|
118
|
+
{
|
119
|
+
if (context) CGContextRelease(context);
|
120
|
+
if (pixels) delete [] (uchar*) pixels;
|
121
|
+
|
122
|
+
width = height = 0;
|
123
|
+
colorspace = COLORSPACE_UNKNOWN;
|
124
|
+
pixels = NULL;
|
125
|
+
context = NULL;
|
126
|
+
dirty = true;
|
127
|
+
}
|
128
|
+
|
129
|
+
};// Bitmap::Data
|
130
|
+
|
131
|
+
|
132
|
+
Bitmap::Bitmap ()
|
133
|
+
{
|
134
|
+
}
|
135
|
+
|
136
|
+
Bitmap::Bitmap (int width, int height, const ColorSpace& colorspace)
|
137
|
+
{
|
138
|
+
self->setup(width, height, colorspace);
|
139
|
+
}
|
140
|
+
|
141
|
+
Bitmap::~Bitmap ()
|
142
|
+
{
|
143
|
+
}
|
144
|
+
|
145
|
+
int
|
146
|
+
Bitmap::width () const
|
147
|
+
{
|
148
|
+
if (!*this) return 0;
|
149
|
+
return self->width;
|
150
|
+
}
|
151
|
+
|
152
|
+
int
|
153
|
+
Bitmap::height () const
|
154
|
+
{
|
155
|
+
if (!*this) return 0;
|
156
|
+
return self->height;
|
157
|
+
}
|
158
|
+
|
159
|
+
const ColorSpace&
|
160
|
+
Bitmap::color_space () const
|
161
|
+
{
|
162
|
+
if (!*this)
|
163
|
+
{
|
164
|
+
static const ColorSpace UNKNOWN = COLORSPACE_UNKNOWN;
|
165
|
+
return UNKNOWN;
|
166
|
+
}
|
167
|
+
return self->colorspace;
|
168
|
+
}
|
169
|
+
|
170
|
+
int
|
171
|
+
Bitmap::pitch () const
|
172
|
+
{
|
173
|
+
return width() * self->colorspace.Bpp();
|
174
|
+
}
|
175
|
+
|
176
|
+
size_t
|
177
|
+
Bitmap::size () const
|
178
|
+
{
|
179
|
+
return pitch() * height();
|
180
|
+
}
|
181
|
+
|
182
|
+
bool
|
183
|
+
Bitmap::dirty () const
|
184
|
+
{
|
185
|
+
return self->dirty;
|
186
|
+
}
|
187
|
+
|
188
|
+
void
|
189
|
+
Bitmap::set_dirty (bool b)
|
190
|
+
{
|
191
|
+
self->dirty = b;
|
192
|
+
}
|
193
|
+
|
194
|
+
void*
|
195
|
+
Bitmap::data ()
|
196
|
+
{
|
197
|
+
if (!*this) return NULL;
|
198
|
+
return self->pixels;
|
199
|
+
}
|
200
|
+
|
201
|
+
const void*
|
202
|
+
Bitmap::data () const
|
203
|
+
{
|
204
|
+
return const_cast<Bitmap*>(this)->data();
|
205
|
+
}
|
206
|
+
|
207
|
+
Bitmap::operator bool () const
|
208
|
+
{
|
209
|
+
return
|
210
|
+
self->width > 0 && self->height > 0 && self->colorspace && self->pixels;
|
211
|
+
}
|
212
|
+
|
213
|
+
bool
|
214
|
+
Bitmap::operator ! () const
|
215
|
+
{
|
216
|
+
return !operator bool();
|
217
|
+
}
|
218
|
+
|
219
|
+
|
220
|
+
bool
|
221
|
+
load_bitmap (Bitmap* bmp, const char* path_)
|
222
|
+
{
|
223
|
+
if (!bmp || !path_) return false;
|
224
|
+
|
225
|
+
NSString* path = [NSString stringWithUTF8String: path_];
|
226
|
+
NSBitmapImageRep* imagerep =
|
227
|
+
[NSBitmapImageRep imageRepWithContentsOfFile: path];
|
228
|
+
if (!imagerep) return false;
|
229
|
+
|
230
|
+
CGImageRef image = [imagerep CGImage];
|
231
|
+
if (!image) return false;
|
232
|
+
|
233
|
+
int width = CGImageGetWidth(image);
|
234
|
+
int height = CGImageGetHeight(image);
|
235
|
+
|
236
|
+
*bmp = Bitmap(width, height, ColorSpace(RGBA, true));
|
237
|
+
if (!*bmp) return false;
|
238
|
+
|
239
|
+
CGContextRef context = bmp->self->get_context();
|
240
|
+
if (!context) return false;
|
241
|
+
|
242
|
+
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
|
243
|
+
return true;
|
244
|
+
}
|
245
|
+
|
246
|
+
bool
|
247
|
+
save_bitmap (const Bitmap& bmp, const char* path_)
|
248
|
+
{
|
249
|
+
boost::shared_ptr<CGImage> img(
|
250
|
+
bmp.self->get_image(), CGImageRelease);
|
251
|
+
if (!img) return false;
|
252
|
+
|
253
|
+
NSString* path = [NSString stringWithUTF8String: path_];
|
254
|
+
NSURL* url = [NSURL fileURLWithPath: path];
|
255
|
+
if (!url) return false;
|
256
|
+
|
257
|
+
boost::shared_ptr<CGImageDestination> dest(
|
258
|
+
CGImageDestinationCreateWithURL((CFURLRef) url, kUTTypePNG, 1, NULL),
|
259
|
+
safe_cfrelease);
|
260
|
+
if (!dest) return false;
|
261
|
+
|
262
|
+
CGImageDestinationAddImage(dest.get(), img.get(), NULL);
|
263
|
+
return CGImageDestinationFinalize(dest.get());
|
264
|
+
}
|
265
|
+
|
266
|
+
|
267
|
+
bool draw_string (
|
268
|
+
CGContextRef, coord, const char*, coord, coord, const Font&);
|
269
|
+
|
270
|
+
bool
|
271
|
+
draw_string (
|
272
|
+
Bitmap* bmp, const char* str, coord x, coord y, const Font& font)
|
273
|
+
{
|
274
|
+
if (!bmp || !*bmp || !str || !font) return false;
|
275
|
+
|
276
|
+
if (*str == '\0') return true;
|
277
|
+
|
278
|
+
if (!draw_string(bmp->self->get_context(), bmp->height(), str, x, y, font))
|
279
|
+
return false;
|
280
|
+
|
281
|
+
bmp->set_dirty();
|
282
|
+
return true;
|
283
|
+
}
|
284
|
+
|
285
|
+
|
286
|
+
}// Rays
|
data/src/cocoa/font.mm
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
// -*- objc -*-
|
2
|
+
#include "rays/font.h"
|
3
|
+
|
4
|
+
|
5
|
+
#include <ApplicationServices/ApplicationServices.h>
|
6
|
+
#include "helpers.h"
|
7
|
+
|
8
|
+
|
9
|
+
namespace Rays
|
10
|
+
{
|
11
|
+
|
12
|
+
|
13
|
+
struct Font::Data
|
14
|
+
{
|
15
|
+
|
16
|
+
CTFontRef font;
|
17
|
+
|
18
|
+
Data ()
|
19
|
+
: font(NULL)
|
20
|
+
{
|
21
|
+
}
|
22
|
+
|
23
|
+
~Data ()
|
24
|
+
{
|
25
|
+
if (font)
|
26
|
+
{
|
27
|
+
CFRelease(font);
|
28
|
+
font = NULL;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
};// Font::Data
|
33
|
+
|
34
|
+
|
35
|
+
static CTLineRef
|
36
|
+
make_line (CTFontRef font, const char* str)
|
37
|
+
{
|
38
|
+
if (!font || !str || *str == '\0')
|
39
|
+
return NULL;
|
40
|
+
|
41
|
+
CFStringRef keys[] = {
|
42
|
+
kCTFontAttributeName,
|
43
|
+
kCTForegroundColorFromContextAttributeName
|
44
|
+
};
|
45
|
+
CFTypeRef values[] = {
|
46
|
+
font,
|
47
|
+
kCFBooleanTrue
|
48
|
+
};
|
49
|
+
size_t nkeys = sizeof(keys) / sizeof(keys[0]);
|
50
|
+
|
51
|
+
CFDictionaryRef attr = CFDictionaryCreate(
|
52
|
+
NULL, (const void**) &keys, (const void**) &values, nkeys,
|
53
|
+
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
54
|
+
|
55
|
+
CFAttributedStringRef attrstr = CFAttributedStringCreate(
|
56
|
+
NULL, cfstring(str).get(), attr);
|
57
|
+
CFRelease(attr);
|
58
|
+
|
59
|
+
CTLineRef line = CTLineCreateWithAttributedString(attrstr);
|
60
|
+
CFRelease(attrstr);
|
61
|
+
|
62
|
+
return line;
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
Font::Font ()
|
67
|
+
{
|
68
|
+
}
|
69
|
+
|
70
|
+
Font::Font (const char* name, coord size)
|
71
|
+
{
|
72
|
+
self->font = name
|
73
|
+
? CTFontCreateWithName(cfstring(name).get(), size, NULL)
|
74
|
+
: CTFontCreateUIFontForLanguage(kCTFontSystemFontType, size, NULL);
|
75
|
+
}
|
76
|
+
|
77
|
+
Font::~Font ()
|
78
|
+
{
|
79
|
+
}
|
80
|
+
|
81
|
+
String
|
82
|
+
Font::name () const
|
83
|
+
{
|
84
|
+
if (!*this) return "";
|
85
|
+
|
86
|
+
CFStringRef str = CTFontCopyFullName(self->font);
|
87
|
+
|
88
|
+
enum {BUFSIZE = 2048};
|
89
|
+
char buf[BUFSIZE + 1];
|
90
|
+
if (!CFStringGetCString(str, buf, BUFSIZE, kCFStringEncodingUTF8))
|
91
|
+
buf[0] = '\0';
|
92
|
+
|
93
|
+
CFRelease(str);
|
94
|
+
return buf;
|
95
|
+
}
|
96
|
+
|
97
|
+
coord
|
98
|
+
Font::size () const
|
99
|
+
{
|
100
|
+
if (!*this) return 0;
|
101
|
+
return CTFontGetSize(self->font);
|
102
|
+
}
|
103
|
+
|
104
|
+
bool
|
105
|
+
Font::get_extent (coord* width, coord* height, const char* str) const
|
106
|
+
{
|
107
|
+
if (!*this) return false;
|
108
|
+
|
109
|
+
if (width) *width = 0;
|
110
|
+
if (height) *height = 0;
|
111
|
+
|
112
|
+
CGFloat ascent = 0, descent = 0, leading = 0;
|
113
|
+
if (width)
|
114
|
+
{
|
115
|
+
CTLineRef line = make_line(self->font, str);
|
116
|
+
if (!line) return false;
|
117
|
+
|
118
|
+
*width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
|
119
|
+
CFRelease(line);
|
120
|
+
}
|
121
|
+
|
122
|
+
if (height)
|
123
|
+
{
|
124
|
+
if (width)
|
125
|
+
*height = ascent + descent + leading;
|
126
|
+
else
|
127
|
+
{
|
128
|
+
*height =
|
129
|
+
CTFontGetAscent(self->font) +
|
130
|
+
CTFontGetDescent(self->font) +
|
131
|
+
CTFontGetLeading(self->font);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
return true;
|
136
|
+
}
|
137
|
+
|
138
|
+
Font::operator bool () const
|
139
|
+
{
|
140
|
+
return !!self->font;
|
141
|
+
}
|
142
|
+
|
143
|
+
bool
|
144
|
+
Font::operator ! () const
|
145
|
+
{
|
146
|
+
return !operator bool();
|
147
|
+
}
|
148
|
+
|
149
|
+
|
150
|
+
const Font&
|
151
|
+
default_font ()
|
152
|
+
{
|
153
|
+
static const Font FONT(NULL);
|
154
|
+
return FONT;
|
155
|
+
}
|
156
|
+
|
157
|
+
|
158
|
+
bool
|
159
|
+
draw_string (
|
160
|
+
CGContextRef context, coord context_height,
|
161
|
+
const char* str, coord x, coord y, const Font& font)
|
162
|
+
{
|
163
|
+
if (!context || !str || !font) return false;
|
164
|
+
|
165
|
+
if (*str == '\0') return true;
|
166
|
+
|
167
|
+
CTLineRef line = make_line(font.self->font, str);
|
168
|
+
if (!line) return false;
|
169
|
+
|
170
|
+
coord width = 0, height = 0;
|
171
|
+
if (!font.get_extent(&width, &height, str))
|
172
|
+
return false;
|
173
|
+
|
174
|
+
CGRect rect = CGRectMake(
|
175
|
+
x, context_height - height - y, width, height);
|
176
|
+
CGContextClearRect(context, rect);
|
177
|
+
//CGContextSetRGBFillColor(context, 0, 0, 0, 1);
|
178
|
+
//CGContextFillRect(context, rect);
|
179
|
+
CGContextSetRGBFillColor(context, 1, 1, 1, 1);
|
180
|
+
|
181
|
+
CGContextSaveGState(context);
|
182
|
+
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
183
|
+
CGContextSetTextPosition(
|
184
|
+
context, x, context_height - CTFontGetAscent(font.self->font) - y);
|
185
|
+
CTLineDraw(line, context);
|
186
|
+
CGContextRestoreGState(context);
|
187
|
+
|
188
|
+
CFRelease(line);
|
189
|
+
return true;
|
190
|
+
}
|
191
|
+
|
192
|
+
|
193
|
+
}// Rays
|