feat: support rendering theme colors with alpha components
This commit is contained in:
parent
3b28286c91
commit
0a43fa853f
9 changed files with 127 additions and 48 deletions
|
@ -1,32 +1,37 @@
|
|||
const vaxis = @import("vaxis");
|
||||
const Style = @import("theme").Style;
|
||||
const Color = @import("theme").Color;
|
||||
const FontStyle = @import("theme").FontStyle;
|
||||
const color = @import("color");
|
||||
|
||||
const Cell = @This();
|
||||
|
||||
cell: vaxis.Cell = .{},
|
||||
|
||||
pub inline fn set_style(self: *Cell, style_: Style) void {
|
||||
if (style_.fg) |fg| self.cell.style.fg = vaxis.Cell.Color.rgbFromUint(fg);
|
||||
if (style_.bg) |bg| self.cell.style.bg = vaxis.Cell.Color.rgbFromUint(bg);
|
||||
if (style_.fs) |fs| {
|
||||
self.cell.style.ul = .default;
|
||||
self.cell.style.ul_style = .off;
|
||||
self.cell.style.bold = false;
|
||||
self.cell.style.dim = false;
|
||||
self.cell.style.italic = false;
|
||||
self.cell.style.blink = false;
|
||||
self.cell.style.reverse = false;
|
||||
self.cell.style.invisible = false;
|
||||
self.cell.style.strikethrough = false;
|
||||
self.set_style_fg(style_);
|
||||
self.set_style_bg(style_);
|
||||
if (style_.fs) |fs| self.set_font_style(fs);
|
||||
}
|
||||
|
||||
switch (fs) {
|
||||
.normal => {},
|
||||
.bold => self.cell.style.bold = true,
|
||||
.italic => self.cell.style.italic = true,
|
||||
.underline => self.cell.style.ul_style = .single,
|
||||
.undercurl => self.cell.style.ul_style = .curly,
|
||||
.strikethrough => self.cell.style.strikethrough = true,
|
||||
}
|
||||
pub inline fn set_font_style(self: *Cell, fs: FontStyle) void {
|
||||
self.cell.style.ul = .default;
|
||||
self.cell.style.ul_style = .off;
|
||||
self.cell.style.bold = false;
|
||||
self.cell.style.dim = false;
|
||||
self.cell.style.italic = false;
|
||||
self.cell.style.blink = false;
|
||||
self.cell.style.reverse = false;
|
||||
self.cell.style.invisible = false;
|
||||
self.cell.style.strikethrough = false;
|
||||
|
||||
switch (fs) {
|
||||
.normal => {},
|
||||
.bold => self.cell.style.bold = true,
|
||||
.italic => self.cell.style.italic = true,
|
||||
.underline => self.cell.style.ul_style = .single,
|
||||
.undercurl => self.cell.style.ul_style = .curly,
|
||||
.strikethrough => self.cell.style.strikethrough = true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,12 +39,24 @@ pub inline fn set_under_color(self: *Cell, arg_rgb: c_uint) void {
|
|||
self.cell.style.ul = vaxis.Cell.Color.rgbFromUint(@intCast(arg_rgb));
|
||||
}
|
||||
|
||||
inline fn apply_alpha(base_vaxis: vaxis.Cell.Color, over_theme: Color) vaxis.Cell.Color {
|
||||
const alpha = over_theme.alpha;
|
||||
return if (alpha == 0xFF or base_vaxis != .rgb)
|
||||
vaxis.Cell.Color.rgbFromUint(over_theme.color)
|
||||
else blk: {
|
||||
const base = color.RGB.from_u8s(base_vaxis.rgb);
|
||||
const over = color.RGB.from_u24(over_theme.color);
|
||||
const result = color.apply_alpha(base, over, alpha);
|
||||
break :blk .{ .rgb = result.to_u8s() };
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn set_style_fg(self: *Cell, style_: Style) void {
|
||||
if (style_.fg) |fg| self.cell.style.fg = vaxis.Cell.Color.rgbFromUint(fg);
|
||||
if (style_.fg) |fg| self.cell.style.fg = apply_alpha(self.cell.style.bg, fg);
|
||||
}
|
||||
|
||||
pub inline fn set_style_bg(self: *Cell, style_: Style) void {
|
||||
if (style_.bg) |bg| self.cell.style.bg = vaxis.Cell.Color.rgbFromUint(bg);
|
||||
if (style_.bg) |bg| self.cell.style.bg = apply_alpha(self.cell.style.bg, bg);
|
||||
}
|
||||
|
||||
pub inline fn set_fg_rgb(self: *Cell, arg_rgb: c_uint) !void {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
const std = @import("std");
|
||||
const Style = @import("theme").Style;
|
||||
const ThemeColor = @import("theme").Color;
|
||||
const FontStyle = @import("theme").FontStyle;
|
||||
const StyleBits = @import("style.zig").StyleBits;
|
||||
const Cell = @import("Cell.zig");
|
||||
const vaxis = @import("vaxis");
|
||||
const Buffer = @import("Buffer");
|
||||
const color = @import("color");
|
||||
const RGB = @import("color").RGB;
|
||||
|
||||
const Plane = @This();
|
||||
|
||||
|
@ -266,12 +269,20 @@ pub fn off_styles(self: *Plane, stylebits: StyleBits) void {
|
|||
if (stylebits.italic) self.style.italic = false;
|
||||
}
|
||||
|
||||
pub fn set_fg_rgb(self: *Plane, channel: u32) !void {
|
||||
self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(channel));
|
||||
pub fn set_fg_rgb(self: *Plane, col: ThemeColor) !void {
|
||||
self.style.fg = to_cell_color(col);
|
||||
}
|
||||
|
||||
pub fn set_bg_rgb(self: *Plane, channel: u32) !void {
|
||||
self.style.bg = vaxis.Cell.Color.rgbFromUint(@intCast(channel));
|
||||
pub fn set_fg_rgb_alpha(self: *Plane, alpha_bg: ThemeColor, col: ThemeColor) !void {
|
||||
self.style.fg = apply_alpha_theme(alpha_bg, col);
|
||||
}
|
||||
|
||||
pub fn set_bg_rgb(self: *Plane, col: ThemeColor) !void {
|
||||
self.style.bg = to_cell_color(col);
|
||||
}
|
||||
|
||||
pub fn set_bg_rgb_alpha(self: *Plane, alpha_bg: ThemeColor, col: ThemeColor) !void {
|
||||
self.style.bg = apply_alpha_theme(alpha_bg, col);
|
||||
}
|
||||
|
||||
pub fn set_fg_palindex(self: *Plane, idx: c_uint) !void {
|
||||
|
@ -283,38 +294,54 @@ pub fn set_bg_palindex(self: *Plane, idx: c_uint) !void {
|
|||
}
|
||||
|
||||
pub inline fn set_base_style(self: *Plane, _: [*c]const u8, style_: Style) void {
|
||||
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.bg = if (style_.bg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.fg = if (style_.fg) |col| to_cell_color(col) else .default;
|
||||
self.style_base.bg = if (style_.bg) |col| to_cell_color(col) else .default;
|
||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||
self.set_style(style_);
|
||||
}
|
||||
|
||||
pub fn set_base_style_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
||||
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.bg = if (style_.bg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.fg = if (style_.fg) |col| to_cell_color(col) else .default;
|
||||
self.style_base.bg = if (style_.bg) |col| to_cell_color(col) else .default;
|
||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||
self.set_style(style_);
|
||||
self.transparent = true;
|
||||
}
|
||||
|
||||
pub fn set_base_style_bg_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
||||
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.bg = if (style_.bg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||
self.style_base.fg = if (style_.fg) |col| to_cell_color(col) else .default;
|
||||
self.style_base.bg = if (style_.bg) |col| to_cell_color(col) else .default;
|
||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||
self.set_style(style_);
|
||||
self.transparent = true;
|
||||
}
|
||||
|
||||
fn apply_alpha(bg: vaxis.Cell.Color, col: ThemeColor) vaxis.Cell.Color {
|
||||
const alpha = col.alpha;
|
||||
return if (alpha == 0xFF or bg != .rgb)
|
||||
.{ .rgb = RGB.to_u8s(RGB.from_u24(col.color)) }
|
||||
else
|
||||
.{ .rgb = color.apply_alpha(RGB.from_u8s(bg.rgb), RGB.from_u24(col.color), alpha).to_u8s() };
|
||||
}
|
||||
|
||||
fn apply_alpha_theme(bg: ThemeColor, col: ThemeColor) vaxis.Cell.Color {
|
||||
const alpha = col.alpha;
|
||||
return if (alpha == 0xFF)
|
||||
.{ .rgb = RGB.to_u8s(RGB.from_u24(col.color)) }
|
||||
else
|
||||
.{ .rgb = color.apply_alpha(RGB.from_u24(bg.color), RGB.from_u24(col.color), alpha).to_u8s() };
|
||||
}
|
||||
|
||||
pub inline fn set_style(self: *Plane, style_: Style) void {
|
||||
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||
if (style_.bg) |color| self.style.bg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||
if (style_.fg) |col| self.style.fg = apply_alpha(self.style_base.bg, col);
|
||||
if (style_.bg) |col| self.style.bg = apply_alpha(self.style_base.bg, col);
|
||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||
self.transparent = false;
|
||||
}
|
||||
|
||||
pub inline fn set_style_bg_transparent(self: *Plane, style_: Style) void {
|
||||
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||
if (style_.bg) |color| self.style.bg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||
if (style_.fg) |col| self.style.fg = apply_alpha(self.style_base.bg, col);
|
||||
if (style_.bg) |col| self.style.bg = apply_alpha(self.style_base.bg, col);
|
||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||
self.transparent = true;
|
||||
}
|
||||
|
@ -395,3 +422,7 @@ const GraphemeCache = struct {
|
|||
return self.buf[self.idx .. self.idx + bytes.len];
|
||||
}
|
||||
};
|
||||
|
||||
fn to_cell_color(col: ThemeColor) vaxis.Cell.Color {
|
||||
return .{ .rgb = RGB.to_u8s(RGB.from_u24(col.color)) };
|
||||
}
|
||||
|
|
|
@ -329,9 +329,9 @@ pub fn set_terminal_title(self: *Self, text: []const u8) void {
|
|||
|
||||
pub fn set_terminal_style(self: *Self, style_: Style) void {
|
||||
if (style_.fg) |color|
|
||||
self.vx.setTerminalForegroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color)).rgb) catch {};
|
||||
self.vx.setTerminalForegroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {};
|
||||
if (style_.bg) |color|
|
||||
self.vx.setTerminalBackgroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color)).rgb) catch {};
|
||||
self.vx.setTerminalBackgroundColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {};
|
||||
}
|
||||
|
||||
pub fn set_terminal_working_directory(self: *Self, absolute_path: []const u8) void {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue