dxrubynd 1.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+