// File: Alcaro[P]bridges/font.cpp
// Function: font::render(image&, int, int, cstring, float, bool) const
uint32_t font::render(image& img, int32_t x, int32_t y, cstring text, float xspace, bool align) const
{
	uint32_t color;
	if (img.fmt == ifmt_0rgb8888) color = this->color & 0x00FFFFFF;
	else color = this->color | 0xFF000000;
	
	uint32_t maxwidth = 0;
	
	float xoff = 0;
	for (size_t i=0;i<text.length();i++)
	{
		uint8_t ch = text[i];
		int32_t xstart = x + (align ? ((int)xoff/this->scale)*this->scale : (int)xoff);
		
		if (ch == '\n')
		{
			y += this->height * this->scale;
			xoff = 0;
			continue;
		}
		else if (ch <= 0x1F)
		{
			this->fallback(img, *this, xstart, y, ch);
			//refresh the color, in case the fallback changed it
			if (img.fmt == ifmt_0rgb8888) color = this->color & 0x00FFFFFF;
			else color = this->color | 0xFF000000;
		}
		else
		{
			for (size_t yp=0;yp<8;yp++)
			{
				for (size_t yps=0;yps<this->scale;yps++)
				{
					uint32_t yt = y + yp*this->scale + yps;
					if (yt < 0 || yt >= img.height) continue;
					
					uint32_t* targetpx = img.pixels32 + yt*img.stride/sizeof(uint32_t);
					
					for (size_t xp=0;xp<8;xp++)
					{
						if (this->characters[ch][yp] & (1<<xp))
						{
							for (size_t xps=0;xps<this->scale;xps++)
							{
								int32_t xt = xstart + xp*this->scale + xps;
								if (xt < 0 || (uint32_t)xt >= img.width) continue;
								
								targetpx[xt] = color;
							}
						}
					}
				}
			}
		}
		
		xoff += this->width[ch] * this->scale;
		if (ch == ' ') xoff += xspace;
		
		//-scale to remove the inter-letter spacing
		maxwidth = max(maxwidth, xoff-this->scale);
	}
	
	return maxwidth;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movb 0x10(%rbp), %al
movq %r8, -0x30(%rbp)
movq %r9, -0x28(%rbp)
movq %rdi, -0x38(%rbp)
movq %rsi, -0x40(%rbp)
movl %edx, -0x44(%rbp)
movl %ecx, -0x48(%rbp)
movss %xmm0, -0x4c(%rbp)
andb $0x1, %al
movb %al, -0x4d(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x40(%rbp), %rax
cmpl $0x7, 0x8(%rax)
jne 0x4744a
movq -0xb0(%rbp), %rax
movl 0x484(%rax), %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, -0x54(%rbp)
jmp 0x4745f
movq -0xb0(%rbp), %rax
movl 0x484(%rax), %eax
orl $0xff000000, %eax       # imm = 0xFF000000
movl %eax, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x5c(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0x30(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x474cb
movq -0xb8(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, -0x14(%rbp)
jmp 0x474d8
movq -0xb8(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0xc0(%rbp), %rax
movl -0x14(%rbp), %ecx
cmpq %rcx, %rax
jae 0x47835
movq -0x68(%rbp), %rax
movl %eax, %esi
leaq -0x30(%rbp), %rdi
callq 0xa1c0
movb %al, -0x69(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0xc4(%rbp)
testb $0x1, -0x4d(%rbp)
je 0x47534
movq -0xb0(%rbp), %rcx
cvttss2si -0x5c(%rbp), %eax
movzbl 0x488(%rcx), %esi
cltd
idivl %esi
movzbl 0x488(%rcx), %ecx
imull %ecx, %eax
movl %eax, -0xc8(%rbp)
jmp 0x4753f
cvttss2si -0x5c(%rbp), %eax
movl %eax, -0xc8(%rbp)
movl -0xc4(%rbp), %eax
movl -0xc8(%rbp), %ecx
addl %ecx, %eax
movl %eax, -0x70(%rbp)
movzbl -0x69(%rbp), %eax
cmpl $0xa, %eax
jne 0x47584
movq -0xb0(%rbp), %rcx
movzbl 0x480(%rcx), %eax
movzbl 0x488(%rcx), %ecx
imull %ecx, %eax
addl -0x48(%rbp), %eax
movl %eax, -0x48(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x5c(%rbp)
jmp 0x47824
movzbl -0x69(%rbp), %eax
cmpl $0x1f, %eax
jg 0x475ee
movq -0xb0(%rbp), %rdx
movq %rdx, %rdi
addq $0x490, %rdi            # imm = 0x490
movq -0x40(%rbp), %rsi
movl -0x70(%rbp), %ecx
movl -0x48(%rbp), %r8d
movzbl -0x69(%rbp), %r9d
callq 0x47fa0
movq -0x40(%rbp), %rax
cmpl $0x7, 0x8(%rax)
jne 0x475d4
movq -0xb0(%rbp), %rax
movl 0x484(%rax), %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, -0x54(%rbp)
jmp 0x475e9
movq -0xb0(%rbp), %rax
movl 0x484(%rax), %eax
orl $0xff000000, %eax       # imm = 0xFF000000
movl %eax, -0x54(%rbp)
jmp 0x477b9
movq $0x0, -0x78(%rbp)
cmpq $0x8, -0x78(%rbp)
jae 0x477b7
movq $0x0, -0x80(%rbp)
movq -0xb0(%rbp), %rcx
movq -0x80(%rbp), %rax
movzbl 0x488(%rcx), %ecx
cmpq %rcx, %rax
jae 0x477a4
movq -0xb0(%rbp), %rdx
movslq -0x48(%rbp), %rax
movq -0x78(%rbp), %rcx
movzbl 0x488(%rdx), %edx
imulq %rdx, %rcx
addq %rcx, %rax
addq -0x80(%rbp), %rax
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x84(%rbp)
jb 0x47663
movl -0x84(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jb 0x47668
jmp 0x47793
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x84(%rbp), %ecx
movq -0x40(%rbp), %rdx
imull 0xc(%rdx), %ecx
movl %ecx, %ecx
shrq $0x2, %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
cmpq $0x8, -0x98(%rbp)
jae 0x47791
movq -0xb0(%rbp), %rax
movzbl -0x69(%rbp), %ecx
shlq $0x3, %rcx
addq %rcx, %rax
movq -0x78(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movq -0x98(%rbp), %rcx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x47778
movq $0x0, -0xa0(%rbp)
movq -0xb0(%rbp), %rcx
movq -0xa0(%rbp), %rax
movzbl 0x488(%rcx), %ecx
cmpq %rcx, %rax
jae 0x47776
movq -0xb0(%rbp), %rdx
movslq -0x70(%rbp), %rax
movq -0x98(%rbp), %rcx
movzbl 0x488(%rdx), %edx
imulq %rdx, %rcx
addq %rcx, %rax
addq -0xa0(%rbp), %rax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa4(%rbp)
jl 0x47749
movl -0xa4(%rbp), %eax
movq -0x40(%rbp), %rcx
cmpl (%rcx), %eax
jb 0x4774b
jmp 0x4775f
movl -0x54(%rbp), %edx
movq -0x90(%rbp), %rax
movslq -0xa4(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x476eb
jmp 0x47778
jmp 0x4777a
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x4769d
jmp 0x47793
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
jmp 0x47609
jmp 0x477a6
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0x475f6
jmp 0x477b9
jmp 0x477bb
movq -0xb0(%rbp), %rcx
movzbl -0x69(%rbp), %eax
movzbl 0x400(%rcx,%rax), %eax
movzbl 0x488(%rcx), %ecx
imull %ecx, %eax
cvtsi2ss %eax, %xmm0
addss -0x5c(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movzbl -0x69(%rbp), %eax
cmpl $0x20, %eax
jne 0x477fe
movss -0x4c(%rbp), %xmm0
addss -0x5c(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movq -0xb0(%rbp), %rax
movl -0x58(%rbp), %edi
movss -0x5c(%rbp), %xmm0
movzbl 0x488(%rax), %eax
cvtsi2ss %eax, %xmm1
subss %xmm1, %xmm0
callq 0x47850
movl %eax, -0x58(%rbp)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x47476
movl -0x58(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)