feat: select text color, alpha blend text

dev
Louis Pearson 2024-02-17 14:30:56 -07:00
parent 008d1b48ef
commit c3d240358a
1 changed files with 45 additions and 47 deletions

View File

@ -31,30 +31,14 @@ const font8x8 = @cImport({
}); });
const Pixel = [4]u8; const Pixel = [4]u8;
const Theme = struct { const Color = struct {
const background = 0x282A36; r: u8,
const current_line = 0x44475A; g: u8,
const foreground = 0xF8F8F2; b: u8,
const comment = 0x6272A4; const White = Color{ .r = 0xFF, .g = 0xFF, .b = 0xFF };
const Black = Color{ .r = 0x00, .g = 0x00, .b = 0x00 };
const cyan = 0x8BE9FD;
const green = 0x50FA7B;
const orange = 0xFFB86C;
const pink = 0xFF79C6;
const purple = 0xBD93F9;
const red = 0xFF5555;
const yellow = 0xF1FA8C;
}; };
fn toPixel(color: u24) Pixel {
return .{
@intCast(color & 0xFF),
@intCast(color >> 8 & 0xFF),
@intCast(color >> 16 & 0xFF),
0xFF,
};
}
pub fn main() !void { pub fn main() !void {
var general_allocator = std.heap.GeneralPurposeAllocator(.{}){}; var general_allocator = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = general_allocator.deinit(); defer _ = general_allocator.deinit();
@ -452,7 +436,7 @@ const Canvas = struct {
} }
} }
fn blitFreetypeBitmap(canvas: Canvas, bitmap: freetype.Bitmap, pos: [2]u32) void { fn blitFreetypeBitmap(canvas: Canvas, bitmap: freetype.Bitmap, pos: [2]u32, color: Color) void {
const fb = canvas.fb; const fb = canvas.fb;
const width = canvas.size[0]; const width = canvas.size[0];
const height = canvas.size[1]; const height = canvas.size[1];
@ -468,34 +452,48 @@ const Canvas = struct {
const row = fb[y * width .. (y + 1) * width]; const row = fb[y * width .. (y + 1) * width];
for (left..right, 0..) |x, a| { for (left..right, 0..) |x, a| {
const pixel = &row[x]; const pixel = &row[x];
const intensity: u16 = buffer[i * cols + a]; const over_alpha = buffer[i * cols + a];
if (intensity != 0) { if (over_alpha != 0) {
pixel.* = .{ const over_color = alphaMult(color, over_alpha);
@intCast(intensity), const under_alpha = 255 -| over_alpha;
@intCast(intensity), const under_color = alphaMult(.{
@intCast(intensity), .b = pixel[0],
0xFF, .g = pixel[1],
}; .r = pixel[2],
}, under_alpha);
// TODO: properly implement blending pixel.* = .{
// const over_alpha = intensity; over_color.b +| under_color.b,
// const under_alpha = pixel[3]; over_color.g +| under_color.g,
// const blended_alpha = over_alpha +| under_alpha *| (255 -| over_alpha); over_color.r +| under_color.r,
// const color1: u16 = intensity * over_alpha + pixel[0] *| under_alpha *| (255 -| over_alpha); over_alpha +| under_alpha,
// const color2: u16 = intensity * over_alpha + pixel[1] *| under_alpha *| (255 -| over_alpha); };
// const color3: u16 = intensity * over_alpha + pixel[2] *| under_alpha *| (255 -| over_alpha);
// pixel.* = .{
// @intCast(color1 / 255),
// @intCast(color2 / 255),
// @intCast(color3 / 255),
// @intCast(blended_alpha / 255),
// };
} }
} }
} }
} }
fn print(canvas: Canvas, face: freetype.Face, string: []const u8, pos: [2]u32) !void { fn alphaMult(color: Color, alpha: u8) Color {
var red: u16, var green: u16, var blue: u16 = .{ color.r, color.g, color.b };
red *= alpha;
green *= alpha;
blue *= alpha;
red += 0x80;
green += 0x80;
blue += 0x80;
red += red >> 8;
green += green >> 8;
blue += blue >> 8;
return .{
.r = @truncate(red >> 8),
.g = @truncate(green >> 8),
.b = @truncate(blue >> 8),
};
}
fn print(canvas: Canvas, face: freetype.Face, string: []const u8, pos: [2]u32, color: Color) !void {
const unicode_view = try std.unicode.Utf8View.init(string); const unicode_view = try std.unicode.Utf8View.init(string);
var unicode_iter = unicode_view.iterator(); var unicode_iter = unicode_view.iterator();
var x: i32 = @intCast(pos[0]); var x: i32 = @intCast(pos[0]);
@ -505,7 +503,7 @@ const Canvas = struct {
try face.loadGlyph(glyph_index, .{ .render = true }); try face.loadGlyph(glyph_index, .{ .render = true });
const glyph = face.glyph(); const glyph = face.glyph();
const bitmap = glyph.bitmap(); const bitmap = glyph.bitmap();
canvas.blitFreetypeBitmap(bitmap, .{ @intCast(x + glyph.bitmapLeft()), @intCast(y - glyph.bitmapTop()) }); canvas.blitFreetypeBitmap(bitmap, .{ @intCast(x + glyph.bitmapLeft()), @intCast(y - glyph.bitmapTop()) }, color);
x += @intCast(glyph.advance().x >> 6); x += @intCast(glyph.advance().x >> 6);
y += @intCast(glyph.advance().y >> 6); y += @intCast(glyph.advance().y >> 6);
} }
@ -558,7 +556,7 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
// render // render
const canvas = try pool.getFramebuffer(.{ width, height }); const canvas = try pool.getFramebuffer(.{ width, height });
canvas.renderGradient(); canvas.renderGradient();
try canvas.print(app.font_face, "Hello, World!", .{ 10, 60 }); try canvas.print(app.font_face, "Hello, World!", .{ 10, 60 }, Color.White);
try canvas.attach(app.surface); try canvas.attach(app.surface);
try app.callbacks.put(canvas.buffer.id, bufferHandler); try app.callbacks.put(canvas.buffer.id, bufferHandler);
}, },