Page MenuHome

UI: Made toolbar geom icons dark if background is light colored.
Needs ReviewPublic

Authored by Ankit Meel (ankitm) on Thu, Jan 2, 8:52 PM.



As noted in T64177, when the background of toolbar icons is light, it's hard to see light grey icons. This patch makes them darker, specifically darker shade of the color of the geom icon, wherever applies.

To test, go to Blender Preferences, Themes in the sidebar, expand user interface, expand toolbar item. Bump up "inner" to put the dot towards the whiter side, over half of the length. Then reopen blender. Further work to do is to change it without a restart.


The function Color_Dark takes in uint *col = (void *)geom->colors, an array defined outside this function to store the RGBA info as long as col inside uses it, and a theme pointer bTheme *btheme = UI_GetTheme() used in icon_draw_size() of interface_icons.c.

btheme or later testtheme gives data about inner color, its brightness is calculated, the brightness of one cell ( triangle I guess) is also calculated. When both over 0.5f, RGBA → RGB + A → HSL and L-inversion → RGB → RGBA. This is repeated for the three vertices, i.e. col, col + 1, col + 2.

Diff Detail

rB Blender

Event Timeline

There is one thing I would recommend trying to see if it gives you nicer results. You are currently inverting the colors by converting the rbg to HSL, inverting the L, then back to rgb. I think it will come out a bit nicer if you instead convert to HSV, invert the V, then back to rgb. HSV and HSL can seem quite similar but are actually different in how they treat "lightness".

Ankit Meel (ankitm) edited the summary of this revision. (Show Details)Fri, Jan 3, 2:53 PM
Ankit Meel (ankitm) added a comment.EditedFri, Jan 3, 3:03 PM

@Harley Acheson (harley) I had tried HSV first. Here's the crucial difference: V in HSV corresponds to the max(R,G,B) and maps it from 0-255 to 0-100 , while L in HSL corresponds to some weighted average of min(R,G,B) and max(R,G,B) both. So imagine (actually it exits) the scenario: RGB = (100, 0, 0). V would be 100, while L would be 50. After inversion, HSV gives a black pixel which is not what we need.

Check it here: or some other color tool.

So to compensate, 1-V + 0.35 or some other approximation would be required.
1-V, 1-V + 0.35, and 1-L respectively :

Ankit Meel (ankitm) edited the summary of this revision. (Show Details)Fri, Jan 3, 5:40 PM

@Ankit Meel (ankitm) - I had tried HSV first...

Ah, no worries. It just looked like your colors were a little less vibrant and made an assumption. But might have just been the captures. Here is what I was able to get with the code in that other patch for reference:

@Ankit Meel (ankitm) look at the "Icon Saturation" theme option and how desaturation is implemented.
You will find "gpu_shader_image_desaturate_frag.glsl" shader... I guess it's more correct to do something similar, for performance reasons.

Or maybe something like that:

diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 5f25316cf25..5e8b50483f5 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1838,6 +1838,33 @@ static void icon_draw_size(float x,
       ibuf = BKE_icon_geom_rasterize(icon->obj, w, h);
+      /* Invert geom icons. */
+      if (1)
+      {
+        unsigned char *rct = (unsigned char *)ibuf->rect;
+        if (rct) {
+          size_t i;
+          float rgba[4];
+          for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) {
+            rgba_uchar_to_float(rgba, rct);
+            premul_to_straight_v4(rgba);
+            /* invert rgb */
+            rgba[0] = 1.0 - rgba[0];
+            rgba[1] = 1.0 - rgba[1];
+            rgba[2] = 1.0 - rgba[2];
+            /* hue offset 180 */
+            rgb_float_set_hue_float_offset(rgba, 0.5f);
+            straight_to_premul_v4(rgba);
+            rgb_float_to_uchar(rct, rgba);
+          }
+        }
+      }
       di->data.geom.image_cache = ibuf;

You need to find a way to reload the icons when the theme changes.
See btheme->tui.icon_border_intensity for reference.
RNA_def_property_update(prop, 0, "rna_userdef_theme_update_icons")