// File: /workspace/github_c_makefile_star2_O1/michaelforney[P]wld/pixman.c
// Function: renderer_draw_text
void
renderer_draw_text(struct wld_renderer *base,
                   struct font *font, uint32_t color,
                   int32_t x, int32_t y, const char *text,
                   uint32_t length, struct wld_extents *extents)
{
	struct pixman_renderer *renderer = pixman_renderer(base);
	int ret;
	uint32_t c;
	struct glyph *glyph;
	FT_UInt glyph_index;
	pixman_glyph_t *glyphs;
	uint32_t index = 0, origin_x = 0;
	pixman_color_t pixman_color = PIXMAN_COLOR(color);
	pixman_image_t *solid;

	if (length == -1)
		length = strlen(text);
	glyphs = malloc(length * sizeof(glyphs[0]));
	if (!glyphs)
		return;
	solid = pixman_image_create_solid_fill(&pixman_color);

	while ((ret = FcUtf8ToUcs4((FcChar8 *)text, &c, length)) > 0 && c != '\0') {
		text += ret;
		length -= ret;
		glyph_index = FT_Get_Char_Index(font->face, c);

		if (!font_ensure_glyph(font, glyph_index))
			continue;

		glyph = font->glyphs[glyph_index];

		glyphs[index].x = origin_x;
		glyphs[index].y = 0;
		glyphs[index].glyph = pixman_glyph_cache_lookup(renderer->glyph_cache,
		                                                font, glyph);

		/* If we don't have the glyph in our cache, do some conversions to make
		 * pixman happy, and then insert it. */
		if (!glyphs[index].glyph) {
			uint8_t *src, *dst;
			uint32_t row, byte_index, bytes_per_row, pitch;
			pixman_image_t *image;
			FT_Bitmap *bitmap;

			bitmap = &glyph->bitmap;
			image = pixman_image_create_bits(PIXMAN_a1, bitmap->width, bitmap->rows, NULL, bitmap->pitch);

			if (!image)
				goto advance;

			pitch = pixman_image_get_stride(image);
			bytes_per_row = (bitmap->width + 7) / 8;
			src = bitmap->buffer;
			dst = (uint8_t *)pixman_image_get_data(image);

			for (row = 0; row < bitmap->rows; ++row) {
				/* Pixman's A1 format expects the bits in the opposite order
				 * that Freetype gives us. Sigh... */
				for (byte_index = 0; byte_index < bytes_per_row; ++byte_index)
					dst[byte_index] = reverse(src[byte_index]);

				dst += pitch;
				src += bitmap->pitch;
			}

			/* Insert the glyph into the cache. */
			pixman_glyph_cache_freeze(renderer->glyph_cache);
			glyphs[index].glyph = pixman_glyph_cache_insert(renderer->glyph_cache, font, glyph,
			                                                -glyph->x, -glyph->y, image);
			pixman_glyph_cache_thaw(renderer->glyph_cache);

			/* The glyph cache copies the contents of the glyph bitmap. */
			pixman_image_unref(image);
		}

		++index;

	advance:
		origin_x += glyph->advance;
	}

	pixman_composite_glyphs_no_mask(PIXMAN_OP_OVER, solid, renderer->target,
	                                0, 0, x, y, renderer->glyph_cache,
	                                index, glyphs);

	free(glyphs);
	pixman_image_unref(solid);

	if (extents)
		extents->advance = origin_x;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
leaq 0xa409(%rip), %rax      # 0x17b18
movq %rdi, 0x28(%rsp)
cmpq %rax, (%rdi)
jne 0xda22
movq %r9, %r15
movl %r8d, %ebx
movl %ecx, %ebp
movq %rsi, %r12
movl 0xa0(%rsp), %r13d
movl %edx, %eax
shrl $0x10, %eax
movl $0xff, %ecx
movl %eax, %esi
andl %ecx, %esi
shll $0x8, %eax
orl %esi, %eax
movw %ax, 0x10(%rsp)
movl %edx, %eax
shrl $0x8, %eax
andl %ecx, %eax
movl %edx, %esi
andl $0xff00, %esi           # imm = 0xFF00
orl %eax, %esi
movw %si, 0x12(%rsp)
andl %edx, %ecx
movl %edx, %eax
shll $0x8, %eax
orl %ecx, %eax
movw %ax, 0x14(%rsp)
movl %edx, %eax
shrl $0x18, %eax
shldl $0x8, %edx, %eax
movw %ax, 0x16(%rsp)
cmpl $-0x1, %r13d
jne 0xd78b
movq %r15, %rdi
callq 0x9250
movq %rax, %r13
movl %r13d, %edi
shlq $0x4, %rdi
callq 0x9570
movq %rax, 0x20(%rsp)
testq %rax, %rax
je 0xda13
movq %rbx, 0x60(%rsp)
movl %ebp, 0x3c(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x90a0
movq %rax, 0x58(%rsp)
xorl %ebx, %ebx
leaq 0xc(%rsp), %rbp
movq $0x0, (%rsp)
movq %r15, %rdi
movq %rbp, %rsi
movl %r13d, %edx
callq 0x92a0
testl %eax, %eax
jle 0xd9b9
movl 0xc(%rsp), %esi
testl %esi, %esi
je 0xd9b9
movl %eax, %ecx
addq %rcx, %r15
subl %eax, %r13d
movq 0x18(%r12), %rdi
callq 0x9640
movl %eax, %r14d
movq %r12, %rdi
movl %eax, %esi
callq 0xa3b4
testb %al, %al
je 0xd7cc
movq 0x20(%r12), %rax
movl %r14d, %ecx
movq (%rax,%rcx,8), %rdx
movq (%rsp), %r14
movl %r14d, %ebp
shlq $0x4, %rbp
movq %rbx, %rax
movq 0x20(%rsp), %rbx
movq %rax, 0x50(%rsp)
movl %eax, (%rbx,%rbp)
movl $0x0, 0x4(%rbx,%rbp)
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rdi
movq %r12, %rsi
movq %rdx, 0x18(%rsp)
callq 0x9530
movq %rax, 0x8(%rbx,%rbp)
testq %rax, %rax
je 0xd885
incl %r14d
movq %r14, %rbp
movq 0x18(%rsp), %r14
movq %rbp, (%rsp)
movzwl 0x2c(%r14), %eax
movq 0x50(%rsp), %rbx
addl %eax, %ebx
leaq 0xc(%rsp), %rbp
jmp 0xd7cc
movq %rbp, 0x48(%rsp)
movq 0x18(%rsp), %r14
movl (%r14), %edx
movl 0x4(%r14), %esi
movl 0x8(%r14), %r8d
movl $0x1011000, %edi        # imm = 0x1011000
xorl %ecx, %ecx
callq 0x9670
testq %rax, %rax
je 0xd9b0
movq %rax, %rbp
movq %rax, %rdi
callq 0x9510
movl %eax, 0x34(%rsp)
movl 0x4(%r14), %eax
movl %eax, 0x38(%rsp)
movq 0x10(%r14), %rbx
movq %rbp, 0x40(%rsp)
movq %rbp, %rdi
callq 0x97a0
movl 0x38(%rsp), %r10d
cmpl $0x0, (%r14)
movq 0x48(%rsp), %rbp
je 0xd950
addl $0x7, %r10d
movl %r10d, %edx
shrl $0x3, %edx
movl 0x34(%rsp), %ecx
movl %edx, %edx
xorl %esi, %esi
cmpl $0x8, %r10d
jb 0xd93f
xorl %edi, %edi
movb (%rbx,%rdi), %r8b
rolb $0x4, %r8b
movl %r8d, %r9d
andb $0x33, %r9b
shlb $0x2, %r9b
shrb $0x2, %r8b
andb $0x33, %r8b
orb %r9b, %r8b
movl %r8d, %r9d
andb $0x55, %r9b
addb %r9b, %r9b
shrb %r8b
andb $0x55, %r8b
orb %r9b, %r8b
movb %r8b, (%rax,%rdi)
incq %rdi
cmpq %rdi, %rdx
jne 0xd901
addq %rcx, %rax
movslq 0x8(%r14), %rdi
addq %rdi, %rbx
incl %esi
cmpl (%r14), %esi
jb 0xd8f9
addq 0x20(%rsp), %rbp
movq 0x28(%rsp), %rbx
movq 0x18(%rbx), %rdi
callq 0x9660
movq 0x18(%rbx), %rdi
movswl 0x28(%r14), %ecx
negl %ecx
movswl 0x2a(%r14), %r8d
negl %r8d
movq %r12, %rsi
movq %r14, %rdx
movq 0x40(%rsp), %r14
movq %r14, %r9
callq 0x9560
movq %rax, 0x8(%rbp)
movq 0x18(%rbx), %rdi
callq 0x9280
movq %r14, %rdi
callq 0x93e0
testq %r14, %r14
movq (%rsp), %r14
jne 0xd860
jmp 0xd863
movq (%rsp), %rbp
jmp 0xd86b
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rdx
movl $0x3, %edi
movq 0x58(%rsp), %r15
movq %r15, %rsi
xorl %ecx, %ecx
xorl %r8d, %r8d
movl 0x3c(%rsp), %r9d
movq 0x20(%rsp), %r14
pushq %r14
pushq 0x8(%rsp)
pushq 0x18(%rax)
pushq 0x78(%rsp)
callq 0x92e0
addq $0x20, %rsp
movq %r14, %rdi
callq 0x9060
movq %r15, %rdi
callq 0x93e0
movq 0xa8(%rsp), %rax
testq %rax, %rax
je 0xda13
movl %ebx, (%rax)
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x33d0(%rip), %rdi      # 0x10df9
leaq 0x3a94(%rip), %rsi      # 0x114c4
leaq 0x3a96(%rip), %rcx      # 0x114cd
movl $0x38, %edx
callq 0x9380