stevee

My wayland statusbar
git clone git://gtms.dev/stevee
Log | Files | Refs | Submodules | README | LICENSE

commit c9e65cb710b0f12e58146e30324b802b2efb9a82
parent a7bc337352ee21f2e04c0552522dd53026cf66cc
Author: Tomas Nemec <owl@gtms.dev>
Date:   Wed, 28 May 2025 19:09:48 +0200

Merge commit 'f6a4ec234a148937b6168d8ed761aa6752c4399d' as 'deps/zig-fcft'

Diffstat:
Adeps/zig-fcft/.gitignore | 1+
Adeps/zig-fcft/CONTRIBUTING.md | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adeps/zig-fcft/COPYING | 22++++++++++++++++++++++
Adeps/zig-fcft/README.md | 30++++++++++++++++++++++++++++++
Adeps/zig-fcft/build.zig | 12++++++++++++
Adeps/zig-fcft/build.zig.zon | 17+++++++++++++++++
Adeps/zig-fcft/fcft.zig | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 397 insertions(+), 0 deletions(-)

diff --git a/deps/zig-fcft/.gitignore b/deps/zig-fcft/.gitignore @@ -0,0 +1 @@ +.zig-cache diff --git a/deps/zig-fcft/CONTRIBUTING.md b/deps/zig-fcft/CONTRIBUTING.md @@ -0,0 +1,111 @@ +# CONTRIBUTING + +## Commit messages + +Commit messages should start with a prefix indicating which part of the +project is affected by your change, if this a general code patch you may not +add it, followed by a one sentence summary, first word is capitalized. First +line is 50 columns long max. + +Example: + + seat: Add pointer events + + Update to zig 1.0.0 + +You can add everything you feel need to be mentioned in the body of the +commit message, wrap lines at 72 columns. + +A great guide to follow [here](https://gitlab.freedesktop.org/wayland/weston/-/blob/master/CONTRIBUTING.md#formatting-and-separating-commits). + +## Patches + +For patches send a **plain text** mail to the [public inbox](https://lists.sr.ht/~novakane/public-inbox) +[~novakane/public-inbox@lists.sr.ht](mailto:~novakane/public-inbox@lists.sr.ht) +with project prefix set to `zig-fcft`: + +The prefix will looks like this `[PATCH zig-fcft] <commit-message>` + +You can configure your Git repo like so: + +```bash +git config sendemail.to "~novakane/public-inbox@lists.sr.ht" +git config format.subjectPrefix "PATCH zig-fcft" +``` + +Some useful resources if you're not used to send patches by email: + +- Using [git send-email](https://git-send-email.io). +- [plain text email](https://useplaintext.email/), if you need a better email + client and learn how to format your email. +- Learn [git rebase](https://git-rebase.io/). +- [pyonji](https://git.sr.ht/~emersion/pyonji) an easy-to-use cli tool to send e-mail patches. + +`git.sr.ht` also provides a [web UI](https://man.sr.ht/git.sr.ht/#sending-patches-upstream) if you prefer. + +## Issues + +Questions or discussions works the same way than patches, precise the project +name in the subject, you just don't need to add `PATCH` before the project name, +e.g. `[zig-fcft] how do I do this?` + +## Coding style + +Follow [zig style guide](https://ziglang.org/documentation/0.8.0/#Style-Guide) +no other option for _zig_ which is kinda great. + +Some things are not enforced by `zig fmt`, I do have an opinion on some of +these things though: + +- Use snake_case for function name, I know this is a pretty big difference + from the official style guide but it makes code so much more readable. +- Wrap lines at 100 columns unless it helps readability. +- Use the struct name instead of Self. + + ```zig + // Foo.zig + const Foo = @This(); + + // Do this + pub fn init(foo: *Foo) void {} + // instead of this + pub fn init(self: *Foo) void {} + ``` + +- For small `if` condition, use: + + ```zig + if (false) return; + + // or + + if (false) { + return; + } + + // Do not use this: + + if (false) + return; + + ``` + +- Format using `zig fmt` before every commit, some tips to use it: + + ```zig + pub example_function( + args1: type, + args2: type, + args3: type, + args4: type, // <- Use a comma here so zig fmt respect it + ) void {} + ``` + + ```zig + if (cond1 == 1 and // <- Line break after and/or + cond2 == 2 and + cond3 == 3 and cond4 == 4 or // <- Works like this too + cond5 == 5) {} + ``` + + diff --git a/deps/zig-fcft/COPYING b/deps/zig-fcft/COPYING @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2021 Andrea Feletto +Copyright (c) 2022 Hugo Machet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/deps/zig-fcft/README.md b/deps/zig-fcft/README.md @@ -0,0 +1,30 @@ +Idiomatic [zig] bindings for [fcft]. + +## Dependencies + +- [zig] 0.14 +- [fcft] 3.1.8 +- [zig-pixman] + +## Usage + +See the [example] repo. + +## Contributing + +See [CONTRIBUTING.md] + +## Acknowledgement + +Started as a fork of https://git.sr.ht/~andreafeletto/zig-fcft + +## License + +zig-fcft is licensed under the [MIT] license. + +[zig]: https://ziglang.org/download/ +[fcft]: https://codeberg.org/dnkl/fcft +[zig-pixman]: https://codeberg.org/ifreund/zig-pixman +[example]: https://git.sr.ht/~novakane/zig-fcft-example +[contributing.md]: CONTRIBUTING.md +[mit]: COPYING diff --git a/deps/zig-fcft/build.zig b/deps/zig-fcft/build.zig @@ -0,0 +1,12 @@ +const std = @import("std"); +const Build = std.Build; + +pub fn build(b: *Build) !void { + const pixman = b.dependency("pixman", .{}).module("pixman"); + _ = b.addModule("fcft", .{ + .root_source_file = b.path("fcft.zig"), + .imports = &.{ + .{ .name = "pixman", .module = pixman }, + }, + }); +} diff --git a/deps/zig-fcft/build.zig.zon b/deps/zig-fcft/build.zig.zon @@ -0,0 +1,17 @@ +.{ + .name = .fcft, + .version = "2.0.0", + .paths = .{ + "build.zig", + "build.zig.zon", + "COPYING", + "fcft.zig", + }, + .dependencies = .{ + .pixman = .{ + .url = "https://codeberg.org/ifreund/zig-pixman/archive/v0.3.0.tar.gz", + .hash = "pixman-0.3.0-LClMnz2VAAAs7QSCGwLimV5VUYx0JFnX5xWU6HwtMuDX", + }, + }, + .fingerprint = 0x11577bbe0b7acccd, +} diff --git a/deps/zig-fcft/fcft.zig b/deps/zig-fcft/fcft.zig @@ -0,0 +1,204 @@ +const pixman = @import("pixman"); + +pub const Error = error{ + NoFont, + NoGlyph, + NoGrapheme, + NoTextRun, +}; + +pub const EmojiPresentation = enum(c_int) { + default, + text, + emoji, +}; + +// Note that this is ignored if antialiasing has been disabled. +pub const Subpixel = enum(c_int) { + default, + none, + horizontal_rgb, + horizontal_bgr, + vertical_rgb, + vertical_bgr, +}; + +pub const Glyph = extern struct { + cp: u32, + cols: c_int, + + // Name of the font the glyph was loaded from. + // Note that it is always null in text-runs glyphs. + font_name: ?[*:0]const u8, + pix: *pixman.Image, + + x: c_int, + y: c_int, + width: c_int, + height: c_int, + + advance: extern struct { + x: c_int, + y: c_int, + }, +}; + +pub const Grapheme = extern struct { + cols: c_int, + count: usize, + glyphs: [*]*const Glyph, +}; + +pub const TextRun = extern struct { + glyphs: [*]*const Glyph, + cluster: [*]c_int, + count: usize, + + extern fn fcft_text_run_destroy(self: *const TextRun) void; + pub const destroy = fcft_text_run_destroy; +}; + +pub const Font = extern struct { + // Name of the primary font only. + name: ?[*:0]const u8, + + height: c_int, + descent: c_int, + ascent: c_int, + + // Width/height of font's widest glyph. + max_advance: extern struct { + x: c_int, + y: c_int, + }, + + underline: extern struct { + position: c_int, + thickness: c_int, + }, + + strikeout: extern struct { + position: c_int, + thickness: c_int, + }, + + antialias: bool, + + subpixel: Subpixel, + + extern fn fcft_from_name( + count: usize, + names: [*][*:0]const u8, + attributes: ?[*:0]const u8, + ) ?*Font; + pub fn fromName(names: [][*:0]const u8, attributes: ?[*:0]const u8) !*Font { + return fcft_from_name(names.len, names.ptr, attributes) orelse error.NoFont; + } + + extern fn fcft_clone(self: *const Font) ?*Font; + pub const clone = fcft_clone; + + extern fn fcft_destroy(self: *Font) void; + pub const destroy = fcft_destroy; + + extern fn fcft_rasterize_char_utf32(self: *Font, cp: u32, subpixel: Subpixel) ?*const Glyph; + pub fn rasterizeCharUtf32(self: *Font, cp: u32, subpixel: Subpixel) !*const Glyph { + return fcft_rasterize_char_utf32(self, cp, subpixel) orelse error.NoGlyph; + } + + extern fn fcft_rasterize_grapheme_utf32( + self: *Font, + len: usize, + grapheme_cluster: [*]const u32, + subpixel: Subpixel, + ) ?*const Grapheme; + pub fn rasterizeGraphemeUtf32( + self: *Font, + grapheme_cluster: []const u32, + subpixel: Subpixel, + ) !*const Grapheme { + return fcft_rasterize_grapheme_utf32( + self, + grapheme_cluster.len, + grapheme_cluster.ptr, + subpixel, + ) orelse error.NoGrapheme; + } + + extern fn fcft_rasterize_text_run_utf32( + self: *Font, + len: usize, + text: [*]const u32, + subpixel: Subpixel, + ) ?*const TextRun; + pub fn rasterizeTextRunUtf32(self: *Font, text: []const u32, subpixel: Subpixel) !*const TextRun { + return fcft_rasterize_text_run_utf32(self, text.len, text.ptr, subpixel) orelse error.NoTextRun; + } + + extern fn fcft_kerning( + self: *Font, + left: u32, + right: u32, + noalias x: ?*c_long, + noalias y: ?*c_long, + ) bool; + pub const kerning = fcft_kerning; + + extern fn fcft_precompose( + self: *const Font, + base: u32, + comb: u32, + base_is_from_primary: bool, + comb_is_from_primary: bool, + composed_is_from_primary: bool, + ) u32; + pub const precompose = fcft_precompose; + + // Note: this function does not clear the glyph or grapheme caches, call + // before rasterizing any glyphs. + extern fn fcft_set_emoji_presentation(self: *Font, presentation: EmojiPresentation) void; + pub const setEmojiPresentation = fcft_set_emoji_presentation; +}; + +pub const LogColorize = enum(c_int) { + never, + always, + auto, +}; + +pub const LogClass = enum(c_int) { + none, + err, + warning, + info, + debug, +}; + +// Must be called before instantiating fonts. +extern fn fcft_init(colorize: LogColorize, do_syslog: bool, log_level: LogClass) bool; +pub const init = fcft_init; + +// Optional, but needed for clean valgrind runs. +extern fn fcft_fini() void; +pub const fini = fcft_fini; + +pub const Capabilities = struct { + pub const grapheme_shaping = 1 << 0; + pub const text_run_shaping = 1 << 1; +}; + +extern fn fcft_capabilities() u32; +pub const capabilities = fcft_capabilities; + +pub const ScalingFilter = enum(c_int) { + none, + nearest, + bilinear, + cubic, + lanczos3, +}; + +// Note: this function does not clear any caches, call before +// rasterizing any glyphs. +extern fn fcft_set_scaling_filter(filter: ScalingFilter) bool; +pub const setScalingFilter = fcft_set_scaling_filter;