mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

This commit changes a LOT of areas of the code to use decl literals instead of redundantly referring to the type. These changes were mostly driven by some regex searches and then manual adjustment on a case-by-case basis. I almost certainly missed quite a few places where decl literals could be used, but this is a good first step in converting things, and other instances can be addressed when they're discovered. I tested GLFW+Metal and building the framework on macOS and tested a GTK build on Linux, so I'm 99% sure I didn't introduce any syntax errors or other problems with this. (fingers crossed)
169 lines
5.0 KiB
Zig
169 lines
5.0 KiB
Zig
const std = @import("std");
|
|
const assert = std.debug.assert;
|
|
const c = @import("c.zig").c;
|
|
const Error = @import("main.zig").Error;
|
|
const ObjectSet = @import("main.zig").ObjectSet;
|
|
const Property = @import("main.zig").Property;
|
|
const Result = @import("main.zig").Result;
|
|
const Value = @import("main.zig").Value;
|
|
const ValueBinding = @import("main.zig").ValueBinding;
|
|
const Weight = @import("main.zig").Weight;
|
|
|
|
pub const Pattern = opaque {
|
|
pub fn create() *Pattern {
|
|
return @ptrCast(c.FcPatternCreate());
|
|
}
|
|
|
|
pub fn parse(str: [:0]const u8) *Pattern {
|
|
return @ptrCast(c.FcNameParse(str.ptr));
|
|
}
|
|
|
|
pub fn destroy(self: *Pattern) void {
|
|
c.FcPatternDestroy(self.cval());
|
|
}
|
|
|
|
pub fn defaultSubstitute(self: *Pattern) void {
|
|
c.FcDefaultSubstitute(self.cval());
|
|
}
|
|
|
|
pub fn add(self: *Pattern, prop: Property, value: Value, append: bool) bool {
|
|
return c.FcPatternAdd(
|
|
self.cval(),
|
|
prop.cval().ptr,
|
|
value.cval(),
|
|
if (append) c.FcTrue else c.FcFalse,
|
|
) == c.FcTrue;
|
|
}
|
|
|
|
pub fn get(self: *Pattern, prop: Property, id: u32) Error!Value {
|
|
var val: c.struct__FcValue = undefined;
|
|
try @as(Result, @enumFromInt(c.FcPatternGet(
|
|
self.cval(),
|
|
prop.cval().ptr,
|
|
@intCast(id),
|
|
&val,
|
|
))).toError();
|
|
|
|
return .init(&val);
|
|
}
|
|
|
|
pub fn delete(self: *Pattern, prop: Property) bool {
|
|
return c.FcPatternDel(self.cval(), prop.cval()) == c.FcTrue;
|
|
}
|
|
|
|
pub fn filter(self: *Pattern, os: *const ObjectSet) *Pattern {
|
|
return @ptrCast(c.FcPatternFilter(self.cval(), os.cval()));
|
|
}
|
|
|
|
pub fn objectIterator(self: *Pattern) ObjectIterator {
|
|
return .{ .pat = self.cval(), .iter = null };
|
|
}
|
|
|
|
pub fn print(self: *Pattern) void {
|
|
c.FcPatternPrint(self.cval());
|
|
}
|
|
|
|
pub inline fn cval(self: *Pattern) *c.struct__FcPattern {
|
|
return @ptrCast(self);
|
|
}
|
|
|
|
pub const ObjectIterator = struct {
|
|
pat: *c.struct__FcPattern,
|
|
iter: ?c.struct__FcPatternIter,
|
|
|
|
/// Move to the next object, returns true if there is another
|
|
/// object and false otherwise. If this is the first call, this
|
|
/// will be the first object.
|
|
pub fn next(self: *ObjectIterator) bool {
|
|
// Null means our first iterator
|
|
if (self.iter == null) {
|
|
// If we have no objects, do not create iterator
|
|
if (c.FcPatternObjectCount(self.pat) == 0) return false;
|
|
|
|
var iter: c.struct__FcPatternIter = undefined;
|
|
c.FcPatternIterStart(
|
|
self.pat,
|
|
&iter,
|
|
);
|
|
assert(c.FcPatternIterIsValid(self.pat, &iter) == c.FcTrue);
|
|
self.iter = iter;
|
|
|
|
// Return right away because the fontconfig iterator pattern
|
|
// is do/while.
|
|
return true;
|
|
}
|
|
|
|
return c.FcPatternIterNext(self.pat, @ptrCast(&self.iter)) == c.FcTrue;
|
|
}
|
|
|
|
pub fn object(self: *ObjectIterator) []const u8 {
|
|
return std.mem.sliceTo(c.FcPatternIterGetObject(
|
|
self.pat,
|
|
&self.iter.?,
|
|
), 0);
|
|
}
|
|
|
|
pub fn valueLen(self: *ObjectIterator) usize {
|
|
return @intCast(c.FcPatternIterValueCount(self.pat, &self.iter.?));
|
|
}
|
|
|
|
pub fn valueIterator(self: *ObjectIterator) ValueIterator {
|
|
return .{
|
|
.pat = self.pat,
|
|
.iter = &self.iter.?,
|
|
.max = c.FcPatternIterValueCount(self.pat, &self.iter.?),
|
|
};
|
|
}
|
|
};
|
|
|
|
pub const ValueIterator = struct {
|
|
pat: *c.struct__FcPattern,
|
|
iter: *c.struct__FcPatternIter,
|
|
max: c_int,
|
|
id: c_int = 0,
|
|
|
|
pub const Entry = struct {
|
|
result: Result,
|
|
value: Value,
|
|
binding: ValueBinding,
|
|
};
|
|
|
|
pub fn next(self: *ValueIterator) ?Entry {
|
|
if (self.id >= self.max) return null;
|
|
var value: c.struct__FcValue = undefined;
|
|
var binding: c.FcValueBinding = undefined;
|
|
const result = c.FcPatternIterGetValue(self.pat, self.iter, self.id, &value, &binding);
|
|
self.id += 1;
|
|
|
|
return Entry{
|
|
.result = @enumFromInt(result),
|
|
.binding = @enumFromInt(binding),
|
|
.value = .init(&value),
|
|
};
|
|
}
|
|
};
|
|
};
|
|
|
|
test "create" {
|
|
const testing = std.testing;
|
|
|
|
var pat = Pattern.create();
|
|
defer pat.destroy();
|
|
|
|
try testing.expect(pat.add(.family, .{ .string = "monospace" }, false));
|
|
try testing.expect(pat.add(.weight, .{ .integer = @intFromEnum(Weight.bold) }, false));
|
|
|
|
{
|
|
const val = try pat.get(.family, 0);
|
|
try testing.expect(val == .string);
|
|
try testing.expectEqualStrings("monospace", val.string);
|
|
}
|
|
}
|
|
|
|
test "name parse" {
|
|
var pat = Pattern.parse(":monospace");
|
|
defer pat.destroy();
|
|
|
|
pat.defaultSubstitute();
|
|
}
|