diff --git a/src/main.zig b/src/main.zig index 8794ec6..aeb6baf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -31,30 +31,14 @@ const font8x8 = @cImport({ }); const Pixel = [4]u8; -const Theme = struct { - const background = 0x282A36; - const current_line = 0x44475A; - const foreground = 0xF8F8F2; - const comment = 0x6272A4; - - const cyan = 0x8BE9FD; - const green = 0x50FA7B; - const orange = 0xFFB86C; - const pink = 0xFF79C6; - const purple = 0xBD93F9; - const red = 0xFF5555; - const yellow = 0xF1FA8C; +const Color = struct { + r: u8, + g: u8, + b: u8, + const White = Color{ .r = 0xFF, .g = 0xFF, .b = 0xFF }; + const Black = Color{ .r = 0x00, .g = 0x00, .b = 0x00 }; }; -fn toPixel(color: u24) Pixel { - return .{ - @intCast(color & 0xFF), - @intCast(color >> 8 & 0xFF), - @intCast(color >> 16 & 0xFF), - 0xFF, - }; -} - pub fn main() !void { var general_allocator = std.heap.GeneralPurposeAllocator(.{}){}; 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 width = canvas.size[0]; const height = canvas.size[1]; @@ -468,34 +452,48 @@ const Canvas = struct { const row = fb[y * width .. (y + 1) * width]; for (left..right, 0..) |x, a| { const pixel = &row[x]; - const intensity: u16 = buffer[i * cols + a]; - if (intensity != 0) { - pixel.* = .{ - @intCast(intensity), - @intCast(intensity), - @intCast(intensity), - 0xFF, - }; + const over_alpha = buffer[i * cols + a]; + if (over_alpha != 0) { + const over_color = alphaMult(color, over_alpha); + const under_alpha = 255 -| over_alpha; + const under_color = alphaMult(.{ + .b = pixel[0], + .g = pixel[1], + .r = pixel[2], + }, under_alpha); - // TODO: properly implement blending - // const over_alpha = intensity; - // const under_alpha = pixel[3]; - // const blended_alpha = over_alpha +| under_alpha *| (255 -| over_alpha); - // const color1: u16 = intensity * over_alpha + pixel[0] *| under_alpha *| (255 -| over_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), - // }; + pixel.* = .{ + over_color.b +| under_color.b, + over_color.g +| under_color.g, + over_color.r +| under_color.r, + over_alpha +| under_alpha, + }; } } } } - 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); var unicode_iter = unicode_view.iterator(); var x: i32 = @intCast(pos[0]); @@ -505,7 +503,7 @@ const Canvas = struct { try face.loadGlyph(glyph_index, .{ .render = true }); const glyph = face.glyph(); 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); y += @intCast(glyph.advance().y >> 6); } @@ -558,7 +556,7 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) ! // render const canvas = try pool.getFramebuffer(.{ width, height }); 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 app.callbacks.put(canvas.buffer.id, bufferHandler); },