Skip to content

Commit

Permalink
Merge pull request #58 from weihsinyeh/drop_shadow
Browse files Browse the repository at this point in the history
Render drop shadow for active window
  • Loading branch information
jserv authored Feb 4, 2025
2 parents 122f696 + d493323 commit f09d14b
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 9 deletions.
52 changes: 52 additions & 0 deletions apps/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
* All rights reserved.
*/

#include <stddef.h>
#include "apps_multi.h"

#define D(x) twin_double_to_fixed(x)
#define ASSET_PATH "assets/"

static void apps_line_start(twin_screen_t *screen, int x, int y, int w, int h)
{
Expand Down Expand Up @@ -272,6 +274,55 @@ static void apps_flower_start(twin_screen_t *screen, int x, int y, int w, int h)
twin_window_show(window);
}

static void apps_blur(twin_screen_t *screen, int x, int y, int w, int h)
{
twin_pixmap_t *raw_background = NULL;
#if defined(CONFIG_LOADER_PNG)
raw_background = twin_pixmap_from_file(ASSET_PATH "tux.png", TWIN_ARGB32);
#endif
if (!raw_background)
return;
twin_window_t *window = twin_window_create(
screen, TWIN_ARGB32, TwinWindowApplication, x, y, w, h);
twin_window_set_name(window, "Blur");
twin_pixmap_t *scaled_background = twin_pixmap_create(
TWIN_ARGB32, window->pixmap->width, window->pixmap->height);
twin_fixed_t sx, sy;
sx = twin_fixed_div(
twin_int_to_fixed(raw_background->width),
twin_int_to_fixed(window->client.right - window->client.left));
sy = twin_fixed_div(
twin_int_to_fixed(raw_background->height),
twin_int_to_fixed(window->client.bottom - window->client.top));

twin_matrix_scale(&raw_background->transform, sx, sy);
twin_operand_t srcop = {
.source_kind = TWIN_PIXMAP,
.u.pixmap = raw_background,
};

twin_composite(scaled_background, 0, 0, &srcop, 0, 0, 0, 0, 0, TWIN_SOURCE,
scaled_background->width, scaled_background->height);

twin_pointer_t src, dst;
for (int y = window->client.top; y < window->client.bottom; y++)
for (int x = window->client.left; x < window->client.right; x++) {
src =
twin_pixmap_pointer(scaled_background, x - window->client.left,
y - window->client.top);
dst = twin_pixmap_pointer(window->pixmap, x, y);
*dst.argb32 = *src.argb32 | 0xff000000;
}
twin_stack_blur(window->pixmap, 5, window->client.left,
window->client.right, window->client.top,
window->client.bottom);

twin_pixmap_destroy(scaled_background);
twin_pixmap_destroy(raw_background);
twin_window_show(window);
return;
}

void apps_multi_start(twin_screen_t *screen,
const char *name,
int x,
Expand All @@ -286,4 +337,5 @@ void apps_multi_start(twin_screen_t *screen,
apps_ascii_start(screen, x += 20, y += 20, w, h);
apps_jelly_start(screen, x += 20, y += 20, w / 2, h);
apps_flower_start(screen, x += 20, y += 20, w, h);
apps_blur(screen, x += 20, y += 20, w / 2, h / 2);
}
22 changes: 22 additions & 0 deletions configs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ config CURSOR
default n
depends on !BACKEND_VNC

config DROP_SHADOW
bool "Render drop shadow for active window"
default y

config HORIZONTAL_OFFSET
int "Horizontal offset"
default 1
range 1 10
depends on DROP_SHADOW

config VERTICAL_OFFSET
int "Vertical offset"
default 1
range 1 10
depends on DROP_SHADOW

config SHADOW_BLUR
int "Shadow blur radius"
default 10
range 1 10
depends on DROP_SHADOW

endmenu

menu "Image Loaders"
Expand Down
34 changes: 34 additions & 0 deletions include/twin.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@ typedef struct _twin_pixmap {
* Pixels
*/
twin_animation_t *animation;

#if defined(CONFIG_DROP_SHADOW)
/*
* When the pixel map is within the active window, it will have a drop
* shadow to enhance its visual distinction.
*/
bool shadow;
#endif

twin_pointer_t p;
/*
* When representing a window, this point
Expand Down Expand Up @@ -423,6 +432,13 @@ typedef void (*twin_destroy_func_t)(twin_window_t *window);
struct _twin_window {
twin_screen_t *screen;
twin_pixmap_t *pixmap;

#if defined(CONFIG_DROP_SHADOW)
/* Set the shadow range for horizontal and vertical directions. */
twin_coord_t shadow_x;
twin_coord_t shadow_y;
#endif

twin_window_style_t style;
twin_rect_t client;
twin_rect_t damage;
Expand Down Expand Up @@ -652,8 +668,26 @@ void twin_fill(twin_pixmap_t *dst,
* draw-common.c
*/

/* Blur the specified area in the pixel map. */
void twin_stack_blur(twin_pixmap_t *px,
int radius,
twin_coord_t left,
twin_coord_t right,
twin_coord_t top,
twin_coord_t bottom);

void twin_premultiply_alpha(twin_pixmap_t *px);

/*
* Overwrite the original pixel values for a specified number of pixels in
* width.
*/
void twin_cover(twin_pixmap_t *dst,
twin_argb32_t color,
twin_coord_t x,
twin_coord_t y,
twin_coord_t width);

/*
* event.c
*/
Expand Down
55 changes: 54 additions & 1 deletion include/twin_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,51 @@ typedef int64_t twin_xfixed_t;
(((t) = twin_get_8(d, i) + twin_get_8(s, i)), (twin_argb32_t) twin_sat(t) \
<< (i))

#define _twin_add_ARGB(s, d, i, t) (((t) = (s) + twin_get_8(d, i)))
#define _twin_add(s, d, t) (((t) = (s) + (d)))
#define _twin_div(d, den, i, t) \
(((t) = (d) / (den)), (t) = twin_get_8((t), 0), \
(twin_argb32_t) twin_sat(t) << (i))
#define _twin_sub_ARGB(s, d, i, t) (((t) = (s) - twin_get_8(d, i)))
#define _twin_sub(s, d, t) (((t) = (s) - (d)))
#define twin_put_8(d, i, t) (((t) = (d) << (i)))

#define twin_argb32_to_rgb16(s) \
((((s) >> 3) & 0x001f) | (((s) >> 5) & 0x07e0) | (((s) >> 8) & 0xf800))
#define twin_rgb16_to_argb32(s) \
(((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)) | 0xff000000)

#ifndef min
#if defined(__GNUC__) || defined(__clang__)
#define min(x, y) \
({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; \
})
#else
/* Generic implementation: potential side effects */
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif
#endif
#ifndef max
#if defined(__GNUC__) || defined(__clang__)
#define max(x, y) \
({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; \
})
#else
/* Generic implementation: potential side effects */
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif
#endif

typedef union {
twin_pointer_t p;
twin_argb32_t c;
Expand Down Expand Up @@ -468,7 +506,7 @@ void _twin_path_sfinish(twin_path_t *path);
#define twin_glyph_snap_y(g) (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))

/*
* dispatch stuff
* Dispatch stuff
*/
typedef struct _twin_queue {
struct _twin_queue *next;
Expand Down Expand Up @@ -593,6 +631,21 @@ void _twin_button_init(twin_button_t *button,
twin_style_t font_style,
twin_dispatch_proc_t dispatch);

/*
* Visual effect stuff
*/

#if defined(CONFIG_DROP_SHADOW)
/*
* Add a shadow with the specified color, horizontal offset, and vertical
* offset.
*/
void twin_shadow_border(twin_pixmap_t *shadow,
twin_argb32_t color,
twin_coord_t shift_x,
twin_coord_t shift_y);
#endif

/* utility */

#ifdef _MSC_VER
Expand Down
Loading

0 comments on commit f09d14b

Please sign in to comment.