/*
 * Twin - A Tiny Window System
 * Copyright © 2004 Keith Packard <keithp@keithp.com>
 * All rights reserved.
 *
 * This Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with the Twin Library; see the file COPYING.  If not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "twinint.h"

/* op, src, dst */
static twin_src_op  comp2[2][4][3] = {
    {	/* OVER */
	{   /* A8 */
	    _twin_a8_over_a8,
	    _twin_a8_over_rgb16,
	    _twin_a8_over_argb32,
	},
	{   /* RGB16 */
	    _twin_rgb16_over_a8,
	    _twin_rgb16_over_rgb16,
	    _twin_rgb16_over_argb32,
	},
	{   /* ARGB32 */
	    _twin_argb32_over_a8,
	    _twin_argb32_over_rgb16,
	    _twin_argb32_over_argb32,
	},
	{   /* C */
	    _twin_c_over_a8,
	    _twin_c_over_rgb16,
	    _twin_c_over_argb32,
	}
    },
    {	/* SOURCE */
	{   /* A8 */
	    _twin_a8_source_a8,
	    _twin_a8_source_rgb16,
	    _twin_a8_source_argb32,
	},
	{   /* RGB16 */
	    _twin_rgb16_source_a8,
	    _twin_rgb16_source_rgb16,
	    _twin_rgb16_source_argb32,
	},
	{   /* ARGB32 */
	    _twin_argb32_source_a8,
	    _twin_argb32_source_rgb16,
	    _twin_argb32_source_argb32,
	},
	{   /* C */
	    _twin_c_source_a8,
	    _twin_c_source_rgb16,
	    _twin_c_source_argb32,
	}
    }
};

/* op, src, msk, dst */
static twin_src_msk_op	comp3[2][4][4][3] = {
    {	/* OVER */
	{   /* A8 */
	    {	/* A8 */
		_twin_a8_in_a8_over_a8,
		_twin_a8_in_a8_over_rgb16,
		_twin_a8_in_a8_over_argb32,
	    },
	    {	/* RGB16 */
		_twin_a8_in_rgb16_over_a8,
		_twin_a8_in_rgb16_over_rgb16,
		_twin_a8_in_rgb16_over_argb32,
	    },
	    {	/* ARGB32 */
		_twin_a8_in_argb32_over_a8,
		_twin_a8_in_argb32_over_rgb16,
		_twin_a8_in_argb32_over_argb32,
	    },
	    {	/* C */
		_twin_a8_in_c_over_a8,
		_twin_a8_in_c_over_rgb16,
		_twin_a8_in_c_over_argb32,
	    },
	},
	{   /* RGB16 */
	    {	/* A8 */
		_twin_rgb16_in_a8_over_a8,
		_twin_rgb16_in_a8_over_rgb16,
		_twin_rgb16_in_a8_over_argb32,
	    },
	    {	/* RGB16 */
		_twin_rgb16_in_rgb16_over_a8,
		_twin_rgb16_in_rgb16_over_rgb16,
		_twin_rgb16_in_rgb16_over_argb32,
	    },
	    {	/* ARGB32 */
		_twin_rgb16_in_argb32_over_a8,
		_twin_rgb16_in_argb32_over_rgb16,
		_twin_rgb16_in_argb32_over_argb32,
	    },
	    {	/* C */
		_twin_rgb16_in_c_over_a8,
		_twin_rgb16_in_c_over_rgb16,
		_twin_rgb16_in_c_over_argb32,
	    },
	},
	{   /* ARGB32 */
	    {	/* A8 */
		_twin_argb32_in_a8_over_a8,
		_twin_argb32_in_a8_over_rgb16,
		_twin_argb32_in_a8_over_argb32,
	    },
	    {	/* RGB16 */
		_twin_argb32_in_rgb16_over_a8,
		_twin_argb32_in_rgb16_over_rgb16,
		_twin_argb32_in_rgb16_over_argb32,
	    },
	    {	/* ARGB32 */
		_twin_argb32_in_argb32_over_a8,
		_twin_argb32_in_argb32_over_rgb16,
		_twin_argb32_in_argb32_over_argb32,
	    },
	    {	/* C */
		_twin_argb32_in_c_over_a8,
		_twin_argb32_in_c_over_rgb16,
		_twin_argb32_in_c_over_argb32,
	    },
	},
	{   /* C */
	    {	/* A8 */
		_twin_c_in_a8_over_a8,
		_twin_c_in_a8_over_rgb16,
		_twin_c_in_a8_over_argb32,
	    },
	    {	/* RGB16 */
		_twin_c_in_rgb16_over_a8,
		_twin_c_in_rgb16_over_rgb16,
		_twin_c_in_rgb16_over_argb32,
	    },
	    {	/* ARGB32 */
		_twin_c_in_argb32_over_a8,
		_twin_c_in_argb32_over_rgb16,
		_twin_c_in_argb32_over_argb32,
	    },
	    {	/* C */
		_twin_c_in_c_over_a8,
		_twin_c_in_c_over_rgb16,
		_twin_c_in_c_over_argb32,
	    },
	},
    },
    {	/* SOURCE */
	{   /* A8 */
	    {	/* A8 */
		_twin_a8_in_a8_source_a8,
		_twin_a8_in_a8_source_rgb16,
		_twin_a8_in_a8_source_argb32,
	    },
	    {	/* RGB16 */
		_twin_a8_in_rgb16_source_a8,
		_twin_a8_in_rgb16_source_rgb16,
		_twin_a8_in_rgb16_source_argb32,
	    },
	    {	/* ARGB32 */
		_twin_a8_in_argb32_source_a8,
		_twin_a8_in_argb32_source_rgb16,
		_twin_a8_in_argb32_source_argb32,
	    },
	    {	/* C */
		_twin_a8_in_c_source_a8,
		_twin_a8_in_c_source_rgb16,
		_twin_a8_in_c_source_argb32,
	    },
	},
	{   /* RGB16 */
	    {	/* A8 */
		_twin_rgb16_in_a8_source_a8,
		_twin_rgb16_in_a8_source_rgb16,
		_twin_rgb16_in_a8_source_argb32,
	    },
	    {	/* RGB16 */
		_twin_rgb16_in_rgb16_source_a8,
		_twin_rgb16_in_rgb16_source_rgb16,
		_twin_rgb16_in_rgb16_source_argb32,
	    },
	    {	/* ARGB32 */
		_twin_rgb16_in_argb32_source_a8,
		_twin_rgb16_in_argb32_source_rgb16,
		_twin_rgb16_in_argb32_source_argb32,
	    },
	    {	/* C */
		_twin_rgb16_in_c_source_a8,
		_twin_rgb16_in_c_source_rgb16,
		_twin_rgb16_in_c_source_argb32,
	    },
	},
	{   /* ARGB32 */
	    {	/* A8 */
		_twin_argb32_in_a8_source_a8,
		_twin_argb32_in_a8_source_rgb16,
		_twin_argb32_in_a8_source_argb32,
	    },
	    {	/* RGB16 */
		_twin_argb32_in_rgb16_source_a8,
		_twin_argb32_in_rgb16_source_rgb16,
		_twin_argb32_in_rgb16_source_argb32,
	    },
	    {	/* ARGB32 */
		_twin_argb32_in_argb32_source_a8,
		_twin_argb32_in_argb32_source_rgb16,
		_twin_argb32_in_argb32_source_argb32,
	    },
	    {	/* C */
		_twin_argb32_in_c_source_a8,
		_twin_argb32_in_c_source_rgb16,
		_twin_argb32_in_c_source_argb32,
	    },
	},
	{   /* C */
	    {	/* A8 */
		_twin_c_in_a8_source_a8,
		_twin_c_in_a8_source_rgb16,
		_twin_c_in_a8_source_argb32,
	    },
	    {	/* RGB16 */
		_twin_c_in_rgb16_source_a8,
		_twin_c_in_rgb16_source_rgb16,
		_twin_c_in_rgb16_source_argb32,
	    },
	    {	/* ARGB32 */
		_twin_c_in_argb32_source_a8,
		_twin_c_in_argb32_source_rgb16,
		_twin_c_in_argb32_source_argb32,
	    },
	    {	/* C */
		_twin_c_in_c_source_a8,
		_twin_c_in_c_source_rgb16,
		_twin_c_in_c_source_argb32,
	    },
	},
    }
};

    
#define operand_index(o)    ((o)->source_kind == TWIN_SOLID ? 3 : o->u.pixmap->format)

/* XXX Fixme: source clipping is busted
 */
static void _twin_composite_simple (twin_pixmap_t	*dst,
				    twin_coord_t	dst_x,
				    twin_coord_t	dst_y,
				    twin_operand_t	*src,
				    twin_coord_t	src_x,
				    twin_coord_t	src_y,
				    twin_operand_t	*msk,
				    twin_coord_t	msk_x,
				    twin_coord_t	msk_y,
				    twin_operator_t	operator,
				    twin_coord_t	width,
				    twin_coord_t	height)
{
    twin_coord_t    iy;
    twin_coord_t    left, top, right, bottom;
    twin_coord_t    sdx, sdy;
    twin_source_u   s;

    dst_x += dst->origin_x;
    dst_y += dst->origin_y;
    left = dst_x;
    top = dst_y;
    right = dst_x + width;
    bottom = dst_y + height;

    /* clip */
    if (left < dst->clip.left)
	left = dst->clip.left;
    if (top < dst->clip.top)
	top = dst->clip.top;
    if (right > dst->clip.right)
	right = dst->clip.right;
    if (bottom > dst->clip.bottom)
	bottom = dst->clip.bottom;

    if (left >= right || top >= bottom)
	return;

    if (src->source_kind == TWIN_PIXMAP) {
	src_x += src->u.pixmap->origin_x;
	src_y += src->u.pixmap->origin_y;
    } else
        s.c = src->u.argb;
    
    sdx = src_x - dst_x;
    sdy = src_y - dst_y;

    if (msk) {
	twin_src_msk_op	op;
	twin_source_u   m;
	twin_coord_t	mdx, mdy;
	
	if (msk->source_kind == TWIN_PIXMAP) {
	    msk_x += msk->u.pixmap->origin_x;
	    msk_y += msk->u.pixmap->origin_y;
	} else
	    m.c = msk->u.argb;
	
	mdx = msk_x - dst_x;
	mdy = msk_y - dst_y;

	op = comp3[operator][operand_index(src)][operand_index(msk)][dst->format];
	for (iy = top; iy < bottom; iy++)
	{
	    if (src->source_kind == TWIN_PIXMAP)
		s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy);
	    if (msk->source_kind == TWIN_PIXMAP)
		m.p = twin_pixmap_pointer (msk->u.pixmap, left+mdx, iy+mdy);
	    (*op) (twin_pixmap_pointer (dst, left, iy), s, m, right - left);
	}
    }
    else
    {
	twin_src_op	op;
	
	op = comp2[operator][operand_index(src)][dst->format];
	
	for (iy = top; iy < bottom; iy++)
	{
	    if (src->source_kind == TWIN_PIXMAP)
		s.p = twin_pixmap_pointer (src->u.pixmap, left+sdx, iy+sdy);
	    (*op) (twin_pixmap_pointer (dst, left, iy), s, right - left);
	}
    }
    twin_pixmap_damage (dst, left, top, right, bottom);
}
	     
static inline int operand_xindex(twin_operand_t	*o)
{
    int ind = operand_index(o);

    return ind != TWIN_RGB16 ? ind : TWIN_ARGB32;
}

static twin_xform_t *twin_pixmap_init_xform (twin_pixmap_t *pixmap,
					     twin_coord_t left, twin_coord_t width,
					     twin_coord_t src_x, twin_coord_t src_y)
{
    twin_xform_t	*xform;
    twin_format_t	fmt = pixmap->format;

    if (fmt == TWIN_RGB16)
	fmt = TWIN_ARGB32;

    xform = calloc(1, sizeof (twin_xform_t) +
		   width * twin_bytes_per_pixel(fmt));
    if (xform == NULL)
	return NULL;

    xform->span.v = (twin_argb32_t *)(char *)(xform + 1);
    xform->pixmap = pixmap;
    xform->left = left;
    xform->width = width;
    xform->src_x = src_x;
    xform->src_y = src_y;

    return xform;
}

static void twin_pixmap_free_xform (twin_xform_t *xform)
{
    if (xform)
	free (xform);
}

#define FX(x)	twin_int_to_fixed(x)
#define XF(x)	twin_fixed_to_int(x)

/* we are doing clipping on source... dunno if that makes much sense
 * but here we go ... if we decide that source clipping makes no sense
 * then we need to still test wether we fit in the pixmap boundaries
 * here. source clipping is useful if you try to extract one image
 * out of a big picture though.
 */
#define _pix_clipped(pix, x, y) \
	((x) < FX((pix)->clip.left) || (x) >= FX((pix)->clip.right) || \
	 (y) < FX((pix)->clip.top)  || (y) >= FX((pix)->clip.bottom))

#define _get_pix_8(d, pix, x, y) \
    do { \
	(d) = _pix_clipped(pix, x, y) ? 0 : \
	          *((pix)->p.a8 + XF(y) * (pix)->stride + XF(x)); \
    } while(0)

#define _get_pix_16(d, pix, x, y) \
    do { \
	twin_rgb16_t p = _pix_clipped(pix, x, y) ? 0 : \
	    *((pix)->p.argb32 + XF(y) * ((pix)->stride >> 1) + XF(x)); \
	*((twin_argb32_t *)(char *)(d)) = twin_rgb16_to_argb32(p); \
    } while(0)

#define _get_pix_32(d, pix, x, y) \
    do { \
	twin_argb32_t p = _pix_clipped(pix, x, y) ? 0 : \
	    *((pix)->p.argb32 + XF(y) * ((pix)->stride >> 2) + XF(x)); \
	*((twin_argb32_t *)(char *)(d)) = p; \
    } while(0)


#define _pix_saucemix(tl, tr, bl, br, wx, wy) \
	(( ((((br * wx) + (bl * (TWIN_FIXED_ONE - wx))) >> 16) \
		* wy) + \
	   ((((tr * wx) + (tl * (TWIN_FIXED_ONE - wx))) >> 16) \
		* (TWIN_FIXED_ONE - wy)) \
	 ) >> 16)


static void twin_pixmap_read_xform_8 (twin_xform_t *xform, twin_coord_t line)
{
    twin_fixed_t dx, dy, sx, sy;
    unsigned int wx, wy;
    twin_a8_t pts[4];
    twin_a8_t *dst = xform->span.a8;
    twin_pixmap_t *pix = xform->pixmap;
    twin_matrix_t *tfm = &xform->pixmap->transform;

    /* for each row in the dest line */
    dy = twin_int_to_fixed(line);
    for (dx = 0; dx < twin_int_to_fixed(xform->width); dx += TWIN_FIXED_ONE) {
	sx = _twin_matrix_fx(tfm, dx, dy) + FX(xform->src_x);
	sy = _twin_matrix_fy(tfm, dx, dy) + FX(xform->src_y);
	_get_pix_8(pts[0], pix, sx, sy);
	_get_pix_8(pts[1], pix, sx + TWIN_FIXED_ONE, sy);
	_get_pix_8(pts[2], pix, sx, sy + TWIN_FIXED_ONE);
	_get_pix_8(pts[3], pix, sx, sy + TWIN_FIXED_ONE);
	wx = sx & 0xffff;
	wy = sy & 0xffff;
	*(dst++) = _pix_saucemix(pts[0], pts[1], pts[2], pts[4], wx, wy);
    }
}

static void twin_pixmap_read_xform_16 (twin_xform_t *xform, twin_coord_t line)
{
    twin_fixed_t dx, dy, sx, sy;
    unsigned int wx, wy;
    twin_a8_t pts[4][4];
    twin_a8_t *dst = xform->span.a8;
    twin_pixmap_t *pix = xform->pixmap;
    twin_matrix_t *tfm = &xform->pixmap->transform;

    /* for each row in the dest line */
    dy = twin_int_to_fixed(line);
    for (dx = 0; dx < twin_int_to_fixed(xform->width); dx += TWIN_FIXED_ONE) {
	sx = _twin_matrix_fx(tfm, dx, dy) + FX(xform->src_x);
	sy = _twin_matrix_fy(tfm, dx, dy) + FX(xform->src_y);
	_get_pix_16(pts[0], pix, sx, sy);
	_get_pix_16(pts[1], pix, sx + TWIN_FIXED_ONE, sy);
	_get_pix_16(pts[2], pix, sx, sy + TWIN_FIXED_ONE);
	_get_pix_16(pts[3], pix, sx + TWIN_FIXED_ONE, sy + TWIN_FIXED_ONE);
	wx = sx & 0xffff;
	wy = sy & 0xffff;
	*(dst++) = _pix_saucemix(pts[0][0], pts[1][0],
				 pts[2][0], pts[3][0], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][1], pts[1][1],
				 pts[2][1], pts[3][1], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][2], pts[1][2],
				 pts[2][2], pts[3][2], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][3], pts[1][3],
				 pts[2][3], pts[3][3], wx, wy);
    }
}

static void twin_pixmap_read_xform_32 (twin_xform_t *xform, twin_coord_t line)
{
    twin_fixed_t dx, dy, sx, sy;
    unsigned int wx, wy;
    twin_a8_t pts[4][4];
    twin_a8_t *dst = xform->span.a8;
    twin_pixmap_t *pix = xform->pixmap;
    twin_matrix_t *tfm = &xform->pixmap->transform;

    /* for each row in the dest line */
    dy = twin_int_to_fixed(line);
    for (dx = 0; dx < twin_int_to_fixed(xform->width); dx += TWIN_FIXED_ONE) {
	sx = _twin_matrix_fx(tfm, dx, dy) + FX(xform->src_x);
	sy = _twin_matrix_fy(tfm, dx, dy) + FX(xform->src_y);
	_get_pix_32(pts[0], pix, sx, sy);
	_get_pix_32(pts[1], pix, sx + TWIN_FIXED_ONE, sy);
	_get_pix_32(pts[2], pix, sx, sy + TWIN_FIXED_ONE);
	_get_pix_32(pts[3], pix, sx + TWIN_FIXED_ONE, sy + TWIN_FIXED_ONE);
	wx = sx & 0xffff;
	wy = sy & 0xffff;
	*(dst++) = _pix_saucemix(pts[0][0], pts[1][0],
				 pts[2][0], pts[3][0], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][1], pts[1][1],
				 pts[2][1], pts[3][1], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][2], pts[1][2],
				 pts[2][2], pts[3][2], wx, wy);
	*(dst++) = _pix_saucemix(pts[0][3], pts[1][3],
				 pts[2][3], pts[3][3], wx, wy);
    }
}

static void twin_pixmap_read_xform (twin_xform_t *xform, twin_coord_t line)
{
    if (xform->pixmap->format == TWIN_A8)
	twin_pixmap_read_xform_8(xform, line);
    else if (xform->pixmap->format == TWIN_RGB16)
	twin_pixmap_read_xform_16(xform, line);
    else if (xform->pixmap->format == TWIN_ARGB32)
	twin_pixmap_read_xform_32(xform, line);
}

static void _twin_composite_xform (twin_pixmap_t	*dst,
				   twin_coord_t		dst_x,
				   twin_coord_t		dst_y,
				   twin_operand_t	*src,
				   twin_coord_t		src_x,
				   twin_coord_t		src_y,
				   twin_operand_t	*msk,
				   twin_coord_t		msk_x,
				   twin_coord_t		msk_y,
				   twin_operator_t	operator,
				   twin_coord_t		width,
				   twin_coord_t		height)
{
    twin_coord_t    iy;
    twin_coord_t    left, top, right, bottom;
    twin_xform_t    *sxform = NULL, *mxform = NULL;
    twin_source_u   s;

    dst_x += dst->origin_x;
    dst_y += dst->origin_y;
    left = dst_x;
    top = dst_y;
    right = dst_x + width;
    bottom = dst_y + height;

    /* clip */
    if (left < dst->clip.left)
	left = dst->clip.left;
    if (top < dst->clip.top)
	top = dst->clip.top;
    if (right > dst->clip.right)
	right = dst->clip.right;
    if (bottom > dst->clip.bottom)
	bottom = dst->clip.bottom;

    if (left >= right || top >= bottom)
	return;

    width = right - left;
    height = bottom - top;

    if (src->source_kind == TWIN_PIXMAP) {	
	src_x += src->u.pixmap->origin_x;
	src_y += src->u.pixmap->origin_y;
	sxform = twin_pixmap_init_xform(src->u.pixmap, left, width,
					src_x, src_y);
	if (sxform == NULL)
	    return;
	s.p = sxform->span;
    } else
        s.c = src->u.argb;

    if (msk) {
	twin_src_msk_op	op;
	twin_source_u   m;
	
	if (msk->source_kind == TWIN_PIXMAP) {
	    msk_x += msk->u.pixmap->origin_x;
	    msk_y += msk->u.pixmap->origin_y;
	    mxform = twin_pixmap_init_xform(msk->u.pixmap, left, width,
					    msk_x, msk_y);
	    if (mxform == NULL)
		return;
	    m.p = mxform->span;
	} else
	    m.c = msk->u.argb;
	
	op = comp3[operator][operand_xindex(src)][operand_xindex(msk)]
		[dst->format];
	for (iy = top; iy < bottom; iy++) {
	    if (src->source_kind == TWIN_PIXMAP)
		twin_pixmap_read_xform (sxform, iy - top);
	    if (msk->source_kind == TWIN_PIXMAP)
		twin_pixmap_read_xform (mxform, iy - top);
	    (*op) (twin_pixmap_pointer (dst, left, iy), s, m, right - left);
	}
    } else {
	twin_src_op	op;
	
	op = comp2[operator][operand_xindex(src)][dst->format];	

	for (iy = top; iy < bottom; iy++) {
	     if (src->source_kind == TWIN_PIXMAP)
		twin_pixmap_read_xform (sxform, iy - top);
	    (*op) (twin_pixmap_pointer (dst, left, iy), s, right - left);
	}
    }
    twin_pixmap_damage (dst, left, top, right, bottom);
    twin_pixmap_free_xform(sxform);
    twin_pixmap_free_xform(mxform);
}

void twin_composite (twin_pixmap_t	*dst,
		     twin_coord_t	dst_x,
		     twin_coord_t	dst_y,
		     twin_operand_t	*src,
		     twin_coord_t	src_x,
		     twin_coord_t	src_y,
		     twin_operand_t	*msk,
		     twin_coord_t	msk_x,
		     twin_coord_t	msk_y,
		     twin_operator_t	operator,
		     twin_coord_t	width,
		     twin_coord_t	height)
{
    if ((src->source_kind == TWIN_PIXMAP &&
       !twin_matrix_is_identity(&src->u.pixmap->transform)) ||
        (msk && (msk->source_kind == TWIN_PIXMAP &&
		 !twin_matrix_is_identity(&msk->u.pixmap->transform))))
        _twin_composite_xform(dst, dst_x, dst_y,
				  src, src_x, src_y,
				  msk, msk_x, msk_y,
				  operator, width, height);
    else
	_twin_composite_simple(dst, dst_x, dst_y,
			       src, src_x, src_y,
			       msk, msk_x, msk_y,
			       operator, width, height);
}

static twin_argb32_t _twin_apply_alpha(twin_argb32_t v)
{
    uint16_t t1, t2, t3;
    twin_a8_t alpha = twin_get_8(v, (__BYTE_ORDER == __BIG_ENDIAN) ? 24 : 0);

    /* clear RGB data if alpha is zero */

    if (!alpha)
	return 0;

    /* twin needs ARGB format */

    if (__BYTE_ORDER == __BIG_ENDIAN)
	return alpha << 24 |
	    twin_int_mult(twin_get_8(v, 16), alpha, t1) << 16 |
	    twin_int_mult(twin_get_8(v, 8), alpha, t2) << 8 |
	    twin_int_mult(twin_get_8(v, 0), alpha, t3) << 0;

    return alpha << 24 |
	twin_int_mult(twin_get_8(v, 8), alpha, t1) << 16 |
	twin_int_mult(twin_get_8(v, 16), alpha, t2) << 8 |
	twin_int_mult(twin_get_8(v, 24), alpha, t3) << 0;
}

void twin_premultiply_alpha(twin_pixmap_t *px)
{
    int x, y;
    twin_pointer_t p;

    if (px->format != TWIN_ARGB32)
	return;

    for (y = 0; y < px->height; y++) {
	p.b = px->p.b + y * px->stride;

	for (x = 0; x < px->width; x++)
	    p.argb32[x] = _twin_apply_alpha(p.argb32[x]);
    }
}

/*
 * array primary    index is OVER SOURCE
 * array secondary  index is ARGB32 RGB16 A8
 */
static twin_src_op  fill[2][3] = {
    {	/* OVER */
	_twin_c_over_a8,
	_twin_c_over_rgb16,
	_twin_c_over_argb32,
    },
    {	/* SOURCE */
	_twin_c_source_a8,
	_twin_c_source_rgb16,
	_twin_c_source_argb32,
    }
};

void
twin_fill (twin_pixmap_t    *dst,
	   twin_argb32_t    pixel,
	   twin_operator_t  operator,
	   twin_coord_t	    left,
	   twin_coord_t	    top,
	   twin_coord_t	    right,
	   twin_coord_t	    bottom)
{
    twin_src_op	    op;
    twin_source_u   src;
    twin_coord_t    iy;

    /* offset */
    left += dst->origin_x;
    top += dst->origin_y;
    right += dst->origin_x;
    bottom += dst->origin_y;

    /* clip */
    if (left < dst->clip.left)
	left = dst->clip.left;
    if (right > dst->clip.right)
	right = dst->clip.right;
    if (top < dst->clip.top)
	top = dst->clip.top;
    if (bottom > dst->clip.bottom)
	bottom = dst->clip.bottom;
    if (left >= right || top >= bottom)
	return;
    src.c = pixel;
    op = fill[operator][dst->format];
    for (iy = top; iy < bottom; iy++)
	(*op) (twin_pixmap_pointer (dst, left, iy), src, right - left);
    twin_pixmap_damage (dst, left, top, right, bottom);
}

void
_twin_draw_set_features(void)
{
#ifdef HAVE_ALTIVEC
    if (twin_has_feature(TWIN_FEATURE_ALTIVEC)) {
	    comp2[TWIN_SOURCE][TWIN_ARGB32][TWIN_ARGB32] =
		    _twin_vec_argb32_source_argb32;
	    comp2[TWIN_OVER][TWIN_ARGB32][TWIN_ARGB32] =
		    _twin_vec_argb32_over_argb32;
    }
#endif /* HAVE_ALTIVEC */
}

