feat: select text color, alpha blend text
parent
008d1b48ef
commit
c3d240358a
90
src/main.zig
90
src/main.zig
|
@ -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) {
|
||||||
|
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);
|
||||||
|
|
||||||
pixel.* = .{
|
pixel.* = .{
|
||||||
@intCast(intensity),
|
over_color.b +| under_color.b,
|
||||||
@intCast(intensity),
|
over_color.g +| under_color.g,
|
||||||
@intCast(intensity),
|
over_color.r +| under_color.r,
|
||||||
0xFF,
|
over_alpha +| 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),
|
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue