summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2024-04-05 21:48:53 -0700
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2024-04-05 21:48:53 -0700
commitb77513de1a6bcfd9d23fc35bcfb5cb86e8cabaaf (patch)
treeff6f01144d70bffd87a4fc9bd7fa5bc1cc131c67 /src
parent6aa659c4b5c7ad23c1fb2197e3f85f115b137d46 (diff)
font/harfbuzz: work with new font structures
Diffstat (limited to 'src')
-rw-r--r--src/font/Collection.zig2
-rw-r--r--src/font/shaper/harfbuzz.zig118
2 files changed, 60 insertions, 60 deletions
diff --git a/src/font/Collection.zig b/src/font/Collection.zig
index 89d4aee4c..38f4b92f8 100644
--- a/src/font/Collection.zig
+++ b/src/font/Collection.zig
@@ -554,6 +554,8 @@ test getIndex {
}
test autoItalicize {
+ if (comptime !@hasDecl(Face, "italicize")) return error.SkipZigTest;
+
const testing = std.testing;
const alloc = testing.allocator;
const testFont = @import("test.zig").fontRegular;
diff --git a/src/font/shaper/harfbuzz.zig b/src/font/shaper/harfbuzz.zig
index 04143c090..13988ecf3 100644
--- a/src/font/shaper/harfbuzz.zig
+++ b/src/font/shaper/harfbuzz.zig
@@ -4,10 +4,10 @@ const Allocator = std.mem.Allocator;
const harfbuzz = @import("harfbuzz");
const font = @import("../main.zig");
const Face = font.Face;
+const Collection = font.Collection;
const DeferredFace = font.DeferredFace;
-const Group = font.Group;
-const GroupCache = font.GroupCache;
const Library = font.Library;
+const SharedGrid = font.SharedGrid;
const Style = font.Style;
const Presentation = font.Presentation;
const terminal = @import("../../terminal/main.zig");
@@ -83,7 +83,7 @@ pub const Shaper = struct {
/// and assume the y value matches.
pub fn runIterator(
self: *Shaper,
- group: *GroupCache,
+ grid: *SharedGrid,
screen: *const terminal.Screen,
row: terminal.Pin,
selection: ?terminal.Selection,
@@ -91,7 +91,7 @@ pub const Shaper = struct {
) font.shape.RunIterator {
return .{
.hooks = .{ .shaper = self },
- .group = group,
+ .grid = grid,
.screen = screen,
.row = row,
.selection = selection,
@@ -110,7 +110,13 @@ pub const Shaper = struct {
// We only do shaping if the font is not a special-case. For special-case
// fonts, the codepoint == glyph_index so we don't need to run any shaping.
if (run.font_index.special() == null) {
- const face = try run.group.group.faceFromIndex(run.font_index);
+ // We have to lock the grid to get the face and unfortunately
+ // freetype faces (typically used with harfbuzz) are not thread
+ // safe so this has to be an exclusive lock.
+ run.grid.lock.lock();
+ defer run.grid.lock.unlock();
+
+ const face = try run.grid.resolver.collection.getFace(run.font_index);
const i = if (!face.quirks_disable_default_font_features) 0 else i: {
// If we are disabling default font features we just offset
// our features by the hardcoded items because always
@@ -251,7 +257,7 @@ test "run iterator" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -270,7 +276,7 @@ test "run iterator" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -290,7 +296,7 @@ test "run iterator" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -342,7 +348,7 @@ test "run iterator: empty cells with background set" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -385,7 +391,7 @@ test "shape" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -414,7 +420,7 @@ test "shape inconsolata ligs" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -439,7 +445,7 @@ test "shape inconsolata ligs" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -473,7 +479,7 @@ test "shape monaspace ligs" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -507,7 +513,7 @@ test "shape emoji width" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -547,7 +553,7 @@ test "shape emoji width long" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -586,7 +592,7 @@ test "shape variation selector VS15" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -623,7 +629,7 @@ test "shape variation selector VS16" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -657,7 +663,7 @@ test "shape with empty cells in between" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -695,7 +701,7 @@ test "shape Chinese characters" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -722,13 +728,6 @@ test "shape box glyphs" {
var testdata = try testShaper(alloc);
defer testdata.deinit();
- // Setup the box font
- testdata.cache.group.sprite = font.sprite.Face{
- .width = 18,
- .height = 36,
- .thickness = 2,
- };
-
var buf: [32]u8 = undefined;
var buf_idx: usize = 0;
buf_idx += try std.unicode.utf8Encode(0x2500, buf[buf_idx..]); // horiz line
@@ -742,7 +741,7 @@ test "shape box glyphs" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -779,7 +778,7 @@ test "shape selection boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
terminal.Selection.init(
@@ -802,7 +801,7 @@ test "shape selection boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
terminal.Selection.init(
@@ -825,7 +824,7 @@ test "shape selection boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
terminal.Selection.init(
@@ -848,7 +847,7 @@ test "shape selection boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
terminal.Selection.init(
@@ -871,7 +870,7 @@ test "shape selection boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
terminal.Selection.init(
@@ -907,7 +906,7 @@ test "shape cursor boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -926,7 +925,7 @@ test "shape cursor boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -945,7 +944,7 @@ test "shape cursor boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -964,7 +963,7 @@ test "shape cursor boundary" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -996,7 +995,7 @@ test "shape cursor boundary and colored emoji" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1015,7 +1014,7 @@ test "shape cursor boundary and colored emoji" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1032,7 +1031,7 @@ test "shape cursor boundary and colored emoji" {
// Get our run iterator
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1062,7 +1061,7 @@ test "shape cell attribute change" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1086,7 +1085,7 @@ test "shape cell attribute change" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1111,7 +1110,7 @@ test "shape cell attribute change" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1136,7 +1135,7 @@ test "shape cell attribute change" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1160,7 +1159,7 @@ test "shape cell attribute change" {
var shaper = &testdata.shaper;
var it = shaper.runIterator(
- testdata.cache,
+ testdata.grid,
&screen,
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
null,
@@ -1178,13 +1177,13 @@ test "shape cell attribute change" {
const TestShaper = struct {
alloc: Allocator,
shaper: Shaper,
- cache: *GroupCache,
+ grid: *SharedGrid,
lib: Library,
pub fn deinit(self: *TestShaper) void {
self.shaper.deinit();
- self.cache.deinit(self.alloc);
- self.alloc.destroy(self.cache);
+ self.grid.deinit(self.alloc);
+ self.alloc.destroy(self.grid);
self.lib.deinit();
}
};
@@ -1210,17 +1209,11 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
var lib = try Library.init();
errdefer lib.deinit();
- var cache_ptr = try alloc.create(GroupCache);
- errdefer alloc.destroy(cache_ptr);
- cache_ptr.* = try GroupCache.init(alloc, try Group.init(
- alloc,
- lib,
- .{ .points = 12 },
- ));
- errdefer cache_ptr.*.deinit(alloc);
+ var c = try Collection.init(alloc);
+ c.load_options = .{ .library = lib };
// Setup group
- _ = try cache_ptr.group.addFace(.regular, .{ .loaded = try Face.init(
+ _ = try c.add(alloc, .regular, .{ .loaded = try Face.init(
lib,
testFont,
.{ .size = .{ .points = 12 } },
@@ -1228,7 +1221,7 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
if (font.options.backend != .coretext) {
// Coretext doesn't support Noto's format
- _ = try cache_ptr.group.addFace(.regular, .{ .loaded = try Face.init(
+ _ = try c.add(alloc, .regular, .{ .loaded = try Face.init(
lib,
testEmoji,
.{ .size = .{ .points = 12 } },
@@ -1245,21 +1238,26 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
defer disco_it.deinit();
var face = (try disco_it.next()).?;
errdefer face.deinit();
- _ = try cache_ptr.group.addFace(.regular, .{ .deferred = face });
+ _ = try c.add(alloc, .regular, .{ .deferred = face });
}
- _ = try cache_ptr.group.addFace(.regular, .{ .loaded = try Face.init(
+ _ = try c.add(alloc, .regular, .{ .loaded = try Face.init(
lib,
testEmojiText,
.{ .size = .{ .points = 12 } },
) });
+ const grid_ptr = try alloc.create(SharedGrid);
+ errdefer alloc.destroy(grid_ptr);
+ grid_ptr.* = try SharedGrid.init(alloc, .{ .collection = c }, false);
+ errdefer grid_ptr.*.deinit(alloc);
+
var shaper = try Shaper.init(alloc, .{});
errdefer shaper.deinit();
return TestShaper{
.alloc = alloc,
.shaper = shaper,
- .cache = cache_ptr,
+ .grid = grid_ptr,
.lib = lib,
};
}