Subversion Repositories Kolibri OS

Rev

Rev 2177 | Rev 2230 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1535 IgorA 1
format MS COFF
2
public EXPORTS
3
section '.flat' code readable align 16
4
 
5
include '../../../../macros.inc'
6
include '../../../../proc32.inc'
7
 
8
;-----------------------------------------------------------------------------
9
mem.alloc   dd ? ;функция для выделения памяти
10
mem.free    dd ? ;функция для освобождения памяти
11
mem.realloc dd ? ;функция для перераспределения памяти
12
dll.load    dd ?
13
 
14
BUF_STRUCT_SIZE equ 21
15
buf2d_data equ dword[edi] ;данные буфера изображения
16
buf2d_w equ dword[edi+8] ;ширина буфера
17
buf2d_h equ dword[edi+12] ;высота буфера
1538 IgorA 18
buf2d_l equ word[edi+4]
1535 IgorA 19
buf2d_t equ word[edi+6] ;отступ сверху
20
buf2d_size_lt equ dword[edi+4] ;отступ слева и справа для буфера
21
buf2d_color equ dword[edi+16] ;цвет фона буфера
22
buf2d_bits equ byte[edi+20] ;количество бит в 1-й точке изображения
23
 
24
struct buf_2d_header
25
	img_data dd ?
26
	left dw ? ;+4 left
27
	top dw ? ;+6 top
28
	size_x dd ? ;+8 w
29
	size_y dd ? ;+12 h
30
	color dd ? ;+16 color
31
	bit_pp db ? ;+21 bit in pixel
32
ends
33
 
34
macro swap v1, v2 {
35
  push v1
36
  push v2
37
  pop v1
38
  pop v2
39
}
40
 
41
;флаги, для функции обрезания буфера
42
BUF2D_OPT_CROP_TOP equ 1 ;обрезка сверху
43
BUF2D_OPT_CROP_LEFT equ 2 ;обрезка слева
44
BUF2D_OPT_CROP_BOTTOM equ 4 ;обрезка снизу
45
BUF2D_OPT_CROP_RIGHT equ 8 ;обрезка справа
46
BUF2D_BIT_OPT_CROP_TOP equ 0
47
BUF2D_BIT_OPT_CROP_LEFT equ 1
48
BUF2D_BIT_OPT_CROP_BOTTOM equ 2
49
BUF2D_BIT_OPT_CROP_RIGHT equ 3
50
 
51
;input:
52
; eax = указатель на функцию выделения памяти
53
; ebx = ... освобождения памяти
54
; ecx = ... перераспределения памяти
55
; edx = ... загрузки библиотеки (пока не используется)
56
align 16
57
lib_init:
58
	mov dword[mem.alloc], eax
59
	mov dword[mem.free], ebx
60
	mov dword[mem.realloc], ecx
61
	mov dword[dll.load], edx
62
	ret
63
 
64
;input:
65
; ebx = coord x
66
; ecx = coord y
67
; edx = pixel color
68
; edi = pointer to buffer struct
69
align 4
70
draw_pixel:
71
	;cmp buf2d_bits,24
72
	;jne @f
73
	bt ebx,31
74
	jc @f
75
	bt ecx,31
76
	jc @f
77
	cmp ebx,buf2d_w
78
	jge @f
79
	cmp ecx,buf2d_h
80
	jge @f
81
	push esi
82
		mov esi,buf2d_w ;size x
83
		imul esi,ecx ;size_x*y
84
		add esi,ebx	 ;size_x*y+x
85
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
86
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
1684 IgorA 87
 
1535 IgorA 88
		mov word[esi],dx ;copy pixel color
89
		ror edx,16
90
		mov byte[esi+2],dl
91
		ror edx,16
92
	pop esi
93
	@@:
94
	ret
95
 
1684 IgorA 96
;input:
97
; ebx = coord x
98
; ecx = coord y
99
; edi = pointer to buffer struct
100
;output:
101
; eax = цвет точки
102
; в случае ошибки eax = 0xffffffff
103
align 4
104
get_pixel_24:
105
	mov eax,0xffffffff
106
 
107
	bt ebx,31
108
	jc @f
109
	bt ecx,31
110
	jc @f
111
	cmp ebx,buf2d_w
112
	jge @f
113
	cmp ecx,buf2d_h
114
	jge @f
115
	push esi
116
		mov esi,buf2d_w ;size x
117
		imul esi,ecx ;size_x*y
118
		add esi,ebx	 ;size_x*y+x
119
		lea esi,[esi+esi*2] ;(size_x*y+x)*3
120
		add esi,buf2d_data  ;ptr+(size_x*y+x)*3
121
 
122
		xor eax,eax
123
		mov ax,word[esi] ;copy pixel color
124
		ror eax,16
125
		mov al,byte[esi+2]
126
		ror eax,16
127
	pop esi
128
	@@:
129
	ret
130
 
131
 
1535 IgorA 132
;создание буфера
133
align 4
134
proc buf_create, buf_struc:dword
135
	pushad
136
	mov edi,dword[buf_struc]
137
	mov ecx,buf2d_w
138
	mov ebx,buf2d_h
139
	imul ecx,ebx
140
	cmp buf2d_bits,24
141
	jne @f
142
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
143
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
144
	@@:
145
	cmp buf2d_bits,32
146
	jne @f
147
		shl ecx,2 ; 32 bit = 4
148
	@@:
149
	invoke mem.alloc,ecx
150
	mov buf2d_data,eax
151
 
152
	stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
153
	popad
154
	ret
155
endp
156
 
157
;создание буфера на основе изображения rgb
158
align 4
159
proc buf_create_f_img, buf_struc:dword, rgb_data:dword
160
	pushad
161
	mov edi,dword[buf_struc]
162
	mov ecx,buf2d_w
163
	mov ebx,buf2d_h
164
	imul ecx,ebx
165
	cmp buf2d_bits,24
166
	jne @f
167
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
168
		;;;inc ecx ;запасной байт в конце буфера, что-бы не глючили некоторые функции на изображениях кратных 4К
169
	@@:
170
	cmp buf2d_bits,32
171
	jne @f
172
		shl ecx,2 ; 32 bit = 4
173
	@@:
174
	invoke mem.alloc,ecx
175
	mov buf2d_data,eax
176
 
177
	cmp buf2d_bits,24
178
	jne @f
179
		cld
180
		mov esi,[rgb_data]
181
		mov edi,eax ;eax=buf2d_data
182
		rep movsb ;копируем биты изображения в буфер
183
		jmp .end_create
184
	@@:
185
		stdcall buf_clear,edi,buf2d_color ;очистка буфера фоновым цветом
186
	.end_create:
187
	popad
188
	ret
189
endp
190
 
191
align 4
192
proc buf_clear, buf_struc:dword, color:dword ;очистка буфера заданым цветом
193
	pushad
194
	mov edi,dword[buf_struc]
195
 
196
	mov ecx,buf2d_w
197
	mov ebx,buf2d_h
198
	imul ecx,ebx
199
 
200
	cld
201
 
202
	cmp buf2d_bits,8
203
	jne .end_clear_8
204
		mov edi,buf2d_data
205
		mov al,byte[color]
206
		rep stosb
207
		jmp .end_clear_32
208
	.end_clear_8:
209
 
210
	cmp buf2d_bits,24
211
	jne .end_clear_24
212
		mov edi,buf2d_data
213
		mov eax,dword[color]
214
		mov ebx,eax
215
		shr ebx,16
216
		@@:
217
			stosw
218
			mov byte[edi],bl
219
			inc edi
220
			loop @b
221
		jmp .end_clear_32
222
	.end_clear_24:
223
 
224
	cmp buf2d_bits,32
225
	jne .end_clear_32
226
		mov edi,buf2d_data
227
		mov eax,dword[color]
228
		rep stosd
229
		;jmp .end_clear_32
230
	.end_clear_32:
231
	popad
232
	ret
233
endp
234
 
1538 IgorA 235
;функция для обрезания буферов 8 и 24 битных, по заданому цвету.
236
;параметр opt задается комбинацией констант:
237
; BUF2D_OPT_CROP_TOP - обрезка сверху
238
; BUF2D_OPT_CROP_LEFT - обрезка слева
239
; BUF2D_OPT_CROP_BOTTOM - обрезка снизу
240
; BUF2D_OPT_CROP_RIGHT - обрезка справа
1535 IgorA 241
align 4
1538 IgorA 242
proc buf_crop_color, buf_struc:dword, color:dword, opt:dword
1535 IgorA 243
locals
244
	crop_r dd ?
245
endl
246
	pushad
247
	mov edi,dword[buf_struc]
248
	cmp buf2d_bits,24
249
	jne .24end_f
250
 
251
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
252
	jae .24no_crop_bottom
253
		mov eax,dword[color]
254
		mov edx,eax ;ax = colors - r,g
255
		shr edx,16 ;dl = color - b
256
		mov ecx,buf2d_h
1555 IgorA 257
		cmp ecx,1
258
		jle .24no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 259
		mov ebx,buf2d_w
260
		imul ecx,ebx
261
		lea esi,[ecx+ecx*2] ;esi=3*ecx
262
		add esi,buf2d_data
263
		cld
264
		@@:
265
			sub esi,3
266
			cmp word[esi],ax
267
			jne @f
268
			cmp byte[esi+2],dl
269
			jne @f
270
			loop @b
271
		@@:
272
		lea ebx,[ebx+ebx*2]
273
		xor edx,edx
274
		mov eax,buf2d_h
275
		imul eax,ebx
276
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
277
		@@:
278
			add esi,ebx
279
			cmp esi,eax
280
			jge @f
281
			inc edx ;вычисляем число полных строк для обрезания
282
			loop @b
283
		@@:
284
		cmp edx,0
285
		je .24no_crop_bottom
286
			cmp edx,buf2d_h
287
			jge .24no_crop_bottom ;что-бы не получить пустой буфер
288
			sub buf2d_h,edx ;уменьшаем высоту буфера
289
			mov ecx,buf2d_h
290
			imul ecx,ebx ;ecx = новый размер изображения
291
			invoke mem.realloc,buf2d_data,ecx
292
			mov buf2d_data,eax ;на случай если изменился указатель на данные
293
	.24no_crop_bottom:
294
 
295
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
296
	jae .24no_crop_top
297
		mov eax,dword[color]
298
		mov edx,eax ;ax = colors - r,g
299
		shr edx,16 ;dl = color - b
300
		mov esi,buf2d_data
301
		mov ecx,buf2d_h
1555 IgorA 302
		cmp ecx,1
303
		jle .24no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 304
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
305
		mov ebx,buf2d_w
306
		imul ecx,ebx
307
		cld
308
		@@:
309
			cmp word[esi],ax
310
			jne @f
311
			cmp byte[esi+2],dl
312
			jne @f
313
			add esi,3
314
			loop @b
315
		@@:
316
		lea ebx,[ebx+ebx*2]
317
		xor edx,edx
318
		@@:
319
			sub esi,ebx
320
			cmp esi,buf2d_data
321
			jl @f
322
			inc edx ;вычисляем число полных строк для обрезания
323
			loop @b
324
		@@:
325
		cmp edx,0
326
		je .24no_crop_top
327
			xor eax,eax
328
			sub eax,edx
329
			mov ebx,buf2d_h
330
			sub ebx,edx
331
			stdcall buf_offset_h, edi, eax, edx, ebx ;сдвигаем изображение в буфере вверх (eax<0)
332
			sub buf2d_h,edx ;уменьшаем высоту буфера
333
			mov ecx,buf2d_h
334
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
335
			mov ebx,buf2d_w
336
			imul ecx,ebx
337
			lea ecx,[ecx+ecx*2]
338
			invoke mem.realloc,buf2d_data,ecx
339
			mov buf2d_data,eax ;на случай если изменился указатель на данные
340
	.24no_crop_top:
341
 
342
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
343
	jae .24no_crop_right
344
		mov eax,dword[color]
345
		mov edx,eax ;ax = colors - r,g
346
		shr edx,16 ;dl = color - b
347
		mov ebx,buf2d_w
1555 IgorA 348
		cmp ebx,1
349
		jle .24no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 350
		lea ebx,[ebx+ebx*2]
351
		mov esi,ebx
352
		imul esi,buf2d_h
353
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
354
		mov dword[crop_r],0
355
		cld
1538 IgorA 356
		.24found_beg_right:
1535 IgorA 357
		sub esi,3 ;двигаемся на 1-ну колонку влево
358
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
359
		@@:
360
			cmp word[esi],ax
1538 IgorA 361
			jne .24found_right
1535 IgorA 362
			cmp byte[esi+2],dl
1538 IgorA 363
			jne .24found_right
1535 IgorA 364
			sub esi,ebx ;прыгаем на верхнюю строку
365
			loop @b
366
		inc dword[crop_r]
367
 
368
		mov ecx,buf2d_w
369
		dec ecx ;1 колонка на запас
370
		cmp dword[crop_r],ecx
1538 IgorA 371
		jge .24found_right
1535 IgorA 372
 
373
		sub esi,3 ;двигаемся на 1-ну колонку влево
374
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
375
		@@:
376
			add esi,ebx ;прыгаем на нижнюю строку
377
			cmp word[esi],ax
1538 IgorA 378
			jne .24found_right
1535 IgorA 379
			cmp byte[esi+2],dl
1538 IgorA 380
			jne .24found_right
1535 IgorA 381
			loop @b
382
		inc dword[crop_r]
383
 
384
		mov ecx,buf2d_w
385
		dec ecx ;1 колонка на запас
386
		cmp dword[crop_r],ecx
1538 IgorA 387
		jl .24found_beg_right
1535 IgorA 388
 
1538 IgorA 389
		.24found_right:
1535 IgorA 390
		cmp dword[crop_r],0
391
		je .24no_crop_right
392
			mov ecx,buf2d_w
393
			sub ecx,dword[crop_r]
1538 IgorA 394
			stdcall img_rgb_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 395
			mov buf2d_w,ecx ;ставим новую ширину для буфера
396
			mov ebx,buf2d_h
397
			imul ecx,ebx
398
			lea ecx,[ecx+ecx*2]
399
			invoke mem.realloc,buf2d_data,ecx
400
			mov buf2d_data,eax ;на случай если изменился указатель на данные
401
	.24no_crop_right:
402
 
1538 IgorA 403
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
404
	jae .24no_crop_left
405
		mov eax,dword[color]
406
		mov edx,eax ;ax = colors - r,g
407
		shr edx,16 ;dl = color - b
408
		mov ebx,buf2d_w
1555 IgorA 409
		cmp ebx,1
410
		jle .24no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 411
		lea ebx,[ebx+ebx*2]
412
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
413
		mov dword[crop_r],0
414
		cld
415
		.24found_beg_left:
416
 
417
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
418
		@@:
419
			cmp word[esi],ax
420
			jne .24found_left
421
			cmp byte[esi+2],dl
422
			jne .24found_left
423
			add esi,ebx ;прыгаем на нижнюю строку
424
			loop @b
425
		inc dword[crop_r]
426
		add esi,3 ;двигаемся на 1-ну колонку вправо
427
 
428
		mov ecx,buf2d_w
429
		dec ecx ;1 колонка на запас
430
		cmp dword[crop_r],ecx
431
		jge .24found_left
432
 
433
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
434
		@@:
435
			sub esi,ebx ;прыгаем на верхнюю строку
436
			cmp word[esi],ax
437
			jne .24found_left
438
			cmp byte[esi+2],dl
439
			jne .24found_left
440
			loop @b
441
		inc dword[crop_r]
442
		add esi,3 ;двигаемся на 1-ну колонку вправо
443
 
444
		mov ecx,buf2d_w
445
		dec ecx ;1 колонка на запас
446
		cmp dword[crop_r],ecx
447
		jl .24found_beg_left
448
 
449
		.24found_left:
450
		cmp dword[crop_r],0
451
		je .24no_crop_left
452
			mov ecx,buf2d_w
453
			sub ecx,dword[crop_r]
454
			stdcall img_rgb_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
455
			mov buf2d_w,ecx ;ставим новую ширину для буфера
456
			mov ebx,buf2d_h
457
			imul ecx,ebx
458
			lea ecx,[ecx+ecx*2]
459
			invoke mem.realloc,buf2d_data,ecx
460
			mov buf2d_data,eax ;на случай если изменился указатель на данные
461
			mov eax,dword[crop_r]
462
			add buf2d_l,ax
463
	.24no_crop_left:
464
 
1535 IgorA 465
	.24end_f:
466
 
467
 
468
	cmp buf2d_bits,8
469
	jne .8end_f
470
 
471
	bt dword[opt],BUF2D_BIT_OPT_CROP_BOTTOM
472
	jae .8no_crop_bottom
473
		mov eax,dword[color]
474
		mov esi,buf2d_data
475
		mov ecx,buf2d_h
1555 IgorA 476
		cmp ecx,1
477
		jle .8no_crop_bottom ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 478
		mov ebx,buf2d_w
479
		imul ecx,ebx
480
		mov esi,ecx
481
		add esi,buf2d_data
482
		cld
483
		@@:
484
			dec esi
485
			cmp byte[esi],al
486
			jne @f
487
			loop @b
488
		@@:
489
		xor edx,edx
490
		mov eax,buf2d_h
491
		imul eax,ebx
492
		add eax,buf2d_data ;eax - указатель на конец буфера изображения
493
		@@:
494
			add esi,ebx
495
			cmp esi,eax
496
			jge @f
497
			inc edx
498
			loop @b
499
		@@:
500
		cmp edx,0
501
		je .8no_crop_bottom
502
			cmp edx,buf2d_h
503
			jge .8no_crop_bottom ;что-бы не получить пустой буфер
504
			sub buf2d_h,edx ;уменьшаем высоту буфера
505
			mov ecx,buf2d_h
506
			imul ecx,ebx ;ecx = новый размер изображения
507
			invoke mem.realloc,buf2d_data,ecx
508
			mov buf2d_data,eax ;на случай если изменился указатель на данные
509
	.8no_crop_bottom:
510
 
511
	bt dword[opt],BUF2D_BIT_OPT_CROP_TOP
512
	jae .8no_crop_top
513
		mov eax,dword[color]
514
		mov esi,buf2d_data
515
		mov ecx,buf2d_h
1555 IgorA 516
		cmp ecx,1
517
		jle .8no_crop_top ;проверяем на случай если высота буфера 1 пиксель
1535 IgorA 518
		dec ecx ;при обрезании должна остаться минимум 1-на строка пикселей
519
		mov ebx,buf2d_w
520
		imul ecx,ebx
521
		cld
522
		@@:
523
			cmp byte[esi],al
524
			jne @f
525
			inc esi
526
			loop @b
527
		@@:
528
		xor edx,edx
529
		@@:
530
			sub esi,ebx
531
			cmp esi,buf2d_data
532
			jl @f
533
			inc edx
534
			loop @b
535
		@@:
536
		cmp edx,0
537
		je .8no_crop_top
538
			xor eax,eax
539
			sub eax,edx
540
			mov ebx,buf2d_h
541
			sub ebx,edx
542
			stdcall buf_offset_h, edi, eax, edx, ebx
543
			mov ecx,buf2d_h
544
			sub ecx,edx
545
			mov buf2d_h,ecx ;уменьшаем высоту буфера
546
			add buf2d_t,dx ;сдвигаем отступ вниз, на число обрезанных строк
547
			mov ebx,buf2d_w
548
			imul ecx,ebx
549
			invoke mem.realloc,buf2d_data,ecx
550
			mov buf2d_data,eax ;на случай если изменился указатель на данные
551
	.8no_crop_top:
552
 
553
	bt dword[opt],BUF2D_BIT_OPT_CROP_RIGHT
554
	jae .8no_crop_right
555
		mov eax,dword[color]
556
		mov ebx,buf2d_w
1555 IgorA 557
		cmp ebx,1
558
		jle .8no_crop_right ;на случай если ширина буфера 1 пиксель
1535 IgorA 559
		mov esi,ebx
560
		imul esi,buf2d_h
561
		add esi,buf2d_data ;esi - указатель на конец буфера изображения
562
		xor edx,edx
563
		cld
564
 
565
		.8found_beg:
566
		dec esi ;двигаемся на 1-ну колонку влево
567
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
568
		@@:
569
			cmp byte[esi],al
570
			jne .8found
571
			sub esi,ebx ;прыгаем на верхнюю строку
572
			loop @b
573
		inc edx
574
		mov ecx,buf2d_w
575
		dec ecx ;1 колонка на запас
576
		cmp edx,ecx
577
		jge .8found
578
 
579
		dec esi ;двигаемся на 1-ну колонку влево
580
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
581
		@@:
582
			add esi,ebx ;прыгаем на нижнюю строку
583
			cmp byte[esi],al
584
			jne .8found
585
			loop @b
586
		inc edx
587
 
588
		mov ecx,buf2d_w
589
		dec ecx ;1 колонка на запас
590
		cmp edx,ecx
591
		jl .8found_beg
592
 
593
		.8found:
594
		cmp edx,0
595
		je .8no_crop_right
596
			mov ecx,buf2d_w
597
			sub ecx,edx
1538 IgorA 598
			stdcall img_gray_crop_r, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
1535 IgorA 599
			mov buf2d_w,ecx ;ставим новую ширину для буфера
600
			mov ebx,buf2d_h
601
			imul ecx,ebx
602
			invoke mem.realloc,buf2d_data,ecx
603
			mov buf2d_data,eax ;на случай если изменился указатель на данные
604
	.8no_crop_right:
605
 
1538 IgorA 606
	bt dword[opt],BUF2D_BIT_OPT_CROP_LEFT
607
	jae .8no_crop_left
608
		mov eax,dword[color]
609
		mov ebx,buf2d_w
1555 IgorA 610
		cmp ebx,1
611
		jle .8no_crop_left ;на случай если ширина буфера 1 пиксель
1538 IgorA 612
		mov esi,buf2d_data ;esi - указатель на начоло буфера изображения
613
		mov edx,0
614
		cld
615
		.8found_beg_left:
616
 
617
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
618
		@@:
619
			cmp word[esi],ax
620
			jne .8found_left
621
			add esi,ebx ;прыгаем на нижнюю строку
622
			loop @b
623
		inc edx
624
		inc esi ;двигаемся на 1-ну колонку вправо
625
 
626
		mov ecx,buf2d_w
627
		dec ecx ;1 колонка на запас
628
		cmp edx,ecx
629
		jge .8found_left
630
 
631
		mov ecx,buf2d_h ;восстановление ecx для нового цикла
632
		@@:
633
			sub esi,ebx ;прыгаем на верхнюю строку
634
			cmp word[esi],ax
635
			jne .8found_left
636
			loop @b
637
		inc edx
638
		inc esi ;двигаемся на 1-ну колонку вправо
639
 
640
		mov ecx,buf2d_w
641
		dec ecx ;1 колонка на запас
642
		cmp edx,ecx
643
		jl .8found_beg_left
644
 
645
		.8found_left:
646
		cmp edx,0
647
		je .8no_crop_left
648
			mov ecx,buf2d_w
649
			sub ecx,edx
650
			stdcall img_gray_crop_l, buf2d_data, buf2d_w, ecx, buf2d_h ;обрезаем буфер, по новому размеру
651
			mov buf2d_w,ecx ;ставим новую ширину для буфера
652
			mov ebx,buf2d_h
653
			imul ecx,ebx
654
			invoke mem.realloc,buf2d_data,ecx
655
			mov buf2d_data,eax ;на случай если изменился указатель на данные
656
			mov eax,edx
657
			add buf2d_l,ax
658
	.8no_crop_left:
659
 
1535 IgorA 660
	.8end_f:
661
 
662
	popad
663
	ret
664
endp
665
 
1538 IgorA 666
;обрезаем цветное изображение с правой стороны
1535 IgorA 667
;input:
668
;data_rgb - pointer to rgb data
669
;size_w_old - width img in pixels
670
;size_w_new - new width img in pixels
671
;size_h - height img in pixels
672
align 4
1538 IgorA 673
proc img_rgb_crop_r, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 674
	pushad
675
	mov eax, dword[size_w_old]
676
	lea eax, dword[eax+eax*2] ;eax = width(old) * 3(rgb)
677
	mov ebx, dword[size_w_new]
678
	lea ebx, dword[ebx+ebx*2] ;ebx = width(new) * 3(rgb)
679
	mov edx, dword[size_h]
680
	mov edi, dword[data_rgb] ;edi - получает данные
681
	mov esi, edi
682
	add edi, ebx
683
	add esi, eax
684
	cld
685
	@@:
686
		dec edx ;уменьшаем счетчик оставшихся строк на 1
687
		cmp edx,0
688
		jle @f
689
		mov ecx, ebx
690
		rep movsb ;перенос (копирование) строки пикселей
691
		add esi,eax ;переход на новую строчку изображения
692
		sub esi,ebx
693
		jmp @b
694
	@@:
695
	popad
696
	ret
697
endp
698
 
1538 IgorA 699
;обрезаем серое изображение с правой стороны
1535 IgorA 700
;input:
701
;data_gray - pointer to gray data
702
;size_w_old - width img in pixels
703
;size_w_new - new width img in pixels
704
;size_h - height img in pixels
705
align 4
1538 IgorA 706
proc img_gray_crop_r, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
1535 IgorA 707
	pushad
708
	mov eax, dword[size_w_old]
709
	mov ebx, dword[size_w_new]
710
	mov edx, dword[size_h]
711
	mov edi, dword[data_gray] ;edi - получает данные
712
	mov esi, edi
713
	add edi, ebx
714
	add esi, eax
715
	cld
716
	@@:
717
		dec edx ;уменьшаем счетчик оставшихся строк на 1
718
		cmp edx,0
719
		jle @f
720
		mov ecx, ebx
721
		rep movsb ;перенос (копирование) строки пикселей
722
		add esi,eax ;переход на новую строчку изображения
723
		sub esi,ebx
724
		jmp @b
725
	@@:
726
	popad
727
	ret
728
endp
729
 
1538 IgorA 730
;обрезаем цветное изображение с левой стороны
731
;input:
732
;data_rgb - pointer to rgb data
733
;size_w_old - width img in pixels
734
;size_w_new - new width img in pixels
735
;size_h - height img in pixels
736
align 4
737
proc img_rgb_crop_l, data_rgb:dword, size_w_old:dword, size_w_new:dword, size_h:dword
738
	pushad
739
	mov edi,dword[data_rgb]
740
	mov esi,edi
741
	mov eax,dword[size_w_old]
742
	mov ebx,dword[size_w_new]
743
	cmp eax,ebx
744
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
745
		lea eax,[eax+eax*2]
746
		lea ebx,[ebx+ebx*2]
747
		sub eax,ebx
748
		mov edx,dword[size_h] ;высота изображения
749
		cld
750
		@@:
751
			add esi,eax
752
			mov ecx,ebx
753
			rep movsb
754
			dec edx
755
			cmp edx,0
756
			jg @b
757
	.end_f:
758
	popad
759
	ret
760
endp
761
 
762
;обрезаем серое изображение с левой стороны
763
;input:
764
;data_gray - pointer to gray data
765
;size_w_old - width img in pixels
766
;size_w_new - new width img in pixels
767
;size_h - height img in pixels
768
align 4
769
proc img_gray_crop_l, data_gray:dword, size_w_old:dword, size_w_new:dword, size_h:dword
770
	pushad
771
	mov edi,dword[data_gray]
772
	mov esi,edi
773
	mov eax,dword[size_w_old]
774
	mov ebx,dword[size_w_new]
775
	cmp eax,ebx
776
	jle .end_f ;старый размер изображения не может быть меньше нового (при условии обрезания картинки)
777
		sub eax,ebx
778
		mov edx,dword[size_h] ;высота изображения
779
		cld
780
		@@:
781
			add esi,eax
782
			mov ecx,ebx
783
			rep movsb
784
			dec edx
785
			cmp edx,0
786
			jg @b
787
	.end_f:
788
	popad
789
	ret
790
endp
791
 
1535 IgorA 792
;hoffs - колличество пикселей на котрые поднимается/опускается изображение
793
;img_t - высота, с которой начинается двигающаяся часть изображения
794
align 4
795
proc buf_offset_h, buf_struc:dword, hoffs:dword, img_t:dword, img_h:dword ;сдвигает изображение по высоте
796
	pushad
797
	mov edi,dword[buf_struc]
798
	cmp buf2d_bits,24
799
	jne .end_move_24
800
 
801
	mov eax,[hoffs]
802
	cmp eax,0
803
	je .end_move_24
804
		mov ebx,buf2d_w
805
		mov edx,dword[img_t]
806
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
807
			cmp ecx,buf2d_h
808
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
809
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
810
			lea ecx,[ecx+ecx*2]
811
		imul ebx,edx
812
		lea ebx,[ebx+ebx*2]
813
		mov esi,buf2d_data
814
		add esi,ebx
815
 
816
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
817
		mov ebx,buf2d_w
818
		imul ebx,edx
819
		lea ebx,[ebx+ebx*2]
820
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
821
		add edi,ebx
822
 
823
		cmp eax,0
824
		jg .move_down_24
825
			;двигаем изображение вверх
826
			cld
827
			rep movsb
828
			jmp .end_f
829
		.move_down_24:
830
			;двигаем изображение вниз
831
			add esi,ecx
832
			dec esi
833
			add edi,ecx
834
			dec edi
835
			std
836
			rep movsb
837
			jmp .end_f
838
	.end_move_24:
839
 
840
;stdcall print_err,sz_buf2d_offset_h,txt_err_n24b
841
 
842
	cmp buf2d_bits,8
843
	jne .end_move_8
844
 
845
	mov eax,[hoffs]
846
	cmp eax,0
847
	je .end_move_8
848
		;двигаем изображение вверх
849
		mov ebx,buf2d_w
850
		mov edx,dword[img_t]
851
			mov ecx,dword[img_h] ;ecx - высота сдвигаемых данных
852
			cmp ecx,buf2d_h
853
			jge .end_f ;ошибочное условие, высота изображения меньше чем высота сдвигаемого изображения
854
			imul ecx,ebx ;ecx - колличество пикселей в сдвигаемых данных
855
		imul ebx,edx
856
		mov esi,buf2d_data
857
		add esi,ebx
858
 
859
		add edx,eax ;edx = img_t+hoffs (hoffs<0)
860
		mov ebx,buf2d_w
861
		imul ebx,edx
862
		mov edi,buf2d_data ;позиция, куда будет двигаться изображение
863
		add edi,ebx
864
 
865
		cmp eax,0
866
		jg .move_down_8
867
			cld
868
			rep movsb
869
			jmp .end_f
870
		.move_down_8:
871
			;двигаем изображение вниз
872
			add esi,ecx
873
			dec esi
874
			add edi,ecx
875
			dec edi
876
			std
877
			rep movsb
878
			jmp .end_f
879
	.end_move_8:
880
 
881
	.end_f:
882
	popad
883
	ret
884
endp
885
 
886
 
887
align 4
888
proc buf_draw_buf, buf_struc:dword
889
	pushad
890
	mov edi,dword[buf_struc]
891
	cmp buf2d_bits,24
892
	jne .error
893
		mov eax,7
894
		mov ebx,buf2d_data
895
 
896
		mov ecx,buf2d_w
897
		ror ecx,16
898
		mov edx,buf2d_h
899
		mov cx,dx
900
 
901
		mov edx,buf2d_size_lt
902
		ror edx,16
903
		int 0x40
904
		jmp .end_draw_24
905
	.error:
906
		stdcall print_err,sz_buf2d_draw,txt_err_n24b
907
	.end_draw_24:
908
	popad
909
	ret
910
endp
911
 
912
align 4
913
proc buf_delete, buf_struc:dword
2136 IgorA 914
	push eax edi
1535 IgorA 915
	mov edi,dword[buf_struc]
916
	invoke mem.free,buf2d_data
2136 IgorA 917
	pop edi eax
1535 IgorA 918
	ret
919
endp
920
 
921
align 4
2136 IgorA 922
proc buf_resize, buf_struc:dword, new_w:dword, new_h:dword
923
	pushad
924
	mov edi,dword[buf_struc]
925
	cmp buf2d_bits,24
926
	jne .24bit
927
		mov eax,dword[new_w]
928
		cmp eax,1
929
		jl @f
930
			mov buf2d_w,eax
931
		@@:
932
		mov ecx,buf2d_w
933
		mov eax,dword[new_h]
934
		cmp eax,1
935
		jl @f
936
			mov buf2d_h,eax
937
		@@:
938
		mov ebx,buf2d_h
939
		imul ecx,ebx
940
		lea ecx,[ecx+ecx*2] ; 24 bit = 3
941
		invoke mem.realloc,buf2d_data,ecx ;изменяем память занимаемую буфером
942
		mov buf2d_data,eax ;на случай если изменился указатель на данные
943
	.24bit:
944
	popad
945
	ret
946
endp
947
 
948
align 4
1535 IgorA 949
proc buf_line_brs, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, coord_y1:dword, color:dword
950
locals
951
	loc_1 dd ?
952
	loc_2 dd ?
953
	napravl db ?
954
endl
955
	pushad
956
		mov edx,dword[color]
957
 
958
		mov eax,dword[coord_x1]
959
		sub eax,dword[coord_x0]
960
		bt eax,31
961
		jae @f
962
			neg eax
963
			inc eax
964
		@@:
965
		mov ebx,dword[coord_y1]
966
		sub ebx,dword[coord_y0]
967
		bt ebx,31
968
		jae @f
969
			neg ebx
970
			inc ebx
971
		@@:
972
 
973
		mov [napravl],byte 0 ;bool steep=false
974
		cmp eax,ebx
975
		jle @f
976
			mov [napravl],byte 1 ;bool steep=true
977
			swap dword[coord_x0],dword[coord_y0] ;swap(x0, y0);
978
			swap dword[coord_x1],dword[coord_y1] ;swap(x1, y1);
979
		@@:
980
		mov eax,dword[coord_y0] ;x0
981
		cmp eax,dword[coord_y1] ;if(x0>x1)
982
		jle @f
983
			swap dword[coord_y0],dword[coord_y1] ;swap(x0, x1);
984
			swap dword[coord_x0],dword[coord_x1] ;swap(y0, y1);
985
		@@:
986
 
987
; int deltax esi
988
; int deltay edi
989
; int error  ebp-6
990
; int ystep  ebp-8
991
 
992
		mov eax,dword[coord_y0]
993
		mov esi,dword[coord_y1]
994
		sub esi,eax ;deltax = y1-y0
995
		mov ebx,esi
996
		shr ebx,1
997
		mov [loc_1],ebx ;error = deltax/2
998
 
999
		mov eax,dword[coord_x0]
1000
		mov edi,dword[coord_x1]
1001
		mov [loc_2],dword -1 ;ystep = -1
1002
		cmp eax,edi ;if (x0
1003
		jge @f
1004
			mov [loc_2],dword 1 ;ystep = 1
1005
		@@:
1006
		sub edi,eax ;x1-x0
1007
 
1008
		bts edi,31
1009
		jae @f
1010
			neg edi
1011
			inc edi
1012
		@@:
1013
		and edi,0x7fffffff ;deltay = abs(x1-x0)
1014
 
1015
		mov eax,edi
1016
		mov edi,[buf_struc]
1017
		cmp buf2d_bits,24
1018
		jne .coord_end
1019
 
1020
		cmp [napravl],0
1021
		jne .coord_yx
1022
			mov ebx,dword[coord_x0]
1023
			mov ecx,dword[coord_y0]
1024
 
1025
			@@: ;for (x=x0 ; x
1026
				cmp ecx,dword[coord_y1]
1027
				jg @f ;jge ???
1028
				call draw_pixel
1029
 
1030
				sub dword[loc_1],eax ;error -= deltay
1031
				cmp dword[loc_1],0 ;if(error<0)
1032
				jge .if0
1033
					add ebx,[loc_2] ;y += ystep
1034
					add [loc_1],esi ;error += deltax
1035
				.if0:
1036
				inc ecx
1037
				jmp @b
1038
			@@:
1039
			jmp .coord_end
1040
		.coord_yx:
1041
			mov ebx,dword[coord_y0]
1042
			mov ecx,dword[coord_x0]
1043
 
1044
			@@: ;for (x=x0 ; x
1045
				cmp ebx,dword[coord_y1]
1046
				jg @f ;jge ???
1047
				call draw_pixel
1048
 
1049
				sub dword[loc_1],eax ;error -= deltay
1050
				cmp dword[loc_1],0 ;if(error<0)
1051
				jge .if1
1052
					add ecx,[loc_2] ;y += ystep
1053
					add [loc_1],esi ;error += deltax
1054
				.if1:
1055
				inc ebx
1056
				jmp @b
1057
			@@:
1058
	.coord_end:
1059
	popad
1060
	ret
1061
endp
1062
 
1653 IgorA 1063
;рисование горизонтальной линии, потому нет параметра coord_y1
1535 IgorA 1064
align 4
1634 IgorA 1065
proc buf_line_h, buf_struc:dword, coord_x0:dword, coord_y0:dword, coord_x1:dword, color:dword
1066
	pushad
1067
		mov edi,[buf_struc]
1068
		cmp buf2d_bits,24
1684 IgorA 1069
		jne .end24
1634 IgorA 1070
 
2177 IgorA 1071
		mov ecx,dword[coord_y0]
1072
		bt ecx,31
1073
		jc .end24 ;если координата y0 отрицательная
1074
		cmp ecx,buf2d_h
1075
		jge .end24 ;если координата y0 больше высоты буфера
1076
 
1634 IgorA 1077
		mov ebx,dword[coord_x0]
1078
		mov esi,dword[coord_x1]
1717 IgorA 1079
		cmp ebx,esi
1080
		jle @f
1081
			xchg ebx,esi ;если x0 > x1 то меняем местами x0 и x1
2177 IgorA 1082
		@@:
2185 IgorA 1083
		bt ebx,31
1084
		jae @f
1085
			;если координата x0 отрицательная
1086
			xor ebx,ebx
1087
		@@:
2177 IgorA 1088
		cmp esi,buf2d_w
1089
		jl @f
2185 IgorA 1090
			;если координата x0 больше ширины буфера
2177 IgorA 1091
			mov esi,buf2d_w
1092
			;dec esi
1093
		@@:
2185 IgorA 1094
		cmp ebx,esi
1095
		jge .end24 ;если x0 >= x1 может возникнуть когда обе координаты x0, x1 находились за одним из пределов буфера
1717 IgorA 1096
 
2177 IgorA 1097
		;в eax вычисляем начало 1-й точки линии в буфере изображения
1098
		mov eax,buf2d_w ;size x
1099
		imul eax,ecx ;size_x*y
1100
		add eax,ebx	 ;size_x*y+x
1101
		lea eax,[eax+eax*2] ;(size_x*y+x)*3
1102
		add eax,buf2d_data  ;ptr+(size_x*y+x)*3
1103
 
2185 IgorA 1104
		mov ecx,esi
1105
		sub ecx,ebx ;в ecx колличество точек линии выводимых в буфер
2177 IgorA 1106
		mov edx,dword[color]
2185 IgorA 1107
		mov ebx,edx ;координата x0 в ebx уже не нужна
1108
		ror edx,16 ;поворачиваем регистр что бы 3-й байт попал в dl
1109
		cld
1717 IgorA 1110
		@@: ;цикл по оси x от x0 до x1
2185 IgorA 1111
			mov word[eax],bx ;copy pixel color
1112
			mov byte[eax+2],dl
1113
			add eax,3
1114
			loop @b
1684 IgorA 1115
		.end24:
1634 IgorA 1116
	popad
1117
	ret
1118
endp
1119
 
1120
align 4
1121
proc buf_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1122
pushad
1123
	mov edi,[buf_struc]
1124
	cmp buf2d_bits,24
1125
	jne .coord_end
1126
 
1127
		mov eax,[coord_x]
1128
		mov ebx,[coord_y]
1129
		mov ecx,[w]
1642 IgorA 1130
		cmp ecx,1
1131
		jl .coord_end
1634 IgorA 1132
		add ecx,eax
1642 IgorA 1133
		dec ecx
1634 IgorA 1134
		mov edx,[h]
1642 IgorA 1135
		cmp edx,1
1136
		jl .coord_end
1137
 
1634 IgorA 1138
		add edx,ebx
1642 IgorA 1139
		dec edx
1634 IgorA 1140
		mov esi,dword[color]
1141
		stdcall buf_line_h, edi, eax, ebx, ecx, esi ;линия -
1142
		stdcall buf_line_brs, edi, eax, ebx, eax, edx, esi ;линия |
1143
		stdcall buf_line_h, edi, eax, edx, ecx, esi ;линия -
1144
		stdcall buf_line_brs, edi, ecx, ebx, ecx, edx, esi ;линия |
1145
	.coord_end:
1146
popad
1147
	ret
1148
endp
1149
 
1150
align 4
1642 IgorA 1151
proc buf_filled_rect_by_size, buf_struc:dword, coord_x:dword,coord_y:dword,w:dword,h:dword, color:dword
1152
pushad
1153
	mov edi,[buf_struc]
1154
	cmp buf2d_bits,24
1155
	jne .coord_end
1156
		mov eax,[coord_x]
1157
		mov ebx,[coord_y]
1158
		mov edx,[w]
1159
		add edx,eax
1160
		mov ecx,[h]
1717 IgorA 1161
		cmp ecx,1 ;сравнение с минимально возможной высотой
1162
		jl .coord_end ;если высота меньше 1-го пикселя
1642 IgorA 1163
		mov esi,dword[color]
1164
		cld
1165
		@@:
1166
			stdcall buf_line_h, edi, eax, ebx, edx, esi ;линия -
1167
			inc ebx
1168
			loop @b
1169
	.coord_end:
1170
popad
1171
	ret
1172
endp
1173
 
1174
align 4
1535 IgorA 1175
proc buf_circle, buf_struc:dword, coord_x:dword, coord_y:dword, r:dword, color:dword
1176
locals
1177
	po_x dd ?
1178
	po_y dd ?
1179
endl
1180
	pushad
1181
	mov edi,dword[buf_struc]
1182
	cmp buf2d_bits,24
1183
	jne .error
1184
		mov edx,dword[color]
1185
 
1186
		finit
1187
		fild dword[coord_x]
1188
		fild dword[coord_y]
1189
		fild dword[r]
1190
		fldz ;px=0
1191
		fld st1 ;py=r
1192
 
1193
		fldpi
1194
		fmul st0,st3
1195
		fistp dword[po_x]
1196
		mov esi,dword[po_x] ;esi=pi*r
1197
		shl esi,1 ;esi=2*pi*r
1198
 
1199
		;st0 = py
1200
		;st1 = px
1201
		;st2 = r
1202
		;st3 = y
1203
		;st4 = x
1204
 
1205
		@@:
1206
			;Point(px + x, y - py)
1207
			fld st1 ;st0=px
1208
			fadd st0,st5 ;st0=px+x
1209
			fistp dword[po_x]
1210
			mov ebx,dword[po_x]
1211
			fld st3 ;st0=y
1212
			fsub st0,st1 ;st0=y-py
1213
			fistp dword[po_y]
1214
			mov ecx,dword[po_y]
1215
			call draw_pixel
1216
			;px += py/r
1217
			fld st0 ;st0=py
1218
			fdiv st0,st3 ;st0=py/r
1219
			faddp st2,st0 ;st3+=st0
1220
			;py -= px/r
1221
			fld st1 ;st0=px
1222
			fdiv st0,st3 ;st0=px/r
1223
			fsubp st1,st0 ;st2-=st0
1224
 
1225
			dec esi
1226
			cmp esi,0
1227
			jge @b
1228
		jmp .exit_fun
1229
	.error:
1230
		stdcall print_err,sz_buf2d_circle,txt_err_n24b
1231
	.exit_fun:
1232
 
1233
	popad
1234
	ret
1235
endp
1236
 
1684 IgorA 1237
;функция для заливки области выбранным цветом
1535 IgorA 1238
align 4
1684 IgorA 1239
proc buf_flood_fill, buf_struc:dword, coord_x:dword, coord_y:dword, mode:dword, color_f:dword, color_b:dword
1240
	pushad
1241
		mov edi,[buf_struc]
1242
		cmp buf2d_bits,24
1243
		jne .end24
1244
 
1245
			mov ebx,dword[coord_x]
1246
			mov ecx,dword[coord_y]
1247
			mov edx,dword[color_f]
1248
			mov esi,dword[color_b]
1249
 
1250
			cmp dword[mode],1 ;в зависимости от 'mode' определяем каким алгоритмом будем пользоваться
1251
			je @f
1252
				call buf_flood_fill_recurs_0 ;заливаем до пикселей цвета esi
1253
				jmp .end24
1254
			@@:
1255
				call buf_flood_fill_recurs_1 ;заливаем пиксели имеющие цвет esi
1256
 
1257
		.end24:
1258
	popad
1259
	ret
1260
endp
1261
 
1262
;input:
1263
; ebx = coord_x
1264
; ecx = coord_y
1265
; edx = цвет заливки
1266
; esi = цвет границы, до которой будет ити заливка
1267
; edi = buf_struc
1268
;output:
1269
; eax = портится
1270
align 4
1271
buf_flood_fill_recurs_0:
1272
	call get_pixel_24
1273
	cmp eax,0xffffffff ;if error coords
1274
	je .end_fun
1275
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1276
	je .end_fun
1277
 
1278
		call draw_pixel
1279
 
1280
		dec ebx
1281
		call get_pixel_24
1282
		cmp eax,esi
1283
		je @f
1284
			call buf_flood_fill_recurs_0
1285
		@@:
1286
		inc ebx
1287
 
1288
 
1289
		inc ebx
1290
		call get_pixel_24
1291
		cmp eax,esi
1292
		je @f
1293
			call buf_flood_fill_recurs_0
1294
		@@:
1295
		dec ebx
1296
 
1297
		dec ecx
1298
		call get_pixel_24
1299
		cmp eax,esi
1300
		je @f
1301
			call buf_flood_fill_recurs_0
1302
		@@:
1303
		inc ecx
1304
 
1305
		inc ecx
1306
		call get_pixel_24
1307
		cmp eax,esi
1308
		je @f
1309
			call buf_flood_fill_recurs_0
1310
		@@:
1311
		dec ecx
1312
 
1313
	.end_fun:
1314
	ret
1315
 
1316
;input:
1317
; ebx = coord_x
1318
; ecx = coord_y
1319
; edx = цвет заливки
1320
; esi = цвет пикселей, по которым будет ити заливка
1321
; edi = buf_struc
1322
;output:
1323
; eax = портится
1324
align 4
1325
buf_flood_fill_recurs_1:
1326
	call get_pixel_24
1327
	cmp eax,0xffffffff ;if error coords
1328
	je .end_fun
1329
	cmp eax,edx ;если цвет пикселя совпал с цветом заливки, значит заливка в этой области уже была сделана
1330
	je .end_fun
1331
	cmp eax,esi ;если цвет пикселя не совпал с заливаемым цветом заливки, то прекращаем заливку
1332
	jne .end_fun
1333
 
1334
		call draw_pixel
1335
 
1336
		dec ebx
1337
		call get_pixel_24
1338
		cmp eax,esi
1339
		jne @f
1340
			call buf_flood_fill_recurs_1
1341
		@@:
1342
		inc ebx
1343
 
1344
 
1345
		inc ebx
1346
		call get_pixel_24
1347
		cmp eax,esi
1348
		jne @f
1349
			call buf_flood_fill_recurs_1
1350
		@@:
1351
		dec ebx
1352
 
1353
		dec ecx
1354
		call get_pixel_24
1355
		cmp eax,esi
1356
		jne @f
1357
			call buf_flood_fill_recurs_1
1358
		@@:
1359
		inc ecx
1360
 
1361
		inc ecx
1362
		call get_pixel_24
1363
		cmp eax,esi
1364
		jne @f
1365
			call buf_flood_fill_recurs_1
1366
		@@:
1367
		dec ecx
1368
 
1369
	.end_fun:
1370
	ret
1371
 
1910 IgorA 1372
;функция для рисования точки
1684 IgorA 1373
align 4
1910 IgorA 1374
proc buf_set_pixel, buf_struc:dword, coord_x:dword, coord_y:dword, color:dword
1375
	pushad
1376
		mov edi,[buf_struc]
1377
		cmp buf2d_bits,24
1378
		jne .end24
1379
			mov ebx,dword[coord_x]
1380
			mov ecx,dword[coord_y]
1381
			mov edx,dword[color]
1382
			call draw_pixel
1383
		.end24:
1384
	popad
1385
	ret
1386
endp
1387
 
1388
align 4
1535 IgorA 1389
proc buf_img_wdiv2, buf_struc:dword
1390
	pushad
1391
	mov edi,dword[buf_struc]
1392
	cmp buf2d_bits,24
1393
	jne .end_draw_24
1394
		mov eax,buf2d_w
1395
		mov ecx,buf2d_h
1396
		imul ecx,eax
1397
		stdcall img_rgb24_wdiv2, buf2d_data,ecx
1398
	.end_draw_24:
1399
	popad
1400
	ret
1401
endp
1402
 
1403
;input:
1404
;data_rgb - pointer to rgb data
1405
;size - count img pixels (size img data / 3(rgb) )
1406
align 4
1407
proc img_rgb24_wdiv2 data_rgb:dword, size:dword
1408
  ;push eax ebx ecx edx
1409
  mov eax,dword[data_rgb]
1410
  mov ecx,dword[size] ;ecx = size
1411
  lea ecx,[ecx+ecx*2]
1412
  cld
1413
  @@: ;затемнение цвета пикселей
1538 IgorA 1414
		shr byte[eax],1
1415
		inc eax
1416
		loop @b
1535 IgorA 1417
 
1418
  mov eax,dword[data_rgb]
1419
  mov ecx,dword[size] ;ecx = size
1420
  shr ecx,1
1421
  @@: ;сложение цветов пикселей
1538 IgorA 1422
		mov bx,word[eax+3] ;копируем цвет соседнего пикселя
1423
		add word[eax],bx
1424
		mov bl,byte[eax+5] ;копируем цвет соседнего пикселя
1425
		add byte[eax+2],bl
1426
		add eax,6 ;=2*3
1427
		loop @b
1535 IgorA 1428
 
1429
  mov eax,dword[data_rgb]
1430
  add eax,3
1431
  mov ebx,eax
1432
  add ebx,3
1433
  mov ecx,dword[size] ;ecx = size
1434
  shr ecx,1
1435
  dec ecx ;лишний пиксель
1436
  @@: ;поджатие пикселей
1538 IgorA 1437
		mov edx,dword[ebx]
1438
		mov word[eax],dx
1439
		shr edx,16
1440
		mov byte[eax+2],dl
1535 IgorA 1441
 
1538 IgorA 1442
		add eax,3
1443
		add ebx,6
1444
		loop @b
1535 IgorA 1445
  ;pop edx ecx ebx eax
1446
  ret
1447
endp
1448
 
1449
align 4
1450
proc buf_img_hdiv2, buf_struc:dword
1451
	pushad
1452
	mov edi,dword[buf_struc]
1453
	cmp buf2d_bits,24
1454
	jne .end_draw_24
1455
		mov eax,buf2d_w
1456
		mov ecx,buf2d_h
1457
		imul ecx,eax
1458
		stdcall img_rgb24_hdiv2, buf2d_data,ecx,eax
1459
	.end_draw_24:
1460
	popad
1461
	ret
1462
endp
1463
 
1464
;input:
1465
;data_rgb - pointer to rgb data
1466
;size - count img pixels (size img data / 3(rgb) )
1467
;size_w - width img in pixels
1468
align 4
1469
proc img_rgb24_hdiv2, data_rgb:dword, size:dword, size_w:dword
1470
  ;pushad
1471
 
1472
  mov eax,dword[data_rgb] ;eax =
1473
  mov ecx,dword[size]	  ;ecx = size
1474
  lea ecx,[ecx+ecx*2]
1475
  cld
1476
  @@: ;затемнение цвета пикселей
1477
    shr byte[eax],1
1478
    inc eax
1479
    loop @b
1480
 
1481
  mov eax,dword[data_rgb] ;eax =
1482
  mov edi,dword[size_w]
1483
  lea esi,[edi+edi*2] ;esi = width*3(rgb)
1484
  mov ebx,esi
1485
  add ebx,eax
1486
  mov ecx,dword[size]  ;ecx = size
1487
  shr ecx,1
1488
  xor edi,edi
1489
  @@: ;сложение цветов пикселей
1490
    mov dx,word[ebx] ;копируем цвет нижнего пикселя
1491
    add word[eax],dx
1492
    mov dl,byte[ebx+2] ;копируем цвет нижнего пикселя
1493
    add byte[eax+2],dl
1494
 
1495
    add eax,3
1496
    add ebx,3
1497
    inc edi
1498
    cmp edi,dword[size_w]
1499
    jl .old_line
1500
      add eax,esi
1501
      add ebx,esi
1502
      xor edi,edi
1503
    .old_line:
1504
    loop @b
1505
 
1506
 
1507
  mov eax,dword[data_rgb] ;eax =
1508
  add eax,esi ;esi = width*3(rgb)
1509
  mov ebx,esi
1510
  add ebx,eax
1511
  mov ecx,dword[size] ;ecx = size
1512
  shr ecx,1
1513
  sub ecx,dword[size_w] ;лишняя строка пикселей
1514
  xor edi,edi
1515
  @@: ;поджатие пикселей
1516
    mov edx,dword[ebx] ;копируем цвет нижнего пикселя
1517
    mov word[eax],dx
1518
    shr edx,16
1519
    mov byte[eax+2],dl
1520
 
1521
    add eax,3
1522
    add ebx,3
1523
    inc edi
1524
    cmp edi,dword[size_w]
1525
    jl .old_line_2
1526
      add ebx,esi
1527
      xor edi,edi
1528
    .old_line_2:
1529
    loop @b
1530
 
1531
  ;popad
1532
  ret
1533
endp
1534
 
1535
;преобразование буфера из 24-битного в 8-битный
1536
; spectr - определяет какой спектр брать при преобразовании 0-синий, 1-зеленый, 2-красный
1537
align 4
1538
proc buf_conv_24_to_8, buf_struc:dword, spectr:dword
1539
	pushad
1540
	mov edi,dword[buf_struc]
1541
	cmp buf2d_bits,24
1542
	jne .error
1543
		mov eax,buf2d_w
1544
		mov ecx,buf2d_h
1545
		imul ecx,eax
1546
		mov esi,ecx
1547
		;ebx - память из которой копируется
1548
		;edx - память куда копируется
1549
		mov edx,buf2d_data
1550
		mov ebx,edx
1551
		cmp [spectr],3
1552
		jge @f
1553
			add ebx,[spectr]
1554
		@@:
1555
			mov al,byte[ebx]
1556
			mov byte[edx],al
1557
			add ebx,3
1558
			inc edx
1559
			loop @b
1560
		mov buf2d_bits,8
1561
		invoke mem.realloc,buf2d_data,esi ;уменьшаем память занимаемую буфером
1562
		jmp .end_conv
1563
	.error:
1564
		stdcall print_err,sz_buf2d_conv_24_to_8,txt_err_n24b
1565
	.end_conv:
1566
	popad
1567
	ret
1568
endp
1569
 
1570
;преобразование буфера из 24-битного в 32-битный
1571
align 4
1572
proc buf_conv_24_to_32, buf_struc:dword, buf_str8:dword
1573
	pushad
1574
	mov edi,dword[buf_struc]
1575
	cmp buf2d_bits,24
1576
	jne .error1
1577
		mov ecx,buf2d_w
1578
		mov ebx,buf2d_h
1579
		imul ebx,ecx
1580
		mov ecx,ebx ;ecx = size  8 b
1581
		shl ebx,2   ;ebx = size 32 b
1582
		invoke mem.realloc,buf2d_data,ebx ;увеличиваем память занимаемую буфером
1583
		mov buf2d_data,eax ;на случай если изменился указатель на данные
1584
		mov buf2d_bits,32
1585
		mov edx,ebx ;edx = size 32 b
1586
		sub ebx,ecx ;ebx = size 24 b
1587
		mov eax,ecx
1588
		;eax - размер  8 битных данных
1589
		;ebx - размер 24 битных данных
1590
		;edx - размер 32 битных данных
1591
		add ebx,buf2d_data
1592
		add edx,buf2d_data
1593
		mov edi,dword[buf_str8]
1594
		cmp buf2d_bits,8
1595
		jne .error2
1596
		add eax,buf2d_data
1597
		mov edi,edx
1598
		;eax - указатель на конец  8 битных данных
1599
		;ebx - указатель на конец 24 битных данных
1600
		;edi - указатель на конец 32 битных данных
1601
		@@:
1602
			sub edi,4 ;отнимаем в начале цикла,
1603
			sub ebx,3 ; потому, что указатели стоят
1604
			dec eax   ; за пределами буферов
1605
			mov edx,dword[ebx]
1606
			mov dword[edi],edx
1607
			mov dl,byte[eax]
1608
			mov byte[edi+3],dl
1609
			loop @b
1610
 
1611
		jmp .end_conv
1612
	.error1:
1613
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n24b
1614
		jmp .end_conv
1615
	.error2:
1616
		stdcall print_err,sz_buf2d_conv_24_to_32,txt_err_n8b
1617
	.end_conv:
1618
	popad
1619
	ret
1620
endp
1621
 
1622
;функция копирует изображение из буфера buf_source (24b|32b) в buf_destination (24b)
1623
; указываются координаты вставки буфера buf_source относительно buf_destination
1624
; прозрачность при копировании не учитывается
1625
align 4
1626
proc buf_bit_blt, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1627
	locals
1628
		right_bytes dd ?
1629
	endl
1630
	pushad
1631
 
1632
	mov edi,[buf_source]
1633
	cmp buf2d_bits,24
1634
	je .sou24
1635
	cmp buf2d_bits,32
1636
	je .sou32
1637
		jmp .copy_end ;формат буфера не поодерживается
1638
 
1648 IgorA 1639
	.sou24: ;в источнике 24 битная картинка
1535 IgorA 1640
	mov eax,buf2d_w
1641
	mov edx,buf2d_h ;высота копируемой картинки
1642
	mov esi,buf2d_data ;данные копируемой картинки
1643
 
1644
	mov edi,[buf_destination]
1645
	cmp buf2d_bits,24
1646
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 1647
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
1648
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
1649
	jge .copy_end     ;если изображение полностью вылазит за правую сторону
1535 IgorA 1650
		mov ebx,buf2d_h ;ebx - высота основного буфера
1651
		mov ecx,[coord_y]
1652
		cmp ecx,ebx
1653
		jge .copy_end ;если координата 'y' больше высоты буфера
1654
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1655
		cmp ecx,ebx
1656
		jle @f
1657
			sub ecx,ebx
1658
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1659
		@@:
1660
		mov ebx,buf2d_w
1661
		mov ecx,ebx ;ecx используем для временных целей
1662
		imul ecx,[coord_y]
1663
		add ecx,[coord_x]
1664
		lea ecx,[ecx+ecx*2]
1665
		add ecx,buf2d_data
1666
		sub ebx,eax
1667
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1668
 
1669
	mov [right_bytes],0
1670
	mov ecx,[coord_x]
1671
	cmp ecx,ebx
1672
	jl @f
1673
		sub ecx,ebx
1674
		sub eax,ecx ;укорачиваем копируемую строку
1675
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1676
		lea ecx,[ecx+ecx*2] ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1677
		mov [right_bytes],ecx
1678
	@@:
1679
 
1680
	lea eax,[eax+eax*2] ;колличество байт в 1-й строке копируемой картинки
1681
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1682
 
1683
	cld
1684
	cmp [right_bytes],0
1685
	jg .copy_1
1686
	.copy_0: ;простое копирование
1687
		mov ecx,eax
1688
		rep movsb
1689
		add edi,ebx
1690
		dec edx
1691
		cmp edx,0
1692
		jg .copy_0
1693
	jmp .copy_end
1694
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
1695
		mov ecx,eax
1696
		rep movsb
1697
		add edi,ebx
1698
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1699
		dec edx
1700
		cmp edx,0
1701
		jg .copy_1
1702
	jmp .copy_end
1703
 
1704
	.sou32: ;в источнике 32 битная картинка
1705
	mov eax,buf2d_w
1706
	mov edx,buf2d_h ;высота копируемой картинки
1707
	mov esi,buf2d_data ;данные копируемой картинки
1708
 
1709
	mov edi,[buf_destination]
1710
	cmp buf2d_bits,24
1711
	jne .copy_end ;формат буфера не поодерживается
1648 IgorA 1712
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
1713
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
1714
	jge .copy_end     ;если изображение полностью вылазит за правую сторону
1535 IgorA 1715
		mov ebx,buf2d_h ;ebx - высота основного буфера
1716
		mov ecx,[coord_y]
1717
		cmp ecx,ebx
1718
		jge .copy_end ;если координата 'y' больше высоты буфера
1719
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1720
		cmp ecx,ebx
1721
		jle @f
1722
			sub ecx,ebx
1723
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1724
		@@:
1725
		mov ebx,buf2d_w
1726
		mov ecx,ebx ;ecx используем для временных целей
1727
		imul ecx,[coord_y]
1728
		add ecx,[coord_x]
1729
		lea ecx,[ecx+ecx*2]
1730
		add ecx,buf2d_data
1731
		sub ebx,eax
1732
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1733
 
1734
	mov [right_bytes],0
1735
	mov ecx,[coord_x]
1736
	cmp ecx,ebx
1737
	jl @f
1738
		sub ecx,ebx
1739
		sub eax,ecx ;укорачиваем копируемую строку
1740
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1741
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1742
		mov [right_bytes],ecx
1743
	@@:
1744
 
1745
	;eax - колличество пикселей в 1-й строке копируемой картинки
1746
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1747
 
1748
	cld
1749
	cmp [right_bytes],0
1750
	jg .copy_3
1751
	.copy_2: ;простое копирование
1752
		mov ecx,eax
1753
		@@:
1754
			movsw
1755
			movsb
1756
			inc esi
1757
			loop @b
1758
		add edi,ebx
1759
		dec edx
1760
		cmp edx,0
1761
		jg .copy_2
1762
	jmp .copy_end
1763
	.copy_3: ;не простое копирование (картинка вылазит за правую сторону)
1764
		mov ecx,eax
1765
		@@:
1766
			movsw
1767
			movsb
1768
			inc esi
1769
			loop @b
1770
		add edi,ebx
1771
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1772
		dec edx
1773
		cmp edx,0
1774
		jg .copy_3
1775
 
1776
	.copy_end:
1777
	popad
1778
	ret
1779
endp
1780
 
1781
;input:
1782
; esi = pointer to color1 + transparent
1783
; edi = pointer to background color2
1784
;output:
1785
; [edi] = combine color
1786
align 4
1787
combine_colors:
1788
	push ax bx cx dx
1789
	mov bx,0x00ff ;---get transparent---
1790
	mov cl,byte[esi+3] ;pro
1791
	xor ch,ch
1792
	sub bx,cx ;256-pro
1653 IgorA 1793
	;---blye---
1535 IgorA 1794
	xor ah,ah
1653 IgorA 1795
	mov al,byte[esi]
1535 IgorA 1796
	imul ax,bx
1797
	xor dh,dh
1653 IgorA 1798
	mov dl,byte[edi]
1535 IgorA 1799
	imul dx,cx
1800
	add ax,dx
1653 IgorA 1801
	mov byte[edi],ah
1535 IgorA 1802
	;---green---
1803
	xor ah,ah
1804
	mov al,byte[esi+1]
1805
	imul ax,bx
1806
	xor dh,dh
1807
	mov dl,byte[edi+1]
1808
	imul dx,cx
1809
	add ax,dx
1810
	mov byte[edi+1],ah
1653 IgorA 1811
	;---red---
1535 IgorA 1812
	xor ah,ah
1653 IgorA 1813
	mov al,byte[esi+2]
1535 IgorA 1814
	imul ax,bx
1815
	xor dh,dh
1653 IgorA 1816
	mov dl,byte[edi+2]
1535 IgorA 1817
	imul dx,cx
1818
	add ax,dx
1653 IgorA 1819
	mov byte[edi+2],ah
1535 IgorA 1820
 
1821
	pop dx cx bx ax
1822
	ret
1823
 
1824
;функция копирует изображение из буфера buf_source (32b) в buf_destination (24b)
1825
; указываются координаты вставки буфера buf_source относительно buf_destination
1826
; при копировании учитывается прозрачность
1827
align 4
1828
proc buf_bit_blt_transp, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword
1829
	locals
1830
		right_bytes dd ?
1831
	endl
1832
	pushad
1833
 
1834
	mov edi,[buf_source]
1835
	cmp buf2d_bits,32
1836
	jne .copy_end ;формат буфера не поодерживается
1837
	mov eax,buf2d_w
1838
	mov edx,buf2d_h ;высота копируемой картинки
1839
	mov esi,buf2d_data ;данные копируемой картинки
1840
 
1841
	mov edi,[buf_destination]
1842
	cmp buf2d_bits,24
1843
	jne .copy_end ;формат буфера не поодерживается
1844
		mov ebx,buf2d_h ;ebx - высота основного буфера
1845
		mov ecx,[coord_y]
1846
		cmp ecx,ebx
1847
		jge .copy_end ;если координата 'y' больше высоты буфера
1848
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1849
		cmp ecx,ebx
1850
		jle @f
1851
			sub ecx,ebx
1852
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1853
		@@:
1854
		mov ebx,buf2d_w
1855
		mov ecx,ebx ;ecx используем для временных целей
1856
		imul ecx,[coord_y]
1857
		add ecx,[coord_x]
1858
		lea ecx,[ecx+ecx*2]
1859
		add ecx,buf2d_data
1860
		sub ebx,eax
1861
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1862
 
1863
	mov [right_bytes],0
1864
	mov ecx,[coord_x]
1865
	cmp ecx,ebx
1866
	jl @f
1867
		sub ecx,ebx
1868
		sub eax,ecx ;укорачиваем копируемую строку
1869
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
1870
		shl ecx,2 ;ecx - число байт в 1-й строке картинки, которые вылазят за правую сторону
1871
		mov [right_bytes],ecx
1872
	@@:
1873
 
1874
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
1875
 
1876
	cld
1877
	cmp [right_bytes],0
1878
	jg .copy_1
1879
	.copy_0: ;простое копирование
1880
		mov ecx,eax
1881
		@@:
1882
			call combine_colors
1883
			add edi,3
1884
			add esi,4
1885
			loop @b
1886
		add edi,ebx
1887
		dec edx
1888
		cmp edx,0
1889
		jg .copy_0
1890
	jmp .copy_end
1891
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
1892
		mov ecx,eax
1893
		@@:
1894
			call combine_colors
1895
			add edi,3
1896
			add esi,4
1897
			loop @b
1898
		add edi,ebx
1899
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
1900
		dec edx
1901
		cmp edx,0
1902
		jg .copy_1
1903
 
1904
	.copy_end:
1905
	popad
1906
	ret
1907
endp
1908
 
1909
;input:
1910
; ebx - color1
1911
; esi = pointer to transparent
1912
; edi = pointer to background color2
1913
;output:
1914
; [edi] = combine color
1915
align 4
1916
combine_colors_2:
1917
	push ax ebx cx dx si
1918
	mov cl,byte[esi] ;pro
1919
	xor ch,ch
1920
	mov si,0x00ff ;---get transparent---
1921
	sub si,cx ;256-pro
1922
 
1653 IgorA 1923
		;---blye---
1535 IgorA 1924
		mov al,bl
1925
		xor ah,ah
1926
		shr ebx,8
1927
		imul ax,si
1928
		xor dh,dh
1653 IgorA 1929
		mov dl,byte[edi]
1535 IgorA 1930
		imul dx,cx
1931
		add ax,dx
1653 IgorA 1932
		mov byte[edi],ah
1535 IgorA 1933
		;---green---
1934
		mov al,bl
1935
		xor ah,ah
1936
		shr ebx,8
1937
		imul ax,si
1938
		xor dh,dh
1939
		mov dl,byte[edi+1]
1940
		imul dx,cx
1941
		add ax,dx
1942
		mov byte[edi+1],ah
1943
		;---red---
1944
		mov al,bl
1945
		xor ah,ah
1946
		imul ax,si
1947
		xor dh,dh
1653 IgorA 1948
		mov dl,byte[edi+2]
1535 IgorA 1949
		imul dx,cx
1950
		add ax,dx
1653 IgorA 1951
		mov byte[edi+2],ah
1535 IgorA 1952
 
1953
	pop si dx cx ebx ax
1954
	ret
1955
 
1956
;функция копирует изображение из буфера buf_source (8b) в buf_destination (24b)
1957
; указываются координаты вставки буфера buf_source относительно buf_destination
1958
align 4
1959
proc buf_bit_blt_alpha, buf_destination:dword, coord_x:dword, coord_y:dword, buf_source:dword, color:dword
1960
	locals
1961
		right_bytes dd ?
1962
		dest_w_bytes dd ? ;колличество байт в буфере приемнике по ширине - ширина вставляемой картинки
1963
	endl
1964
	pushad
1965
 
1966
	mov edi,[buf_source]
1967
	cmp buf2d_bits,8
1968
	jne .error1 ;формат буфера не поодерживается
1969
	mov eax,buf2d_w
1970
	mov edx,buf2d_h ;высота копируемой картинки
1971
	mov esi,buf2d_data ;данные копируемой картинки
1972
 
1973
	mov edi,[buf_destination]
1974
	cmp buf2d_bits,24
1975
	jne .error2 ;формат буфера не поодерживается
1642 IgorA 1976
	mov ebx,[coord_x] ;в ebx временно ставим отступ изображения (для проверки)
1977
	cmp ebx,buf2d_w   ;проверяем влазит ли изображение по ширине
1978
	jge .copy_end     ;если изображение полностью вылазит за правую сторону
1535 IgorA 1979
		mov ebx,buf2d_h ;ebx - высота основного буфера
1980
		mov ecx,[coord_y]
1981
		cmp ecx,ebx
1982
		jge .copy_end ;если координата 'y' больше высоты буфера
1983
		add ecx,edx ;ecx - нижняя координата копируемой картинки
1984
		cmp ecx,ebx
1985
		jle @f
1986
			sub ecx,ebx
1987
			sub edx,ecx ;уменьшаем высоту копируемой картинки, в случе когда она вылазит за нижнюю границу
1988
		@@:
1989
		mov ebx,buf2d_w
1990
		mov ecx,ebx ;ecx используем для временных целей
1991
		imul ecx,[coord_y]
1992
		add ecx,[coord_x]
1993
		lea ecx,[ecx+ecx*2]
1994
		add ecx,buf2d_data
1995
		sub ebx,eax
1996
		mov edi,ecx ;edi указатель на данные буфера, куда будет производится копирование
1997
 
1998
	mov [right_bytes],0
1999
	mov ecx,[coord_x]
2000
	cmp ecx,ebx
2001
	jl @f
2002
		sub ecx,ebx
2003
		sub eax,ecx ;укорачиваем копируемую строку
2004
		add ebx,ecx ;удлинняем строку для сдвига главной картинки буфера
2005
		;ecx - число пикселей в 1-й строке картинки, которые вылазят за правую сторону
2006
		mov [right_bytes],ecx
2007
	@@:
2008
 
2009
	lea ebx,[ebx+ebx*2] ;колличество байт в 1-й строке буфера минус число байт в 1-й строке копируемой картинки
2010
	mov [dest_w_bytes],ebx
2011
	mov ebx,[color]
2012
 
2013
	cld
2014
	cmp [right_bytes],0
2015
	jg .copy_1
2016
	.copy_0: ;простое копирование
2017
		mov ecx,eax
2018
		@@:
2019
			call combine_colors_2
2020
			add edi,3
2021
			inc esi
2022
			loop @b
2023
		add edi,[dest_w_bytes]
2024
		dec edx
2025
		cmp edx,0
2026
		jg .copy_0
2027
	jmp .copy_end
2028
	.copy_1: ;не простое копирование (картинка вылазит за правую сторону)
2029
		mov ecx,eax
2030
		@@:
2031
			call combine_colors_2
2032
			add edi,3
2033
			inc esi
2034
			loop @b
2035
		add edi,[dest_w_bytes]
2036
		add esi,[right_bytes] ;добавляем байты, которые вылазят за правую границу
2037
		dec edx
2038
		cmp edx,0
2039
		jg .copy_1
2040
 
2041
	jmp .copy_end
2042
	.error1:
2043
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n8b
2044
		jmp .copy_end
2045
	.error2:
2046
		stdcall print_err,sz_buf2d_bit_blt_alpha,txt_err_n24b
2047
	.copy_end:
2048
	popad
2049
	ret
2050
endp
2051
 
2052
;преобразование 8-битного буфера размером 16*16 в размер 1*256 символов
2053
align 4
2054
proc buf_convert_text_matrix, buf_struc:dword
2055
	locals
2056
		tmp_mem dd ?
2057
		c1 dw ?
2058
		c2 dd ?
2059
		c3 dw ?
2060
	endl
2061
	pushad
2062
	mov edi,dword[buf_struc]
2063
	cmp buf2d_bits,8
2064
	jne .error
2065
		mov ecx,buf2d_h
2066
		mov ebx,ecx
2067
		shr ebx,4 ;предполагаем что в буфере 16 строк с символами, потому делим на 2^4
2068
		mov edx,buf2d_w
2069
		imul ecx,edx ;ecx = size  8 b
2070
		invoke mem.alloc,ecx ;выделяем временную память
2071
		mov [tmp_mem],eax ;eax - new memory
2072
 
2073
		shr edx,4 ;предполагаем что в буфере 16 колонок с символами, потому делим на 2^4
2074
		mov eax,ebx
2075
		imul ebx,edx ;вычисляем кооличество пикселей на 1 символ
2076
		;eax = bhe - высота буквы
2077
		;ebx = bwi*bhe - колличество пикселей в 1-й букве
2078
		;edx = bwi - ширина буквы
2079
		;ecx,esi,edi - используются в цикле .c_0
2080
		shr buf2d_w,4
2081
		shl buf2d_h,4 ;преобразовываем размеры буфера
2082
 
2083
		cld
2084
		mov esi,buf2d_data
2085
		mov edi,[tmp_mem]
2086
		mov word[c3],16
2087
		.c_3:
2088
			mov dword[c2],eax
2089
			.c_2:
2090
				mov word[c1],16
2091
				.c_1:
2092
					mov ecx,edx ;.c_0:
2093
					rep movsb
2094
					add edi,ebx
2095
					sub edi,edx ;edi+=(bwi*bhe-bwi)
2096
					dec word[c1]
2097
					cmp word[c1],0
2098
					jg .c_1
2099
				add edi,edx
2100
				shl ebx,4
2101
				sub edi,ebx ;edi-=(16*bwi*bhe-bwi)
2102
				shr ebx,4
2103
				dec dword[c2]
2104
				cmp dword[c2],0
2105
				jg .c_2
2106
			sub edi,ebx
2107
			shl ebx,4
2108
			add edi,ebx ;edi+=(15*bwi*bhe)
2109
			shr ebx,4
2110
			dec word[c3]
2111
			cmp word[c3],0
2112
			jg .c_3
2113
 
2114
		mov edi,dword[buf_struc] ;копирование новой матрицы в основной буфер
2115
		mov edi,buf2d_data
2116
		mov esi,[tmp_mem]
2117
		mov ecx,ebx
2118
		shl ecx,8
2119
		rep movsb
2120
		invoke mem.free,[tmp_mem] ;чистим временную память
2121
		jmp .end_conv
2122
	.error:
2123
		stdcall print_err,sz_buf2d_convert_text_matrix,txt_err_n8b
2124
	.end_conv:
2125
	popad
2126
	ret
2127
endp
2128
 
2129
align 4
2130
buf_s_matr buf_2d_header ? ;локальная матрица символа
2131
 
2132
align 4
2133
proc buf_draw_text, buf_struc:dword, buf_t_matr:dword, text:dword, coord_x:dword, coord_y:dword, color:dword
2134
	locals
2135
		buf_t_matr_offs dd ?
2136
	endl
2137
	pushad
2138
	mov edi,dword[buf_struc]
2139
	cmp buf2d_bits,24
2140
	jne .error2
2141
	mov edi,dword[buf_t_matr]
2142
	cmp buf2d_bits,8
2143
	jne .error1
2144
		mov edx,buf2d_data
2145
		mov [buf_t_matr_offs],edx
2146
		mov ecx,BUF_STRUCT_SIZE ;копируем структуру текстовой матрицы
2147
		mov esi,edi
2148
		lea edi,[buf_s_matr]
2149
		cld
2150
		rep movsb
2151
		lea edi,[buf_s_matr]
2152
		shr buf2d_h,8 ;делим высоту символьного буфера на 256, для нахождения высоты 1-го символа
2153
		mov ebx,buf2d_h ;берем высоту символа
2154
		mov ecx,buf2d_w ;берем ширину символа
2155
 
2156
		mov eax,[coord_x]
2157
		mov esi,[text]
2158
		cmp byte[esi],0
2159
		je .end_draw ;если пустая строка
2160
		@@:
2161
			xor edx,edx
2162
			mov dl,byte[esi] ;берем код символа
2163
			imul edx,ebx ;умножаем его на высоту символа
2164
			imul edx,ecx ;умножаем на ширину символа
2165
			add edx,[buf_t_matr_offs] ;прибавляем смещение 0-го символа, т. е. получается смещение выводимого символа
2166
			mov buf2d_data,edx ;в локальный буфер символа, ставим указатель на нужный символ из буфера buf_t_matr
2167
			stdcall buf_bit_blt_alpha, [buf_struc], eax,[coord_y], edi,[color]
2168
			add eax,ecx
2169
			.new_s:
2170
				inc esi
2171
				cmp byte[esi],13
2172
				jne .no_13
2173
					mov eax,[coord_x]
2174
					add [coord_y],ebx
2175
					jmp .new_s
2176
				.no_13:
2177
			cmp byte[esi],0
2178
			jne @b
2179
		jmp .end_draw
2180
	.error1:
2181
		stdcall print_err,sz_buf2d_draw_text,txt_err_n8b
2182
		jmp .end_draw
2183
	.error2:
2184
		stdcall print_err,sz_buf2d_draw_text,txt_err_n24b
2185
	.end_draw:
2186
	popad
2187
	ret
2188
endp
2189
 
2190
align 4
2191
proc print_err, fun:dword, mes:dword ;выводим сообщение об шибке на доску отладки
2192
	pushad
2193
	mov eax,63
2194
	mov ebx,1
2195
 
2196
	mov esi,[fun]
2197
	@@:
2198
		mov cl,byte[esi]
2199
		int 0x40
2200
		inc esi
2201
		cmp byte[esi],0
2202
		jne @b
2203
	mov cl,':'
2204
	int 0x40
2205
	mov cl,' '
2206
	int 0x40
2207
	mov esi,[mes]
2208
	@@:
2209
		mov cl,byte[esi]
2210
		int 0x40
2211
		inc esi
2212
		cmp byte[esi],0
2213
		jne @b
2214
	popad
2215
	ret
2216
endp
2217
 
2218
;input:
2219
; ebp+8  = p0
2220
; ebp+12 = p1
2221
align 4
2222
line_len4i:
2223
	push ebp
2224
	mov ebp,esp
2225
		finit
2226
		fild word [ebp+8]
2227
		fisub word [ebp+12]
2228
		fmul st0,st0 ;st0=x^2
2229
		fild word [ebp+10]
2230
		fisub word [ebp+14]
2231
		fmul st0,st0 ;st0=y^2
2232
		fadd st0,st1
2233
		fsqrt
2234
		fstp dword [ebp+12]
2235
	pop ebp
2236
	ret 4 ;8
2237
 
2238
align 4
1727 IgorA 2239
proc buf_curve_bezier, buffer:dword, coord_p0:dword,coord_p1:dword,coord_p2:dword, color:dword
1535 IgorA 2240
	locals
2241
		delt_t dd ?
2242
		opr_param dd ?
2243
		v_poi_0 dd ?
2244
	endl
2245
	pushad
2246
 
2247
;float t, xt,yt;
2248
;for(t=.0;t<1.;t+=.005){
2249
;  xt=pow(1.-t,2)*x0+2*t*(1.-t)*x1+pow(t,2)*x2;
2250
;  yt=pow(1.-t,2)*y0+2*t*(1.-t)*y1+pow(t,2)*y2;
2251
;  dc.SetPixel(xt,yt,255L);
2252
;}
2253
 
1727 IgorA 2254
	mov edx,[color] ;set curve color
1535 IgorA 2255
	mov edi,[buffer]
2256
	xor ebx,ebx
2257
	xor ecx,ecx
2258
 
2259
	finit
2260
 
2261
	; calculate delta t
2262
	stdcall line_len4i, dword[coord_p1],dword[coord_p0]
2263
	fadd dword[esp]
2264
	add esp,4 ;pop ...
2265
 
2266
	stdcall line_len4i, dword[coord_p2],dword[coord_p1]
2267
	fadd dword[esp]
2268
	add esp,4 ;pop ...
2269
 
2270
	fadd st0,st0 ; len*=2
2271
	ftst
2272
	fstsw ax
2273
 
2274
	fld1
2275
	sahf
2276
	jle @f ;избегаем деления на 0
2277
		fdiv st0,st1
2278
	@@:
2279
	fstp dword[delt_t]
2280
 
2281
	finit
2282
 
2283
	;fild word[coord_p2+2] ;y2
2284
	fild word[coord_p1+2] ;y1
2285
	fild word[coord_p0+2] ;y0
2286
	fild word[coord_p2] ;x2
2287
	fild word[coord_p1] ;x1
2288
	fild word[coord_p0] ;x0
2289
	fld dword[delt_t]
2290
	fldz ;t=.0
2291
 
2292
	@@:
2293
		fld1
2294
		fsub st0,st1 ;1.-t
2295
		fmul st0,st0 ;pow(1.-t,2)
2296
		fmul st0,st3 ;...*x0
2297
		fstp dword[opr_param]
2298
 
2299
		fld1
2300
		fsub st0,st1 ;1.-t
2301
		fmul st0,st1 ;(1.-t)*t
2302
		fadd st0,st0
2303
		fmul st0,st4 ;...*x1
2304
		mov esi,dword[opr_param]
2305
		fstp dword[opr_param]
2306
 
2307
		fldz
2308
		fadd st0,st1 ;0+t
2309
		fmul st0,st0 ;t*t
2310
		fmul st0,st5 ;...*x2
2311
 
2312
		fadd dword[opr_param]
2313
		mov dword[opr_param],esi
2314
		fadd dword[opr_param]
2315
		fistp word[v_poi_0] ;x
2316
 
2317
		fld1
2318
		fsub st0,st1 ;1.-t
2319
		fmul st0,st0 ;pow(1.-t,2)
2320
		fmul st0,st6 ;...*y0
2321
		fstp dword[opr_param]
2322
 
2323
		fld1
2324
		fsub st0,st1 ;1.-t
2325
		fmul st0,st1 ;(1.-t)*t
2326
		fadd st0,st0
2327
		fmul st0,st7 ;...*y1
2328
		mov esi,dword[opr_param]
2329
		fstp dword[opr_param]
2330
 
2331
		fldz
2332
		fadd st0,st1 ;0+t
2333
		fmul st0,st0 ;t*t
2334
		fimul word[coord_p2+2] ;...*y2
2335
 
2336
		fadd dword[opr_param]
2337
		mov dword[opr_param],esi
2338
		fadd dword[opr_param]
2339
		fistp word[v_poi_0+2] ;y
2340
 
2341
		mov eax,1
2342
		mov bx,word[v_poi_0+2]
2343
		mov cx,word[v_poi_0]
2344
		call draw_pixel
2345
 
2346
		fadd st0,st1 ;t+dt
2347
 
2348
		fld1
2349
		fcomp
2350
		fstsw ax
2351
		sahf
2352
	jae @b
2353
 
2354
	popad
2355
	ret
2356
endp
2357
 
2358
txt_err_n8b db 'need buffer 8 bit',13,10,0
2359
txt_err_n24b db 'need buffer 24 bit',13,10,0
2360
 
2361
align 16
2362
EXPORTS:
2363
	dd sz_lib_init, lib_init
2364
	dd sz_buf2d_create, buf_create
2365
	dd sz_buf2d_create_f_img, buf_create_f_img
2366
	dd sz_buf2d_clear, buf_clear
2367
	dd sz_buf2d_draw, buf_draw_buf
2368
	dd sz_buf2d_delete, buf_delete
2136 IgorA 2369
	dd sz_buf2d_resize, buf_resize
1535 IgorA 2370
	dd sz_buf2d_line, buf_line_brs
1634 IgorA 2371
	dd sz_buf2d_rect_by_size, buf_rect_by_size
1642 IgorA 2372
	dd sz_buf2d_filled_rect_by_size, buf_filled_rect_by_size
1535 IgorA 2373
	dd sz_buf2d_circle, buf_circle
2374
	dd sz_buf2d_img_hdiv2, buf_img_hdiv2
2375
	dd sz_buf2d_img_wdiv2, buf_img_wdiv2
2376
	dd sz_buf2d_conv_24_to_8, buf_conv_24_to_8
2377
	dd sz_buf2d_conv_24_to_32, buf_conv_24_to_32
2378
	dd sz_buf2d_bit_blt, buf_bit_blt
2379
	dd sz_buf2d_bit_blt_transp, buf_bit_blt_transp
2380
	dd sz_buf2d_bit_blt_alpha, buf_bit_blt_alpha
1727 IgorA 2381
	dd sz_buf2d_curve_bezier, buf_curve_bezier
1535 IgorA 2382
	dd sz_buf2d_convert_text_matrix, buf_convert_text_matrix
2383
	dd sz_buf2d_draw_text, buf_draw_text
2384
	dd sz_buf2d_crop_color, buf_crop_color
2385
	dd sz_buf2d_offset_h, buf_offset_h
1684 IgorA 2386
	dd sz_buf2d_flood_fill, buf_flood_fill
1910 IgorA 2387
	dd sz_buf2d_set_pixel, buf_set_pixel
1535 IgorA 2388
	dd 0,0
2389
	sz_lib_init db 'lib_init',0
2390
	sz_buf2d_create db 'buf2d_create',0
2391
	sz_buf2d_create_f_img db 'buf2d_create_f_img',0
2392
	sz_buf2d_clear db 'buf2d_clear',0 ;очистка буфера указанным цветом
2393
	sz_buf2d_draw db 'buf2d_draw',0
2394
	sz_buf2d_delete db 'buf2d_delete',0
2136 IgorA 2395
	sz_buf2d_resize db 'buf2d_resize',0
1535 IgorA 2396
	sz_buf2d_line db 'buf2d_line',0 ;рисование линии
1642 IgorA 2397
	sz_buf2d_rect_by_size db 'buf2d_rect_by_size',0 ;рисование рамки прямоугольника, 2-я координата задана по размеру
2398
	sz_buf2d_filled_rect_by_size db 'buf2d_filled_rect_by_size',0 ;рисование залитого прямоугольника, 2-я координата задана по размеру
1535 IgorA 2399
	sz_buf2d_circle db 'buf2d_circle',0 ;рисование окружности
2400
	sz_buf2d_img_hdiv2 db 'buf2d_img_hdiv2',0 ;сжатие изображения по высоте в 2 раза (размер буфера не меняется)
2401
	sz_buf2d_img_wdiv2 db 'buf2d_img_wdiv2',0 ;сжатие изображения по ширине в 2 раза (размер буфера не меняется)
2402
	sz_buf2d_conv_24_to_8 db 'buf2d_conv_24_to_8',0
2403
	sz_buf2d_conv_24_to_32 db 'buf2d_conv_24_to_32',0
2404
	sz_buf2d_bit_blt db 'buf2d_bit_blt',0
2405
	sz_buf2d_bit_blt_transp db 'buf2d_bit_blt_transp',0
2406
	sz_buf2d_bit_blt_alpha db 'buf2d_bit_blt_alpha',0
1727 IgorA 2407
	sz_buf2d_curve_bezier db 'buf2d_curve_bezier',0
1535 IgorA 2408
	sz_buf2d_convert_text_matrix db 'buf2d_convert_text_matrix',0
2409
	sz_buf2d_draw_text db 'buf2d_draw_text',0
2410
	sz_buf2d_crop_color db 'buf2d_crop_color',0
2411
	sz_buf2d_offset_h db 'buf2d_offset_h',0
1684 IgorA 2412
	sz_buf2d_flood_fill db 'buf2d_flood_fill',0
1910 IgorA 2413
	sz_buf2d_set_pixel db 'buf2d_set_pixel',0
1684 IgorA 2414