[Bf-blender-cvs] [5f7eebda23b] master: Themes: add setting to draw border around icons, use for Blender Light

Jeroen Bakker noreply at git.blender.org
Thu May 9 19:55:47 CEST 2019


Commit: 5f7eebda23b844e932294b1ecaced46b5c75dde0
Author: Jeroen Bakker
Date:   Thu May 9 15:53:44 2019 +0200
Branches: master
https://developer.blender.org/rB5f7eebda23b844e932294b1ecaced46b5c75dde0

Themes: add setting to draw border around icons, use for Blender Light

Monochrome colored icons don't work well on a dark background, so now we can
add a border around them. Note that most icons in the interface will remain
without a border, just the outliner and properties editor navigation have
colored icons and those will get a border. Other icons continue to be drawn
in the text colored without a border.

Differential Revision: https://developer.blender.org/D4787

===================================================================

M	release/scripts/presets/interface_theme/blender_light.xml
M	release/scripts/startup/bl_ui/space_userpref.py
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/makesdna/DNA_userdef_types.h
M	source/blender/makesrna/intern/rna_userdef.c

===================================================================

diff --git a/release/scripts/presets/interface_theme/blender_light.xml b/release/scripts/presets/interface_theme/blender_light.xml
index 0420092c3a8..bb2b14a18d2 100644
--- a/release/scripts/presets/interface_theme/blender_light.xml
+++ b/release/scripts/presets/interface_theme/blender_light.xml
@@ -16,12 +16,13 @@
         gizmo_secondary="#63ffff"
         gizmo_a="#4da84d"
         gizmo_b="#a33535"
-        icon_scene="#000000ff"
-        icon_collection="#000000ff"
-        icon_object="#000000ff"
-        icon_object_data="#000000ff"
-        icon_modifier="#000000ff"
-        icon_shading="#000000ff"
+        icon_scene="#e6e6e6ff"
+        icon_collection="#e6e6e6ff"
+        icon_object="#e49759ff"
+        icon_object_data="#89e689ff"
+        icon_modifier="#84b8ffff"
+        icon_shading="#ff6060ff"
+        icon_border_intensity="0.75"
         >
         <wcol_regular>
           <ThemeWidgetColors
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 6db31775257..46cd4bfa904 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -895,6 +895,7 @@ class USERPREF_PT_theme_interface_icons(PreferencePanel, Panel):
         flow.prop(ui, "icon_object_data")
         flow.prop(ui, "icon_modifier")
         flow.prop(ui, "icon_shading")
+        flow.prop(ui, "icon_border_intensity")
 
 
 class USERPREF_PT_theme_text_style(PreferencePanel, Panel):
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 5666421c27f..8b9f439ec1c 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -52,6 +52,7 @@ typedef struct IconFile {
  * Resizable Icons for Blender
  */
 void UI_icons_init(void);
+void UI_icons_reload_internal_textures(void);
 int UI_icon_get_width(int icon_id);
 int UI_icon_get_height(int icon_id);
 
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 4cfc942d3f5..7fdaa99c464 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -37,6 +37,7 @@
 #include "BLI_utildefines.h"
 #include "BLI_fileops_types.h"
 #include "BLI_math_vector.h"
+#include "BLI_math_color_blend.h"
 
 #include "DNA_brush_types.h"
 #include "DNA_curve_types.h"
@@ -83,6 +84,7 @@
 #  define ICON_GRID_COLS 26
 #  define ICON_GRID_ROWS 30
 
+#  define ICON_MONO_BORDER_OUTSET 2
 #  define ICON_GRID_MARGIN 10
 #  define ICON_GRID_W 32
 #  define ICON_GRID_H 32
@@ -138,7 +140,8 @@ typedef struct DrawInfo {
 } DrawInfo;
 
 typedef struct IconTexture {
-  GLuint id;
+  GLuint id[2];
+  int num_textures;
   int w;
   int h;
   float invw;
@@ -154,7 +157,7 @@ typedef struct IconType {
 /* static here to cache results of icon directory scan, so it's not
  * scanning the filesystem each time the menu is drawn */
 static struct ListBase iconfilelist = {NULL, NULL};
-static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
+static IconTexture icongltex = {{0, 0}, 0, 0, 0, 0.0f, 0.0f};
 
 #ifndef WITH_HEADLESS
 
@@ -714,38 +717,146 @@ static void icon_verify_datatoc(IconImage *iimg)
   }
 }
 
-static void init_internal_icons(void)
+static ImBuf *create_mono_icon_with_border(ImBuf *buf,
+                                           int resolution_divider,
+                                           float border_intensity)
 {
-  //  bTheme *btheme = UI_GetTheme();
-  ImBuf *b16buf = NULL, *b32buf = NULL;
-  int x, y;
+  ImBuf *result = IMB_dupImBuf(buf);
+  const float border_sharpness = 16.0 / (resolution_divider * resolution_divider);
 
-#    if 0  // temp disabled
-  if ((btheme != NULL) && btheme->tui.iconfile[0]) {
-    char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
-    char iconfilestr[FILE_MAX];
+  float blurred_alpha_buffer[(ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) *
+                             (ICON_GRID_H + 2 * ICON_MONO_BORDER_OUTSET)];
+  const int icon_width = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
+  const int icon_height = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider;
 
-    if (icondir) {
-      BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
+  for (int y = 0; y < ICON_GRID_ROWS; y++) {
+    for (int x = 0; x < ICON_GRID_COLS; x++) {
+      IconType icontype = icontypes[y * ICON_GRID_COLS + x];
+      if (icontype.type != ICON_TYPE_MONO_TEXTURE) {
+        continue;
+      }
 
-      /* if the image is missing bbuf will just be NULL */
-      bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
+      int sx = x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN - ICON_MONO_BORDER_OUTSET;
+      int sy = y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN - ICON_MONO_BORDER_OUTSET;
+      sx = sx / resolution_divider;
+      sy = sy / resolution_divider;
+
+      /* blur the alpha channel and store it in blurred_alpha_buffer */
+      int blur_size = 2 / resolution_divider;
+      for (int bx = 0; bx < icon_width; bx++) {
+        const int asx = MAX2(bx - blur_size, 0);
+        const int aex = MIN2(bx + blur_size + 1, icon_width);
+        for (int by = 0; by < icon_height; by++) {
+          const int asy = MAX2(by - blur_size, 0);
+          const int aey = MIN2(by + blur_size + 1, icon_height);
+
+          // blur alpha channel
+          const int write_offset = by * (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) + bx;
+          float alpha_accum = 0.0;
+          unsigned int alpha_samples = 0;
+          for (int ax = asx; ax < aex; ax++) {
+            for (int ay = asy; ay < aey; ay++) {
+              const int offset_read = (sy + ay) * buf->x + (sx + ax);
+              unsigned int color_read = buf->rect[offset_read];
+              const float alpha_read = ((color_read & 0xff000000) >> 24) / 255.0;
+              alpha_accum += alpha_read;
+              alpha_samples += 1;
+            }
+          }
+          blurred_alpha_buffer[write_offset] = alpha_accum / alpha_samples;
+        }
+      }
 
-      if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
-        printf(
-            "\n***WARNING***\n"
-            "Icons file '%s' too small.\n"
-            "Using built-in Icons instead\n",
-            iconfilestr);
-        IMB_freeImBuf(bbuf);
-        bbuf = NULL;
+      /* apply blurred alpha */
+      for (int bx = 0; bx < icon_width; bx++) {
+        for (int by = 0; by < icon_height; by++) {
+          const int blurred_alpha_offset = by * (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) + bx;
+          const int offset_write = (sy + by) * buf->x + (sx + bx);
+          const float blurred_alpha = blurred_alpha_buffer[blurred_alpha_offset];
+          float border_srgb[4] = {
+              0, 0, 0, MIN2(1.0, blurred_alpha * border_sharpness) * border_intensity};
+
+          const unsigned int color_read = buf->rect[offset_write];
+          const unsigned char *orig_color = (unsigned char *)&color_read;
+
+          float border_rgba[4];
+          float orig_rgba[4];
+          float dest_rgba[4];
+          float dest_srgb[4];
+
+          srgb_to_linearrgb_v4(border_rgba, border_srgb);
+          srgb_to_linearrgb_uchar4(orig_rgba, orig_color);
+          blend_color_interpolate_float(dest_rgba, orig_rgba, border_rgba, 1.0 - orig_rgba[3]);
+          linearrgb_to_srgb_v4(dest_srgb, dest_rgba);
+
+          unsigned int alpha_mask = ((unsigned int)(dest_srgb[3] * 255)) << 24;
+          unsigned int cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask;
+          result->rect[offset_write] = cpack;
+        }
       }
     }
-    else {
-      printf("%s: 'icons' data path not found, continuing\n", __func__);
+  }
+  return result;
+}
+
+/* Generate the mipmap levels for the icon textures
+ * During creation the source16 ImBuf will be freed to reduce memory overhead
+ * A new ImBuf will be returned that needs is owned by the caller.
+ *
+ * FIXME: Mipmap levels are generated until the width of the image is 1, which
+ *        are too many levels than that are needed.*/
+static ImBuf *create_mono_icon_mipmaps(ImBuf *source32, ImBuf *source16, int level)
+{
+  if (level == 0) {
+    glTexImage2D(GL_TEXTURE_2D,
+                 level,
+                 GL_RGBA8,
+                 source32->x,
+                 source32->y,
+                 0,
+                 GL_RGBA,
+                 GL_UNSIGNED_BYTE,
+                 source32->rect);
+    return create_mono_icon_mipmaps(source32, source16, level + 1);
+  }
+  else {
+    glTexImage2D(GL_TEXTURE_2D,
+                 level,
+                 GL_RGBA8,
+                 source16->x,
+                 source16->y,
+                 0,
+                 GL_RGBA,
+                 GL_UNSIGNED_BYTE,
+                 source16->rect);
+    if (source16->x > 1) {
+      ImBuf *nbuf = IMB_onehalf(source16);
+      IMB_freeImBuf(source16);
+      source16 = create_mono_icon_mipmaps(source32, nbuf, level + 1);
     }
+    return source16;
   }
-#    endif
+}
+
+static void free_icons_textures(void)
+{
+  if (icongltex.num_textures > 0) {
+    glDeleteTextures(icongltex.num_textures, icongltex.id);
+    icongltex.id[0] = 0;
+    icongltex.id[1] = 0;
+    icongltex.num_textures = 0;
+  }
+}
+
+/* Reload the textures for internal icons.
+ * This function will release the previous textures. */
+void UI_icons_reload_internal_textures(void)
+{
+  bTheme *btheme = UI_GetTheme();
+  ImBuf *b16buf = NULL, *b32buf = NULL, *b16buf_border = NULL, *b32buf_border = NULL;
+  const float icon_border_intensity = btheme->tui.icon_border_intensity;
+  bool need_icons_with_border = icon_border_intensity > 0.0f;
+
   if (b16buf == NULL) {
     b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png,
                                    datatoc_blender_icons16_png_size,
@@ -754,6 +865,10 @@ static void init_internal_icons(void)
                                    "<blender icons>");
   }
   if (b16buf) {
+    if (need_icons_with_border) {
+      b16buf_border =

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list