Subversion Repositories Kolibri OS

Rev

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