dxrubynd 1.4.7

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.
@@ -0,0 +1,3391 @@
1
+ #define WINVER 0x0500 /* �o�[�W������` Windows2000�ȏ� */
2
+ #define _WIN32_WINNT WINVER
3
+
4
+ #include "ruby.h"
5
+ #ifndef RUBY_ST_H
6
+ #include "st.h"
7
+ #endif
8
+
9
+ #define DXRUBY_EXTERN 1
10
+ #include "dxruby.h"
11
+ #include "image.h"
12
+ #include "font.h"
13
+
14
+ VALUE cImage; /* �C���[�W�N���X */
15
+
16
+ #ifdef DXRUBY_USE_TYPEDDATA
17
+ extern rb_data_type_t Font_data_type;
18
+ #endif
19
+
20
+ /* �F */
21
+ struct DXRubyColor {
22
+ unsigned char blue;
23
+ unsigned char green;
24
+ unsigned char red;
25
+ unsigned char alpha;
26
+ };
27
+
28
+
29
+ /*********************************************************************
30
+ * Image�N���X
31
+ *
32
+ * �`��p�̉摜��ێ�����N���X�B
33
+ * �t�@�C������n����load����Ɠǂݍ��܂�AWindow::draw�ɓn���ĕ`�悷��B
34
+ *********************************************************************/
35
+
36
+ /*--------------------------------------------------------------------
37
+ �Q�Ƃ���Ȃ��Ȃ����Ƃ���GC����Ă΂��֐�
38
+ ---------------------------------------------------------------------*/
39
+ static void Image_free( struct DXRubyImage *image )
40
+ {
41
+ /* �e�N�X�`���I�u�W�F�N�g�̊J�� */
42
+ image->texture->refcount--;
43
+ if( image->texture->refcount == 0 )
44
+ {
45
+ RELEASE( image->texture->pD3DTexture );
46
+ free( image->texture );
47
+ image->texture = NULL;
48
+ }
49
+ }
50
+
51
+ void Image_release( struct DXRubyImage *image )
52
+ {
53
+ if( image->texture )
54
+ {
55
+ Image_free( image );
56
+ }
57
+ free( image );
58
+ image = NULL;
59
+
60
+ g_iRefAll--;
61
+ if( g_iRefAll == 0 )
62
+ {
63
+ CoUninitialize();
64
+ }
65
+ }
66
+
67
+ #ifdef DXRUBY_USE_TYPEDDATA
68
+ const rb_data_type_t Image_data_type = {
69
+ "Image",
70
+ {
71
+ 0,
72
+ Image_release,
73
+ 0,
74
+ },
75
+ NULL, NULL
76
+ };
77
+ #endif
78
+
79
+ /*--------------------------------------------------------------------
80
+ Image�N���X��dispose�B
81
+ ---------------------------------------------------------------------*/
82
+ VALUE Image_dispose( VALUE self )
83
+ {
84
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, self );
85
+ DXRUBY_CHECK_DISPOSE( image, texture );
86
+ Image_free( image );
87
+ return self;
88
+ }
89
+
90
+
91
+ /*--------------------------------------------------------------------
92
+ Image�N���X��disposed?�B
93
+ ---------------------------------------------------------------------*/
94
+ static VALUE Image_check_disposed( VALUE self )
95
+ {
96
+ if( DXRUBY_GET_STRUCT( Image, self )->texture == NULL )
97
+ {
98
+ return Qtrue;
99
+ }
100
+
101
+ return Qfalse;
102
+ }
103
+
104
+ ///*--------------------------------------------------------------------
105
+ // Image�N���X��locked?
106
+ // ---------------------------------------------------------------------*/
107
+ //static VALUE Image_check_locked( VALUE self )
108
+ //{
109
+ // if( DXRUBY_GET_STRUCT( Image, self )->lockcount == 1 )
110
+ // {
111
+ // return Qtrue;
112
+ // }
113
+ //
114
+ // return Qfalse;
115
+ //}
116
+
117
+ /*--------------------------------------------------------------------
118
+ Image�N���X��delayed_dispose�B
119
+ ---------------------------------------------------------------------*/
120
+ static VALUE Image_delayed_dispose( VALUE self )
121
+ {
122
+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
123
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, self );
124
+ DXRUBY_CHECK_DISPOSE( image, texture );
125
+
126
+ rb_ary_push( g_WindowInfo.image_array, self );
127
+
128
+ return self;
129
+ }
130
+
131
+
132
+ /*--------------------------------------------------------------------
133
+ Texture���[�h
134
+ ---------------------------------------------------------------------*/
135
+ static struct DXRubyTexture *Image_textureload( char *filename, D3DXIMAGE_INFO *psrcinfo)
136
+ {
137
+ HRESULT hr;
138
+ struct DXRubyTexture *texture;
139
+
140
+ /* �e�N�X�`���������擾 */
141
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
142
+
143
+ if( texture == NULL )
144
+ {
145
+ rb_raise( eDXRubyError, "Out of memory - Image_textureload" );
146
+ }
147
+
148
+ /* �t�@�C����ǂݍ���Ńe�N�X�`���I�u�W�F�N�g���쐬���� */
149
+ DXRUBY_RETRY_START;
150
+ hr = D3DXCreateTextureFromFileEx( g_pD3DDevice, filename,psrcinfo->Width, psrcinfo->Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
151
+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
152
+ 0, 0, &texture->pD3DTexture);
153
+ DXRUBY_RETRY_END;
154
+ if( FAILED( hr ) )
155
+ {
156
+ rb_raise( eDXRubyError, "Load error - %s", filename );
157
+ }
158
+
159
+ return texture;
160
+ }
161
+
162
+
163
+ /*--------------------------------------------------------------------
164
+ �C���[�W�I�u�W�F�N�g��dup/clone
165
+ ---------------------------------------------------------------------*/
166
+ VALUE Image_initialize_copy( VALUE self, VALUE obj )
167
+ {
168
+ struct DXRubyImage *srcimage;
169
+ struct DXRubyImage *dstimage;
170
+ struct DXRubyTexture *texture;
171
+ D3DLOCKED_RECT srctrect;
172
+ D3DLOCKED_RECT dsttrect;
173
+ int i, j;
174
+ RECT srcrect;
175
+ RECT dstrect;
176
+ HRESULT hr;
177
+ D3DSURFACE_DESC desc;
178
+ int *psrc;
179
+ int *pdst;
180
+
181
+ DXRUBY_CHECK_TYPE( Image, obj );
182
+
183
+ dstimage = DXRUBY_GET_STRUCT( Image, self );
184
+ // DXRUBY_CHECK_DISPOSE( dstimage, texture );
185
+ srcimage = DXRUBY_GET_STRUCT( Image, obj );
186
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
187
+
188
+ g_iRefAll++;
189
+
190
+ /* �e�N�X�`���������擾 */
191
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
192
+ if( texture == NULL )
193
+ {
194
+ rb_raise( eDXRubyError, "Out of memory - Image_dup" );
195
+ }
196
+
197
+ DXRUBY_RETRY_START;
198
+ /* �e�N�X�`���I�u�W�F�N�g���쐬���� */
199
+ hr = D3DXCreateTexture( g_pD3DDevice, srcimage->width, srcimage->height,
200
+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
201
+ &texture->pD3DTexture);
202
+ DXRUBY_RETRY_END;
203
+ if( FAILED( hr ) )
204
+ {
205
+ rb_raise( eDXRubyError, "Create texture error - Image_dup" );
206
+ }
207
+
208
+ texture->refcount = 1;
209
+
210
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
211
+ texture->width = (float)desc.Width;
212
+ texture->height = (float)desc.Height;
213
+
214
+ dstimage->texture = texture;
215
+ dstimage->x = 0;
216
+ dstimage->y = 0;
217
+ dstimage->width = srcimage->width;
218
+ dstimage->height =srcimage-> height;
219
+ // dstimage->lockcount = 0;
220
+
221
+ /* �C���[�W�R�s�[ */
222
+ dstrect.left = 0;
223
+ dstrect.top = 0;
224
+ dstrect.right = srcimage->width;
225
+ dstrect.bottom = srcimage->height;
226
+ srcrect.left = srcimage->x;
227
+ srcrect.top = srcimage->y;
228
+ srcrect.right = srcimage->x + srcimage->width;
229
+ srcrect.bottom = srcimage->y + srcimage->height;
230
+
231
+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
232
+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
233
+
234
+ for( i = 0; i < srcimage->height; i++)
235
+ {
236
+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
237
+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
238
+ for( j = 0; j < srcimage->width; j++)
239
+ {
240
+ *(pdst++) = *(psrc++);
241
+ }
242
+ }
243
+
244
+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
245
+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
246
+
247
+ return self;
248
+ }
249
+
250
+
251
+ /*--------------------------------------------------------------------
252
+ Image�N���X��allocate�B���������m�ۂ���ׂ�initialize�O�ɌĂ΂��B
253
+ ---------------------------------------------------------------------*/
254
+ VALUE Image_allocate( VALUE klass )
255
+ {
256
+ VALUE obj;
257
+ struct DXRubyImage *image;
258
+
259
+ /* DXRubyImage�̃������擾��Image�I�u�W�F�N�g���� */
260
+ image = malloc(sizeof(struct DXRubyImage));
261
+ if( image == NULL ) rb_raise( eDXRubyError, "malloc error - Image_allocate" );
262
+ #ifdef DXRUBY_USE_TYPEDDATA
263
+ obj = TypedData_Wrap_Struct( klass, &Image_data_type, image );
264
+ #else
265
+ obj = Data_Wrap_Struct(klass, 0, Image_release, image);
266
+ #endif
267
+ /* �Ƃ肠�����e�N�X�`���I�u�W�F�N�g��NULL�ɂ��Ă��� */
268
+ image->texture = NULL;
269
+ // image->lockcount = 0;
270
+
271
+ return obj;
272
+ }
273
+
274
+
275
+ /*--------------------------------------------------------------------
276
+ �C���[�W�̃f�[�^�ݒ�(���������pbox�`��)
277
+ ---------------------------------------------------------------------*/
278
+ static void fill( int x1, int y1, int x2, int y2, int col, struct DXRubyImage *image )
279
+ {
280
+ D3DLOCKED_RECT texrect;
281
+ int x, y;
282
+ RECT rect;
283
+ int *p;
284
+
285
+ rect.left = x1 + image->x;
286
+ rect.top = y1 + image->y;
287
+ rect.right = x2 + image->x + 1;
288
+ rect.bottom = y2 + image->y + 1;
289
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
290
+ for( y = 0; y <= y2 - y1; y++ )
291
+ {
292
+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
293
+ for( x = 0; x <= x2 - x1; x++ )
294
+ {
295
+ *(p++) = col;
296
+ }
297
+ }
298
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
299
+ return;
300
+ }
301
+
302
+
303
+ /*--------------------------------------------------------------------
304
+ �z�񂩂�F�擾
305
+ ---------------------------------------------------------------------*/
306
+ int array2color( VALUE color )
307
+ {
308
+ int col;
309
+
310
+ Check_Type(color, T_ARRAY);
311
+
312
+ if( RARRAY_LEN( color ) == 3 )
313
+ {
314
+ col = D3DCOLOR_ARGB(255, NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)), NUM2INT(rb_ary_entry(color, 2)));
315
+ }
316
+ else
317
+ {
318
+ col = D3DCOLOR_ARGB(NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)),
319
+ NUM2INT(rb_ary_entry(color, 2)), NUM2INT(rb_ary_entry(color, 3)));
320
+ }
321
+ return col;
322
+ }
323
+
324
+
325
+ /*--------------------------------------------------------------------
326
+ Image�N���X��Initialize
327
+ ---------------------------------------------------------------------*/
328
+ VALUE Image_initialize( int argc, VALUE *argv, VALUE obj )
329
+ {
330
+ struct DXRubyImage *image;
331
+ struct DXRubyTexture *texture;
332
+ HRESULT hr;
333
+ D3DSURFACE_DESC desc;
334
+ VALUE vwidth, vheight, vary;
335
+ int col = 0, width, height;
336
+
337
+ g_iRefAll++;
338
+
339
+ rb_scan_args( argc, argv, "21", &vwidth, &vheight, &vary );
340
+
341
+ width = NUM2INT( vwidth );
342
+ height = NUM2INT( vheight );
343
+
344
+ if( width <= 0 || height <= 0 || width > 8192 || height > 8192)
345
+ {
346
+ rb_raise( eDXRubyError, "invalid size(must be between 1 to 8192) - Image_initialize" );
347
+ }
348
+
349
+ if( vary != Qnil )
350
+ {
351
+ Check_Type( vary, T_ARRAY );
352
+ col = array2color( vary );
353
+ }
354
+
355
+ /* �e�N�X�`���������擾 */
356
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
357
+
358
+ if( texture == NULL )
359
+ {
360
+ rb_raise( eDXRubyError, "malloc error - Image_initialize" );
361
+ }
362
+
363
+ DXRUBY_RETRY_START;
364
+ /* �e�N�X�`���I�u�W�F�N�g���쐬���� */
365
+ hr = D3DXCreateTexture( g_pD3DDevice, width, height,
366
+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
367
+ &texture->pD3DTexture);
368
+ DXRUBY_RETRY_END;
369
+ if( FAILED( hr ) )
370
+ {
371
+ rb_raise( eDXRubyError, "D3DXCreateTexture error - Image_initialize" );
372
+ }
373
+
374
+ texture->refcount = 1;
375
+
376
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
377
+ texture->width = (float)desc.Width;
378
+ texture->height = (float)desc.Height;
379
+
380
+ /* Image�I�u�W�F�N�g�ݒ� */
381
+ image = DXRUBY_GET_STRUCT( Image, obj );
382
+ if( image->texture )
383
+ {
384
+ Image_free( image );
385
+ g_iRefAll--;
386
+ }
387
+
388
+ image->texture = texture;
389
+ image->x = 0;
390
+ image->y = 0;
391
+ image->width = width;
392
+ image->height = height;
393
+
394
+ fill( 0, 0, width - 1, height - 1, col, image );
395
+
396
+ return obj;
397
+ }
398
+
399
+
400
+ /*--------------------------------------------------------------------
401
+ Image�N���X��load
402
+ ---------------------------------------------------------------------*/
403
+ static VALUE Image_load( int argc, VALUE *argv, VALUE klass )
404
+ {
405
+ struct DXRubyImage *image;
406
+ struct DXRubyTexture *texture;
407
+ D3DXIMAGE_INFO srcinfo;
408
+ D3DSURFACE_DESC desc;
409
+ HRESULT hr;
410
+ VALUE vfilename, vx, vy, vwidth, vheight, obj, vsjisstr;
411
+ int x, y, width, height;
412
+
413
+ /* �f�o�C�X�I�u�W�F�N�g�̏������`�F�b�N */
414
+ if( g_pD3DDevice == NULL )
415
+ {
416
+ rb_raise( eDXRubyError, "DirectX Graphics not initialized" );
417
+ }
418
+
419
+ rb_scan_args( argc, argv, "14", &vfilename, &vx, &vy, &vwidth, &vheight );
420
+
421
+ Check_Type(vfilename, T_STRING);
422
+
423
+ /* �t�@�C�����擾 */
424
+ if( rb_enc_get_index( vfilename ) != 0 )
425
+ {
426
+ vsjisstr = rb_str_export_to_enc( vfilename, g_enc_sys );
427
+ }
428
+ else
429
+ {
430
+ vsjisstr = vfilename;
431
+ }
432
+
433
+ hr = D3DXGetImageInfoFromFile( RSTRING_PTR( vsjisstr ), &srcinfo );
434
+
435
+ if( FAILED( hr ) )
436
+ {
437
+ rb_raise( eDXRubyError, "Load error - %s", RSTRING_PTR( vsjisstr ) );
438
+ }
439
+
440
+ if( vx == Qnil )
441
+ {
442
+ x = 0;
443
+ y = 0;
444
+ width = srcinfo.Width;
445
+ height = srcinfo.Height;
446
+ }
447
+ else
448
+ {
449
+ x = NUM2INT( vx );
450
+ y = vy == Qnil ? 0 : NUM2INT( vy );
451
+ if( x < 0 || x >= srcinfo.Width || y < 0 || y >= srcinfo.Height )
452
+ {
453
+ rb_raise( eDXRubyError, "Invalid the origin position(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_load", x, y, srcinfo.Width, srcinfo.Height );
454
+ }
455
+ width = vwidth == Qnil ? srcinfo.Width - x : NUM2INT( vwidth );
456
+ height = vheight == Qnil ? srcinfo.Height - y : NUM2INT( vheight );
457
+ if( srcinfo.Width - x < width || x + width > srcinfo.Width || srcinfo.Height - y < height || y + height > srcinfo.Height ||
458
+ width < 0 || height < 0 )
459
+ {
460
+ rb_raise( eDXRubyError, "Invalid size - Image_load" );
461
+ }
462
+ }
463
+
464
+ /* �e�N�X�`�����[�h */
465
+ texture = Image_textureload( RSTRING_PTR( vsjisstr ), &srcinfo );
466
+ texture->refcount = 1;
467
+
468
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
469
+ texture->width = (float)desc.Width;
470
+ texture->height = (float)desc.Height;
471
+
472
+ /* Image�I�u�W�F�N�g�ݒ� */
473
+ obj = Image_allocate( cImage );
474
+ image = DXRUBY_GET_STRUCT( Image, obj );
475
+
476
+ image->texture = texture;
477
+ image->x = x;
478
+ image->y = y;
479
+ image->width = width;
480
+ image->height = height;
481
+ // image->lockcount = 0;
482
+
483
+ g_iRefAll++;
484
+
485
+ return obj;
486
+ }
487
+
488
+
489
+ /*--------------------------------------------------------------------
490
+ Image�N���X��loadFromFileInMemory
491
+ ---------------------------------------------------------------------*/
492
+ static VALUE Image_loadFromFileInMemory( VALUE klass, VALUE vstr )
493
+ {
494
+ struct DXRubyImage *image;
495
+ struct DXRubyTexture *texture;
496
+ D3DXIMAGE_INFO srcinfo;
497
+ D3DSURFACE_DESC desc;
498
+ HRESULT hr;
499
+ VALUE obj;
500
+ int size, x, y, width, height;
501
+
502
+ /* �f�o�C�X�I�u�W�F�N�g�̏������`�F�b�N */
503
+ if( g_pD3DDevice == NULL )
504
+ {
505
+ rb_raise( eDXRubyError, "DirectX Graphics not initialized" );
506
+ }
507
+
508
+ Check_Type(vstr, T_STRING);
509
+
510
+ /* �t�@�C�����擾 */
511
+ size = RSTRING_LEN( vstr );
512
+
513
+ hr = D3DXGetImageInfoFromFileInMemory( RSTRING_PTR( vstr ), size, &srcinfo );
514
+
515
+ if( FAILED( hr ) )
516
+ {
517
+ rb_raise( eDXRubyError, "Load error - Image_loadFromFileInMemory" );
518
+ }
519
+
520
+ /* �e�N�X�`���������擾 */
521
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
522
+
523
+ if( texture == NULL )
524
+ {
525
+ rb_raise( eDXRubyError, "Out of memory - Image_loadFromFileInMemory" );
526
+ }
527
+
528
+ DXRUBY_RETRY_START;
529
+ /* �t�@�C����ǂݍ���Ńe�N�X�`���I�u�W�F�N�g���쐬���� */
530
+ hr = D3DXCreateTextureFromFileInMemoryEx( g_pD3DDevice, RSTRING_PTR( vstr ), size, srcinfo.Width, srcinfo.Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
531
+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
532
+ 0, 0, &texture->pD3DTexture);
533
+ DXRUBY_RETRY_END;
534
+ if( FAILED( hr ) )
535
+ {
536
+ rb_raise( eDXRubyError, "Load error - Image_loadFromFileInMemory" );
537
+ }
538
+
539
+ texture->refcount = 1;
540
+
541
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
542
+ texture->width = (float)desc.Width;
543
+ texture->height = (float)desc.Height;
544
+
545
+ /* Image�I�u�W�F�N�g�ݒ� */
546
+ obj = Image_allocate( cImage );
547
+ image = DXRUBY_GET_STRUCT( Image, obj );
548
+
549
+ image->texture = texture;
550
+ image->x = 0;
551
+ image->y = 0;
552
+ image->width = srcinfo.Width;
553
+ image->height = srcinfo.Height;
554
+ // image->lockcount = 0;
555
+
556
+ g_iRefAll++;
557
+
558
+ return obj;
559
+ }
560
+
561
+
562
+ /*--------------------------------------------------------------------
563
+ Image�I�u�W�F�N�g�̕����쐬
564
+ ---------------------------------------------------------------------*/
565
+ static VALUE Image_loadToArray( int argc, VALUE *argv, VALUE klass )
566
+ {
567
+ // VALUE vfilename, vx, vy, vswitch;
568
+ VALUE vimage, ary[3];
569
+
570
+ if( argc < 3 || argc > 4 ) rb_raise( rb_eArgError, "wrong number of arguments (%d for %d..%d)", argc, 3, 4 );
571
+ // rb_scan_args( argc, argv, "31", &vfilename, &vx, &vy, &vswitch );
572
+
573
+ vimage = Image_load( 1, &argv[0], cImage );
574
+ ary[0] = argv[1];
575
+ ary[1] = argv[2];
576
+ ary[2] = argc < 4 ? Qtrue : argv[3];
577
+ return Image_sliceToArray( 3, ary, vimage );
578
+ }
579
+
580
+
581
+ /*--------------------------------------------------------------------
582
+ �z�񂩂�C���[�W�����
583
+ ---------------------------------------------------------------------*/
584
+ static VALUE Image_createFromArray( VALUE klass, VALUE vwidth, VALUE vheight, VALUE array )
585
+ {
586
+ struct DXRubyImage *image;
587
+ struct DXRubyTexture *texture;
588
+ HRESULT hr;
589
+ int i, j, x, y;
590
+ D3DLOCKED_RECT LockedRect;
591
+ VALUE obj;
592
+ int width, height;
593
+ D3DSURFACE_DESC desc;
594
+
595
+ /* �f�o�C�X�I�u�W�F�N�g�̏������`�F�b�N */
596
+ if( g_pD3DDevice == NULL )
597
+ {
598
+ rb_raise( eDXRubyError, "DirectX Graphics not initialized" );
599
+ }
600
+
601
+ width = NUM2INT( vwidth );
602
+ height = NUM2INT( vheight );
603
+ Check_Type(array, T_ARRAY);
604
+
605
+ if( width <= 0 || height <= 0 ) rb_raise( eDXRubyError, "Invalid size(width=%d,height=%d) - Image_loadToArray", width, height );
606
+
607
+ /* �e�N�X�`���������擾 */
608
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
609
+ if( texture == NULL )
610
+ {
611
+ rb_raise( eDXRubyError, "Out of memory - Image_textureload" );
612
+ }
613
+
614
+ /* �e�N�X�`���T�C�Y����o�� */
615
+ for( x = 1; x < width; x = x * 2 );
616
+ for( y = 1; y < height; y = y * 2 );
617
+
618
+ DXRUBY_RETRY_START;
619
+ /* �e�N�X�`���I�u�W�F�N�g���쐬���� */
620
+ hr = D3DXCreateTexture( g_pD3DDevice, x, y,
621
+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
622
+ &texture->pD3DTexture);
623
+ DXRUBY_RETRY_END;
624
+ if( FAILED( hr ) )
625
+ {
626
+ rb_raise( eDXRubyError, "Create texture error - Image_initialize" );
627
+ }
628
+
629
+ /* �e�N�X�`�����b�N */
630
+ hr = texture->pD3DTexture->lpVtbl->LockRect( texture->pD3DTexture, 0, &LockedRect, NULL, 0 );
631
+ if( FAILED( hr ) )
632
+ {
633
+ rb_raise( eDXRubyError, "Surface lock error - LockRect" );
634
+ }
635
+
636
+ /* �������� */
637
+ for( i = 0; i < height; i++ )
638
+ {
639
+ for( j = 0; j < width * 4; j += 4 )
640
+ {
641
+ int a1 = NUM2INT(rb_ary_entry(array, j + i * width * 4));
642
+ int a2 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 1));
643
+ int a3 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 2));
644
+ int a4 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 3));
645
+ *((int*)((char *)LockedRect.pBits + j + i * LockedRect.Pitch)) = D3DCOLOR_ARGB(a1, a2, a3, a4);
646
+ }
647
+ }
648
+
649
+ /* �e�N�X�`���A�����b�N */
650
+ texture->pD3DTexture->lpVtbl->UnlockRect( texture->pD3DTexture, 0 );
651
+
652
+ texture->refcount = 1;
653
+ texture->pD3DTexture->lpVtbl->GetLevelDesc( texture->pD3DTexture, 0, &desc );
654
+ texture->width = (float)desc.Width;
655
+ texture->height = (float)desc.Height;
656
+
657
+ /* DXRubyImage�̃������擾��Image�I�u�W�F�N�g���� */
658
+ obj = Image_allocate( cImage );
659
+ image = DXRUBY_GET_STRUCT( Image, obj );
660
+
661
+ image->texture = texture;
662
+ image->x = 0;
663
+ image->y = 0;
664
+ image->width = width;
665
+ image->height = height;
666
+ // image->lockcount = 0;
667
+
668
+ g_iRefAll++;
669
+
670
+ return obj;
671
+ }
672
+
673
+
674
+ /*--------------------------------------------------------------------
675
+ Image�I�u�W�F�N�g��slice
676
+ ---------------------------------------------------------------------*/
677
+ static VALUE Image_slice_instance( int argc, VALUE *argv, VALUE vsrcimage )
678
+ {
679
+ struct DXRubyImage *srcimage;
680
+ struct DXRubyImage *image;
681
+ struct DXRubyTexture *texture;
682
+ D3DXIMAGE_INFO srcinfo;
683
+ HRESULT hr;
684
+ VALUE vx, vy, vwidth, vheight, obj;
685
+ int x, y, width, height;
686
+
687
+ rb_scan_args( argc, argv, "04", &vx, &vy, &vwidth, &vheight );
688
+
689
+ srcimage = DXRUBY_GET_STRUCT( Image, vsrcimage );
690
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
691
+
692
+ if( vx == Qnil )
693
+ {
694
+ x = 0;
695
+ y = 0;
696
+ width = srcimage->width;
697
+ height = srcimage->height;
698
+ }
699
+ else
700
+ {
701
+ x = NUM2INT( vx );
702
+ y = vy == Qnil ? 0 : NUM2INT( vy );
703
+ if( x < 0 || x >= srcimage->width || y < 0 || y >= srcimage->height )
704
+ {
705
+ rb_raise( eDXRubyError, "Invalid the origin position(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_slice", x, y, srcimage->width, srcimage->height );
706
+ }
707
+ width = vwidth == Qnil ? srcimage->width - x : NUM2INT( vwidth );
708
+ height = vheight == Qnil ? srcimage->height - y : NUM2INT( vheight );
709
+ if( srcimage->width - x < width || x + width > srcimage->width || srcimage->height - y < height || y + height > srcimage->height ||
710
+ width < 0 || height < 0 )
711
+ {
712
+ rb_raise( eDXRubyError, "Invalid size - Image_slice" );
713
+ }
714
+ }
715
+
716
+ /* �e�N�X�`�����[�h */
717
+ texture = srcimage->texture;
718
+ texture->refcount += 1;
719
+
720
+ /* Image�I�u�W�F�N�g�ݒ� */
721
+ obj = Image_allocate( cImage );
722
+ image = DXRUBY_GET_STRUCT( Image, obj );
723
+
724
+ image->texture = texture;
725
+ image->x = x + srcimage->x;
726
+ image->y = y + srcimage->y;
727
+ image->width = width;
728
+ image->height = height;
729
+ // image->lockcount = 0;
730
+
731
+ g_iRefAll++;
732
+
733
+ /* Image�̃R�s�[ */
734
+ return Image_initialize_copy( Image_allocate( cImage ), obj );
735
+ }
736
+
737
+
738
+ /*--------------------------------------------------------------------
739
+ Image�I�u�W�F�N�g��flush
740
+ ---------------------------------------------------------------------*/
741
+ static VALUE Image_flush( VALUE self, VALUE vcolor )
742
+ {
743
+ struct DXRubyImage *dstimage = DXRUBY_GET_STRUCT( Image, self );
744
+ struct DXRubyImage *image;
745
+ VALUE obj;
746
+ D3DLOCKED_RECT texrect;
747
+ RECT rect;
748
+ int y;
749
+ int color;
750
+
751
+ DXRUBY_CHECK_DISPOSE( dstimage, texture );
752
+ Check_Type(vcolor, T_ARRAY);
753
+
754
+ /* ��Image�̃R�s�[ */
755
+ obj = Image_initialize_copy( Image_allocate( cImage ), self );
756
+
757
+ /* �VImage�̃|�C���^�擾 */
758
+ image = DXRUBY_GET_STRUCT( Image, obj );
759
+
760
+ /* �摜�ҏW */
761
+ rect.left = 0;
762
+ rect.top = 0;
763
+ rect.right = image->width;
764
+ rect.bottom = image->height;
765
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
766
+
767
+ if( RARRAY_LEN( vcolor ) == 3 )
768
+ {
769
+ color = D3DCOLOR_ARGB(0, NUM2INT(rb_ary_entry(vcolor, 0)), NUM2INT(rb_ary_entry(vcolor, 1)), NUM2INT(rb_ary_entry(vcolor, 2)));
770
+ for( y = 0; y < image->height; y++ )
771
+ {
772
+ int *p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
773
+ int x;
774
+
775
+ for( x = 0; x < image->width; x++ )
776
+ {
777
+ if( (*p & 0xff000000) != 0 )
778
+ {
779
+ *p = color | (*p & 0xff000000);
780
+ }
781
+ p++;
782
+ }
783
+ }
784
+ }
785
+ else
786
+ {
787
+ color = D3DCOLOR_ARGB(NUM2INT(rb_ary_entry(vcolor, 0)), NUM2INT(rb_ary_entry(vcolor, 1)),
788
+ NUM2INT(rb_ary_entry(vcolor, 2)), NUM2INT(rb_ary_entry(vcolor, 3)));
789
+ for( y = 0; y < image->height; y++ )
790
+ {
791
+ int *p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
792
+ int x;
793
+
794
+ for( x = 0; x < image->width; x++ )
795
+ {
796
+ if( (*p & 0xff000000) != 0 )
797
+ {
798
+ *p = color;
799
+ }
800
+ p++;
801
+ }
802
+ }
803
+ }
804
+
805
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
806
+
807
+ return obj;
808
+ }
809
+
810
+
811
+ /*--------------------------------------------------------------------
812
+ Imgae�I�u�W�F�N�g��sliceToArray
813
+ ---------------------------------------------------------------------*/
814
+ VALUE Image_sliceToArray( int argc, VALUE *argv, VALUE self )
815
+ {
816
+ struct DXRubyImage *srcimage;
817
+ struct DXRubyTexture *texture;
818
+ HRESULT hr;
819
+ int x, y, i, j;
820
+ VALUE array, obj;
821
+ // VALUE vx, vy, vswitch;
822
+
823
+ if( argc < 2 || argc > 3 ) rb_raise( rb_eArgError, "wrong number of arguments (%d for %d..%d)", argc, 2, 3 );
824
+ // rb_scan_args( argc, argv, "21", &vx, &vy, &vswitch );
825
+
826
+ x = NUM2INT( argv[0] );
827
+ y = NUM2INT( argv[1] );
828
+
829
+ if( x <= 0 || y <= 0 ) rb_raise( eDXRubyError, "Invalid count(x=%d,y=%d) - Image_sliceToArray", x, y );
830
+
831
+ /* ��Image�̃`�F�b�N */
832
+ srcimage = DXRUBY_GET_STRUCT( Image, self );
833
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
834
+
835
+ /* ��Image�̃R�s�[ */
836
+ obj = Image_initialize_copy( Image_allocate( cImage ), self );
837
+
838
+ /* �R�s�[����Image����slice */
839
+ srcimage = DXRUBY_GET_STRUCT( Image, obj );
840
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
841
+
842
+ texture = srcimage->texture;
843
+ texture->refcount += x * y;
844
+
845
+ /* Ruby�z��쐬 */
846
+ array = rb_ary_new();
847
+
848
+ if( argc < 3 || RTEST(argv[2]) )
849
+ {
850
+ for( i = 0; i < y; i++ )
851
+ {
852
+ for( j = 0; j < x; j++ )
853
+ {
854
+ struct DXRubyImage *image;
855
+ /* DXRubyImage�̃������擾��Image�I�u�W�F�N�g���� */
856
+ obj = Image_allocate( cImage );
857
+ image = DXRUBY_GET_STRUCT( Image, obj );
858
+
859
+ image->texture = texture;
860
+ image->x = srcimage->x + j * (srcimage->width / x);
861
+ image->y = srcimage->y + i * (srcimage->height / y);
862
+ image->width = srcimage->width / x;
863
+ image->height = srcimage->height / y;
864
+ // image->lockcount = 0;
865
+ rb_ary_push( array, obj );
866
+ g_iRefAll++;
867
+ }
868
+ }
869
+ }
870
+ else
871
+ {
872
+ for( i = 0; i < y; i++ )
873
+ {
874
+ for( j = 0; j < x; j++ )
875
+ {
876
+ VALUE ary[4] = {INT2FIX(srcimage->x + j * (srcimage->width / x)),
877
+ INT2FIX(srcimage->y + i * (srcimage->height / y)),
878
+ INT2FIX(srcimage->width / x),
879
+ INT2FIX(srcimage->height / y)};
880
+ rb_ary_push( array, Image_slice_instance( 4, ary, obj ) );
881
+ }
882
+ }
883
+ }
884
+ return array;
885
+ }
886
+
887
+
888
+ /*--------------------------------------------------------------------
889
+ �C���[�W�̃f�[�^�擾
890
+ ---------------------------------------------------------------------*/
891
+ static VALUE Image_getPixel( VALUE obj, VALUE vx, VALUE vy )
892
+ {
893
+ struct DXRubyImage *image;
894
+ VALUE ary[4];
895
+ struct DXRubyColor a;
896
+ D3DLOCKED_RECT texrect;
897
+ int x, y;
898
+ RECT rect;
899
+
900
+ x = NUM2INT( vx );
901
+ y = NUM2INT( vy );
902
+
903
+ image = DXRUBY_GET_STRUCT( Image, obj );
904
+ DXRUBY_CHECK_DISPOSE( image, texture );
905
+
906
+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
907
+ {
908
+ ary[0] = ary[1] = ary[2] = ary[3] = INT2FIX( 0 );
909
+ return rb_ary_new4( 4, ary );
910
+ }
911
+
912
+ rect.left = x + image->x;
913
+ rect.top = y + image->y;
914
+ rect.right = x + image->x + 1;
915
+ rect.bottom = y + image->y + 1;
916
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
917
+
918
+ a = *(struct DXRubyColor *)texrect.pBits;
919
+
920
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
921
+
922
+ ary[0] = INT2FIX( a.alpha );
923
+ ary[1] = INT2FIX( a.red );
924
+ ary[2] = INT2FIX( a.green );
925
+ ary[3] = INT2FIX( a.blue );
926
+
927
+ return rb_ary_new4( 4, ary );
928
+ }
929
+
930
+
931
+ /*--------------------------------------------------------------------
932
+ �C���[�W�̃f�[�^�ݒ�
933
+ ---------------------------------------------------------------------*/
934
+ static VALUE Image_setPixel( VALUE obj, VALUE vx, VALUE vy, VALUE color )
935
+ {
936
+ struct DXRubyImage *image;
937
+ int a1, a2, a3, a4;
938
+ D3DLOCKED_RECT texrect;
939
+ int x, y;
940
+ RECT rect;
941
+
942
+ x = NUM2INT( vx );
943
+ y = NUM2INT( vy );
944
+ Check_Type(color, T_ARRAY);
945
+
946
+ image = DXRUBY_GET_STRUCT( Image, obj );
947
+ DXRUBY_CHECK_DISPOSE( image, texture );
948
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
949
+
950
+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
951
+ {
952
+ return obj;
953
+ }
954
+
955
+ rect.left = x + image->x;
956
+ rect.top = y + image->y;
957
+ rect.right = x + image->x + 1;
958
+ rect.bottom = y + image->y + 1;
959
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
960
+
961
+ *((int*)((char *)texrect.pBits)) = array2color( color );
962
+
963
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
964
+
965
+ return color;
966
+ }
967
+
968
+
969
+ /*--------------------------------------------------------------------
970
+ �C���[�W�̐F��r
971
+ ---------------------------------------------------------------------*/
972
+ static VALUE Image_compare( VALUE obj, VALUE vx, VALUE vy, VALUE color )
973
+ {
974
+ struct DXRubyImage *image;
975
+ DWORD a;
976
+ D3DLOCKED_RECT texrect;
977
+ int x, y, col;
978
+ int a1, a2, a3, a4;
979
+ RECT rect;
980
+
981
+ x = NUM2INT( vx );
982
+ y = NUM2INT( vy );
983
+ Check_Type(color, T_ARRAY);
984
+
985
+ image = DXRUBY_GET_STRUCT( Image, obj );
986
+ DXRUBY_CHECK_DISPOSE( image, texture );
987
+
988
+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
989
+ {
990
+ return INT2FIX( 0 );
991
+ }
992
+
993
+ col = array2color( color );
994
+
995
+ rect.left = x + image->x;
996
+ rect.top = y + image->y;
997
+ rect.right = x + image->x + 1;
998
+ rect.bottom = y + image->y + 1;
999
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
1000
+
1001
+ a = *(LPDWORD)texrect.pBits;
1002
+
1003
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1004
+
1005
+ if( RARRAY_LEN( color ) == 3 )
1006
+ {
1007
+
1008
+ if( (a & 0x00ffffff) == ((DWORD)col & 0x00ffffff) )
1009
+ {
1010
+ return Qtrue;
1011
+ }
1012
+ else
1013
+ {
1014
+ return Qfalse;
1015
+ }
1016
+ }
1017
+ else
1018
+ {
1019
+ if( a == (DWORD)col )
1020
+ {
1021
+ return Qtrue;
1022
+ }
1023
+ else
1024
+ {
1025
+ return Qfalse;
1026
+ }
1027
+ }
1028
+ }
1029
+
1030
+
1031
+ /*--------------------------------------------------------------------
1032
+ �C���[�W�̃f�[�^�ݒ�(box�`��h��‚Ԃ��Ȃ�)
1033
+ ---------------------------------------------------------------------*/
1034
+ static VALUE Image_box( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
1035
+ {
1036
+ struct DXRubyImage *image;
1037
+ D3DLOCKED_RECT texrect;
1038
+ int x, y, x1, y1, x2, y2;
1039
+ int col;
1040
+ RECT rect;
1041
+
1042
+ image = DXRUBY_GET_STRUCT( Image, obj );
1043
+ DXRUBY_CHECK_DISPOSE( image, texture );
1044
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1045
+
1046
+ x1 = NUM2INT( vx1 );
1047
+ y1 = NUM2INT( vy1 );
1048
+ x2 = NUM2INT( vx2 );
1049
+ y2 = NUM2INT( vy2 );
1050
+
1051
+ /* ���ォ��E���̎w��ɏC�� */
1052
+ if( x1 > x2 )
1053
+ {
1054
+ x = x2;
1055
+ x2 = x1;
1056
+ x1 = x;
1057
+ }
1058
+ if( y1 > y2 )
1059
+ {
1060
+ y = y2;
1061
+ y2 = y1;
1062
+ y1 = y;
1063
+ }
1064
+
1065
+ /* �͈͊O�̎w��͖��� */
1066
+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
1067
+ {
1068
+ return obj;
1069
+ }
1070
+
1071
+ /* �N���b�v */
1072
+ if( x1 < 0 )
1073
+ {
1074
+ x1 = 0;
1075
+ }
1076
+ if( x2 > image->width - 1 )
1077
+ {
1078
+ x2 = image->width - 1;
1079
+ }
1080
+ if( y1 < 0 )
1081
+ {
1082
+ y1 = 0;
1083
+ }
1084
+ if( y2 > image->height - 1 )
1085
+ {
1086
+ y2 = image->height - 1;
1087
+ }
1088
+
1089
+ Check_Type(color, T_ARRAY);
1090
+ col = array2color( color );
1091
+
1092
+ rect.left = x1 + image->x;
1093
+ rect.top = y1 + image->y;
1094
+ rect.right = x2 + image->x + 1;
1095
+ rect.bottom = y2 + image->y + 1;
1096
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1097
+ for( y = 0; y <= y2 - y1; y++ )
1098
+ {
1099
+ *((int*)((char *)texrect.pBits + y * texrect.Pitch)) = col;
1100
+ *((int*)((char *)texrect.pBits + (x2 - x1)* 4 + y * texrect.Pitch)) = col;
1101
+ }
1102
+ for( x = 0; x <= x2 - x1; x++ )
1103
+ {
1104
+ *((int*)((char *)texrect.pBits + x * 4)) = col;
1105
+ *((int*)((char *)texrect.pBits + x * 4 + (y2 - y1) * texrect.Pitch)) = col;
1106
+ }
1107
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1108
+
1109
+ return obj;
1110
+ }
1111
+
1112
+
1113
+ /*--------------------------------------------------------------------
1114
+ �C���[�W�̃f�[�^�ݒ�(box�`��h��‚Ԃ�)
1115
+ ---------------------------------------------------------------------*/
1116
+ static VALUE Image_boxFill( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
1117
+ {
1118
+ struct DXRubyImage *image;
1119
+ int x, y, x1, y1, x2, y2;
1120
+ int col;
1121
+
1122
+ image = DXRUBY_GET_STRUCT( Image, obj );
1123
+ DXRUBY_CHECK_DISPOSE( image, texture );
1124
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1125
+
1126
+ x1 = NUM2INT( vx1 );
1127
+ y1 = NUM2INT( vy1 );
1128
+ x2 = NUM2INT( vx2 );
1129
+ y2 = NUM2INT( vy2 );
1130
+
1131
+ /* ���ォ��E���̎w��ɏC�� */
1132
+ if( x1 > x2 )
1133
+ {
1134
+ x = x2;
1135
+ x2 = x1;
1136
+ x1 = x;
1137
+ }
1138
+ if( y1 > y2 )
1139
+ {
1140
+ y = y2;
1141
+ y2 = y1;
1142
+ y1 = y;
1143
+ }
1144
+
1145
+ /* �͈͊O�̎w��͖��� */
1146
+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
1147
+ {
1148
+ return obj;
1149
+ }
1150
+
1151
+ /* �N���b�v */
1152
+ if( x1 < 0 )
1153
+ {
1154
+ x1 = 0;
1155
+ }
1156
+ if( x2 > image->width - 1 )
1157
+ {
1158
+ x2 = image->width - 1;
1159
+ }
1160
+ if( y1 < 0 )
1161
+ {
1162
+ y1 = 0;
1163
+ }
1164
+ if( y2 > image->height - 1 )
1165
+ {
1166
+ y2 = image->height - 1;
1167
+ }
1168
+
1169
+ Check_Type(color, T_ARRAY);
1170
+ col = array2color( color );
1171
+
1172
+ fill( x1, y1, x2, y2, col, image );
1173
+
1174
+ return obj;
1175
+ }
1176
+
1177
+
1178
+ /*--------------------------------------------------------------------
1179
+ �C���[�W�̃f�[�^�ݒ�(�S�������F�œh��‚Ԃ�)
1180
+ ---------------------------------------------------------------------*/
1181
+ static VALUE Image_clear( VALUE obj )
1182
+ {
1183
+ struct DXRubyImage *image;
1184
+
1185
+ image = DXRUBY_GET_STRUCT( Image, obj );
1186
+ DXRUBY_CHECK_DISPOSE( image, texture );
1187
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1188
+
1189
+ fill( 0, 0, image->width-1, image->height-1, 0, image );
1190
+
1191
+ return obj;
1192
+ }
1193
+
1194
+
1195
+ /*--------------------------------------------------------------------
1196
+ �C���[�W�̃f�[�^�ݒ�(�S���h��‚Ԃ�)
1197
+ ---------------------------------------------------------------------*/
1198
+ static VALUE Image_fill( VALUE obj, VALUE color )
1199
+ {
1200
+ struct DXRubyImage *image;
1201
+ int col;
1202
+
1203
+ image = DXRUBY_GET_STRUCT( Image, obj );
1204
+ DXRUBY_CHECK_DISPOSE( image, texture );
1205
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1206
+
1207
+ Check_Type(color, T_ARRAY);
1208
+ col = array2color( color );
1209
+
1210
+ fill( 0, 0, image->width-1, image->height-1, col, image );
1211
+
1212
+ return obj;
1213
+ }
1214
+
1215
+
1216
+ /*--------------------------------------------------------------------
1217
+ �C���[�W�̃J���[�L�[�ݒ�B���͎̂w��F�𓧖��ɁB
1218
+ ---------------------------------------------------------------------*/
1219
+ static VALUE Image_setColorKey( VALUE obj, VALUE color )
1220
+ {
1221
+ struct DXRubyImage *image;
1222
+ int col;
1223
+ D3DLOCKED_RECT texrect;
1224
+ int x, y;
1225
+ RECT rect;
1226
+ int *p;
1227
+
1228
+ image = DXRUBY_GET_STRUCT( Image, obj );
1229
+ DXRUBY_CHECK_DISPOSE( image, texture );
1230
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1231
+
1232
+ Check_Type(color, T_ARRAY);
1233
+ col = array2color( color ) & 0x00ffffff;
1234
+
1235
+ rect.left = image->x;
1236
+ rect.top = image->y;
1237
+ rect.right = image->x + image->width;
1238
+ rect.bottom = image->y + image->height;
1239
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1240
+ for( y = 0; y < image->height; y++ )
1241
+ {
1242
+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
1243
+ for( x = 0; x < image->width; x++ )
1244
+ {
1245
+ if( (*p & 0x00ffffff) == col )
1246
+ {
1247
+ *p = col;
1248
+ }
1249
+ p++;
1250
+ }
1251
+ }
1252
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1253
+
1254
+ return obj;
1255
+ }
1256
+
1257
+
1258
+ /*--------------------------------------------------------------------
1259
+ �C���[�W�̃f�[�^�ݒ�(circle�p��line�`��)
1260
+ ---------------------------------------------------------------------*/
1261
+ static void Image_circle_line( int x1, int x2, int y, RECT *rect, int col, D3DLOCKED_RECT *texrect )
1262
+ {
1263
+ int x;
1264
+ int *p;
1265
+
1266
+ if( y < 0 || y >= rect->bottom - rect->top )
1267
+ {
1268
+ return;
1269
+ }
1270
+
1271
+ /* �N���b�v */
1272
+ if( x1 < 0 )
1273
+ {
1274
+ x1 = 0;
1275
+ }
1276
+ if( x2 > rect->right - rect->left - 1 )
1277
+ {
1278
+ x2 = rect->right - rect->left - 1;
1279
+ }
1280
+ if( x1 > x2 )
1281
+ {
1282
+ return;
1283
+ }
1284
+
1285
+ p = (int*)((char *)texrect->pBits + y * texrect->Pitch + x1 * 4);
1286
+ for( x = 0; x <= x2 - x1; x++ )
1287
+ {
1288
+ *(p++) = col;
1289
+ }
1290
+ }
1291
+
1292
+
1293
+ /*--------------------------------------------------------------------
1294
+ �C���[�W�̃f�[�^�ݒ�(circle�`��h��‚Ԃ�)
1295
+ ---------------------------------------------------------------------*/
1296
+ static VALUE Image_circleFill( VALUE obj, VALUE vx0, VALUE vy0, VALUE vr, VALUE color )
1297
+ {
1298
+ struct DXRubyImage *image;
1299
+ int x0, y0, F, x, y;
1300
+ float r;
1301
+ int col;
1302
+ D3DLOCKED_RECT texrect;
1303
+ RECT rect;
1304
+ HRESULT hr;
1305
+ int tempx, tempy;
1306
+
1307
+ image = DXRUBY_GET_STRUCT( Image, obj );
1308
+ DXRUBY_CHECK_DISPOSE( image, texture );
1309
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1310
+
1311
+ x0 = NUM2INT( vx0 );
1312
+ y0 = NUM2INT( vy0 );
1313
+ r = NUM2FLOAT( vr );
1314
+
1315
+ Check_Type(color, T_ARRAY);
1316
+ col = array2color( color );
1317
+
1318
+ rect.left = (LONG)(x0 < r ? image->x : x0 + image->x - r);
1319
+ rect.top = (LONG)(y0 < r ? image->y : y0 + image->y - r);
1320
+ rect.right = (LONG)(x0 + r >= image->width ? image->x + image->width : x0 + image->x + r + 1);
1321
+ rect.bottom = (LONG)(y0 + r >= image->height ? image->y + image->height : y0 + image->y + r + 1);
1322
+ if( rect.left >= rect.right || rect.top >= rect.bottom )
1323
+ {
1324
+ return obj;
1325
+ }
1326
+
1327
+ hr = image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1328
+
1329
+ {//http://dencha.ojaru.jp/programs_07/pg_graphic_09a2.html
1330
+ int tempx = -rect.left + (int)image->x;
1331
+ int tempy = -rect.top + (int)image->y;
1332
+ int xm = x0, ym = y0;
1333
+ int diameter = (int)(r*2);
1334
+
1335
+ LONG cx = 0, cy=diameter/2+1;
1336
+ double d;
1337
+ int dx, dy;
1338
+ d = -diameter*diameter + 4*cy*cy -4*cy +2;
1339
+ dx = 4;
1340
+ dy = -8*cy+8;
1341
+ if( (diameter & 1) == 0 )
1342
+ {
1343
+ xm--;
1344
+ ym--;
1345
+ }
1346
+
1347
+ for( cx = 0; cx <= cy; cx++ )
1348
+ {
1349
+ if( d > 0 )
1350
+ {
1351
+ d += dy;
1352
+ dy += 8;
1353
+ cy--;
1354
+ }
1355
+ Image_circle_line( tempx - cx + x0, tempx + cx + xm, tempy - cy + y0, &rect, col, &texrect );
1356
+ Image_circle_line( tempx - cy + x0, tempx + cy + xm, tempy - cx + y0, &rect, col, &texrect );
1357
+ Image_circle_line( tempx - cy + x0, tempx + cy + xm, tempy + cx + ym, &rect, col, &texrect );
1358
+ Image_circle_line( tempx - cx + x0, tempx + cx + xm, tempy + cy + ym, &rect, col, &texrect );
1359
+
1360
+ d += dx;
1361
+ dx+=8;
1362
+ }
1363
+ }
1364
+
1365
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1366
+
1367
+ return obj;
1368
+ }
1369
+
1370
+
1371
+ /*--------------------------------------------------------------------
1372
+ �C���[�W�̃f�[�^�ݒ�(���������ppixel�`��)
1373
+ ---------------------------------------------------------------------*/
1374
+ static void Image_circle_pixel( int x, int y, RECT *rect, int col, D3DLOCKED_RECT *texrect )
1375
+ {
1376
+ if( x < 0 || x >= rect->right - rect->left || y < 0 || y >= rect->bottom - rect->top )
1377
+ {
1378
+ return;
1379
+ }
1380
+
1381
+ *((int*)((char *)texrect->pBits + x * 4 + y * texrect->Pitch)) = col;
1382
+
1383
+ return;
1384
+ }
1385
+
1386
+
1387
+ /*--------------------------------------------------------------------
1388
+ �C���[�W�̃f�[�^�ݒ�(circle�`��h��‚Ԃ��Ȃ�)
1389
+ ---------------------------------------------------------------------*/
1390
+ static VALUE Image_circle( VALUE obj, VALUE vx0, VALUE vy0, VALUE vr, VALUE color )
1391
+ {
1392
+ struct DXRubyImage *image;
1393
+ D3DLOCKED_RECT texrect;
1394
+ int x0, y0, F, x, y;
1395
+ float r;
1396
+ int col;
1397
+ RECT rect;
1398
+
1399
+ image = DXRUBY_GET_STRUCT( Image, obj );
1400
+ DXRUBY_CHECK_DISPOSE( image, texture );
1401
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1402
+
1403
+ x0 = NUM2INT( vx0 );
1404
+ y0 = NUM2INT( vy0 );
1405
+ r = NUM2FLOAT( vr );
1406
+
1407
+ Check_Type(color, T_ARRAY);
1408
+ col = array2color( color );
1409
+
1410
+ rect.left = (LONG)(x0 < r ? image->x : x0 + image->x - r);
1411
+ rect.top = (LONG)(y0 < r ? image->y : y0 + image->y - r);
1412
+ rect.right = (LONG)(x0 + r >= image->width ? image->x + image->width : x0 + image->x + r + 1);
1413
+ rect.bottom = (LONG)(y0 + r >= image->height ? image->y + image->height : y0 + image->y + r + 1);
1414
+ if( rect.left >= rect.right || rect.top >= rect.bottom )
1415
+ {
1416
+ return obj;
1417
+ }
1418
+
1419
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1420
+
1421
+ {//http://dencha.ojaru.jp/programs_07/pg_graphic_09a2.html
1422
+ int tempx = -rect.left + (int)image->x;
1423
+ int tempy = -rect.top + (int)image->y;
1424
+ int xm = x0, ym = y0;
1425
+ int diameter = (int)(r*2);
1426
+
1427
+ LONG cx = 0, cy=diameter/2+1;
1428
+ double d;
1429
+ int dx, dy;
1430
+ d = -diameter*diameter + 4*cy*cy -4*cy +2;
1431
+ dx = 4;
1432
+ dy = -8*cy+8;
1433
+ if( (diameter & 1) == 0 )
1434
+ {
1435
+ xm--;
1436
+ ym--;
1437
+ }
1438
+
1439
+ for( cx = 0; cx <= cy; cx++ )
1440
+ {
1441
+ if( d > 0 )
1442
+ {
1443
+ d += dy;
1444
+ dy += 8;
1445
+ cy--;
1446
+ }
1447
+ Image_circle_pixel( tempx - cy + x0, tempy - cx + y0, &rect, col, &texrect );
1448
+ Image_circle_pixel( tempx - cx + x0, tempy - cy + y0, &rect, col, &texrect );
1449
+
1450
+ Image_circle_pixel( tempx + cx + xm, tempy - cy + y0, &rect, col, &texrect );
1451
+ Image_circle_pixel( tempx + cy + xm, tempy - cx + y0, &rect, col, &texrect );
1452
+
1453
+ Image_circle_pixel( tempx + cy + xm, tempy + cx + ym, &rect, col, &texrect );
1454
+ Image_circle_pixel( tempx + cx + xm, tempy + cy + ym, &rect, col, &texrect );
1455
+
1456
+ Image_circle_pixel( tempx - cx + x0, tempy + cy + ym, &rect, col, &texrect );
1457
+ Image_circle_pixel( tempx - cy + x0, tempy + cx + ym, &rect, col, &texrect );
1458
+
1459
+ d += dx;
1460
+ dx+=8;
1461
+ }
1462
+ }
1463
+
1464
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1465
+
1466
+ return obj;
1467
+ }
1468
+
1469
+
1470
+ /*--------------------------------------------------------------------
1471
+ �C���[�W�̃f�[�^�ݒ�(line�`��)
1472
+ ---------------------------------------------------------------------*/
1473
+ static VALUE Image_line( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
1474
+ {
1475
+ struct DXRubyImage *image;
1476
+ D3DLOCKED_RECT texrect;
1477
+ int x1, y1, x2, y2, xp, yp;
1478
+ int col;
1479
+ int c, d, dx, dy, i;
1480
+ RECT rect;
1481
+
1482
+ image = DXRUBY_GET_STRUCT( Image, obj );
1483
+ DXRUBY_CHECK_DISPOSE( image, texture );
1484
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1485
+
1486
+ x1 = NUM2INT( vx1 );
1487
+ y1 = NUM2INT( vy1 );
1488
+ x2 = NUM2INT( vx2 );
1489
+ y2 = NUM2INT( vy2 );
1490
+
1491
+ Check_Type(color, T_ARRAY);
1492
+ col = array2color( color );
1493
+
1494
+ rect.left = (x1 < x2 ? x1 : x2) < image->x ? image->x : (x1 < x2 ? x1 : x2);
1495
+ rect.top = (y1 < y2 ? y1 : y2) < image->y ? image->y : (y1 < y2 ? y1 : y2);
1496
+ rect.right = (x1 > x2 ? x1 : x2) >= image->width ? image->x + image->width : image->x + (x1 > x2 ? x1 : x2) + 1;
1497
+ rect.bottom = (y1 > y2 ? y1 : y2) >= image->height ? image->y + image->height : image->y + (y1 > y2 ? y1 : y2) + 1;
1498
+ if( rect.left >= rect.right || rect.top >= rect.bottom )
1499
+ {
1500
+ return obj;
1501
+ }
1502
+
1503
+ x1 = x1 - rect.left + image->x;
1504
+ x2 = x2 - rect.left + image->x;
1505
+ y1 = y1 - rect.top + image->y;
1506
+ y2 = y2 - rect.top + image->y;
1507
+
1508
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1509
+
1510
+ dx = x2 > x1 ? x2 - x1 : x1 - x2;
1511
+ dy = y2 > y1 ? y2 - y1 : y1 - y2;
1512
+
1513
+ /* �u���[���n���A���S���Y���ɂ������`�� */
1514
+ if( dx < dy )
1515
+ {
1516
+ xp = x1 < x2 ? 1 : -1;
1517
+ d = y1 < y2 ? 1 : -1;
1518
+ c = dy;
1519
+ for( i = 0; i <= dy; i++ )
1520
+ {
1521
+ if( x1 >= 0 && x1 < (int)rect.right - rect.left && y1 >= 0 && y1 < (int)rect.bottom - rect.top )
1522
+ {
1523
+ *((int*)((char *)texrect.pBits + x1 * 4 + y1 * texrect.Pitch)) = col;
1524
+ }
1525
+ y1 = y1 + d;
1526
+ c = c + dx*2;
1527
+ if( c >= dy*2 )
1528
+ {
1529
+ c = c - dy*2;
1530
+ x1 = x1 + xp;
1531
+ }
1532
+ }
1533
+ }
1534
+ else
1535
+ {
1536
+ yp = y1 < y2 ? 1 : -1;
1537
+ d = x1 < x2 ? 1 : -1;
1538
+ c = dx;
1539
+ for( i = 0; i <= dx; i++ )
1540
+ {
1541
+ if( x1 >= 0 && x1 < (int)rect.right - rect.left && y1 >= 0 && y1 < (int)rect.bottom - rect.top )
1542
+ {
1543
+ *((int*)((char *)texrect.pBits + x1 * 4 + y1 * texrect.Pitch)) = col;
1544
+ }
1545
+ x1 = x1 + d;
1546
+ c = c + dy*2;
1547
+ if( c >= dx*2 )
1548
+ {
1549
+ c = c - dx*2;
1550
+ y1 = y1 + yp;
1551
+ }
1552
+ }
1553
+ }
1554
+
1555
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1556
+
1557
+ return obj;
1558
+ }
1559
+
1560
+
1561
+ /*--------------------------------------------------------------------
1562
+ �C���[�W�O�p�`�`��
1563
+ ---------------------------------------------------------------------*/
1564
+ static VALUE Image_triangle( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE vx3, VALUE vy3, VALUE color )
1565
+ {
1566
+ Image_line( obj, vx1, vy1, vx2, vy2, color );
1567
+ Image_line( obj, vx2, vy2, vx3, vy3, color );
1568
+ Image_line( obj, vx3, vy3, vx1, vy1, color );
1569
+
1570
+ return obj;
1571
+ }
1572
+
1573
+
1574
+ static void Image_triangle_line( int x1, int y1, int x2, int y2, int *buf_x_min, int *buf_x_max, RECT *rect )
1575
+ {
1576
+ int dx, dy, c, d, xp, yp, i;
1577
+
1578
+ dx = x2 > x1 ? x2 - x1 : x1 - x2;
1579
+ dy = y2 > y1 ? y2 - y1 : y1 - y2;
1580
+
1581
+ /* �u���[���n���A���S���Y���ɂ������`�� */
1582
+ if( dx < dy )
1583
+ {
1584
+ xp = x1 < x2 ? 1 : -1;
1585
+ d = y1 < y2 ? 1 : -1;
1586
+ c = dy;
1587
+ for( i = 0; i <= dy; i++ )
1588
+ {
1589
+ if( y1 >= 0 && y1 < (int)rect->bottom - rect->top )
1590
+ {
1591
+ if( x1 < buf_x_min[y1] )
1592
+ {
1593
+ buf_x_min[y1] = x1;
1594
+ }
1595
+ if( x1 > buf_x_max[y1] )
1596
+ {
1597
+ buf_x_max[y1] = x1;
1598
+ }
1599
+ }
1600
+ y1 = y1 + d;
1601
+ c = c + dx*2;
1602
+ if( c >= dy*2 )
1603
+ {
1604
+ c = c - dy*2;
1605
+ x1 = x1 + xp;
1606
+ }
1607
+ }
1608
+ }
1609
+ else
1610
+ {
1611
+ yp = y1 < y2 ? 1 : -1;
1612
+ d = x1 < x2 ? 1 : -1;
1613
+ c = dx;
1614
+ for( i = 0; i <= dx; i++ )
1615
+ {
1616
+ if( y1 >= 0 && y1 < (int)rect->bottom - rect->top )
1617
+ {
1618
+ if( x1 < buf_x_min[y1] )
1619
+ {
1620
+ buf_x_min[y1] = x1;
1621
+ }
1622
+ if( x1 > buf_x_max[y1] )
1623
+ {
1624
+ buf_x_max[y1] = x1;
1625
+ }
1626
+ }
1627
+ x1 = x1 + d;
1628
+ c = c + dy*2;
1629
+ if( c >= dx*2 )
1630
+ {
1631
+ c = c - dx*2;
1632
+ y1 = y1 + yp;
1633
+ }
1634
+ }
1635
+ }
1636
+ }
1637
+
1638
+ /*--------------------------------------------------------------------
1639
+ �C���[�W�O�p�`�`��(�h��‚Ԃ�)
1640
+ ---------------------------------------------------------------------*/
1641
+ static VALUE Image_triangle_fill( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE vx3, VALUE vy3, VALUE color )
1642
+ {
1643
+ struct DXRubyImage *image;
1644
+ D3DLOCKED_RECT texrect;
1645
+ int x[3], y[3]; /* ���_ */
1646
+ int col;
1647
+ RECT rect;
1648
+ int i;
1649
+ int xv1, yv1, xv2, yv2; /* ���E�{�����[�� */
1650
+
1651
+ image = DXRUBY_GET_STRUCT( Image, obj );
1652
+ DXRUBY_CHECK_DISPOSE( image, texture );
1653
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
1654
+
1655
+ x[0] = NUM2INT( vx1 );
1656
+ y[0] = NUM2INT( vy1 );
1657
+ x[1] = NUM2INT( vx2 );
1658
+ y[1] = NUM2INT( vy2 );
1659
+ x[2] = NUM2INT( vx3 );
1660
+ y[2] = NUM2INT( vy3 );
1661
+
1662
+ Check_Type(color, T_ARRAY);
1663
+ col = array2color( color );
1664
+
1665
+ /* �e�N�X�`�����b�N�p���E�{�����[���쐬 */
1666
+ xv1 = xv2 = x[2];
1667
+ yv1 = yv2 = y[2];
1668
+ for( i = 0; i < 2; i++ )
1669
+ {
1670
+ if( xv1 > x[i] )
1671
+ {
1672
+ xv1 = x[i];
1673
+ }
1674
+ if( xv2 < x[i] )
1675
+ {
1676
+ xv2 = x[i];
1677
+ }
1678
+ if( yv1 > y[i] )
1679
+ {
1680
+ yv1 = y[i];
1681
+ }
1682
+ if( yv2 < y[i] )
1683
+ {
1684
+ yv2 = y[i];
1685
+ }
1686
+ }
1687
+
1688
+ rect.left = xv1 < image->x ? image->x : xv1;
1689
+ rect.top = yv1 < image->y ? image->y : yv1;
1690
+ rect.right = xv2 >= image->width ? image->x + image->width : xv2 + 1;
1691
+ rect.bottom = yv2 >= image->height ? image->y + image->height : image->y + yv2 + 1;
1692
+ if( rect.left >= rect.right || rect.top >= rect.bottom )
1693
+ {
1694
+ return obj;
1695
+ }
1696
+
1697
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1698
+
1699
+ {
1700
+ int *buf_x_min, *buf_x_max;
1701
+ buf_x_min = alloca( sizeof(int) * (rect.bottom - rect.top) );
1702
+ buf_x_max = alloca( sizeof(int) * (rect.bottom - rect.top) );
1703
+
1704
+ for( i = 0; i < rect.bottom - rect.top; i++ )
1705
+ {
1706
+ buf_x_min[i] = image->width;
1707
+ buf_x_max[i] = -1;
1708
+ }
1709
+
1710
+ Image_triangle_line( x[0] - rect.left + image->x, y[0] - rect.top + image->y, x[1] - rect.left + image->x, y[1] - rect.top + image->y, buf_x_min, buf_x_max, &rect );
1711
+ Image_triangle_line( x[1] - rect.left + image->x, y[1] - rect.top + image->y, x[2] - rect.left + image->x, y[2] - rect.top + image->y, buf_x_min, buf_x_max, &rect );
1712
+ Image_triangle_line( x[2] - rect.left + image->x, y[2] - rect.top + image->y, x[0] - rect.left + image->x, y[0] - rect.top + image->y, buf_x_min, buf_x_max, &rect );
1713
+
1714
+ for( i = 0; i < rect.bottom - rect.top; i++ )
1715
+ {
1716
+ // printf("y = %d, left = %d, right = %d\n", i, buf_x_min[i], buf_x_max[i]);
1717
+ Image_circle_line( buf_x_min[i], buf_x_max[i], i, &rect, col, &texrect );
1718
+ }
1719
+ }
1720
+
1721
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1722
+
1723
+ return obj;
1724
+ }
1725
+
1726
+
1727
+ /*--------------------------------------------------------------------
1728
+ �C���[�W�I�u�W�F�N�g�ԃf�[�^�]��
1729
+ ---------------------------------------------------------------------*/
1730
+ static VALUE Image_copyRect( int argc, VALUE *argv, VALUE obj )
1731
+ {
1732
+ struct DXRubyImage *srcimage;
1733
+ struct DXRubyImage *dstimage;
1734
+ D3DLOCKED_RECT srctrect;
1735
+ D3DLOCKED_RECT dsttrect;
1736
+ VALUE vx, vy, data, vx1, vy1, vwidth, vheight;
1737
+ int x, y, x1, y1, width, height;
1738
+ int i, j;
1739
+ RECT srcrect;
1740
+ RECT dstrect;
1741
+ int *psrc;
1742
+ int *pdst;
1743
+
1744
+ rb_scan_args( argc, argv, "34", &vx, &vy, &data, &vx1, &vy1, &vwidth, &vheight );
1745
+
1746
+ dstimage = DXRUBY_GET_STRUCT( Image, obj );
1747
+ DXRUBY_CHECK_DISPOSE( dstimage, texture );
1748
+ // DXRUBY_CHECK_IMAGE_LOCK( dstimage );
1749
+ DXRUBY_CHECK_TYPE( Image, data );
1750
+ srcimage = DXRUBY_GET_STRUCT( Image, data );
1751
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
1752
+
1753
+ if( dstimage == srcimage ) rb_raise( eDXRubyError, "The same Image object is specified as the drawing source and the destination - Image_copyRect" );
1754
+
1755
+ x = NUM2INT( vx );
1756
+ y = NUM2INT( vy );
1757
+ x1 = vx1 == Qnil ? 0 : NUM2INT( vx1 );
1758
+ y1 = vy1 == Qnil ? 0 : NUM2INT( vy1 );
1759
+ width = vwidth == Qnil ? srcimage->width - x1 : NUM2INT( vwidth );
1760
+ height = vheight == Qnil ? srcimage->height - y1 : NUM2INT( vheight );
1761
+
1762
+ /* �摜�̃N���b�s���O */
1763
+ if( x < 0 )
1764
+ {
1765
+ x1 -= x;
1766
+ width -= x;
1767
+ x = 0;
1768
+ }
1769
+ if( y < 0 )
1770
+ {
1771
+ y1 -= y;
1772
+ height -= y;
1773
+ y = 0;
1774
+ }
1775
+ if( x1 < 0 )
1776
+ {
1777
+ x -=x1;
1778
+ width -= x1;
1779
+ x1 = 0;
1780
+ }
1781
+ if( y1 < 0 )
1782
+ {
1783
+ y -=y1;
1784
+ height -= y1;
1785
+ y1 = 0;
1786
+ }
1787
+ if( x + width > dstimage->width )
1788
+ {
1789
+ width -= x + width - dstimage->width;
1790
+ }
1791
+ if( y + height > dstimage->height )
1792
+ {
1793
+ height -= y + height - dstimage->height;
1794
+ }
1795
+ if( x1 + width > srcimage->width )
1796
+ {
1797
+ width -= x1 + width - srcimage->width;
1798
+ }
1799
+ if( y1 + height > srcimage->height )
1800
+ {
1801
+ height -= y1 + height - srcimage->height;
1802
+ }
1803
+
1804
+ /* �͈͊O */
1805
+ if( x >= dstimage->width || y >= dstimage->height || x1 >= srcimage->width || y1 >= srcimage->height ||
1806
+ width < 0 || height < 0 )
1807
+ {
1808
+ return obj;
1809
+ }
1810
+
1811
+ dstrect.left = x + dstimage->x;
1812
+ dstrect.top = y + dstimage->y;
1813
+ dstrect.right = x + dstimage->x + width;
1814
+ dstrect.bottom = y + dstimage->y + height;
1815
+ srcrect.left = x1 + srcimage->x;
1816
+ srcrect.top = y1 + srcimage->y;
1817
+ srcrect.right = x1 + srcimage->x + width;
1818
+ srcrect.bottom = y1 + srcimage->y + height;
1819
+
1820
+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
1821
+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
1822
+
1823
+ for( i = 0; i < height; i++)
1824
+ {
1825
+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
1826
+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
1827
+ for( j = 0; j < width; j++)
1828
+ {
1829
+ *(pdst++) = *(psrc++);
1830
+ }
1831
+ }
1832
+
1833
+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
1834
+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
1835
+
1836
+ return obj;
1837
+ }
1838
+
1839
+
1840
+ /*--------------------------------------------------------------------
1841
+ �C���[�W�I�u�W�F�N�g�ԃ��‚��f�[�^�]��
1842
+ ---------------------------------------------------------------------*/
1843
+ static VALUE Image_draw( int argc, VALUE *argv, VALUE obj )
1844
+ {
1845
+ struct DXRubyImage *srcimage;
1846
+ struct DXRubyImage *dstimage;
1847
+ D3DLOCKED_RECT srctrect;
1848
+ D3DLOCKED_RECT dsttrect;
1849
+ VALUE vx, vy, data, vx1, vy1, vwidth, vheight;
1850
+ int x, y, x1, y1, width, height;
1851
+ int i, j;
1852
+ RECT srcrect;
1853
+ RECT dstrect;
1854
+ int *psrc;
1855
+ int *pdst;
1856
+
1857
+ rb_scan_args( argc, argv, "34", &vx, &vy, &data, &vx1, &vy1, &vwidth, &vheight );
1858
+
1859
+ dstimage = DXRUBY_GET_STRUCT( Image, obj );
1860
+ DXRUBY_CHECK_DISPOSE( dstimage, texture );
1861
+ // DXRUBY_CHECK_IMAGE_LOCK( dstimage );
1862
+ DXRUBY_CHECK_TYPE( Image, data );
1863
+ srcimage = DXRUBY_GET_STRUCT( Image, data );
1864
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
1865
+
1866
+ if( dstimage == srcimage ) rb_raise( eDXRubyError, "The same Image object is specified as the drawing source and the destination - Image_draw" );
1867
+
1868
+ x = NUM2INT( vx );
1869
+ y = NUM2INT( vy );
1870
+ x1 = vx1 == Qnil ? 0 : NUM2INT( vx1 );
1871
+ y1 = vy1 == Qnil ? 0 : NUM2INT( vy1 );
1872
+ width = vwidth == Qnil ? srcimage->width - x1 : NUM2INT( vwidth );
1873
+ height = vheight == Qnil ? srcimage->height - y1 : NUM2INT( vheight );
1874
+
1875
+ /* �摜�̃N���b�s���O */
1876
+ if( x < 0 )
1877
+ {
1878
+ x1 -= x;
1879
+ width -= x;
1880
+ x = 0;
1881
+ }
1882
+ if( y < 0 )
1883
+ {
1884
+ y1 -= y;
1885
+ height -= y;
1886
+ y = 0;
1887
+ }
1888
+ if( x1 < 0 )
1889
+ {
1890
+ x -=x1;
1891
+ width -= x1;
1892
+ x1 = 0;
1893
+ }
1894
+ if( y1 < 0 )
1895
+ {
1896
+ y -=y1;
1897
+ height -= y1;
1898
+ y1 = 0;
1899
+ }
1900
+ if( x + width > dstimage->width )
1901
+ {
1902
+ width -= x + width - dstimage->width;
1903
+ }
1904
+ if( y + height > dstimage->height )
1905
+ {
1906
+ height -= y + height - dstimage->height;
1907
+ }
1908
+ if( x1 + width > srcimage->width )
1909
+ {
1910
+ width -= x1 + width - srcimage->width;
1911
+ }
1912
+ if( y1 + height > srcimage->height )
1913
+ {
1914
+ height -= y1 + height - srcimage->height;
1915
+ }
1916
+
1917
+ /* �͈͊O */
1918
+ if( x >= dstimage->width || y >= dstimage->height || x1 >= srcimage->width || y1 >= srcimage->height ||
1919
+ width < 0 || height < 0 )
1920
+ {
1921
+ return obj;
1922
+ }
1923
+
1924
+ dstrect.left = x + dstimage->x;
1925
+ dstrect.top = y + dstimage->y;
1926
+ dstrect.right = x + dstimage->x + width;
1927
+ dstrect.bottom = y + dstimage->y + height;
1928
+ srcrect.left = x1 + srcimage->x;
1929
+ srcrect.top = y1 + srcimage->y;
1930
+ srcrect.right = x1 + srcimage->x + width;
1931
+ srcrect.bottom = y1 + srcimage->y + height;
1932
+
1933
+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
1934
+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
1935
+
1936
+ for( i = 0; i < height; i++)
1937
+ {
1938
+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
1939
+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
1940
+ for( j = 0; j < width; j++)
1941
+ {
1942
+ struct DXRubyColor s = *((struct DXRubyColor*)(psrc));
1943
+
1944
+ if( s.alpha == 255 )
1945
+ {
1946
+ *((struct DXRubyColor*)(pdst)) = s;
1947
+ }
1948
+ else if( s.alpha != 0 )
1949
+ {
1950
+ struct DXRubyColor d = *((struct DXRubyColor*)(pdst));
1951
+ int alpha = (255 - s.alpha) * d.alpha + s.alpha * 255;
1952
+
1953
+ s.red = (((int)s.alpha * (int)s.red * 255) + (int)d.alpha * (int)d.red * (255 - s.alpha) ) / alpha;
1954
+ s.green = (((int)s.alpha * (int)s.green * 255) + (int)d.alpha * (int)d.green * (255 - s.alpha) ) / alpha;
1955
+ s.blue = (((int)s.alpha * (int)s.blue * 255) + (int)d.alpha * (int)d.blue * (255 - s.alpha) ) / alpha;
1956
+ s.alpha = alpha / 255;
1957
+
1958
+ *((struct DXRubyColor*)(pdst)) = s;
1959
+ }
1960
+ psrc++;
1961
+ pdst++;
1962
+ }
1963
+ }
1964
+
1965
+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
1966
+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
1967
+
1968
+ return obj;
1969
+ }
1970
+
1971
+
1972
+ static void get_color( VALUE vcolor, int *cr, int *cg, int *cb )
1973
+ {
1974
+ Check_Type(vcolor, T_ARRAY);
1975
+ if( RARRAY_LEN(vcolor) == 4 )
1976
+ {
1977
+ *cr = NUM2INT(rb_ary_entry(vcolor, 1));
1978
+ *cg = NUM2INT(rb_ary_entry(vcolor, 2));
1979
+ *cb = NUM2INT(rb_ary_entry(vcolor, 3));
1980
+ }
1981
+ else
1982
+ {
1983
+ *cr = NUM2INT(rb_ary_entry(vcolor, 0));
1984
+ *cg = NUM2INT(rb_ary_entry(vcolor, 1));
1985
+ *cb = NUM2INT(rb_ary_entry(vcolor, 2));
1986
+ }
1987
+ }
1988
+ static void drawfont_sub( int blackboxX, int blackboxY, int baseX, int baseY, int pitch, char *buf, D3DLOCKED_RECT *dsttrect, int cr, int cg, int cb, int width, int height )
1989
+ {
1990
+ int v, u, xx, yy;
1991
+
1992
+ for( v = baseY < 0 ? -baseY : 0; v < blackboxY; v++ )
1993
+ {
1994
+ int yy = baseY + v;
1995
+ int p1, p2;
1996
+
1997
+ if( yy >= height )
1998
+ {
1999
+ break;
2000
+ }
2001
+
2002
+ p1 = v * pitch;
2003
+ p2 = yy * dsttrect->Pitch;
2004
+ for( u = baseX < 0 ? -baseX : 0; u < blackboxX; u++ )
2005
+ {
2006
+ int xx, src;
2007
+
2008
+ xx = baseX + u;
2009
+ if( xx >= width )
2010
+ {
2011
+ break;
2012
+ }
2013
+
2014
+ src = (int)buf[ u + p1 ];
2015
+
2016
+ if( src == 64 )
2017
+ {
2018
+ *((LPDWORD)((char*)dsttrect->pBits + xx * 4 + p2)) = D3DCOLOR_ARGB(0xff, cr, cg, cb);
2019
+ }
2020
+ else if( src != 0 )
2021
+ {
2022
+ struct DXRubyColor d = *((struct DXRubyColor*)((char*)dsttrect->pBits + xx * 4 + p2));
2023
+ struct DXRubyColor data;
2024
+ int temp;
2025
+ src = src * 255 / 64;
2026
+
2027
+ temp = (255 - src) * d.alpha + src * 255;
2028
+ data.alpha = temp / 255;
2029
+ data.red = (src * cr * 255 + (int)d.alpha * d.red * (255 - src)) / temp;
2030
+ data.green = (src * cg * 255 + (int)d.alpha * d.green * (255 - src)) / temp;
2031
+ data.blue = (src * cb * 255 + (int)d.alpha * d.blue * (255 - src)) / temp;
2032
+
2033
+ *((struct DXRubyColor*)((char*)dsttrect->pBits + xx * 4 + yy * dsttrect->Pitch)) = data;
2034
+ }
2035
+ }
2036
+ }
2037
+ }
2038
+
2039
+ /*--------------------------------------------------------------------
2040
+ �C���[�W�Ƀt�H���g�`��
2041
+ ---------------------------------------------------------------------*/
2042
+ static VALUE Image_drawFont( int argc, VALUE *argv, VALUE obj )
2043
+ {
2044
+ struct DXRubyFont *font;
2045
+ struct DXRubyImage *image;
2046
+ VALUE vx, vy, vcolor, vstr, vfont;
2047
+ int cr=255, cg=255, cb=255, x, y;
2048
+ LPDIRECT3DSURFACE9 pD3DSurface;
2049
+ HDC hDC;
2050
+ RECT rc;
2051
+ HRESULT hr;
2052
+ D3DLOCKED_RECT srctrect;
2053
+ D3DLOCKED_RECT dsttrect;
2054
+ int i, j;
2055
+ int h;
2056
+ RECT srcrect;
2057
+ RECT dstrect;
2058
+ TEXTMETRIC tm;
2059
+ GLYPHMETRICS gm;
2060
+
2061
+ LPWSTR widestr;
2062
+ VALUE vwidestr;
2063
+ MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}};
2064
+
2065
+ /* �����擾 */
2066
+ rb_scan_args( argc, argv, "41", &vx, &vy, &vstr, &vfont, &vcolor);
2067
+
2068
+ Check_Type(vstr, T_STRING);
2069
+
2070
+ /* �����̃t�H���g�I�u�W�F�N�g���璆�g�����o�� */
2071
+ image = DXRUBY_GET_STRUCT( Image, obj );
2072
+ DXRUBY_CHECK_DISPOSE( image, texture );
2073
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
2074
+ DXRUBY_CHECK_TYPE( Font, vfont );
2075
+ font = DXRUBY_GET_STRUCT( Font, vfont );
2076
+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
2077
+
2078
+ x = NUM2INT( vx );
2079
+ y = NUM2INT( vy );
2080
+ if( vcolor != Qnil )
2081
+ {
2082
+ get_color( vcolor, &cr, &cg, &cb );
2083
+ }
2084
+
2085
+ if( x >= image->width || y >= image->height )
2086
+ {
2087
+ return obj;
2088
+ }
2089
+
2090
+ /* �`�敶����UTF16LE�� */
2091
+ if( rb_enc_get_index( vstr ) != 0 )
2092
+ {
2093
+ vwidestr = rb_str_export_to_enc( vstr, g_enc_utf16 );
2094
+ }
2095
+ else
2096
+ {
2097
+ vwidestr = rb_str_conv_enc( vstr, g_enc_sys, g_enc_utf16 );
2098
+ }
2099
+ widestr = (LPWSTR)RSTRING_PTR( vwidestr );
2100
+
2101
+ hDC = GetDC( g_hWnd );
2102
+ SelectObject( hDC, font->hFont );
2103
+ GetTextMetrics( hDC, &tm );
2104
+
2105
+ dstrect.left = image->x;
2106
+ dstrect.top = image->y;
2107
+ dstrect.right = image->x + image->width;
2108
+ dstrect.bottom = image->y + image->height;
2109
+
2110
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
2111
+ for( i = 0; i < RSTRING_LEN( vwidestr ) / 2; i++ )
2112
+ {
2113
+ char *buf = Font_getGlyph( vfont, *(widestr + i), hDC, &gm, Qnil );
2114
+ if( buf )
2115
+ {
2116
+ drawfont_sub( gm.gmBlackBoxX, gm.gmBlackBoxY, x + gm.gmptGlyphOrigin.x, y + tm.tmAscent - gm.gmptGlyphOrigin.y, (gm.gmBlackBoxX + 3) & 0xfffc, buf, &dsttrect, cr, cg, cb, image->width, image->height );
2117
+ }
2118
+ x += gm.gmCellIncX;
2119
+ if( x >= image->width )
2120
+ {
2121
+ break;
2122
+ }
2123
+ }
2124
+
2125
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
2126
+
2127
+ ReleaseDC( g_hWnd, hDC );
2128
+ return obj;
2129
+ }
2130
+
2131
+
2132
+ /* fast_int_hypot from http://demo.and.or.jp/makedemo/effect/math/hypot/fast_hypot.c */
2133
+ int fast_int_hypot(int lx, int ly)
2134
+ {
2135
+ int len1, len2,t,length;
2136
+
2137
+ /* lx = abs(lx); */
2138
+ /* ly = abs(ly); */
2139
+ if(lx<0) lx = -lx;
2140
+ if(ly<0) ly = -ly;
2141
+ /*
2142
+ CWD
2143
+ XOR EAX,EDX
2144
+ SUB EAX,EDX
2145
+ */
2146
+
2147
+ if (lx >= ly)
2148
+ {
2149
+ len1 = lx ; len2 = ly;
2150
+ }
2151
+ else
2152
+ {
2153
+ len1 = ly ; len2 = lx;
2154
+ }
2155
+
2156
+ t = len2 + (len2 >> 1) ;
2157
+ length = len1 - (len1 >> 5) - (len1 >> 7) + (t >> 2) + (t >> 6) ;
2158
+ return length;
2159
+ }
2160
+ /*--------------------------------------------------------------------
2161
+ �C���[�W�Ƀt�H���g�`�捂�@�\��
2162
+ ---------------------------------------------------------------------*/
2163
+ VALUE Image_drawFontEx( int argc, VALUE *argv, VALUE obj )
2164
+ {
2165
+ struct DXRubyFont *font;
2166
+ struct DXRubyImage *image;
2167
+ VALUE vx, vy, vcolor, vstr, vfont, voption, vaa_flag;
2168
+ VALUE vedge;
2169
+ VALUE vshadow;
2170
+ int edge_width, edge_level, shadow_x, shadow_y, shadow_edge;
2171
+ int cr=255, cg=255, cb=255, x, y;
2172
+ int br=0, bg=0, bb=0;
2173
+ int sr=0, sg=0, sb=0;
2174
+ LPDIRECT3DSURFACE9 pD3DSurface;
2175
+ HDC hDC;
2176
+ RECT rc;
2177
+ HRESULT hr;
2178
+ D3DLOCKED_RECT srctrect;
2179
+ D3DLOCKED_RECT dsttrect;
2180
+ int i, j;
2181
+ RECT srcrect;
2182
+ RECT dstrect;
2183
+ TEXTMETRIC tm;
2184
+ GLYPHMETRICS gm;
2185
+
2186
+ LPWSTR widestr;
2187
+ VALUE vwidestr;
2188
+ MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}};
2189
+
2190
+ /* �����擾 */
2191
+ if( argc < 4 || argc > 5 ) rb_raise( rb_eArgError, "wrong number of arguments (%d for %d..%d)", argc, 4, 5 );
2192
+
2193
+ vx = argv[0];
2194
+ vy = argv[1];
2195
+ vstr = argv[2];
2196
+ vfont = argv[3];
2197
+
2198
+ x = NUM2INT( vx );
2199
+ y = NUM2INT( vy );
2200
+
2201
+ Check_Type(vstr, T_STRING);
2202
+
2203
+ /* �����̃t�H���g�I�u�W�F�N�g���璆�g�����o�� */
2204
+ image = DXRUBY_GET_STRUCT( Image, obj );
2205
+ DXRUBY_CHECK_DISPOSE( image, texture );
2206
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
2207
+ DXRUBY_CHECK_TYPE( Font, vfont );
2208
+ font = DXRUBY_GET_STRUCT( Font, vfont );
2209
+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
2210
+
2211
+ if( argc < 5 || argv[4] == Qnil )
2212
+ {
2213
+ voption = rb_hash_new();
2214
+ }
2215
+ else
2216
+ {
2217
+ Check_Type( argv[4], T_HASH );
2218
+ voption = argv[4];
2219
+ }
2220
+
2221
+ /* �����̐F */
2222
+ vcolor = hash_lookup( voption, symbol_color );
2223
+ if( vcolor != Qnil )
2224
+ {
2225
+ get_color( vcolor, &cr, &cg, &cb );
2226
+ }
2227
+
2228
+ /* �G�b�W�I�v�V���� */
2229
+ vedge = hash_lookup( voption, symbol_edge );
2230
+ if( vedge == Qnil || vedge == Qfalse )
2231
+ {
2232
+ edge_width = 0;
2233
+ edge_level = 0;
2234
+ }
2235
+ else
2236
+ {
2237
+ VALUE vedge_color, vedge_width, vedge_level;
2238
+ vedge_color = hash_lookup( voption, symbol_edge_color );
2239
+ if( vedge_color != Qnil )
2240
+ {
2241
+ get_color( vedge_color, &br, &bg, &bb );
2242
+ }
2243
+
2244
+ vedge_width = hash_lookup( voption, symbol_edge_width );
2245
+ edge_width = vedge_width == Qnil ? 2 : NUM2INT( vedge_width ); /* �G�b�W�̕� */
2246
+
2247
+ vedge_level = hash_lookup( voption, symbol_edge_level );
2248
+ edge_level = vedge_level == Qnil ? 4 : NUM2INT( vedge_level ); /* �G�b�W�̋��� */
2249
+ }
2250
+
2251
+ /* �e�I�v�V���� */
2252
+ vshadow = hash_lookup( voption, symbol_shadow );
2253
+ if( vshadow == Qnil || vshadow == Qfalse )
2254
+ {
2255
+ shadow_x = 0;
2256
+ shadow_y = 0;
2257
+ }
2258
+ else
2259
+ {
2260
+ VALUE vshadow_color, vshadow_x, vshadow_y, vshadow_edge;
2261
+ vshadow_color = hash_lookup( voption, symbol_shadow_color );
2262
+ if( vshadow_color != Qnil )
2263
+ {
2264
+ get_color( vshadow_color, &sr, &sg, &sb );
2265
+ }
2266
+
2267
+ vshadow_x = hash_lookup( voption, symbol_shadow_x );
2268
+ shadow_x = vshadow_x == Qnil ? NUM2INT( Font_getSize( vfont ) ) / 24 + 1 : NUM2INT(vshadow_x);
2269
+
2270
+ vshadow_y = hash_lookup( voption, symbol_shadow_y );
2271
+ shadow_y = vshadow_y == Qnil ? NUM2INT( Font_getSize( vfont ) ) / 24 + 1 : NUM2INT(vshadow_y);
2272
+
2273
+ vshadow_edge = hash_lookup( voption, symbol_shadow_edge );
2274
+ if( vshadow_edge == Qnil || vshadow_edge == Qfalse )
2275
+ {
2276
+ shadow_edge = 0;
2277
+ }
2278
+ else
2279
+ {
2280
+ shadow_edge = 1;
2281
+ }
2282
+ }
2283
+
2284
+ /* aa�t���O */
2285
+ vaa_flag = hash_lookup( voption, symbol_aa );
2286
+
2287
+ if( x >= image->width || y >= image->height )
2288
+ {
2289
+ return obj;
2290
+ }
2291
+
2292
+ /* �`�敶����UTF16LE�� */
2293
+ if( rb_enc_get_index( vstr ) != 0 )
2294
+ {
2295
+ vwidestr = rb_str_export_to_enc( vstr, g_enc_utf16 );
2296
+ }
2297
+ else
2298
+ {
2299
+ vwidestr = rb_str_conv_enc( vstr, g_enc_sys, g_enc_utf16 );
2300
+ }
2301
+ widestr = (LPWSTR)RSTRING_PTR( vwidestr );
2302
+
2303
+ hDC = GetDC( g_hWnd );
2304
+ SelectObject( hDC, font->hFont );
2305
+ GetTextMetrics( hDC, &tm );
2306
+
2307
+ dstrect.left = image->x;
2308
+ dstrect.top = image->y;
2309
+ dstrect.right = image->x + image->width;
2310
+ dstrect.bottom = image->y + image->height;
2311
+
2312
+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
2313
+
2314
+ for( i = 0; i < RSTRING_LEN( vwidestr ) / 2; i++ )
2315
+ {
2316
+ char *buf = Font_getGlyph( vfont, *(widestr + i), hDC, &gm, vaa_flag );
2317
+ if( buf )
2318
+ {
2319
+ int v, u;
2320
+
2321
+ if( edge_width > 0 && edge_level > 0 )
2322
+ { /* �G�b�W�����B�g���g��2�̃\�[�X���Q�l�ɂ��Ă���B */
2323
+ int edge_pitch = ((gm.gmBlackBoxX + edge_width * 2 - 1) >> 2) + 1 << 2;
2324
+ unsigned char *blurbuf = alloca( edge_pitch * (gm.gmBlackBoxY + edge_width * 2) ); /* �o�b�t�@ */
2325
+ int lvsum = 0;
2326
+ memset( blurbuf, 0, edge_pitch * (gm.gmBlackBoxY + edge_width * 2) ); /* �o�b�t�@�̃N���A */
2327
+
2328
+ for( v = -edge_width; v <= edge_width; v++ )
2329
+ {
2330
+ for( u = -edge_width; u <= edge_width; u++ )
2331
+ {
2332
+ int len = fast_int_hypot(u, v);
2333
+ if(len <= edge_width)
2334
+ lvsum += (edge_width - len + 1);
2335
+ }
2336
+ }
2337
+
2338
+ if( lvsum )
2339
+ {
2340
+ lvsum = (1<<18) / lvsum;
2341
+ }
2342
+ else
2343
+ {
2344
+ lvsum = (1<<18);
2345
+ }
2346
+
2347
+ for( v = -edge_width; v <= edge_width; v++ )
2348
+ {
2349
+ for( u = -edge_width; u <= edge_width; u++ )
2350
+ {
2351
+ int len = fast_int_hypot(u, v);
2352
+ if( len <= edge_width )
2353
+ {
2354
+ int sx, sy;
2355
+ for( sy = 0; sy < gm.gmBlackBoxY; sy++ )
2356
+ {
2357
+ for( sx = 0; sx < gm.gmBlackBoxX; sx++ )
2358
+ {
2359
+ int temp;
2360
+ temp = blurbuf[(v + sy + edge_width) * edge_pitch + u + sx + edge_width] + ((buf[ sx + sy * ((gm.gmBlackBoxX + 3) & 0xfffc) ] * lvsum * (edge_width - len + 1) * edge_level) >> 18);
2361
+ if( temp > 64 ) temp = 64;
2362
+ blurbuf[(v + sy + edge_width) * edge_pitch + u + sx + edge_width] = temp;
2363
+ }
2364
+ }
2365
+ }
2366
+ }
2367
+ }
2368
+
2369
+ if( shadow_x != 0 || shadow_y != 0 )
2370
+ {
2371
+ /* �G�b�W������ꍇ�̉e�̕`�� */
2372
+ if( shadow_edge == 1 )
2373
+ {
2374
+ drawfont_sub( gm.gmBlackBoxX + edge_width * 2, gm.gmBlackBoxY + edge_width * 2, x + gm.gmptGlyphOrigin.x - edge_width + shadow_x, y + tm.tmAscent - gm.gmptGlyphOrigin.y - edge_width + shadow_y, edge_pitch, blurbuf, &dsttrect, sr, sg, sb, image->width, image->height );
2375
+ }
2376
+ /* �G�b�W�����邯�ǃG�b�W�����e�̕`�� */
2377
+ else
2378
+ {
2379
+ drawfont_sub( gm.gmBlackBoxX, gm.gmBlackBoxY, x + gm.gmptGlyphOrigin.x + shadow_x, y + tm.tmAscent - gm.gmptGlyphOrigin.y + shadow_y, (gm.gmBlackBoxX + 3) & 0xfffc, buf, &dsttrect, sr, sg, sb, image->width, image->height );
2380
+ }
2381
+ }
2382
+
2383
+ /* �G�b�W�̕`�� */
2384
+ drawfont_sub( gm.gmBlackBoxX + edge_width * 2, gm.gmBlackBoxY + edge_width * 2, x + gm.gmptGlyphOrigin.x - edge_width, y + tm.tmAscent - gm.gmptGlyphOrigin.y - edge_width, edge_pitch, blurbuf, &dsttrect, br, bg, bb, image->width, image->height );
2385
+
2386
+ }
2387
+ else if( shadow_x != 0 || shadow_y != 0 ) /* �G�b�W���Ȃ��ꍇ�̉e�̕`�� */
2388
+ {
2389
+ drawfont_sub( gm.gmBlackBoxX, gm.gmBlackBoxY, x + gm.gmptGlyphOrigin.x + shadow_x, y + tm.tmAscent - gm.gmptGlyphOrigin.y + shadow_y, (gm.gmBlackBoxX + 3) & 0xfffc, buf, &dsttrect, sr, sg, sb, image->width, image->height );
2390
+ }
2391
+
2392
+ /* �����̕`�� */
2393
+ drawfont_sub( gm.gmBlackBoxX, gm.gmBlackBoxY, x + gm.gmptGlyphOrigin.x, y + tm.tmAscent - gm.gmptGlyphOrigin.y, (gm.gmBlackBoxX + 3) & 0xfffc, buf, &dsttrect, cr, cg, cb, image->width, image->height );
2394
+
2395
+ }
2396
+ x += gm.gmCellIncX;
2397
+ if( x >= image->width )
2398
+ {
2399
+ break;
2400
+ }
2401
+ }
2402
+
2403
+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
2404
+
2405
+ ReleaseDC( g_hWnd, hDC );
2406
+ return obj;
2407
+ }
2408
+
2409
+
2410
+ /*--------------------------------------------------------------------
2411
+ �摜�ɃG�t�F�N�g��������
2412
+ ---------------------------------------------------------------------*/
2413
+ VALUE Image_effect( int argc, VALUE *argv, VALUE self )
2414
+ {
2415
+ struct DXRubyImage *srcimage;
2416
+ struct DXRubyImage *dstimage;
2417
+ struct DXRubyTexture *texture;
2418
+ VALUE vx, vy, vcolor, vstr, vfont, voption;
2419
+ VALUE vedge;
2420
+ VALUE vshadow;
2421
+ int edge_width, edge_level, shadow_x, shadow_y, shadow_edge;
2422
+ int cr=255, cg=255, cb=255, x, y;
2423
+ int br=0, bg=0, bb=0;
2424
+ int sr=0, sg=0, sb=0;
2425
+ LPDIRECT3DSURFACE9 pD3DSurface;
2426
+ RECT rc;
2427
+ HRESULT hr;
2428
+ D3DLOCKED_RECT srctrect;
2429
+ D3DLOCKED_RECT dsttrect;
2430
+ int i, j;
2431
+ RECT srcrect;
2432
+ RECT dstrect;
2433
+ char *buf;
2434
+ VALUE obj;
2435
+ D3DSURFACE_DESC desc;
2436
+
2437
+ if( argc < 0 || argc > 1 ) rb_raise( rb_eArgError, "wrong number of arguments (%d for %d..%d)", argc, 0, 1 );
2438
+
2439
+ srcimage = DXRUBY_GET_STRUCT( Image, self );
2440
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
2441
+ // DXRUBY_CHECK_IMAGE_LOCK( srcimage );
2442
+
2443
+ if( argc < 1 || argv[0] == Qnil )
2444
+ {
2445
+ voption = rb_hash_new();
2446
+ }
2447
+ else
2448
+ {
2449
+ voption = argv[0];
2450
+ }
2451
+
2452
+ /* �����̐F */
2453
+ vcolor = hash_lookup( voption, symbol_color );
2454
+ if( vcolor != Qnil )
2455
+ {
2456
+ get_color( vcolor, &cr, &cg, &cb );
2457
+ }
2458
+
2459
+ /* �G�b�W�I�v�V���� */
2460
+ vedge = hash_lookup( voption, symbol_edge );
2461
+ if( vedge == Qnil || vedge == Qfalse )
2462
+ {
2463
+ edge_width = 0;
2464
+ edge_level = 0;
2465
+ }
2466
+ else
2467
+ {
2468
+ VALUE vedge_color, vedge_width, vedge_level;
2469
+ vedge_color = hash_lookup( voption, symbol_edge_color );
2470
+ if( vedge_color != Qnil )
2471
+ {
2472
+ get_color( vedge_color, &br, &bg, &bb );
2473
+ }
2474
+
2475
+ vedge_width = hash_lookup( voption, symbol_edge_width );
2476
+ edge_width = vedge_width == Qnil ? 2 : NUM2INT( vedge_width ); /* �G�b�W�̕� */
2477
+
2478
+ vedge_level = hash_lookup( voption, symbol_edge_level );
2479
+ edge_level = vedge_level == Qnil ? 4 : NUM2INT( vedge_level ); /* �G�b�W�̋��� */
2480
+ }
2481
+
2482
+ /* �e�I�v�V���� */
2483
+ vshadow = hash_lookup( voption, symbol_shadow );
2484
+ if( vshadow == Qnil || vshadow == Qfalse )
2485
+ {
2486
+ shadow_x = 0;
2487
+ shadow_y = 0;
2488
+ }
2489
+ else
2490
+ {
2491
+ VALUE vshadow_color, vshadow_x, vshadow_y, vshadow_edge;
2492
+ vshadow_color = hash_lookup( voption, symbol_shadow_color );
2493
+ if( vshadow_color != Qnil )
2494
+ {
2495
+ get_color( vshadow_color, &sr, &sg, &sb );
2496
+ }
2497
+
2498
+ vshadow_x = hash_lookup( voption, symbol_shadow_x );
2499
+ shadow_x = vshadow_x == Qnil ? (int)srcimage->height / 24 + 1 : NUM2INT(vshadow_x);
2500
+
2501
+ vshadow_y = hash_lookup( voption, symbol_shadow_y );
2502
+ shadow_y = vshadow_y == Qnil ? (int)srcimage->height / 24 + 1 : NUM2INT(vshadow_y);
2503
+
2504
+ vshadow_edge = hash_lookup( voption, symbol_shadow_edge );
2505
+ if( vshadow_edge == Qnil || vshadow_edge == Qfalse )
2506
+ {
2507
+ shadow_edge = 0;
2508
+ }
2509
+ else
2510
+ {
2511
+ shadow_edge = 1;
2512
+ }
2513
+ }
2514
+
2515
+ srcrect.left = srcimage->x;
2516
+ srcrect.top = srcimage->y;
2517
+ srcrect.right = srcimage->x + srcimage->width;
2518
+ srcrect.bottom = srcimage->y + srcimage->height;
2519
+
2520
+ buf = alloca( srcimage->width * srcimage->height );
2521
+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
2522
+ for( y = 0; y < srcimage->height; y++ )
2523
+ {
2524
+ for( x = 0; x < srcimage->width; x++)
2525
+ {
2526
+ buf[y * (int)srcimage->width + x] = (char)(((int)*((unsigned char *)srctrect.pBits + x * 4 + y * srctrect.Pitch + 2)) *
2527
+ ((int)*((unsigned char *)srctrect.pBits + x * 4 + y * srctrect.Pitch + 3)) * 64 / 255 / 255);
2528
+ }
2529
+ }
2530
+
2531
+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
2532
+
2533
+ /* �VImage���� */
2534
+ obj = Image_allocate( cImage );
2535
+
2536
+ /* �VImage�̃|�C���^�擾 */
2537
+ dstimage = DXRUBY_GET_STRUCT( Image, obj );
2538
+
2539
+ /* �e�N�X�`���������擾 */
2540
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2541
+
2542
+ if( texture == NULL )
2543
+ {
2544
+ rb_raise( eDXRubyError, "Out of memory - Image_initialize" );
2545
+ }
2546
+
2547
+ DXRUBY_RETRY_START;
2548
+ /* �e�N�X�`���I�u�W�F�N�g���쐬���� */
2549
+ hr = D3DXCreateTexture( g_pD3DDevice, srcimage->width + edge_width * 2 + shadow_x, srcimage->height + edge_width * 2 + shadow_y,
2550
+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2551
+ &texture->pD3DTexture);
2552
+ DXRUBY_RETRY_END;
2553
+ if( FAILED( hr ) )
2554
+ {
2555
+ rb_raise( eDXRubyError, "Create texture error - Image_initialize" );
2556
+ }
2557
+
2558
+ texture->refcount = 1;
2559
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2560
+ texture->width = (float)desc.Width;
2561
+ texture->height = (float)desc.Height;
2562
+
2563
+ g_iRefAll++;
2564
+
2565
+ dstimage->texture = texture;
2566
+ dstimage->x = 0;
2567
+ dstimage->y = 0;
2568
+ dstimage->width = srcimage->width + edge_width * 2 + shadow_x;
2569
+ dstimage->height = srcimage->height + edge_width * 2 + shadow_y;
2570
+ // dstimage->lockcount = 0;
2571
+
2572
+ fill( 0, 0, dstimage->width - 1, dstimage->height - 1, 0, dstimage );
2573
+
2574
+ dstrect.left = 0;
2575
+ dstrect.top = 0;
2576
+ dstrect.right = dstimage->width;
2577
+ dstrect.bottom = dstimage->height;
2578
+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
2579
+
2580
+ x = y = edge_width;
2581
+
2582
+ {
2583
+ int v, u;
2584
+
2585
+ if( edge_width > 0 && edge_level > 0 )
2586
+ { /* �G�b�W�����B�g���g��2�̃\�[�X���Q�l�ɂ��Ă���B */
2587
+ int edge_pitch = (((int)srcimage->width + edge_width * 2 - 1) >> 2) + 1 << 2;
2588
+ unsigned char *blurbuf = alloca( edge_pitch * (srcimage->height + edge_width * 2) ); /* �o�b�t�@ */
2589
+ int lvsum = 0;
2590
+ memset( blurbuf, 0, edge_pitch * (srcimage->height + edge_width * 2) ); /* �o�b�t�@�̃N���A */
2591
+
2592
+ for( v = -edge_width; v <= edge_width; v++ )
2593
+ {
2594
+ for( u = -edge_width; u <= edge_width; u++ )
2595
+ {
2596
+ int len = fast_int_hypot(u, v);
2597
+ if(len <= edge_width)
2598
+ lvsum += (edge_width - len + 1);
2599
+ }
2600
+ }
2601
+
2602
+ if( lvsum )
2603
+ {
2604
+ lvsum = (1<<18) / lvsum;
2605
+ }
2606
+ else
2607
+ {
2608
+ lvsum = (1<<18);
2609
+ }
2610
+
2611
+ for( v = -edge_width; v <= edge_width; v++ )
2612
+ {
2613
+ for( u = -edge_width; u <= edge_width; u++ )
2614
+ {
2615
+ int len = fast_int_hypot(u, v);
2616
+ if( len <= edge_width )
2617
+ {
2618
+ int sx, sy;
2619
+ for( sy = 0; sy < srcimage->height; sy++ )
2620
+ {
2621
+ for( sx = 0; sx < srcimage->width; sx++ )
2622
+ {
2623
+ int temp;
2624
+ temp = blurbuf[(v + sy + edge_width) * edge_pitch + u + sx + edge_width] + ((buf[ sx + sy * (int)srcimage->width ] * lvsum * (edge_width - len + 1) * edge_level) >> 18);
2625
+ if( temp > 64 ) temp = 64;
2626
+ blurbuf[(v + sy + edge_width) * edge_pitch + u + sx + edge_width] = temp;
2627
+ }
2628
+ }
2629
+ }
2630
+ }
2631
+ }
2632
+
2633
+ if( shadow_x != 0 || shadow_y != 0 )
2634
+ {
2635
+ /* �G�b�W������ꍇ�̉e�̕`�� */
2636
+ if( shadow_edge == 1 )
2637
+ {
2638
+ drawfont_sub( srcimage->width + edge_width * 2, srcimage->height + edge_width * 2, x - edge_width + shadow_x, y - edge_width + shadow_y, edge_pitch, blurbuf, &dsttrect, sr, sg, sb, dstimage->width, dstimage->height );
2639
+ }
2640
+ /* �G�b�W�����邯�ǃG�b�W�����e�̕`�� */
2641
+ else
2642
+ {
2643
+ drawfont_sub( srcimage->width, srcimage->height, x + shadow_x, y + shadow_y, srcimage->width, buf, &dsttrect, sr, sg, sb, dstimage->width, dstimage->height );
2644
+ }
2645
+ }
2646
+
2647
+ /* �G�b�W�̕`�� */
2648
+ drawfont_sub( srcimage->width + edge_width * 2, srcimage->height + edge_width * 2, x - edge_width, y - edge_width, edge_pitch, blurbuf, &dsttrect, br, bg, bb, dstimage->width, dstimage->height );
2649
+
2650
+ }
2651
+ else if( shadow_x != 0 || shadow_y != 0 ) /* �G�b�W���Ȃ��ꍇ�̉e�̕`�� */
2652
+ {
2653
+ drawfont_sub( srcimage->width, srcimage->height,x + shadow_x,y + shadow_y, srcimage->width, buf, &dsttrect, sr, sg, sb, dstimage->width, dstimage->height );
2654
+ }
2655
+
2656
+ /* �����̕`�� */
2657
+ drawfont_sub( srcimage->width, srcimage->height, x, y, srcimage->width, buf, &dsttrect, cr, cg, cb, dstimage->width, dstimage->height );
2658
+
2659
+ }
2660
+
2661
+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
2662
+
2663
+ return obj;
2664
+ }
2665
+
2666
+
2667
+ /*--------------------------------------------------------------------
2668
+ HLS�ŐF�𒲐�����
2669
+ ---------------------------------------------------------------------*/
2670
+ static void RGBToHSB( unsigned int rgb, int *hue, int *saturation, int *brightness )
2671
+ {
2672
+ float r, g, b, h, s, l, cmax, cmin, sum, dif;
2673
+
2674
+ r = ((rgb & 0x00ff0000) >> 16) / 255.0f;
2675
+ g = ((rgb & 0x0000ff00) >> 8 ) / 255.0f;
2676
+ b = ((rgb & 0x000000ff) ) / 255.0f;
2677
+
2678
+ cmax = (r > g) ? ((b > r) ? b : r) : ((b > g) ? b : g);
2679
+ cmin = (r < g) ? ((b < r) ? b : r) : ((b < g) ? b : g);
2680
+ // printf("max %f\n", cmax);
2681
+ // printf("min %f\n", cmin);
2682
+
2683
+ sum = cmax + cmin;
2684
+ dif = cmax - cmin;
2685
+ // printf("sum %f\n", sum);
2686
+ // printf("dif %f\n", dif);
2687
+
2688
+ l = sum / 2.0f;
2689
+
2690
+ if( dif == 0.0f )
2691
+ {
2692
+ h = 0;
2693
+ s = 0;
2694
+ }
2695
+ else
2696
+ {
2697
+ if( l <= 0.5f )
2698
+ {
2699
+ s = dif / sum;
2700
+ }
2701
+ else
2702
+ {
2703
+ s = dif / (2.0f - sum);
2704
+ }
2705
+
2706
+ if( r == cmax )
2707
+ {
2708
+ h = (g - b) / dif;
2709
+ }
2710
+ if( g == cmax )
2711
+ {
2712
+ h = 2.0f + (b - r) / dif;
2713
+ }
2714
+ if( b == cmax )
2715
+ {
2716
+ h = 4.0f + (r - g) / dif;
2717
+ }
2718
+
2719
+ h = h * 60.0f;
2720
+ if( h < 0.0f )
2721
+ {
2722
+ h = h + 360.0f;
2723
+ }
2724
+ }
2725
+
2726
+ *hue = (int)h;
2727
+ *saturation = (int)(s * 100);
2728
+ *brightness = (int)(l * 100);
2729
+ }
2730
+
2731
+ static int HToRGB( float cmin, float cmax, int hue )
2732
+ {
2733
+ int h = hue % 360;
2734
+ if( h < 0 )
2735
+ {
2736
+ h = h + 360;
2737
+ }
2738
+
2739
+ if( h < 60 )
2740
+ {
2741
+ return (int)((cmin + (cmax - cmin) * h / 60) * 255);
2742
+ }
2743
+ else if( h < 180 )
2744
+ {
2745
+ return (int)(cmax * 255);
2746
+ }
2747
+ else if( h < 240 )
2748
+ {
2749
+ return (int)((cmin + (cmax - cmin) * (240 - h) / 60) * 255);
2750
+ }
2751
+ else
2752
+ {
2753
+ return (int)(cmin * 255);
2754
+ }
2755
+ }
2756
+
2757
+ static int HSBToRGB( int hue, int saturation, int brightness )
2758
+ {
2759
+ int h;
2760
+ float s, l, cmax, cmin;
2761
+
2762
+ s = saturation / 100.0f;
2763
+ l = brightness / 100.0f;
2764
+
2765
+ h = hue % 360;
2766
+ if( h < 0 )
2767
+ {
2768
+ h = h + 360;
2769
+ }
2770
+
2771
+ if( l < 0.0f )
2772
+ {
2773
+ l = 0.0f;
2774
+ }
2775
+ if( l > 1.0f )
2776
+ {
2777
+ l = 1.0f;
2778
+ }
2779
+
2780
+ if( s < 0.0f )
2781
+ {
2782
+ s = 0.0f;
2783
+ }
2784
+ if( s > 1.0f )
2785
+ {
2786
+ s = 1.0f;
2787
+ }
2788
+
2789
+ if( l <= 0.5f )
2790
+ {
2791
+ cmin = l * (1.0f - s);
2792
+ cmax = 2.0f * l - cmin;
2793
+ }
2794
+ else
2795
+ {
2796
+ cmax = l * (1.0f - s) + s;
2797
+ cmin = 2.0f * l - cmax;
2798
+ }
2799
+
2800
+ return (HToRGB(cmin, cmax, h + 120) << 16) | (HToRGB(cmin, cmax, h) << 8) | HToRGB(cmin, cmax, h - 120);
2801
+ }
2802
+
2803
+ VALUE Image_change_hls( int argc, VALUE *argv, VALUE self )
2804
+ {
2805
+ struct DXRubyImage *srcimage = DXRUBY_GET_STRUCT( Image, self );
2806
+ struct DXRubyImage *dstimage;
2807
+ struct DXRubyTexture *texture;
2808
+ D3DLOCKED_RECT srctrect;
2809
+ D3DLOCKED_RECT dsttrect;
2810
+ int i, j;
2811
+ RECT srcrect;
2812
+ RECT dstrect;
2813
+ HRESULT hr;
2814
+ D3DSURFACE_DESC desc;
2815
+ int *psrc;
2816
+ int *pdst;
2817
+ VALUE obj;
2818
+ int hue, luminance, saturation;
2819
+ int dhue, dluminance, dsaturation;
2820
+
2821
+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
2822
+
2823
+ if( argc < 1 || argc > 3 ) rb_raise( rb_eArgError, "wrong number of arguments (%d for %d..%d)", argc, 1, 3 );
2824
+
2825
+ dhue = NUM2INT( argv[0] );
2826
+ dluminance = argc < 2 || argv[1] == Qnil ? 0 : NUM2INT( argv[1] );
2827
+ dsaturation = argc < 3 || argv[2] == Qnil ? 0 : NUM2INT( argv[2] );
2828
+
2829
+ obj = Image_allocate( cImage );
2830
+ dstimage = DXRUBY_GET_STRUCT( Image, obj );
2831
+ g_iRefAll++;
2832
+
2833
+ /* �e�N�X�`���������擾 */
2834
+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2835
+ if( texture == NULL )
2836
+ {
2837
+ rb_raise( eDXRubyError, "Out of memory - Image_change_hls" );
2838
+ }
2839
+
2840
+ DXRUBY_RETRY_START;
2841
+ /* �e�N�X�`���I�u�W�F�N�g���쐬���� */
2842
+ hr = D3DXCreateTexture( g_pD3DDevice, srcimage->width, srcimage->height,
2843
+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2844
+ &texture->pD3DTexture);
2845
+ DXRUBY_RETRY_END;
2846
+ if( FAILED( hr ) )
2847
+ {
2848
+ rb_raise( eDXRubyError, "Create texture error - Image_change_hls" );
2849
+ }
2850
+
2851
+ texture->refcount = 1;
2852
+
2853
+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2854
+ texture->width = (float)desc.Width;
2855
+ texture->height = (float)desc.Height;
2856
+
2857
+ dstimage->texture = texture;
2858
+ dstimage->x = 0;
2859
+ dstimage->y = 0;
2860
+ dstimage->width = srcimage->width;
2861
+ dstimage->height =srcimage-> height;
2862
+ // dstimage->lockcount = 0;
2863
+
2864
+ /* �C���[�W�R�s�[ */
2865
+ dstrect.left = 0;
2866
+ dstrect.top = 0;
2867
+ dstrect.right = srcimage->width;
2868
+ dstrect.bottom = srcimage->height;
2869
+ srcrect.left = srcimage->x;
2870
+ srcrect.top = srcimage->y;
2871
+ srcrect.right = srcimage->x + srcimage->width;
2872
+ srcrect.bottom = srcimage->y + srcimage->height;
2873
+
2874
+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
2875
+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
2876
+
2877
+ for( i = 0; i < srcimage->height; i++)
2878
+ {
2879
+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
2880
+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
2881
+ for( j = 0; j < srcimage->width; j++)
2882
+ {
2883
+ int s = *(psrc++);
2884
+ if( (s & 0xff000000) == 0 )
2885
+ {
2886
+ *(pdst++) = s;
2887
+ }
2888
+ else
2889
+ {
2890
+ int col;
2891
+ RGBToHSB( s, &hue, &saturation, &luminance );
2892
+ col = HSBToRGB( hue + dhue, saturation + dsaturation, luminance + dluminance );
2893
+ *(pdst++) = (s & 0xff000000) | col ;
2894
+ }
2895
+ }
2896
+ }
2897
+
2898
+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
2899
+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
2900
+
2901
+ return obj;
2902
+ }
2903
+
2904
+
2905
+ /*--------------------------------------------------------------------
2906
+ �C���[�W���t�@�C���ɕۑ�����B
2907
+ ---------------------------------------------------------------------*/
2908
+ VALUE Image_save( int argc, VALUE *argv, VALUE self )
2909
+ {
2910
+ HRESULT hr;
2911
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, self );
2912
+ VALUE vfilename, vformat, vsjisstr, vdowncase;
2913
+ char ext[5][6] = {".jpeg", ".jpg", ".png", ".bmp", ".dds"};
2914
+ char len[5] = {4, 3, 3, 3, 3};
2915
+ int format[5] = {FORMAT_JPG, FORMAT_JPG, FORMAT_PNG, FORMAT_BMP, FORMAT_DDS};
2916
+ int i, j, k, f;
2917
+
2918
+ rb_scan_args( argc, argv, "11", &vfilename, &vformat );
2919
+
2920
+ DXRUBY_CHECK_DISPOSE( image, texture );
2921
+
2922
+ if( rb_enc_get_index( vfilename ) != 0 )
2923
+ {
2924
+ vsjisstr = rb_str_export_to_enc( vfilename, g_enc_sys );
2925
+ }
2926
+ else
2927
+ {
2928
+ vsjisstr = vfilename;
2929
+ }
2930
+
2931
+ vdowncase = rb_funcall( vsjisstr, rb_intern("downcase"), 0, Qnil );
2932
+ if( vformat == Qnil )
2933
+ {
2934
+ for( i = 0; i < 5; i++ )
2935
+ {
2936
+ for( j = RSTRING_LEN(vdowncase) - 1, k = len[i]; k >= 0 && j >= 0; k--, j-- )
2937
+ {
2938
+ if( RSTRING_PTR(vdowncase)[j] != ext[i][k] )
2939
+ {
2940
+ break;
2941
+ }
2942
+ }
2943
+
2944
+ if( ext[i][k + 1] == '.' && RSTRING_PTR(vdowncase)[j + 1] == '.' )
2945
+ {
2946
+ f = format[i];
2947
+ break;
2948
+ }
2949
+ }
2950
+ if( i == 5 )
2951
+ {
2952
+ f = FORMAT_PNG;
2953
+ }
2954
+ }
2955
+ else
2956
+ {
2957
+ f = FIX2INT( vformat );
2958
+ }
2959
+
2960
+ hr = D3DXSaveTextureToFile(
2961
+ RSTRING_PTR( vsjisstr ), /* �ۑ��t�@�C���� */
2962
+ f, /* �t�@�C���t�H�[�}�b�g */
2963
+ (IDirect3DBaseTexture9*)image->texture->pD3DTexture,/* �ۑ�����T�[�t�F�X */
2964
+ NULL); /* �p���b�g */
2965
+ if( FAILED( hr ) )
2966
+ {
2967
+ rb_raise( eDXRubyError, "Save error - Image_save" );
2968
+ }
2969
+
2970
+ return self;
2971
+ }
2972
+
2973
+
2974
+ /*--------------------------------------------------------------------
2975
+ �C���[�W�̊J�n�ʒux��Ԃ��B
2976
+ ---------------------------------------------------------------------*/
2977
+ static VALUE Image_getX( VALUE obj )
2978
+ {
2979
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
2980
+
2981
+ DXRUBY_CHECK_DISPOSE( image, texture );
2982
+
2983
+ return INT2FIX( image->x );
2984
+ }
2985
+
2986
+
2987
+ /*--------------------------------------------------------------------
2988
+ �C���[�W�̊J�n�ʒuy��Ԃ��B
2989
+ ---------------------------------------------------------------------*/
2990
+ static VALUE Image_getY( VALUE obj )
2991
+ {
2992
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
2993
+
2994
+ DXRUBY_CHECK_DISPOSE( image, texture );
2995
+
2996
+ return INT2FIX( image->y );
2997
+ }
2998
+
2999
+
3000
+ /*--------------------------------------------------------------------
3001
+ �C���[�W�̃T�C�Y�i���j��Ԃ��B
3002
+ ---------------------------------------------------------------------*/
3003
+ static VALUE Image_getWidth( VALUE obj )
3004
+ {
3005
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3006
+
3007
+ DXRUBY_CHECK_DISPOSE( image, texture );
3008
+
3009
+ return INT2FIX( image->width );
3010
+ }
3011
+
3012
+
3013
+ /*--------------------------------------------------------------------
3014
+ �C���[�W�̃T�C�Y�i�����j��Ԃ��B
3015
+ ---------------------------------------------------------------------*/
3016
+ static VALUE Image_getHeight( VALUE obj )
3017
+ {
3018
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3019
+
3020
+ DXRUBY_CHECK_DISPOSE( image, texture );
3021
+
3022
+ return INT2FIX( image->height );
3023
+ }
3024
+
3025
+
3026
+ /*--------------------------------------------------------------------
3027
+ �C���[�W�̊J�n�ʒux��ݒ肷��B
3028
+ ---------------------------------------------------------------------*/
3029
+ static VALUE Image_setX( VALUE obj, VALUE vx )
3030
+ {
3031
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3032
+ int x = NUM2INT( vx );
3033
+
3034
+ DXRUBY_CHECK_DISPOSE( image, texture );
3035
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
3036
+
3037
+ if( x < 0 || x + image->width > image->texture->width )
3038
+ {
3039
+ rb_raise( eDXRubyError, "bad value of x - Image#x=" );
3040
+ }
3041
+
3042
+ image->x = x;
3043
+ return vx;
3044
+ }
3045
+
3046
+
3047
+ /*--------------------------------------------------------------------
3048
+ �C���[�W�̊J�n�ʒuy��ݒ肷��B
3049
+ ---------------------------------------------------------------------*/
3050
+ static VALUE Image_setY( VALUE obj, VALUE vy )
3051
+ {
3052
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3053
+ int y = NUM2INT( vy );
3054
+
3055
+ DXRUBY_CHECK_DISPOSE( image, texture );
3056
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
3057
+
3058
+ if( y < 0 || y + image->height > image->texture->height )
3059
+ {
3060
+ rb_raise( eDXRubyError, "bad value of y - Image#y=" );
3061
+ }
3062
+
3063
+ image->y = y;
3064
+ return vy;
3065
+ }
3066
+
3067
+
3068
+ /*--------------------------------------------------------------------
3069
+ �C���[�W�̃T�C�Y�i���j��ݒ肷��B
3070
+ ---------------------------------------------------------------------*/
3071
+ static VALUE Image_setWidth( VALUE obj, VALUE vwidth )
3072
+ {
3073
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3074
+ int width = NUM2INT( vwidth );
3075
+
3076
+ DXRUBY_CHECK_DISPOSE( image, texture );
3077
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
3078
+
3079
+ if( width < 1 || width + image->x > image->texture->width )
3080
+ {
3081
+ rb_raise( eDXRubyError, "bad value of width - Image#width=" );
3082
+ }
3083
+
3084
+ image->width = width;
3085
+ return vwidth;
3086
+ }
3087
+
3088
+
3089
+ /*--------------------------------------------------------------------
3090
+ �C���[�W�̃T�C�Y�i�����j��ݒ肷��B
3091
+ ---------------------------------------------------------------------*/
3092
+ static VALUE Image_setHeight( VALUE obj, VALUE vheight )
3093
+ {
3094
+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, obj );
3095
+ int height = NUM2INT( vheight );
3096
+
3097
+ DXRUBY_CHECK_DISPOSE( image, texture );
3098
+ // DXRUBY_CHECK_IMAGE_LOCK( image );
3099
+
3100
+ if( height < 1 || height + image->y > image->texture->height )
3101
+ {
3102
+ rb_raise( eDXRubyError, "bad value of height - Image#height=" );
3103
+ }
3104
+
3105
+ image->height = height;
3106
+ return vheight;
3107
+ }
3108
+
3109
+
3110
+ /*--------------------------------------------------------------------
3111
+ Perlin Noise
3112
+ ---------------------------------------------------------------------*/
3113
+
3114
+ //http://postd.cc/understanding-perlin-noise/
3115
+ static int permutation[512] = { 151,160,137,91,90,15, // Hash lookup table as defined by Ken Perlin. This is a randomly
3116
+ 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, // arranged array of all numbers from 0-255 inclusive.
3117
+ 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
3118
+ 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
3119
+ 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
3120
+ 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
3121
+ 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
3122
+ 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
3123
+ 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
3124
+ 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
3125
+ 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
3126
+ 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
3127
+ 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
3128
+ };
3129
+
3130
+ static int *perlinp;
3131
+
3132
+ static double grad(int hash, double x, double y, double z) {
3133
+ switch(hash & 0xF)
3134
+ {
3135
+ case 0x0: return x + y;
3136
+ case 0x1: return -x + y;
3137
+ case 0x2: return x - y;
3138
+ case 0x3: return -x - y;
3139
+ case 0x4: return x + z;
3140
+ case 0x5: return -x + z;
3141
+ case 0x6: return x - z;
3142
+ case 0x7: return -x - z;
3143
+ case 0x8: return y + z;
3144
+ case 0x9: return -y + z;
3145
+ case 0xA: return y - z;
3146
+ case 0xB: return -y - z;
3147
+ case 0xC: return y + x;
3148
+ case 0xD: return -y + z;
3149
+ case 0xE: return y - x;
3150
+ case 0xF: return -y - z;
3151
+ default: return 0; // never happens
3152
+ }
3153
+ }
3154
+
3155
+ static double fade(double t) {
3156
+ // Fade function as defined by Ken Perlin. This eases coordinate values
3157
+ // so that they will "ease" towards integral values. This ends up smoothing
3158
+ // the final output.
3159
+ return t * t * t * (t * (t * 6 - 15) + 10); // 6t^5 - 15t^4 + 10t^3
3160
+ }
3161
+
3162
+ static double lerp(double a, double b, double x) {
3163
+ return a + x * (b - a);
3164
+ }
3165
+
3166
+ static double perlin(double x, double y, double z, int repeat_x, int repeat_y, int repeat_z) {
3167
+ {
3168
+ int xi = (int)x % repeat_x; // Calculate the "unit cube" that the point asked will be located in
3169
+ int yi = (int)y % repeat_y; // The left bound is ( |_x_|,|_y_|,|_z_| ) and the right bound is that
3170
+ int zi = (int)z % repeat_z; // plus 1. Next we calculate the location (from 0.0 to 1.0) in that cube.
3171
+ double xf = x-(int)x; // We also fade the location to smooth the result.
3172
+ double yf = y-(int)y;
3173
+ double zf = z-(int)z;
3174
+ double u = fade(xf);
3175
+ double v = fade(yf);
3176
+ double w = fade(zf);
3177
+ double x1, x2, y1, y2;
3178
+
3179
+ int aaa, aba, aab, abb, baa, bba, bab, bbb;
3180
+ aaa = perlinp[perlinp[perlinp[ xi ]+ yi ]+ zi ];
3181
+ aba = perlinp[perlinp[perlinp[ xi ]+(yi+1)%repeat_y]+ zi ];
3182
+ aab = perlinp[perlinp[perlinp[ xi ]+ yi ]+(zi+1)%repeat_z];
3183
+ abb = perlinp[perlinp[perlinp[ xi ]+(yi+1)%repeat_y]+(zi+1)%repeat_z];
3184
+ baa = perlinp[perlinp[perlinp[(xi+1)%repeat_x]+ yi ]+ zi ];
3185
+ bba = perlinp[perlinp[perlinp[(xi+1)%repeat_x]+(yi+1)%repeat_y]+ zi ];
3186
+ bab = perlinp[perlinp[perlinp[(xi+1)%repeat_x]+ yi ]+(zi+1)%repeat_z];
3187
+ bbb = perlinp[perlinp[perlinp[(xi+1)%repeat_x]+(yi+1)%repeat_y]+(zi+1)%repeat_z];
3188
+
3189
+ x1 = lerp(grad (aaa, xf , yf , zf), // The gradient function calculates the dot product between a pseudorandom
3190
+ grad (baa, xf-1, yf , zf), // gradient vector and the vector from the input coordinate to the 8
3191
+ u); // surrounding points in its unit cube.
3192
+ x2 = lerp(grad (aba, xf , yf-1, zf), // This is all then lerped together as a sort of weighted average based on the faded (u,v,w)
3193
+ grad (bba, xf-1, yf-1, zf), // values we made earlier.
3194
+ u);
3195
+ y1 = lerp(x1, x2, v);
3196
+
3197
+ x1 = lerp(grad (aab, xf , yf , zf-1),
3198
+ grad (bab, xf-1, yf , zf-1),
3199
+ u);
3200
+ x2 = lerp(grad (abb, xf , yf-1, zf-1),
3201
+ grad (bbb, xf-1, yf-1, zf-1),
3202
+ u);
3203
+ y2 = lerp (x1, x2, v);
3204
+
3205
+ return (lerp (y1, y2, w)+1)/2; // For convenience we bound it to 0 - 1 (theoretical min/max before is -1 - 1)
3206
+ }
3207
+ }
3208
+
3209
+ static double OctavePerlin(double x, double y, double z, int octaves, double persistence, int repeat_x, int repeat_y, int repeat_z) {
3210
+ double total = 0;
3211
+ double frequency = 1;
3212
+ double amplitude = 1;
3213
+ double maxValue = 0; // Used for normalizing result to 0.0 - 1.0
3214
+ int i;
3215
+
3216
+ for( i = 0; i < octaves; i++ )
3217
+ {
3218
+ total += perlin( x * frequency, y * frequency, z * frequency, repeat_x, repeat_y, repeat_z ) * amplitude;
3219
+ maxValue += amplitude;
3220
+ amplitude *= persistence;
3221
+ frequency *= 2;
3222
+ }
3223
+ return total / maxValue;
3224
+ }
3225
+
3226
+ static double CustomPerlin(double x, double y, double z, VALUE vary, int repeat_x, int repeat_y, int repeat_z) {
3227
+ double total = 0;
3228
+ double amplitude = 1;
3229
+ double maxValue = 0; // Used for normalizing result to 0.0 - 1.0
3230
+ int i;
3231
+
3232
+ for( i = 0; i < RARRAY_LEN(vary); i++)
3233
+ {
3234
+ double frequency = NUM2DBL( rb_ary_entry( rb_ary_entry( vary, i ), 0 ) );
3235
+ double amplitude = NUM2DBL( rb_ary_entry( rb_ary_entry( vary, i ), 1 ) );
3236
+
3237
+ total += perlin( x * frequency, y * frequency, z * frequency, repeat_x, repeat_y, repeat_z ) * amplitude;
3238
+ maxValue += amplitude;
3239
+ }
3240
+ return total / maxValue;
3241
+ }
3242
+
3243
+ static VALUE Image_perlin_noise( int argc, VALUE *argv, VALUE obj )
3244
+ {
3245
+ VALUE vx, vy, vz, vrepeat_x, vrepeat_y, vrepeat_z;
3246
+ int repeat_x, repeat_y, repeat_z;
3247
+
3248
+ rb_scan_args( argc, argv, "33", &vx, &vy, &vz, &vrepeat_x, &vrepeat_y, &vrepeat_z );
3249
+
3250
+ repeat_x = vrepeat_x == Qnil ? 256 : NUM2INT(vrepeat_x);
3251
+ repeat_y = vrepeat_y == Qnil ? 256 : NUM2INT(vrepeat_y);
3252
+ repeat_z = vrepeat_z == Qnil ? 256 : NUM2INT(vrepeat_z);
3253
+
3254
+ return rb_float_new( perlin( NUM2DBL(vx), NUM2DBL(vy), NUM2DBL(vz), repeat_x, repeat_y, vrepeat_z ) );
3255
+ }
3256
+
3257
+ static VALUE Image_octave_perlin_noise( int argc, VALUE *argv, VALUE obj )
3258
+ {
3259
+ VALUE vx, vy, vz, voctave, vpersistence, vrepeat_x, vrepeat_y, vrepeat_z;
3260
+ int repeat_x, repeat_y, repeat_z;
3261
+
3262
+ rb_scan_args( argc, argv, "53", &vx, &vy, &vz, &voctave, &vpersistence, &vrepeat_x, &vrepeat_y, &vrepeat_z );
3263
+
3264
+ repeat_x = vrepeat_x == Qnil ? 256 : NUM2INT(vrepeat_x);
3265
+ repeat_y = vrepeat_y == Qnil ? 256 : NUM2INT(vrepeat_y);
3266
+ repeat_z = vrepeat_z == Qnil ? 256 : NUM2INT(vrepeat_z);
3267
+
3268
+ return rb_float_new( OctavePerlin( NUM2DBL(vx), NUM2DBL(vy), NUM2DBL(vz), NUM2INT(voctave), NUM2DBL(vpersistence), repeat_x, repeat_y, repeat_z ) );
3269
+ }
3270
+
3271
+ static VALUE Image_custom_perlin_noise( int argc, VALUE *argv, VALUE obj )
3272
+ {
3273
+ VALUE vx, vy, vz, vary, vrepeat_x, vrepeat_y, vrepeat_z;
3274
+ int repeat_x, repeat_y, repeat_z;
3275
+
3276
+ rb_scan_args( argc, argv, "43", &vx, &vy, &vz, &vary, &vrepeat_x, &vrepeat_y, &vrepeat_z );
3277
+
3278
+ Check_Type( vary, T_ARRAY );
3279
+
3280
+ repeat_x = vrepeat_x == Qnil ? 256 : NUM2INT(vrepeat_x);
3281
+ repeat_y = vrepeat_y == Qnil ? 256 : NUM2INT(vrepeat_y);
3282
+ repeat_z = vrepeat_z == Qnil ? 256 : NUM2INT(vrepeat_z);
3283
+
3284
+ return rb_float_new( CustomPerlin( NUM2DBL(vx), NUM2DBL(vy), NUM2DBL(vz), vary, repeat_x, repeat_y, vrepeat_z ) );
3285
+ }
3286
+
3287
+ static VALUE Image_perlin_seed( VALUE obj, VALUE vseed )
3288
+ {
3289
+ int i;
3290
+
3291
+ srand(NUM2INT(vseed));
3292
+
3293
+ free( perlinp );
3294
+ perlinp = malloc(512*sizeof(int));
3295
+
3296
+ for( i = 0; i < 256; i++ )
3297
+ {
3298
+ perlinp[i] = perlinp[i+256] = rand() % 256;
3299
+ }
3300
+
3301
+ return Qnil;
3302
+ }
3303
+
3304
+ void Init_dxruby_Image()
3305
+ {
3306
+ int i;
3307
+
3308
+ /* Image�N���X��` */
3309
+ cImage = rb_define_class_under( mDXRuby, "Image", rb_cObject );
3310
+
3311
+ /* Image�N���X�ɃN���X���\�b�h�o�^*/
3312
+ rb_define_singleton_method( cImage, "load", Image_load, -1 );
3313
+ rb_define_singleton_method( cImage, "load_to_array", Image_loadToArray, -1 );
3314
+ rb_define_singleton_method( cImage, "loadToArray", Image_loadToArray, -1 );
3315
+ rb_define_singleton_method( cImage, "load_tiles", Image_loadToArray, -1 );
3316
+ rb_define_singleton_method( cImage, "loadTiles", Image_loadToArray, -1 );
3317
+ rb_define_singleton_method( cImage, "create_from_array", Image_createFromArray, 3 );
3318
+ rb_define_singleton_method( cImage, "createFromArray", Image_createFromArray, 3 );
3319
+ rb_define_singleton_method( cImage, "load_from_file_in_memory", Image_loadFromFileInMemory, 1 );
3320
+ rb_define_singleton_method( cImage, "loadFromFileInMemory", Image_loadFromFileInMemory, 1 );
3321
+ rb_define_singleton_method( cImage, "load_from_memory", Image_loadFromFileInMemory, 1 );
3322
+ rb_define_singleton_method( cImage, "loadFromMemory", Image_loadFromFileInMemory, 1 );
3323
+ rb_define_singleton_method( cImage, "perlin_noise", Image_perlin_noise, -1);
3324
+ rb_define_singleton_method( cImage, "octave_perlin_noise", Image_octave_perlin_noise, -1);
3325
+ rb_define_singleton_method( cImage, "custom_perlin_noise", Image_custom_perlin_noise, -1);
3326
+ rb_define_singleton_method( cImage, "perlin_seed", Image_perlin_seed, 1);
3327
+
3328
+ /* Image�N���X�Ƀ��\�b�h�o�^*/
3329
+ rb_define_private_method( cImage, "initialize", Image_initialize, -1 );
3330
+ rb_define_method( cImage, "dispose" , Image_dispose , 0 );
3331
+ rb_define_method( cImage, "disposed?" , Image_check_disposed, 0 );
3332
+ rb_define_method( cImage, "delayed_dispose" , Image_delayed_dispose , 0 );
3333
+ rb_define_method( cImage, "width" , Image_getWidth , 0 );
3334
+ rb_define_method( cImage, "height" , Image_getHeight , 0 );
3335
+ // rb_define_method( cImage, "width=" , Image_setWidth , 1 );
3336
+ // rb_define_method( cImage, "height=" , Image_setHeight , 1 );
3337
+ rb_define_method( cImage, "[]=" , Image_setPixel , 3 );
3338
+ rb_define_method( cImage, "[]" , Image_getPixel , 2 );
3339
+ rb_define_method( cImage, "box" , Image_box , 5 );
3340
+ rb_define_method( cImage, "box_fill" , Image_boxFill , 5 );
3341
+ rb_define_method( cImage, "boxFill" , Image_boxFill , 5 );
3342
+ rb_define_method( cImage, "fill" , Image_fill , 1 );
3343
+ rb_define_method( cImage, "clear" , Image_clear , 0 );
3344
+ rb_define_method( cImage, "line" , Image_line , 5 );
3345
+ rb_define_method( cImage, "triangle" , Image_triangle , 7 );
3346
+ rb_define_method( cImage, "triangle_fill", Image_triangle_fill, 7 );
3347
+ rb_define_method( cImage, "triangleFill" , Image_triangle_fill, 7 );
3348
+ rb_define_method( cImage, "circle" , Image_circle , 4 );
3349
+ rb_define_method( cImage, "circle_fill", Image_circleFill, 4 );
3350
+ rb_define_method( cImage, "circleFill", Image_circleFill, 4 );
3351
+ rb_define_method( cImage, "compare" , Image_compare , 3 );
3352
+ rb_define_method( cImage, "copy_rect" , Image_copyRect , -1 );
3353
+ rb_define_method( cImage, "copyRect" , Image_copyRect , -1 );
3354
+ rb_define_method( cImage, "draw" , Image_draw , -1 );
3355
+ rb_define_method( cImage, "draw_font" , Image_drawFont , -1 );
3356
+ rb_define_method( cImage, "drawFont" , Image_drawFont , -1 );
3357
+ rb_define_method( cImage, "save" , Image_save , -1 );
3358
+ rb_define_method( cImage, "slice" , Image_slice_instance, -1);
3359
+ rb_define_method( cImage, "flush" , Image_flush, 1);
3360
+ rb_define_method( cImage, "set_color_key", Image_setColorKey , 1 );
3361
+ rb_define_method( cImage, "setColorKey", Image_setColorKey , 1 );
3362
+ rb_define_method( cImage, "slice_to_array", Image_sliceToArray , -1 );
3363
+ rb_define_method( cImage, "sliceToArray", Image_sliceToArray , -1 );
3364
+ rb_define_method( cImage, "slice_tiles", Image_sliceToArray , -1 );
3365
+ rb_define_method( cImage, "sliceTiles", Image_sliceToArray , -1 );
3366
+ rb_define_method( cImage, "initialize_copy", Image_initialize_copy , 1 );
3367
+ rb_define_method( cImage, "draw_font_ex" , Image_drawFontEx , -1 );
3368
+ rb_define_method( cImage, "drawFontEx" , Image_drawFontEx , -1 );
3369
+ rb_define_method( cImage, "effect_image_font", Image_effect, -1);
3370
+ rb_define_method( cImage, "effectImageFont", Image_effect, -1);
3371
+ rb_define_method( cImage, "change_hls", Image_change_hls, -1);
3372
+ rb_define_method( cImage, "changeHLS", Image_change_hls, -1);
3373
+
3374
+ /* Image�I�u�W�F�N�g�𐶐���������initialize�̑O�ɌĂ΂�郁�������蓖�Ċ֐��o�^ */
3375
+ rb_define_alloc_func( cImage, Image_allocate );
3376
+
3377
+ /* PerlinNoise������ */
3378
+ perlinp = malloc( 512 * sizeof(int) );
3379
+
3380
+ for( i = 0; i < 256; i++ )
3381
+ {
3382
+ perlinp[i] = perlinp[i + 256] = permutation[i];
3383
+ }
3384
+ }
3385
+
3386
+ void finalize_dxruby_Image()
3387
+ {
3388
+ free( perlinp );
3389
+ }
3390
+
3391
+