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:
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;