diff --git a/Makefile b/Makefile index 47538ca..f0a6c0d 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ libtwin.a_files-y = \ src/pattern.c \ src/spline.c \ src/work.c \ + src/draw-common.c \ src/hull.c \ src/icon.c \ src/pixmap.c \ @@ -61,7 +62,7 @@ libtwin.a_files-$(CONFIG_LOGGING) += src/log.c libtwin.a_files-$(CONFIG_CURSOR) += src/cursor.c # Renderer -libtwin.a_files-$(CONFIG_RENDERER_BUILTIN) += src/draw.c +libtwin.a_files-$(CONFIG_RENDERER_BUILTIN) += src/draw-builtin.c libtwin.a_files-$(CONFIG_RENDERER_PIXMAN) += src/draw-pixman.c libtwin.a_cflags-$(CONFIG_RENDERER_PIXMAN) += $(shell pkg-config --cflags pixman-1) ifeq ($(CONFIG_RENDERER_PIXMAN), y) diff --git a/include/twin.h b/include/twin.h index 4098914..28a1d17 100644 --- a/include/twin.h +++ b/include/twin.h @@ -624,7 +624,7 @@ twin_pixmap_t *twin_make_cursor(int *hx, int *hy); void twin_dispatch(twin_context_t *ctx); /* - * draw.c + * draw-*.c */ void twin_composite(twin_pixmap_t *dst, @@ -648,6 +648,10 @@ void twin_fill(twin_pixmap_t *dst, twin_coord_t right, twin_coord_t bottom); +/* + * draw-common.c + */ + void twin_premultiply_alpha(twin_pixmap_t *px); /* diff --git a/src/draw.c b/src/draw-builtin.c similarity index 95% rename from src/draw.c rename to src/draw-builtin.c index 09dd13c..4b23227 100644 --- a/src/draw.c +++ b/src/draw-builtin.c @@ -681,49 +681,6 @@ void twin_composite(twin_pixmap_t *dst, 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, -#if __BYTE_ORDER == __BIG_ENDIAN - 0 -#else - 24 -#endif - ); - - /* clear RGB data if alpha is zero */ - if (!alpha) - return 0; - -#if __BYTE_ORDER == __BIG_ENDIAN - /* twin needs ARGB format */ - return alpha << 24 | twin_int_mult(twin_get_8(v, 24), alpha, t1) << 16 | - twin_int_mult(twin_get_8(v, 16), alpha, t2) << 8 | - twin_int_mult(twin_get_8(v, 8), alpha, t3) << 0; -#else - return alpha << 24 | twin_int_mult(twin_get_8(v, 0), alpha, t1) << 16 | - twin_int_mult(twin_get_8(v, 8), alpha, t2) << 8 | - twin_int_mult(twin_get_8(v, 16), alpha, t3) << 0; -#endif -} - -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 diff --git a/src/draw-common.c b/src/draw-common.c new file mode 100644 index 0000000..005bd1f --- /dev/null +++ b/src/draw-common.c @@ -0,0 +1,48 @@ +/* + * Twin - A Tiny Window System + * Copyright (c) 2004 Keith Packard + * Copyright (c) 2024 National Cheng Kung University, Taiwan + * All rights reserved. + */ + +#include "twin_private.h" + +static twin_argb32_t _twin_apply_alpha(twin_argb32_t v) +{ + uint16_t t1, t2, t3; + twin_a8_t alpha = twin_get_8(v, +#if __BYTE_ORDER == __BIG_ENDIAN + 0 +#else + 24 +#endif + ); + + /* clear RGB data if alpha is zero */ + if (!alpha) + return 0; + +#if __BYTE_ORDER == __BIG_ENDIAN + /* twin needs ARGB format */ + return alpha << 24 | twin_int_mult(twin_get_8(v, 24), alpha, t1) << 16 | + twin_int_mult(twin_get_8(v, 16), alpha, t2) << 8 | + twin_int_mult(twin_get_8(v, 8), alpha, t3) << 0; +#else + return alpha << 24 | twin_int_mult(twin_get_8(v, 0), alpha, t1) << 16 | + twin_int_mult(twin_get_8(v, 8), alpha, t2) << 8 | + twin_int_mult(twin_get_8(v, 16), alpha, t3) << 0; +#endif +} + +void twin_premultiply_alpha(twin_pixmap_t *px) +{ + if (px->format != TWIN_ARGB32) + return; + + for (twin_coord_t y = 0; y < px->height; y++) { + twin_pointer_t p = {.b = px->p.b + y * px->stride}; + + for (twin_coord_t x = 0; x < px->width; x++) + p.argb32[x] = _twin_apply_alpha(p.argb32[x]); + } +} diff --git a/src/draw-pixman.c b/src/draw-pixman.c index 970a727..9a96e15 100644 --- a/src/draw-pixman.c +++ b/src/draw-pixman.c @@ -166,47 +166,3 @@ void twin_fill(twin_pixmap_t *_dst, pixman_image_unref(dst); } - -/* Same function in draw.c */ -static twin_argb32_t _twin_apply_alpha(twin_argb32_t v) -{ - uint16_t t1, t2, t3; - twin_a8_t alpha = twin_get_8(v, -#if __BYTE_ORDER == __BIG_ENDIAN - 0 -#else - 24 -#endif - ); - - /* clear RGB data if alpha is zero */ - if (!alpha) - return 0; - -#if __BYTE_ORDER == __BIG_ENDIAN - /* twin needs ARGB format */ - return alpha << 24 | twin_int_mult(twin_get_8(v, 24), alpha, t1) << 16 | - twin_int_mult(twin_get_8(v, 16), alpha, t2) << 8 | - twin_int_mult(twin_get_8(v, 8), alpha, t3) << 0; -#else - return alpha << 24 | twin_int_mult(twin_get_8(v, 0), alpha, t1) << 16 | - twin_int_mult(twin_get_8(v, 8), alpha, t2) << 8 | - twin_int_mult(twin_get_8(v, 16), alpha, t3) << 0; -#endif -} - -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]); - } -}