ghostty/pkg/fontconfig/pattern.zig
Qwerasd 2384bd69cc style: use decl literals
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)
2025-05-26 21:50:14 -06:00

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();
}