@@ -533,6 +533,9 @@ highlight_link_id(int id)
533533}
534534#endif
535535
536+ static void resolve_fallback_fg_to_rgb (void );
537+ static void resolve_fallback_bg_to_rgb (void );
538+
536539 void
537540init_highlight (
538541 int both , // include groups where 'bg' doesn't matter
@@ -616,6 +619,8 @@ init_highlight(
616619 }
617620 }
618621#endif
622+ resolve_fallback_fg_to_rgb ();
623+ resolve_fallback_bg_to_rgb ();
619624}
620625
621626#if defined(FEAT_EVAL ) && (defined(FEAT_GUI ) || defined(FEAT_TERMGUICOLORS ))
@@ -1977,6 +1982,8 @@ do_highlight(
19771982 redraw_all_later (UPD_NOT_VALID );
19781983 }
19791984#endif
1985+ resolve_fallback_fg_to_rgb ();
1986+ resolve_fallback_bg_to_rgb ();
19801987#ifdef FEAT_VTP
19811988 control_console_color_rgb ();
19821989#endif
@@ -2091,6 +2098,8 @@ restore_cterm_colors(void)
20912098 cterm_normal_bg_gui_color = INVALCOLOR ;
20922099 cterm_normal_ul_gui_color = INVALCOLOR ;
20932100# endif
2101+ fallback_fg_rgb = INVALCOLOR ;
2102+ fallback_bg_rgb = INVALCOLOR ;
20942103#endif
20952104}
20962105
@@ -3259,6 +3268,53 @@ resolve_color_to_rgb(int cterm_c, guicolor_T rgb UNUSED, int *r, int *g, int *b)
32593268 return false;
32603269}
32613270
3271+ /*
3272+ * get a RGB fallback color from gui, cterm or default color
3273+ */
3274+ static guicolor_T
3275+ resolve_fallback_color (int cterm_c , guicolor_T rgb , guicolor_T default_rgb )
3276+ {
3277+ int red , green , blue ;
3278+ if (!resolve_color_to_rgb (cterm_c , rgb , & red , & green , & blue ))
3279+ return default_rgb ;
3280+ else
3281+ return (red << 16 ) | (green << 8 ) | blue ;
3282+ }
3283+
3284+ /*
3285+ * get a RGB fallback foreground color from guifg, ctermfg or deduced from background
3286+ */
3287+ static void
3288+ resolve_fallback_fg_to_rgb (void )
3289+ {
3290+ guicolor_T fgcolor_or_gui_fgcolor = INVALCOLOR ;
3291+ #ifdef FEAT_TERMGUICOLORS
3292+ fgcolor_or_gui_fgcolor = cterm_normal_fg_gui_color ;
3293+ #endif
3294+ #ifdef FEAT_GUI
3295+ if (gui .in_use )
3296+ fgcolor_or_gui_fgcolor = gui .norm_pixel ;
3297+ #endif
3298+ fallback_fg_rgb = resolve_fallback_color (cterm_normal_fg_color , fgcolor_or_gui_fgcolor , (* p_bg == 'l' ) ? 0x000000 : 0xFFFFFF );
3299+ }
3300+
3301+ /*
3302+ * get a RGB fallback background color from guifg, ctermbg or deduced from background
3303+ */
3304+ static void
3305+ resolve_fallback_bg_to_rgb (void )
3306+ {
3307+ guicolor_T bgcolor_or_gui_bgcolor = INVALCOLOR ;
3308+ #ifdef FEAT_TERMGUICOLORS
3309+ bgcolor_or_gui_bgcolor = cterm_normal_bg_gui_color ;
3310+ #endif
3311+ #ifdef FEAT_GUI
3312+ if (gui .in_use )
3313+ bgcolor_or_gui_bgcolor = gui .back_pixel ;
3314+ #endif
3315+ fallback_bg_rgb = resolve_fallback_color (cterm_normal_bg_color , bgcolor_or_gui_bgcolor , (* p_bg == 'l' ) ? 0xFFFFFF : 0x000000 );
3316+ }
3317+
32623318/*
32633319 * Blend two colors expressed as (cterm 256 index, gui RGB) pairs and
32643320 * return the nearest 1-based cterm 256-color index. Prefers the gui
@@ -3325,14 +3381,7 @@ blend_colors(guicolor_T popup_color, guicolor_T bg_color, int blend_val)
33253381 b1 = popup_color & 0xFF ;
33263382
33273383 if (COLOR_INVALID (bg_color ))
3328- {
3329- // Background color unknown: fade popup color to black as blend increases
3330- // This makes background text more visible at high blend values
3331- r = r1 * (100 - blend_val ) / 100 ;
3332- g = g1 * (100 - blend_val ) / 100 ;
3333- b = b1 * (100 - blend_val ) / 100 ;
3334- return (r << 16 ) | (g << 8 ) | b ;
3335- }
3384+ bg_color = fallback_bg_rgb ;
33363385
33373386 r2 = (bg_color >> 16 ) & 0xFF ;
33383387 g2 = (bg_color >> 8 ) & 0xFF ;
@@ -3392,7 +3441,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
33923441 // blend_fg=TRUE: fade underlying text toward popup bg.
33933442 if (popup_aep -> ae_u .gui .bg_color != INVALCOLOR )
33943443 {
3395- int base_fg = 0xFFFFFF ;
3444+ int base_fg = fallback_fg_rgb ;
33963445 if (char_aep != NULL
33973446 && char_aep -> ae_u .gui .fg_color != INVALCOLOR )
33983447 base_fg = char_aep -> ae_u .gui .fg_color ;
@@ -3414,7 +3463,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
34143463 // Blend background color: blend popup bg toward underlying bg
34153464 if (popup_aep -> ae_u .gui .bg_color != INVALCOLOR )
34163465 {
3417- guicolor_T underlying_bg = INVALCOLOR ;
3466+ guicolor_T underlying_bg = fallback_bg_rgb ;
34183467 if (char_aep != NULL )
34193468 underlying_bg = char_aep -> ae_u .gui .bg_color ;
34203469 new_en .ae_u .gui .bg_color = blend_colors (
@@ -3489,7 +3538,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
34893538#endif
34903539 new_en .ae_u .cterm .fg_color = blend_cterm_colors (
34913540 popup_aep -> ae_u .cterm .bg_color , popup_bg_rgb ,
3492- under_fg , under_fg_rgb , 0xFFFFFF , blend );
3541+ under_fg , under_fg_rgb , fallback_fg_rgb , blend );
34933542 }
34943543 // Approximate cterm bg by blending with the underlying bg
34953544 // in the 256-color palette and mapping to the nearest entry.
@@ -3505,7 +3554,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35053554#endif
35063555 new_en .ae_u .cterm .bg_color = blend_cterm_colors (
35073556 popup_aep -> ae_u .cterm .bg_color , popup_bg_rgb ,
3508- under_bg , under_bg_rgb , 0x000000 , blend );
3557+ under_bg , under_bg_rgb , fallback_bg_rgb , blend );
35093558 }
35103559#ifdef FEAT_TERMGUICOLORS
35113560 // Blend RGB colors for termguicolors mode.
@@ -3529,7 +3578,7 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35293578 // blend_fg=TRUE: fade underlying text toward popup bg.
35303579 if (popup_bg != INVALCOLOR )
35313580 {
3532- int base_fg = 0xFFFFFF ;
3581+ int base_fg = fallback_fg_rgb ;
35333582 // CTERMCOLOR is a sentinel meaning "use the cterm
35343583 // color"; treat it as no underlying color so it is
35353584 // not blended in as a real near-white pixel.
@@ -3554,12 +3603,12 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
35543603 else if (!COLOR_INVALID (cterm_normal_fg_gui_color ))
35553604 new_en .ae_u .cterm .fg_rgb = cterm_normal_fg_gui_color ;
35563605 else
3557- new_en .ae_u .cterm .fg_rgb = 0xFFFFFF ;
3606+ new_en .ae_u .cterm .fg_rgb = fallback_fg_rgb ;
35583607 }
35593608 if (popup_bg != INVALCOLOR )
35603609 {
35613610 // Blend popup bg toward underlying bg
3562- guicolor_T underlying_bg = INVALCOLOR ;
3611+ guicolor_T underlying_bg = fallback_bg_rgb ;
35633612 if (char_aep != NULL
35643613 && !COLOR_INVALID (char_aep -> ae_u .cterm .bg_rgb ))
35653614 underlying_bg = char_aep -> ae_u .cterm .bg_rgb ;
@@ -3626,7 +3675,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36263675 // blend=100 (transparent): fg = underlying_fg (text visible)
36273676 if (popup_aep -> ae_u .gui .bg_color != INVALCOLOR )
36283677 {
3629- int base_fg = 0xFFFFFF ;
3678+ int base_fg = fallback_fg_rgb ;
36303679 if (char_aep != NULL
36313680 && char_aep -> ae_u .gui .fg_color != INVALCOLOR )
36323681 base_fg = char_aep -> ae_u .gui .fg_color ;
@@ -3636,7 +3685,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36363685 // Blend bg: popup bg toward underlying bg.
36373686 if (popup_aep -> ae_u .gui .bg_color != INVALCOLOR )
36383687 {
3639- guicolor_T underlying_bg = INVALCOLOR ;
3688+ guicolor_T underlying_bg = fallback_bg_rgb ;
36403689 if (char_aep != NULL )
36413690 underlying_bg = char_aep -> ae_u .gui .bg_color ;
36423691 new_en .ae_u .gui .bg_color = blend_colors (
@@ -3685,7 +3734,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
36853734#endif
36863735 new_en .ae_u .cterm .fg_color = blend_cterm_colors (
36873736 popup_aep -> ae_u .cterm .bg_color , popup_bg_rgb ,
3688- under_fg , under_fg_rgb , 0xFFFFFF , blend );
3737+ under_fg , under_fg_rgb , fallback_fg_rgb , blend );
36893738 }
36903739 // Approximate cterm bg by blending with the underlying bg
36913740 // in the 256-color palette and mapping to the nearest entry.
@@ -3701,7 +3750,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37013750#endif
37023751 new_en .ae_u .cterm .bg_color = blend_cterm_colors (
37033752 popup_aep -> ae_u .cterm .bg_color , popup_bg_rgb ,
3704- under_bg , under_bg_rgb , 0x000000 , blend );
3753+ under_bg , under_bg_rgb , fallback_bg_rgb , blend );
37053754 }
37063755#ifdef FEAT_TERMGUICOLORS
37073756 // Blend fg_rgb: pum_bg toward underlying_fg.
@@ -3710,7 +3759,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37103759 // as a real near-white pixel.
37113760 if (popup_aep -> ae_u .cterm .bg_rgb != INVALCOLOR )
37123761 {
3713- int base_fg = 0xFFFFFF ;
3762+ int base_fg = fallback_fg_rgb ;
37143763 if (char_aep != NULL
37153764 && !COLOR_INVALID (char_aep -> ae_u .cterm .fg_rgb ))
37163765 base_fg = char_aep -> ae_u .cterm .fg_rgb ;
@@ -3720,7 +3769,7 @@ hl_pum_blend_attr(int char_attr, int popup_attr, int blend UNUSED)
37203769 // Blend bg_rgb.
37213770 if (popup_aep -> ae_u .cterm .bg_rgb != INVALCOLOR )
37223771 {
3723- guicolor_T underlying_bg = INVALCOLOR ;
3772+ guicolor_T underlying_bg = fallback_bg_rgb ;
37243773 if (char_aep != NULL
37253774 && !COLOR_INVALID (char_aep -> ae_u .cterm .bg_rgb ))
37263775 underlying_bg = char_aep -> ae_u .cterm .bg_rgb ;
0 commit comments