Skip to content

Commit f09d14b

Browse files
authored
Merge pull request #58 from weihsinyeh/drop_shadow
Render drop shadow for active window
2 parents 122f696 + d493323 commit f09d14b

File tree

9 files changed

+477
-9
lines changed

9 files changed

+477
-9
lines changed

apps/multi.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
* All rights reserved.
55
*/
66

7+
#include <stddef.h>
78
#include "apps_multi.h"
89

910
#define D(x) twin_double_to_fixed(x)
11+
#define ASSET_PATH "assets/"
1012

1113
static void apps_line_start(twin_screen_t *screen, int x, int y, int w, int h)
1214
{
@@ -272,6 +274,55 @@ static void apps_flower_start(twin_screen_t *screen, int x, int y, int w, int h)
272274
twin_window_show(window);
273275
}
274276

277+
static void apps_blur(twin_screen_t *screen, int x, int y, int w, int h)
278+
{
279+
twin_pixmap_t *raw_background = NULL;
280+
#if defined(CONFIG_LOADER_PNG)
281+
raw_background = twin_pixmap_from_file(ASSET_PATH "tux.png", TWIN_ARGB32);
282+
#endif
283+
if (!raw_background)
284+
return;
285+
twin_window_t *window = twin_window_create(
286+
screen, TWIN_ARGB32, TwinWindowApplication, x, y, w, h);
287+
twin_window_set_name(window, "Blur");
288+
twin_pixmap_t *scaled_background = twin_pixmap_create(
289+
TWIN_ARGB32, window->pixmap->width, window->pixmap->height);
290+
twin_fixed_t sx, sy;
291+
sx = twin_fixed_div(
292+
twin_int_to_fixed(raw_background->width),
293+
twin_int_to_fixed(window->client.right - window->client.left));
294+
sy = twin_fixed_div(
295+
twin_int_to_fixed(raw_background->height),
296+
twin_int_to_fixed(window->client.bottom - window->client.top));
297+
298+
twin_matrix_scale(&raw_background->transform, sx, sy);
299+
twin_operand_t srcop = {
300+
.source_kind = TWIN_PIXMAP,
301+
.u.pixmap = raw_background,
302+
};
303+
304+
twin_composite(scaled_background, 0, 0, &srcop, 0, 0, 0, 0, 0, TWIN_SOURCE,
305+
scaled_background->width, scaled_background->height);
306+
307+
twin_pointer_t src, dst;
308+
for (int y = window->client.top; y < window->client.bottom; y++)
309+
for (int x = window->client.left; x < window->client.right; x++) {
310+
src =
311+
twin_pixmap_pointer(scaled_background, x - window->client.left,
312+
y - window->client.top);
313+
dst = twin_pixmap_pointer(window->pixmap, x, y);
314+
*dst.argb32 = *src.argb32 | 0xff000000;
315+
}
316+
twin_stack_blur(window->pixmap, 5, window->client.left,
317+
window->client.right, window->client.top,
318+
window->client.bottom);
319+
320+
twin_pixmap_destroy(scaled_background);
321+
twin_pixmap_destroy(raw_background);
322+
twin_window_show(window);
323+
return;
324+
}
325+
275326
void apps_multi_start(twin_screen_t *screen,
276327
const char *name,
277328
int x,
@@ -286,4 +337,5 @@ void apps_multi_start(twin_screen_t *screen,
286337
apps_ascii_start(screen, x += 20, y += 20, w, h);
287338
apps_jelly_start(screen, x += 20, y += 20, w / 2, h);
288339
apps_flower_start(screen, x += 20, y += 20, w, h);
340+
apps_blur(screen, x += 20, y += 20, w / 2, h / 2);
289341
}

configs/Kconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ config CURSOR
5555
default n
5656
depends on !BACKEND_VNC
5757

58+
config DROP_SHADOW
59+
bool "Render drop shadow for active window"
60+
default y
61+
62+
config HORIZONTAL_OFFSET
63+
int "Horizontal offset"
64+
default 1
65+
range 1 10
66+
depends on DROP_SHADOW
67+
68+
config VERTICAL_OFFSET
69+
int "Vertical offset"
70+
default 1
71+
range 1 10
72+
depends on DROP_SHADOW
73+
74+
config SHADOW_BLUR
75+
int "Shadow blur radius"
76+
default 10
77+
range 1 10
78+
depends on DROP_SHADOW
79+
5880
endmenu
5981

6082
menu "Image Loaders"

include/twin.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,15 @@ typedef struct _twin_pixmap {
195195
* Pixels
196196
*/
197197
twin_animation_t *animation;
198+
199+
#if defined(CONFIG_DROP_SHADOW)
200+
/*
201+
* When the pixel map is within the active window, it will have a drop
202+
* shadow to enhance its visual distinction.
203+
*/
204+
bool shadow;
205+
#endif
206+
198207
twin_pointer_t p;
199208
/*
200209
* When representing a window, this point
@@ -423,6 +432,13 @@ typedef void (*twin_destroy_func_t)(twin_window_t *window);
423432
struct _twin_window {
424433
twin_screen_t *screen;
425434
twin_pixmap_t *pixmap;
435+
436+
#if defined(CONFIG_DROP_SHADOW)
437+
/* Set the shadow range for horizontal and vertical directions. */
438+
twin_coord_t shadow_x;
439+
twin_coord_t shadow_y;
440+
#endif
441+
426442
twin_window_style_t style;
427443
twin_rect_t client;
428444
twin_rect_t damage;
@@ -652,8 +668,26 @@ void twin_fill(twin_pixmap_t *dst,
652668
* draw-common.c
653669
*/
654670

671+
/* Blur the specified area in the pixel map. */
672+
void twin_stack_blur(twin_pixmap_t *px,
673+
int radius,
674+
twin_coord_t left,
675+
twin_coord_t right,
676+
twin_coord_t top,
677+
twin_coord_t bottom);
678+
655679
void twin_premultiply_alpha(twin_pixmap_t *px);
656680

681+
/*
682+
* Overwrite the original pixel values for a specified number of pixels in
683+
* width.
684+
*/
685+
void twin_cover(twin_pixmap_t *dst,
686+
twin_argb32_t color,
687+
twin_coord_t x,
688+
twin_coord_t y,
689+
twin_coord_t width);
690+
657691
/*
658692
* event.c
659693
*/

include/twin_private.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,51 @@ typedef int64_t twin_xfixed_t;
181181
(((t) = twin_get_8(d, i) + twin_get_8(s, i)), (twin_argb32_t) twin_sat(t) \
182182
<< (i))
183183

184+
#define _twin_add_ARGB(s, d, i, t) (((t) = (s) + twin_get_8(d, i)))
185+
#define _twin_add(s, d, t) (((t) = (s) + (d)))
186+
#define _twin_div(d, den, i, t) \
187+
(((t) = (d) / (den)), (t) = twin_get_8((t), 0), \
188+
(twin_argb32_t) twin_sat(t) << (i))
189+
#define _twin_sub_ARGB(s, d, i, t) (((t) = (s) - twin_get_8(d, i)))
190+
#define _twin_sub(s, d, t) (((t) = (s) - (d)))
191+
#define twin_put_8(d, i, t) (((t) = (d) << (i)))
192+
184193
#define twin_argb32_to_rgb16(s) \
185194
((((s) >> 3) & 0x001f) | (((s) >> 5) & 0x07e0) | (((s) >> 8) & 0xf800))
186195
#define twin_rgb16_to_argb32(s) \
187196
(((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
188197
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
189198
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)) | 0xff000000)
190199

200+
#ifndef min
201+
#if defined(__GNUC__) || defined(__clang__)
202+
#define min(x, y) \
203+
({ \
204+
typeof(x) _x = (x); \
205+
typeof(y) _y = (y); \
206+
(void) (&_x == &_y); \
207+
_x < _y ? _x : _y; \
208+
})
209+
#else
210+
/* Generic implementation: potential side effects */
211+
#define min(x, y) ((x) < (y) ? (x) : (y))
212+
#endif
213+
#endif
214+
#ifndef max
215+
#if defined(__GNUC__) || defined(__clang__)
216+
#define max(x, y) \
217+
({ \
218+
typeof(x) _x = (x); \
219+
typeof(y) _y = (y); \
220+
(void) (&_x == &_y); \
221+
_x > _y ? _x : _y; \
222+
})
223+
#else
224+
/* Generic implementation: potential side effects */
225+
#define max(x, y) ((x) > (y) ? (x) : (y))
226+
#endif
227+
#endif
228+
191229
typedef union {
192230
twin_pointer_t p;
193231
twin_argb32_t c;
@@ -468,7 +506,7 @@ void _twin_path_sfinish(twin_path_t *path);
468506
#define twin_glyph_snap_y(g) (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))
469507

470508
/*
471-
* dispatch stuff
509+
* Dispatch stuff
472510
*/
473511
typedef struct _twin_queue {
474512
struct _twin_queue *next;
@@ -593,6 +631,21 @@ void _twin_button_init(twin_button_t *button,
593631
twin_style_t font_style,
594632
twin_dispatch_proc_t dispatch);
595633

634+
/*
635+
* Visual effect stuff
636+
*/
637+
638+
#if defined(CONFIG_DROP_SHADOW)
639+
/*
640+
* Add a shadow with the specified color, horizontal offset, and vertical
641+
* offset.
642+
*/
643+
void twin_shadow_border(twin_pixmap_t *shadow,
644+
twin_argb32_t color,
645+
twin_coord_t shift_x,
646+
twin_coord_t shift_y);
647+
#endif
648+
596649
/* utility */
597650

598651
#ifdef _MSC_VER

0 commit comments

Comments
 (0)