mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-06-08 21:04:32 +00:00
74 lines
2.3 KiB
Zig
74 lines
2.3 KiB
Zig
//! Various conversions from Freetype formats to Atlas formats. These are
|
|
//! currently implemented naively. There are definitely MUCH faster ways
|
|
//! to do this (likely using SIMD), but I started simple.
|
|
const std = @import("std");
|
|
const freetype = @import("freetype");
|
|
const Atlas = @import("../Atlas.zig");
|
|
const assert = std.debug.assert;
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
/// The mapping from freetype format to atlas format.
|
|
pub const map = genMap();
|
|
|
|
/// The map type.
|
|
pub const Map = [freetype.c.FT_PIXEL_MODE_MAX]AtlasArray;
|
|
|
|
/// Conversion function type. The returning bitmap buffer is guaranteed
|
|
/// to be exactly `width * rows * depth` long for freeing it. The caller must
|
|
/// free the bitmap buffer. The depth is the depth of the atlas format in the
|
|
/// map.
|
|
pub const Func = fn (Allocator, Bitmap) Allocator.Error!Bitmap;
|
|
|
|
/// Alias for the freetype FT_Bitmap type to make it easier to type.
|
|
pub const Bitmap = freetype.c.struct_FT_Bitmap_;
|
|
|
|
const AtlasArray = std.EnumArray(Atlas.Format, ?Func);
|
|
|
|
fn genMap() Map {
|
|
var result: Map = undefined;
|
|
|
|
// Initialize to no converter
|
|
var i: usize = 0;
|
|
while (i < freetype.c.FT_PIXEL_MODE_MAX) : (i += 1) {
|
|
result[i] = AtlasArray.initFill(null);
|
|
}
|
|
|
|
// Map our converters
|
|
result[freetype.c.FT_PIXEL_MODE_MONO].set(.rgba, monoToRGBA);
|
|
|
|
return result;
|
|
}
|
|
|
|
pub fn monoToRGBA(alloc: Allocator, bm: Bitmap) Allocator.Error!Bitmap {
|
|
// NOTE: This was never tested and may not work. I wrote it to
|
|
// solve another issue where this ended up not being needed.
|
|
// TODO: test this!
|
|
|
|
const depth = Atlas.Format.rgba.depth();
|
|
var buf = try alloc.alloc(u8, bm.width * bm.rows * depth);
|
|
errdefer alloc.free(buf);
|
|
|
|
var i: usize = 0;
|
|
while (i < bm.width * bm.rows) : (i += 1) {
|
|
var bit: u3 = 0;
|
|
while (bit <= 7) : (bit += 1) {
|
|
const mask = @as(u8, 1) << (7 - bit);
|
|
const bitval: u8 = if (bm.buffer[i] & mask > 0) 0xFF else 0;
|
|
const buf_i = (i * 8 * depth) + (bit * depth);
|
|
buf[buf_i] = 0xFF - bitval;
|
|
buf[buf_i + 1] = 0xFF - bitval;
|
|
buf[buf_i + 2] = 0xFF - bitval;
|
|
buf[buf_i + 3] = bitval;
|
|
}
|
|
}
|
|
|
|
var copy = bm;
|
|
copy.buffer = buf.ptr;
|
|
copy.pixel_mode = freetype.c.FT_PIXEL_MODE_BGRA;
|
|
return copy;
|
|
}
|
|
|
|
test {
|
|
_ = map;
|
|
}
|