From 04828b7d9909b22061e24ca7e339132cf9459bdc Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Wed, 15 Apr 2020 11:27:56 +0200 Subject: UI: Round splash image corners according to theme preferences Round the corners of the splash screen image according to the theme's User Interface > Menu Back > Roundness preference. Previously the rounding was added to the image itself, which was fiddly to do. The rounded corners of the popup background would not match the one of the image if the preference was changed. The current splash image will likely be updated to not include rounded corners in a separate commit. Differential Revision: https://developer.blender.org/D6847 Reviewed by: Julian Eisel (with some changes) --- .../windowmanager/intern/wm_splash_screen.c | 76 ++++++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) (limited to 'source/blender/windowmanager/intern/wm_splash_screen.c') diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c index 4cf6291c2e4..f953cc6707c 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.c +++ b/source/blender/windowmanager/intern/wm_splash_screen.c @@ -40,6 +40,7 @@ #include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "BKE_appdir.h" @@ -55,6 +56,7 @@ #include "ED_screen.h" #include "UI_interface.h" +#include "UI_resources.h" #include "WM_api.h" #include "WM_types.h" @@ -178,13 +180,65 @@ static void wm_block_splash_add_labels(uiBlock *block, int x, int y) #endif /* WITH_BUILDINFO */ } -static ImBuf *wm_block_splash_image(void) +static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf) +{ + uchar *rct = (uchar *)ibuf->rect; + + if (rct) { + bTheme *btheme = UI_GetTheme(); + const float roundness = btheme->tui.wcol_menu_back.roundness * U.dpi_fac; + const int size = roundness * 20; + + if (size < ibuf->x && size < ibuf->y) { + /* Y-axis initial offset. */ + rct += 4 * (ibuf->y - size) * ibuf->x; + + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++, rct += 4) { + const float pixel = 1.0 / size; + const float u = pixel * x; + const float v = pixel * y; + const float distance = sqrt(u * u + v * v); + + /* Pointer offset to the alpha value of pixel. */ + /* Note, the left corner is flipped in the X-axis. */ + const int offset_l = 4 * (size - x - x - 1) + 3; + const int offset_r = 4 * (ibuf->x - size) + 3; + + if (distance > 1.0) { + rct[offset_l] = 0; + rct[offset_r] = 0; + } + else { + /* Create a single pixel wide transition for anti-aliasing. + * Invert the distance and map its range [0, 1] to [0, pixel]. */ + const float fac = (1.0 - distance) * size; + + if (fac > 1.0) { + continue; + } + + const uchar alpha = unit_float_to_uchar_clamp(fac); + rct[offset_l] = alpha; + rct[offset_r] = alpha; + } + } + + /* X-axis offset to the next row. */ + rct += 4 * (ibuf->x - size); + } + } + } +} + +static ImBuf *wm_block_splash_image(int width, int *r_height) { #ifndef WITH_HEADLESS extern char datatoc_splash_png[]; extern int datatoc_splash_png_size; ImBuf *ibuf = NULL; + int height = 0; if (U.app_template[0] != '\0') { char splash_filepath[FILE_MAX]; @@ -202,6 +256,18 @@ static ImBuf *wm_block_splash_image(void) ibuf = IMB_ibImageFromMemory(splash_data, splash_data_size, IB_rect, NULL, ""); } + if (ibuf) { + height = (width * ibuf->y) / ibuf->x; + if (width != ibuf->x || height != ibuf->y) { + IMB_scaleImBuf(ibuf, width, height); + } + + wm_block_splash_image_roundcorners_add(ibuf); + IMB_premultiply_alpha(ibuf); + } + + *r_height = height; + return ibuf; #else UNUSED_VARS(r_unit_size); @@ -223,12 +289,12 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); + int splash_width = 500.0f * U.dpi_fac; + int splash_height; + /* Would be nice to support caching this, so it only has to be re-read (and likely resized) on * first draw or if the image changed. */ - ImBuf *ibuf = wm_block_splash_image(); - - float splash_width = 500.0f * U.dpi_fac; - float splash_height = (splash_width * ibuf->y) / ibuf->x; + ImBuf *ibuf = wm_block_splash_image(splash_width, &splash_height); but = uiDefButImage(block, ibuf, 0, 0.5f * U.widget_unit, splash_width, splash_height, NULL); -- cgit v1.2.3