Skip to content

Commit

Permalink
lfb: Implement support for transparency
Browse files Browse the repository at this point in the history
  • Loading branch information
fruhland committed Feb 28, 2024
1 parent 39ad7c9 commit bd4cab6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 83 deletions.
6 changes: 3 additions & 3 deletions os/kernel/src/device/lfb_terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl LFBTerminal {
// Draw background
for i in 0..display.size.0 as u32 * lfb::CHAR_WIDTH {
for j in 0..lfb::CHAR_HEIGHT {
display.lfb.lfb().draw_pixel(i, j, color::WHITE);
display.lfb.lfb().draw_pixel(i, j, color::HHU_GREEN);
}
}

Expand All @@ -262,7 +262,7 @@ impl LFBTerminal {
active_process_ids.len(),
active_thread_ids.len());

display.lfb.lfb().draw_string(0, 0, color::HHU_BLUE, color::WHITE, info_string.as_str());
display.lfb.lfb().draw_string(0, 0, color::HHU_BLUE, color::INVISIBLE, info_string.as_str());

// Draw date
if let Some(efi_system_table) = efi_system_table() {
Expand All @@ -271,7 +271,7 @@ impl LFBTerminal {

if let Ok(date) = runtime_services.get_time() {
let date_str = format!("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", date.year(), date.month(), date.day(), date.hour(), date.minute(), date.second());
display.lfb.lfb().draw_string((display.size.0 as u32 - date_str.len() as u32) * lfb::CHAR_WIDTH, 0, color::HHU_BLUE, color::WHITE, &date_str);
display.lfb.lfb().draw_string((display.size.0 as u32 - date_str.len() as u32) * lfb::CHAR_WIDTH, 0, color::HHU_BLUE, color::INVISIBLE, &date_str);
}
}

Expand Down
96 changes: 17 additions & 79 deletions os/library/graphic/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub const WHITE: Color = Color { red: 170, green: 170, blue: 170, alpha: 255, };

// Arbitrary colors
pub const HHU_BLUE: Color = Color { red: 0, green: 106, blue: 179, alpha: 255 };
pub const HHU_GREEN: Color = Color { red: 140, green: 177, blue: 16, alpha: 255 };

impl Color {
pub const fn from_rgb(rgb: u32, bpp: u8) -> Color {
Expand All @@ -63,74 +64,47 @@ impl Color {
let green: u8 = ((rgba & 0x0000ff00) >> 8) as u8;
let blue: u8 = (rgba & 0x000000ff) as u8;

Self {
red,
green,
blue,
alpha,
}
Self { red, green, blue, alpha }
}

pub const fn from_rgb_24(rgb: u32) -> Color {
let red: u8 = ((rgb & 0x00ff0000) >> 16) as u8;
let green: u8 = ((rgb & 0x0000ff00) >> 8) as u8;
let blue: u8 = (rgb & 0x000000ff) as u8;

Self {
red,
green,
blue,
alpha: 0,
}
Self { red, green, blue, alpha: 0 }
}

pub const fn from_rgb_16(rgb: u16) -> Color {
let red: u8 = (((rgb & 0xf800) >> 11) * (256 / 32)) as u8;
let green: u8 = (((rgb & 0x07e0) >> 5) * (256 / 64)) as u8;
let blue: u8 = ((rgb & 0x001f) * (256 / 32)) as u8;

Self {
red,
green,
blue,
alpha: 0,
}
Self { red, green, blue, alpha: 0 }
}

pub const fn from_rgb_15(rgb: u16) -> Color {
let red: u8 = (((rgb & 0x7c00) >> 10) * (256 / 32)) as u8;
let green: u8 = (((rgb & 0x03e0) >> 5) * (256 / 32)) as u8;
let blue: u8 = ((rgb & 0x001f) * (256 / 32)) as u8;

Self {
red,
green,
blue,
alpha: 0,
}
Self { red, green, blue, alpha: 0 }
}

pub const fn rgb_32(&self) -> u32 {
((self.alpha as u32) << 24)
| ((self.red as u32) << 16)
| ((self.green as u32) << 8)
| ((self.blue) as u32)
((self.alpha as u32) << 24) | ((self.red as u32) << 16) | ((self.green as u32) << 8) | ((self.blue) as u32)
}

pub const fn rgb_24(&self) -> u32 {
((self.red as u32) << 16) | ((self.green as u32) << 8) | ((self.blue) as u32)
}

pub const fn rgb_16(&self) -> u16 {
((self.blue as u16) >> 3)
| (((self.green as u16) >> 2) << 5)
| (((self.red as u16) >> 3) << 11)
((self.blue as u16) >> 3) | (((self.green as u16) >> 2) << 5) | (((self.red as u16) >> 3) << 11)
}

pub const fn rgb_15(&self) -> u16 {
((self.blue as u16) >> 3)
| (((self.green as u16) >> 3) << 5)
| (((self.red as u16) >> 3) << 10)
((self.blue as u16) >> 3) | (((self.green as u16) >> 3) << 5) | (((self.red as u16) >> 3) << 10)
}

pub const fn bright(&self) -> Color {
Expand All @@ -150,12 +124,7 @@ impl Color {
b = 0xff;
}

Self {
red: r as u8,
green: g as u8,
blue: b as u8,
alpha: self.alpha,
}
Self { red: r as u8, green: g as u8, blue: b as u8, alpha: self.alpha, }
}

pub const fn dim(&self) -> Color {
Expand All @@ -175,40 +144,20 @@ impl Color {
b = 0;
}

Self {
red: r as u8,
green: g as u8,
blue: b as u8,
alpha: self.alpha,
}
Self { red: r as u8, green: g as u8, blue: b as u8, alpha: self.alpha, }
}

pub const fn with_alpha(&self, alpha: u8) -> Self {
Self {
red: self.red,
green: self.green,
blue: self.blue,
alpha,
}
Self { red: self.red, green: self.green, blue: self.blue, alpha, }
}

pub fn blend(&self, color: Color) -> Color {
if color.alpha == 0 {
return Self {
red: self.red,
green: self.green,
blue: self.blue,
alpha: self.alpha,
};
return Self { red: self.red, green: self.green, blue: self.blue, alpha: self.alpha, };
}

if color.alpha == 0xff {
return Self {
red: color.red,
green: color.green,
blue: color.blue,
alpha: color.alpha,
};
return Self { red: color.red, green: color.green, blue: color.blue, alpha: color.alpha, };
}

if self.alpha == 0 {
Expand All @@ -219,22 +168,11 @@ impl Color {
let alpha2: f64 = (self.alpha as f64) / 255.0;
let alpha3: f64 = alpha1 + (1.0 - alpha1) * alpha2;

let r: u8 = ((1.0 / alpha3)
* (alpha1 * color.red as f64 + (1.0 - alpha1) * alpha2 * self.red as f64))
as u8;
let g: u8 = ((1.0 / alpha3)
* (alpha1 * color.green as f64 + (1.0 - alpha1) * alpha2 * self.green as f64))
as u8;
let b: u8 = ((1.0 / alpha3)
* (alpha1 * color.blue as f64 + (1.0 - alpha1) * alpha2 * self.blue as f64))
as u8;
let r: u8 = ((1.0 / alpha3) * (alpha1 * color.red as f64 + (1.0 - alpha1) * alpha2 * self.red as f64)) as u8;
let g: u8 = ((1.0 / alpha3) * (alpha1 * color.green as f64 + (1.0 - alpha1) * alpha2 * self.green as f64)) as u8;
let b: u8 = ((1.0 / alpha3) * (alpha1 * color.blue as f64 + (1.0 - alpha1) * alpha2 * self.blue as f64)) as u8;
let a: u8 = (alpha3 * 255.0) as u8;

Self {
red: r,
green: g,
blue: b,
alpha: a,
}
Self { red: r, green: g, blue: b, alpha: a }
}
}
25 changes: 24 additions & 1 deletion os/library/graphic/src/lfb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,30 @@ impl LFB {
return;
}

unsafe { (self.pixel_drawer)(self.buffer, self.pitch, x, y, color) };
// Do not draw pixels with alpha = 0
if color.alpha == 0 {
return;
}

// Blend if necessary and draw pixel
if color.alpha < 255 {
unsafe { (self.pixel_drawer)(self.buffer, self.pitch, x, y, self.read_pixel(x, y).blend(color)) };
} else {
unsafe { (self.pixel_drawer)(self.buffer, self.pitch, x, y, color) };
}
}

pub fn read_pixel(&self, x: u32, y: u32) -> Color {
if x > self.width - 1 || y > self.height - 1 {
panic!("LinearFrameBuffer: Trying to read a pixel out of bounds!");
}

let bpp = if self.bpp == 15 { 16 } else { self.bpp() };

unsafe {
let ptr = self.buffer.offset(((x * (bpp / 8) as u32) + y * self.pitch) as isize) as *const u32;
Color::from_rgb(ptr.read(), self.bpp)
}
}

pub fn fill_rect(&self, x: u32, y: u32, width: u32, height: u32, color: Color) {
Expand Down

0 comments on commit bd4cab6

Please sign in to comment.