Skip to content

Commit 695d88e

Browse files
authored
Fix alpha blending formula (#594)
Since `srgb_to_linear` is non-linear we can't use it for premultiplied colors. Instead of unpremultiplying them, I changed the rest of the app to straight alpha and introduced types to ensure we don't mess it up.
1 parent f17552c commit 695d88e

File tree

7 files changed

+309
-174
lines changed

7 files changed

+309
-174
lines changed

benches/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,14 @@ fn bench_hash(c: &mut Criterion) {
127127

128128
fn bench_oklab(c: &mut Criterion) {
129129
c.benchmark_group("oklab")
130-
.bench_function("srgb_to_oklab", |b| b.iter(|| oklab::srgb_to_oklab(black_box(0xff212cbe))))
131-
.bench_function("oklab_blend", |b| {
132-
b.iter(|| oklab::oklab_blend(black_box(0x7f212cbe), black_box(0x7f3aae3f)))
130+
.bench_function("StraightRgba::as_oklab", |b| {
131+
b.iter(|| black_box(oklab::StraightRgba::from_le(0xff212cbe)).as_oklab())
132+
})
133+
.bench_function("StraightRgba::oklab_blend", |b| {
134+
b.iter(|| {
135+
black_box(oklab::StraightRgba::from_le(0x7f212cbe))
136+
.oklab_blend(black_box(oklab::StraightRgba::from_le(0x7f3aae3f)))
137+
})
133138
});
134139
}
135140

src/bin/edit/main.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use edit::arena::{self, Arena, ArenaString, scratch_arena};
2626
use edit::framebuffer::{self, IndexedColor};
2727
use edit::helpers::{CoordType, KIBI, MEBI, MetricFormatter, Rect, Size};
2828
use edit::input::{self, kbmod, vk};
29-
use edit::oklab::oklab_blend;
29+
use edit::oklab::StraightRgba;
3030
use edit::tui::*;
3131
use edit::vt::{self, Token};
3232
use edit::{apperr, arena_format, base64, path, sys, unicode};
@@ -83,15 +83,15 @@ fn run() -> apperr::Result<()> {
8383

8484
let _restore = setup_terminal(&mut tui, &mut state, &mut vt_parser);
8585

86-
state.menubar_color_bg = oklab_blend(
87-
tui.indexed(IndexedColor::Background),
88-
tui.indexed_alpha(IndexedColor::BrightBlue, 1, 2),
89-
);
86+
state.menubar_color_bg = tui.indexed(IndexedColor::Background).oklab_blend(tui.indexed_alpha(
87+
IndexedColor::BrightBlue,
88+
1,
89+
2,
90+
));
9091
state.menubar_color_fg = tui.contrasted(state.menubar_color_bg);
91-
let floater_bg = oklab_blend(
92-
tui.indexed_alpha(IndexedColor::Background, 2, 3),
93-
tui.indexed_alpha(IndexedColor::Foreground, 1, 3),
94-
);
92+
let floater_bg = tui
93+
.indexed_alpha(IndexedColor::Background, 2, 3)
94+
.oklab_blend(tui.indexed_alpha(IndexedColor::Foreground, 1, 3));
9595
let floater_fg = tui.contrasted(floater_bg);
9696
tui.setup_modifier_translations(ModifierTranslations {
9797
ctrl: loc(LocId::Ctrl),
@@ -630,7 +630,7 @@ fn setup_terminal(tui: &mut Tui, state: &mut State, vt_parser: &mut vt::Parser)
630630
}
631631
}
632632

633-
*color = rgb | 0xff000000;
633+
*color = StraightRgba::from_le(rgb | 0xff000000);
634634
color_responses += 1;
635635
osc_buffer.clear();
636636
}

src/bin/edit/state.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::path::{Path, PathBuf};
88

99
use edit::framebuffer::IndexedColor;
1010
use edit::helpers::*;
11+
use edit::oklab::StraightRgba;
1112
use edit::tui::*;
1213
use edit::{apperr, buffer, icu, sys};
1314

@@ -127,8 +128,8 @@ pub struct OscTitleFileStatus {
127128
}
128129

129130
pub struct State {
130-
pub menubar_color_bg: u32,
131-
pub menubar_color_fg: u32,
131+
pub menubar_color_bg: StraightRgba,
132+
pub menubar_color_fg: StraightRgba,
132133

133134
pub documents: DocumentManager,
134135

@@ -176,8 +177,8 @@ pub struct State {
176177
impl State {
177178
pub fn new() -> apperr::Result<Self> {
178179
Ok(Self {
179-
menubar_color_bg: 0,
180-
menubar_color_fg: 0,
180+
menubar_color_bg: StraightRgba::zero(),
181+
menubar_color_fg: StraightRgba::zero(),
181182

182183
documents: Default::default(),
183184

src/buffer/mod.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use crate::clipboard::Clipboard;
4242
use crate::document::{ReadableDocument, WriteableDocument};
4343
use crate::framebuffer::{Framebuffer, IndexedColor};
4444
use crate::helpers::*;
45-
use crate::oklab::oklab_blend;
45+
use crate::oklab::StraightRgba;
4646
use crate::simd::memchr2;
4747
use crate::unicode::{self, Cursor, MeasurementConfig, Utf8Chars};
4848
use crate::{apperr, icu, simd};
@@ -1834,12 +1834,13 @@ impl TextBuffer {
18341834
bottom: top + 1,
18351835
};
18361836

1837-
let mut bg = oklab_blend(
1838-
fb.indexed(IndexedColor::Foreground),
1839-
fb.indexed_alpha(IndexedColor::BrightBlue, 1, 2),
1840-
);
1837+
let mut bg = fb.indexed(IndexedColor::Foreground).oklab_blend(fb.indexed_alpha(
1838+
IndexedColor::BrightBlue,
1839+
1,
1840+
2,
1841+
));
18411842
if !focused {
1842-
bg = oklab_blend(bg, fb.indexed_alpha(IndexedColor::Background, 1, 2))
1843+
bg = bg.oklab_blend(fb.indexed_alpha(IndexedColor::Background, 1, 2));
18431844
};
18441845
let fg = fb.contrasted(bg);
18451846
fb.blend_bg(rect, bg);
@@ -1975,7 +1976,7 @@ impl TextBuffer {
19751976
right: destination.left + self.margin_width,
19761977
bottom: destination.bottom,
19771978
};
1978-
fb.blend_fg(margin, 0x7f3f3f3f);
1979+
fb.blend_fg(margin, StraightRgba::from_le(0x7f7f7f7f));
19791980
}
19801981

19811982
if self.ruler > 0 {
@@ -2023,7 +2024,7 @@ impl TextBuffer {
20232024
right: destination.right,
20242025
bottom: cursor.y + 1,
20252026
},
2026-
0x50282828,
2027+
StraightRgba::from_le(0x7f7f7f7f),
20272028
);
20282029
}
20292030
}

0 commit comments

Comments
 (0)