rays 0.3.11 → 0.3.13
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 +4 -4
- data/.doc/ext/rays/image.cpp +10 -0
- data/.doc/ext/rays/painter.cpp +49 -1
- data/.doc/ext/rays/shader.cpp +8 -6
- data/.github/workflows/release-gem.yml +5 -16
- data/.github/workflows/utils.rb +88 -17
- data/ChangeLog.md +26 -0
- data/README.md +164 -5
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/ext/rays/extconf.rb +3 -4
- data/ext/rays/image.cpp +11 -0
- data/ext/rays/painter.cpp +53 -1
- data/ext/rays/shader.cpp +8 -6
- data/include/rays/coord.h +6 -6
- data/include/rays/defs.h +2 -0
- data/include/rays/image.h +11 -1
- data/include/rays/painter.h +19 -0
- data/include/rays/ruby.h +2 -2
- data/include/rays/shader.h +5 -3
- data/include/rays.h +2 -2
- data/lib/rays/extension.rb +8 -2
- data/lib/rays/image.rb +2 -1
- data/lib/rays/shader.rb +13 -4
- data/rays.gemspec +3 -4
- data/src/color_space.cpp +1 -1
- data/src/coord.h +10 -0
- data/src/font.cpp +1 -1
- data/src/image.cpp +85 -10
- data/src/opengl/painter.cpp +559 -214
- data/src/opengl/render_buffer.cpp +1 -1
- data/src/opengl/sdl/opengl.cpp +6 -0
- data/src/opengl/shader.cpp +68 -51
- data/src/opengl/shader.h +10 -6
- data/src/opengl/shader_program.cpp +21 -7
- data/src/opengl/shader_program.h +2 -1
- data/src/opengl/shader_source.cpp +2 -4
- data/src/opengl/texture.cpp +18 -6
- data/src/osx/bitmap.mm +1 -1
- data/src/painter.cpp +80 -26
- data/src/painter.h +26 -13
- data/src/sdl/font.cpp +358 -9
- data/src/sdl/rays.cpp +5 -0
- data/src/texture.h +6 -0
- data/test/test_painter.rb +36 -25
- data/test/test_painter_batch.rb +254 -0
- metadata +8 -6
data/src/sdl/font.cpp
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
#include "../font.h"
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
#ifdef WASM
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <emscripten.h>
|
|
8
|
+
#endif
|
|
9
|
+
#include <SDL.h>
|
|
10
|
+
#include <SDL_ttf.h>
|
|
4
11
|
#include "rays/exception.h"
|
|
5
12
|
|
|
6
13
|
|
|
@@ -11,22 +18,324 @@ namespace Rays
|
|
|
11
18
|
struct RawFont::Data
|
|
12
19
|
{
|
|
13
20
|
|
|
14
|
-
String
|
|
21
|
+
String name;
|
|
22
|
+
|
|
23
|
+
coord size = 0;
|
|
24
|
+
|
|
25
|
+
virtual ~Data ()
|
|
26
|
+
{
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
virtual void draw_string (SDL_Surface* target, const char* str, coord x, coord y)
|
|
30
|
+
{
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
virtual coord get_width (const char* str)
|
|
34
|
+
{
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
virtual coord get_height (coord* ascent, coord* descent, coord* leading)
|
|
39
|
+
{
|
|
40
|
+
if (ascent) *ascent = 0;
|
|
41
|
+
if (descent) *descent = 0;
|
|
42
|
+
if (leading) *leading = 0;
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
virtual bool is_valid () const
|
|
47
|
+
{
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
virtual Data* dup (coord size) const
|
|
52
|
+
{
|
|
53
|
+
return NULL;
|
|
54
|
+
}
|
|
15
55
|
|
|
16
56
|
};// RawFont::Data
|
|
17
57
|
|
|
18
58
|
|
|
59
|
+
struct SDLFontData : public RawFont::Data
|
|
60
|
+
{
|
|
61
|
+
|
|
62
|
+
TTF_Font* font = NULL;
|
|
63
|
+
|
|
64
|
+
String path;
|
|
65
|
+
|
|
66
|
+
SDLFontData (const char* path, coord size)
|
|
67
|
+
{
|
|
68
|
+
if (!path)
|
|
69
|
+
argument_error(__FILE__, __LINE__);
|
|
70
|
+
|
|
71
|
+
font = TTF_OpenFont(path, (int) size);
|
|
72
|
+
if (!font)
|
|
73
|
+
rays_error(__FILE__, __LINE__, "failed to open font: %s", TTF_GetError());
|
|
74
|
+
|
|
75
|
+
this->path = path;
|
|
76
|
+
this->size = size;
|
|
77
|
+
|
|
78
|
+
const char* family = TTF_FontFaceFamilyName(font);
|
|
79
|
+
if (family) this->name = family;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
~SDLFontData () override
|
|
83
|
+
{
|
|
84
|
+
if (font) TTF_CloseFont(font);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
void draw_string (SDL_Surface* target, const char* str, coord x, coord y) override
|
|
88
|
+
{
|
|
89
|
+
SDL_Surface* surface = TTF_RenderUTF8_Blended(font, str, {255, 255, 255, 255});
|
|
90
|
+
if (!surface)
|
|
91
|
+
rays_error(__FILE__, __LINE__, "TTF_RenderUTF8_Blended failed: %s", TTF_GetError());
|
|
92
|
+
|
|
93
|
+
SDL_Rect dst = {(int) x, (int) y, surface->w, surface->h};
|
|
94
|
+
SDL_FillRect(target, &dst, 0);
|
|
95
|
+
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
|
|
96
|
+
SDL_BlitSurface(surface, NULL, target, &dst);
|
|
97
|
+
SDL_FreeSurface(surface);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
coord get_width (const char* str) override
|
|
101
|
+
{
|
|
102
|
+
int w = 0, h = 0;
|
|
103
|
+
if (TTF_SizeUTF8(font, str, &w, &h) < 0)
|
|
104
|
+
rays_error(__FILE__, __LINE__, "TTF_SizeUTF8 failed: %s", TTF_GetError());
|
|
105
|
+
|
|
106
|
+
return (coord) w;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
coord get_height (coord* ascent, coord* descent, coord* leading) override
|
|
110
|
+
{
|
|
111
|
+
int asc = TTF_FontAscent(font);
|
|
112
|
+
int desc = -TTF_FontDescent(font);// TTF returns negative descent
|
|
113
|
+
int skip = TTF_FontLineSkip(font);
|
|
114
|
+
|
|
115
|
+
if (ascent) *ascent = (coord) asc;
|
|
116
|
+
if (descent) *descent = (coord) desc;
|
|
117
|
+
if (leading) *leading = (coord) (skip - asc - desc);
|
|
118
|
+
|
|
119
|
+
return (coord) (asc + desc);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
bool is_valid () const override
|
|
123
|
+
{
|
|
124
|
+
return font;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Data* dup (coord size) const override
|
|
128
|
+
{
|
|
129
|
+
return new SDLFontData(path.c_str(), size);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
};// SDLData
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
#ifdef WASM
|
|
136
|
+
// Browser-based font implementation: render text via an offscreen
|
|
137
|
+
// HTMLCanvasElement and copy the pixels into an SDL_Surface.
|
|
138
|
+
|
|
139
|
+
EM_JS(void, rays_wasm_font_init_, (),
|
|
140
|
+
{
|
|
141
|
+
if (Module._raysFontCanvas) return;
|
|
142
|
+
Module._raysFontCanvas = document.createElement('canvas');
|
|
143
|
+
Module._raysFontContext = Module._raysFontCanvas.getContext('2d');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
EM_JS(double, rays_wasm_font_text_width_, (
|
|
147
|
+
const char* str, const char* name, double size),
|
|
148
|
+
{
|
|
149
|
+
const s = UTF8ToString(str);
|
|
150
|
+
const n = UTF8ToString(name);
|
|
151
|
+
const c = Module._raysFontContext;
|
|
152
|
+
c.font = `${size}px "${n}"`;
|
|
153
|
+
return c.measureText(s).width;
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
EM_JS(void, rays_wasm_font_get_metrics_, (
|
|
157
|
+
const char* name, double size,
|
|
158
|
+
double* out_ascent, double* out_descent, double* out_leading),
|
|
159
|
+
{
|
|
160
|
+
const n = UTF8ToString(name);
|
|
161
|
+
const c = Module._raysFontContext;
|
|
162
|
+
c.font = `${size}px "${n}"`;
|
|
163
|
+
const m = c.measureText('Mgjpqy');
|
|
164
|
+
const asc = Math.max(
|
|
165
|
+
m. fontBoundingBoxAscent ?? 0,
|
|
166
|
+
m.actualBoundingBoxAscent ?? size * 0.8);
|
|
167
|
+
const dsc = Math.max(
|
|
168
|
+
m. fontBoundingBoxDescent ?? 0,
|
|
169
|
+
m.actualBoundingBoxDescent ?? size * 0.2);
|
|
170
|
+
|
|
171
|
+
setValue(out_ascent, asc, 'double');
|
|
172
|
+
setValue(out_descent, dsc, 'double');
|
|
173
|
+
setValue(out_leading, size * 0.2, 'double');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
EM_JS(void*, rays_wasm_font_render_, (
|
|
177
|
+
const char* str, const char* name, double size,
|
|
178
|
+
int* out_width, int* out_height, double* out_ascent, double* out_descent),
|
|
179
|
+
{
|
|
180
|
+
const s = UTF8ToString(str);
|
|
181
|
+
const n = UTF8ToString(name);
|
|
182
|
+
const c = Module._raysFontContext;
|
|
183
|
+
const cv = Module._raysFontCanvas;
|
|
184
|
+
c.font = `${size}px "${n}"`;
|
|
185
|
+
const m = c.measureText(s);
|
|
186
|
+
const asc = Math.max(
|
|
187
|
+
m. fontBoundingBoxAscent ?? 0,
|
|
188
|
+
m.actualBoundingBoxAscent ?? size * 0.8);
|
|
189
|
+
const dsc = Math.max(
|
|
190
|
+
m. fontBoundingBoxDescent ?? 0,
|
|
191
|
+
m.actualBoundingBoxDescent ?? size * 0.2);
|
|
192
|
+
const w = Math.max(1, Math.ceil(m.width));
|
|
193
|
+
const h = Math.max(1, Math.ceil(asc + dsc));
|
|
194
|
+
|
|
195
|
+
if (cv.width < w) cv.width = w;
|
|
196
|
+
if (cv.height < h) cv.height = h;
|
|
197
|
+
|
|
198
|
+
c.clearRect(0, 0, cv.width, cv.height);
|
|
199
|
+
c.font = `${size}px "${n}"`;// re-apply after canvas resize
|
|
200
|
+
c.fillStyle = 'white';
|
|
201
|
+
c.textBaseline = 'alphabetic';
|
|
202
|
+
c.fillText(s, 0, asc);
|
|
203
|
+
|
|
204
|
+
const data = c.getImageData(0, 0, w, h).data;
|
|
205
|
+
const ptr = _malloc(w * h * 4);
|
|
206
|
+
HEAPU8.set(data, ptr);
|
|
207
|
+
setValue(out_width, w, 'i32');
|
|
208
|
+
setValue(out_height, h, 'i32');
|
|
209
|
+
setValue(out_ascent, asc, 'double');
|
|
210
|
+
setValue(out_descent, dsc, 'double');
|
|
211
|
+
return ptr;
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
EM_JS(const char*, rays_wasm_font_families_, (),
|
|
215
|
+
{
|
|
216
|
+
const list = [
|
|
217
|
+
'sans-serif', 'serif', 'monospace', 'cursive', 'fantasy',
|
|
218
|
+
'system-ui', 'ui-sans-serif', 'ui-serif', 'ui-monospace',
|
|
219
|
+
'Arial', 'Helvetica', 'Times New Roman', 'Times', 'Courier New',
|
|
220
|
+
'Courier', 'Verdana', 'Georgia', 'Trebuchet MS', 'Comic Sans MS',
|
|
221
|
+
'Impact', 'Tahoma', 'Lucida Sans Unicode', 'Lucida Console',
|
|
222
|
+
'Palatino', 'Garamond', 'Book Antiqua', 'Hiragino Sans',
|
|
223
|
+
'Hiragino Kaku Gothic ProN', 'Hiragino Mincho ProN',
|
|
224
|
+
'Yu Gothic', 'Yu Mincho', 'Meiryo', 'MS Gothic', 'MS Mincho'
|
|
225
|
+
];
|
|
226
|
+
const joined = list.join('\0') + '\0';
|
|
227
|
+
const len = lengthBytesUTF8(joined) + 1;
|
|
228
|
+
const ptr = _malloc(len);
|
|
229
|
+
stringToUTF8(joined, ptr, len);
|
|
230
|
+
return ptr;
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
struct CanvasFontData : public RawFont::Data
|
|
235
|
+
{
|
|
236
|
+
|
|
237
|
+
CanvasFontData (const char* name, coord size)
|
|
238
|
+
{
|
|
239
|
+
rays_wasm_font_init_();
|
|
240
|
+
|
|
241
|
+
this->name = name && *name != '\0' ? name : "sans-serif";
|
|
242
|
+
this->size = size;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void draw_string (SDL_Surface* target, const char* str, coord x, coord y) override
|
|
246
|
+
{
|
|
247
|
+
int w = 0, h = 0;
|
|
248
|
+
double ascent = 0, descent = 0;
|
|
249
|
+
std::shared_ptr<void> pixels(
|
|
250
|
+
rays_wasm_font_render_(
|
|
251
|
+
str, name.c_str(), (double) size,
|
|
252
|
+
&w, &h, &ascent, &descent),
|
|
253
|
+
free);
|
|
254
|
+
if (!pixels || w <= 0 || h <= 0) return;
|
|
255
|
+
|
|
256
|
+
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
|
|
257
|
+
pixels.get(), w, h, 32, w * 4,
|
|
258
|
+
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
|
259
|
+
if (!surface)
|
|
260
|
+
rays_error(__FILE__, __LINE__, "SDL_CreateRGBSurfaceFrom failed: %s", SDL_GetError());
|
|
261
|
+
|
|
262
|
+
SDL_Rect dest = {(int) x, (int) y, w, h};
|
|
263
|
+
SDL_FillRect(target, &dest, 0);
|
|
264
|
+
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
|
|
265
|
+
SDL_BlitSurface(surface, NULL, target, &dest);
|
|
266
|
+
SDL_FreeSurface(surface);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
coord get_width (const char* str) override
|
|
270
|
+
{
|
|
271
|
+
return (coord) rays_wasm_font_text_width_(str, name.c_str(), (double) size);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
coord get_height (coord* ascent, coord* descent, coord* leading) override
|
|
275
|
+
{
|
|
276
|
+
double asc = 0, desc = 0, lead = 0;
|
|
277
|
+
rays_wasm_font_get_metrics_(name.c_str(), (double) size, &asc, &desc, &lead);
|
|
278
|
+
|
|
279
|
+
if (ascent) *ascent = (coord) asc;
|
|
280
|
+
if (descent) *descent = (coord) desc;
|
|
281
|
+
if (leading) *leading = (coord) lead;
|
|
282
|
+
|
|
283
|
+
return (coord) (asc + desc);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
bool is_valid () const override
|
|
287
|
+
{
|
|
288
|
+
return size > 0 && !name.empty();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
Data* dup (coord size) const override
|
|
292
|
+
{
|
|
293
|
+
return new CanvasFontData(name.c_str(), size);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
};// CanvasData
|
|
297
|
+
#endif
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
19
301
|
const FontFamilyMap&
|
|
20
302
|
get_font_families ()
|
|
21
303
|
{
|
|
304
|
+
#ifdef WASM
|
|
305
|
+
static const FontFamilyMap MAP = []()
|
|
306
|
+
{
|
|
307
|
+
rays_wasm_font_init_();
|
|
308
|
+
FontFamilyMap map;
|
|
309
|
+
const char* head = rays_wasm_font_families_();
|
|
310
|
+
const char* base = head;
|
|
311
|
+
while (head && *head)
|
|
312
|
+
{
|
|
313
|
+
String name(head);
|
|
314
|
+
if (!name.empty())
|
|
315
|
+
{
|
|
316
|
+
FontFamilyMap::mapped_type array;
|
|
317
|
+
array.emplace_back(name);
|
|
318
|
+
map[name] = array;
|
|
319
|
+
}
|
|
320
|
+
head += name.size() + 1;
|
|
321
|
+
}
|
|
322
|
+
free((void*) base);
|
|
323
|
+
return map;
|
|
324
|
+
}();
|
|
325
|
+
return MAP;
|
|
326
|
+
#else
|
|
22
327
|
static const FontFamilyMap MAP;
|
|
23
328
|
return MAP;
|
|
329
|
+
#endif
|
|
24
330
|
}
|
|
25
331
|
|
|
332
|
+
|
|
26
333
|
RawFont
|
|
27
334
|
RawFont_load (const char* path, coord size)
|
|
28
335
|
{
|
|
29
|
-
|
|
336
|
+
RawFont rawfont;
|
|
337
|
+
rawfont.self.reset(new SDLFontData(path, size));
|
|
338
|
+
return rawfont;
|
|
30
339
|
}
|
|
31
340
|
|
|
32
341
|
|
|
@@ -34,12 +343,28 @@ namespace Rays
|
|
|
34
343
|
{
|
|
35
344
|
}
|
|
36
345
|
|
|
346
|
+
static RawFont::Data*
|
|
347
|
+
create_data (const char* name, coord size)
|
|
348
|
+
{
|
|
349
|
+
#ifdef WASM
|
|
350
|
+
return new CanvasFontData(name, size);
|
|
351
|
+
#else
|
|
352
|
+
if (name)
|
|
353
|
+
not_implemented_error(__FILE__, __LINE__);
|
|
354
|
+
return new SDLFontData("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", size);
|
|
355
|
+
#endif
|
|
356
|
+
}
|
|
357
|
+
|
|
37
358
|
RawFont::RawFont (const char* name, coord size)
|
|
359
|
+
: self(create_data(name, size))
|
|
38
360
|
{
|
|
39
361
|
}
|
|
40
362
|
|
|
41
363
|
RawFont::RawFont (const This& obj, coord size)
|
|
42
364
|
{
|
|
365
|
+
if (!obj) return;
|
|
366
|
+
|
|
367
|
+
self.reset(obj.self->dup(size));
|
|
43
368
|
}
|
|
44
369
|
|
|
45
370
|
RawFont::~RawFont ()
|
|
@@ -48,39 +373,63 @@ namespace Rays
|
|
|
48
373
|
|
|
49
374
|
void
|
|
50
375
|
RawFont::draw_string (
|
|
51
|
-
void*
|
|
376
|
+
void* context, coord context_height,
|
|
52
377
|
const char* str, coord x, coord y) const
|
|
53
378
|
{
|
|
379
|
+
SDL_Surface* target = (SDL_Surface*) context;
|
|
380
|
+
|
|
381
|
+
if (!target)
|
|
382
|
+
argument_error(__FILE__, __LINE__);
|
|
383
|
+
if (!str)
|
|
384
|
+
argument_error(__FILE__, __LINE__);
|
|
385
|
+
|
|
386
|
+
if (*str == '\0') return;
|
|
387
|
+
|
|
388
|
+
if (!*this)
|
|
389
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
390
|
+
|
|
391
|
+
self->draw_string(target, str, x, y);
|
|
54
392
|
}
|
|
55
393
|
|
|
56
394
|
String
|
|
57
395
|
RawFont::name () const
|
|
58
396
|
{
|
|
59
|
-
return "";
|
|
397
|
+
if (!*this) return "";
|
|
398
|
+
return self->name;
|
|
60
399
|
}
|
|
61
400
|
|
|
62
401
|
coord
|
|
63
402
|
RawFont::size () const
|
|
64
403
|
{
|
|
65
|
-
return 0;
|
|
404
|
+
if (!*this) return 0;
|
|
405
|
+
return self->size;
|
|
66
406
|
}
|
|
67
407
|
|
|
68
408
|
coord
|
|
69
409
|
RawFont::get_width (const char* str) const
|
|
70
410
|
{
|
|
71
|
-
if (!str
|
|
72
|
-
|
|
411
|
+
if (!str)
|
|
412
|
+
argument_error(__FILE__, __LINE__);
|
|
413
|
+
if (!*this)
|
|
414
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
415
|
+
|
|
416
|
+
if (*str == '\0') return 0;
|
|
417
|
+
|
|
418
|
+
return self->get_width(str);
|
|
73
419
|
}
|
|
74
420
|
|
|
75
421
|
coord
|
|
76
422
|
RawFont::get_height (coord* ascent, coord* descent, coord* leading) const
|
|
77
423
|
{
|
|
78
|
-
|
|
424
|
+
if (!*this)
|
|
425
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
426
|
+
|
|
427
|
+
return self->get_height(ascent, descent, leading);
|
|
79
428
|
}
|
|
80
429
|
|
|
81
430
|
RawFont::operator bool () const
|
|
82
431
|
{
|
|
83
|
-
return
|
|
432
|
+
return self && self->is_valid();
|
|
84
433
|
}
|
|
85
434
|
|
|
86
435
|
bool
|
data/src/sdl/rays.cpp
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
#include <SDL.h>
|
|
5
|
+
#include <SDL_ttf.h>
|
|
5
6
|
#include "rays/exception.h"
|
|
6
7
|
#include "rays/debug.h"
|
|
7
8
|
#include "../renderer.h"
|
|
@@ -28,6 +29,9 @@ namespace Rays
|
|
|
28
29
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
|
29
30
|
rays_error(__FILE__, __LINE__, SDL_GetError());
|
|
30
31
|
|
|
32
|
+
if (TTF_Init() < 0)
|
|
33
|
+
rays_error(__FILE__, __LINE__, "TTF_Init failed: %s", TTF_GetError());
|
|
34
|
+
|
|
31
35
|
Renderer_init();
|
|
32
36
|
|
|
33
37
|
global::initialized = true;
|
|
@@ -41,6 +45,7 @@ namespace Rays
|
|
|
41
45
|
|
|
42
46
|
Renderer_fin();
|
|
43
47
|
|
|
48
|
+
//TTF_Quit();
|
|
44
49
|
SDL_Quit();
|
|
45
50
|
|
|
46
51
|
global::initialized = false;
|
data/src/texture.h
CHANGED
|
@@ -19,6 +19,8 @@ namespace Rays
|
|
|
19
19
|
class Texture
|
|
20
20
|
{
|
|
21
21
|
|
|
22
|
+
typedef Texture This;
|
|
23
|
+
|
|
22
24
|
public:
|
|
23
25
|
|
|
24
26
|
Texture ();
|
|
@@ -53,6 +55,10 @@ namespace Rays
|
|
|
53
55
|
|
|
54
56
|
bool operator ! () const;
|
|
55
57
|
|
|
58
|
+
friend bool operator == (const This& lhs, const This& rhs);
|
|
59
|
+
|
|
60
|
+
friend bool operator != (const This& lhs, const This& rhs);
|
|
61
|
+
|
|
56
62
|
struct Data;
|
|
57
63
|
|
|
58
64
|
Xot::PSharedImpl<Data> self;
|
data/test/test_painter.rb
CHANGED
|
@@ -193,43 +193,54 @@ class TestPainter < Test::Unit::TestCase
|
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
def test_clip_accessor()
|
|
196
|
-
pa
|
|
197
|
-
pa.clip =
|
|
198
|
-
assert_equal
|
|
199
|
-
pa.clip =
|
|
200
|
-
assert_equal
|
|
201
|
-
pa.clip
|
|
202
|
-
assert_equal
|
|
203
|
-
pa.push clip:
|
|
196
|
+
pa = painter
|
|
197
|
+
pa.clip = [1, 2, 3, 4]
|
|
198
|
+
assert_equal [1, 2, 3, 4], pa.clip.to_a
|
|
199
|
+
pa.clip = [5, 6, 7, 8]
|
|
200
|
+
assert_equal [5, 6, 7, 8], pa.clip.to_a
|
|
201
|
+
pa.clip 1, 2, 3, 4
|
|
202
|
+
assert_equal [1, 2, 3, 4], pa.clip.to_a
|
|
203
|
+
pa.push clip: [5, 6, 7, 8] do |_|
|
|
204
204
|
assert_equal [5, 6, 7, 8], pa.clip.to_a
|
|
205
205
|
end
|
|
206
|
-
assert_equal
|
|
206
|
+
assert_equal [1, 2, 3, 4], pa.clip.to_a
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
def test_font_accessor()
|
|
210
|
-
pa
|
|
210
|
+
pa = painter
|
|
211
211
|
f10, f20 = font(nil, 10), font(nil, 20)
|
|
212
|
-
pa.font
|
|
213
|
-
assert_equal
|
|
214
|
-
pa.font
|
|
215
|
-
assert_equal
|
|
216
|
-
pa.font
|
|
217
|
-
assert_equal
|
|
218
|
-
pa.push font:
|
|
212
|
+
pa.font = f10
|
|
213
|
+
assert_equal f10, pa.font
|
|
214
|
+
pa.font = f20
|
|
215
|
+
assert_equal f20, pa.font
|
|
216
|
+
pa.font f10
|
|
217
|
+
assert_equal f10, pa.font
|
|
218
|
+
pa.push font: f20 do |_|
|
|
219
219
|
assert_equal f20, pa.font
|
|
220
220
|
end
|
|
221
|
-
assert_equal
|
|
221
|
+
assert_equal f10, pa.font
|
|
222
222
|
end
|
|
223
223
|
|
|
224
224
|
def test_font_name_size()
|
|
225
225
|
pa = painter
|
|
226
|
-
pa.font
|
|
227
|
-
assert_equal
|
|
228
|
-
assert_equal
|
|
229
|
-
pa.font
|
|
230
|
-
assert_not_equal "Arial",
|
|
231
|
-
pa.font
|
|
232
|
-
|
|
226
|
+
pa.font "Arial", 10
|
|
227
|
+
assert_equal "Arial", pa.font.name
|
|
228
|
+
assert_equal 10, pa.font.size
|
|
229
|
+
pa.font nil
|
|
230
|
+
assert_not_equal "Arial", pa.font.name
|
|
231
|
+
assert_not_equal 10, pa.font.size
|
|
232
|
+
pa.font nil, 20
|
|
233
|
+
assert_not_equal "Arial", pa.font.name
|
|
234
|
+
assert_equal 20, pa.font.size
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def test_debug_accessor()
|
|
238
|
+
pa = painter
|
|
239
|
+
assert_false pa.debug?
|
|
240
|
+
pa.debug = true
|
|
241
|
+
assert_true pa.debug?
|
|
242
|
+
pa.debug = false
|
|
243
|
+
assert_false pa.debug?
|
|
233
244
|
end
|
|
234
245
|
|
|
235
246
|
def test_color_by_name()
|