; TrueType: WriteBMP
;
; Copr. 1996 Matthias K”ppe

		TITLE	WriteFont

		JUMPS

		LOCALS	@@

	; publics

		PUBLIC	writebmpLine, filteredLine

	; includes

		INCLUDE	scandef.asm

TBitmap		STRUC
bmType		DW	?
bmWidth		DW	?
bmHeight	DW	?
bmWidthBytes	DW	?
bmPlanes	DB	?
bmBitsPixel	DB	?
bmBits		DD	?
bmPalette	DD	?
bmChunks	DW	?
TBitmap		ENDS

TFilter		STRUC
fiSize		DW	?
fiPostScaling	DW	?
fiSupport	DW	?
fiDivisor	DW	?
TFilter		ENDS

	; Code Segment

addb	MACRO	addr, incr
	LOCAL	@@1
	add	BYTE PTR addr, incr
	jnc	SHORT @@1

	mov	BYTE PTR addr, 255
@@1:
	ENDM

CODE		SEGMENT BYTE PUBLIC

		ASSUME	CS: CODE

	.386

writebmpLine	PROC NEAR
		ARG	y: WORD, x2: WORD, x1: WORD, ABitmap: DWORD = ArgSize
		push	bp
		mov	bp, sp
		les	si, ABitmap

	; Handle x

		mov	ax, x1
		mov     bx, x2

	; Clip x1

		or	ax, ax				; left
		jns	@@1
		xor	ax, ax
@@1:
		mov	cx, es:[si].TBitmap.bmWidth	; right
		sal	cx, 3
		cmp	ax, cx
		jge	@@0


	; Clip x2

		mov	cx, es:[si].TBitmap.bmWidth
		sal	cx, 3
		cmp	bx, cx
		jl	@@2
		mov	bx, es:[si].TBitmap.bmWidth
		dec	bx
@@2:
	; Calc bit count

		mov	cl, al
		mov	ch, bl
		and	cx, 0707h
		sar	ax, 3
		mov	di, ax			; DI byte pos
		sar	bx, 3
		sub	bx, ax			; BX byte count - 1
		jnz	SHORT @@3

	; one byte modified

		sub	ch, cl
		inc	ch
		mov	cl, ch			; DL left bit count
		jmp	SHORT @@6
@@3:
	; more than one byte modified

		sub	cl, 8
		neg	cl			; CL left bit count
		inc	ch			; CH right bit count

@@6:
	; Handle y

		mov	ax, y
		sar	ax, 3

		or	ax, ax
		js	@@0

		cmp	ax, es:[si].TBitmap.bmHeight
		jge	@@0

		mul	es:[si].TBitmap.bmWidthBytes ; AX offset
		add	ax, di
		les	di, es:[si].TBitmap.bmBits
		add	di, ax

	; Write loop

		addb	es:[di], cl		; store left mask
		or	bx, bx
		jz	SHORT @@0
@@4:
		inc	di
		dec	bx
		jz	SHORT @@5
		addb	es:[di], 8
		jmp	@@4
@@5:
		addb	es:[di], ch		; store right mask

@@0:
		pop	bp
		ret	ArgSize
writeBmpLine	ENDP

	;
	; generic filter support
	;

filteredLine	PROC NEAR
		ARG	y: WORD, x2: WORD, x1: WORD, ABitmap: DWORD = ArgSize
		LOCAL	Left: WORD, Right: WORD, Top: WORD, \
			BitmapWidth: WORD, VertCount: WORD, HorizCount: WORD,\
			Current: WORD, Value: WORD, FilterRow: WORD = LocalSize
		enter	LocalSize, 0
		les	di, ABitmap
		mov	ax, es:[di].TBitmap.bmWidthBytes
		mov	BitmapWidth, ax

		push	ds
		lds	si, es:[di].TBitmap.bmPalette	; TFilter data

	; calc the range of metapixels

		mov	cx, [si].TFilter.fiPostScaling
		mov	bx, [si].TFilter.fiSupport
		mov	VertCount, bx

		mov	ax, x1
		cwd
		idiv	cx
		shr	bx, 1
		sub	ax, bx
		jns	SHORT @@1

		xor	ax, ax
@@1:
		cmp	ax, BitmapWidth
		jge	@@0
		mov	Left, ax			; leftmost metapixel

		mov	ax, x2
		dec	ax
		cwd
		idiv	cx
		inc	ax
		add	ax, bx
		cmp	ax, Left
		jl	@@0

		cmp	ax, BitmapWidth
		jl	SHORT @@2

		mov	ax, BitmapWidth
		dec	ax
@@2:
		mov	Right, ax			; rightmost metapixel

		mov	ax, y
		cwd
		idiv	cx
	;	sub	ax, bx
		mov	Top, ax				; topmost metapixel

	; calc address of (leftmost, topmost)

		mov	ax, Top
		mul     BitmapWidth
		add	ax, Left
		les	di, es:[di].TBitmap.bmBits
		add	di, ax				; es:di address

	;
	; vertical loop
	;
@@V:
		mov	ax, Top
		mul     [si].TFilter.fiPostScaling
		sub	ax, y
		neg	ax				; ax line in filter
		mul	[si].TFilter.fiSize
		add	ax, si
		add	ax, TYPE TFilter
		mov	FilterRow, ax			; Filter row

		mov	ax, Left
		mov	Current, ax

		mov	cx, Right
		sub	cx, ax
		inc	cx
		mov	HorizCount, cx

		push	di

	; horizontal loop
@@H:
		mov	Value, 0

		mov	ax, Current
		mul	[si].TFilter.fiPostScaling
		mov	cx, [si].TFilter.fiSize
		sub	cx, [si].TFilter.fiPostScaling
		shr	cx, 1
		sub	ax, cx
		mov	cx, ax				; left of support
		mov	dx, cx
		sub	ax, x1				; ax column in filter
		js	SHORT @@H1

		xor	ax, ax
@@H1:
		neg	ax
		add	cx, [si].TFilter.fiSize
		dec	cx				; right of support
		cmp	cx, x2
		jle	SHORT @@H2

		mov	cx, x2
@@H2:
		add	dx, ax
		sub	cx, dx
		jl	@@H0
		inc	cx				; cx count

		mov	bx, FilterRow
		add	bx, ax				; ax offset in filter
@@H3:
		mov	al, [bx]			; get filter byte
		inc	bx
		xor	ah, ah
		add	Value, ax
		loop	@@H3

		mov	ax, Value
		cwd
		div	[si].TFilter.fiDivisor
		cmp	ax, 0FFh
		jbe	SHORT @@H4
		mov	ax, 0FFh
@@H4:
		addb	es:[di], al			; store summed value
@@H0:
		inc	di
		inc	Current
		dec	HorizCount
		jnz	@@H

		pop	di
		add	di, BitmapWidth
		inc	Top
		dec	VertCount
		jnz	@@V

@@0:
		pop	ds
		leave
		ret	ArgSize
filteredLine	ENDP

CODE		ENDS

		END
