diff --git a/src/config/Config.zig b/src/config/Config.zig index 03b6183c1..09491567a 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2965,11 +2965,7 @@ pub const RepeatableCodepointMap = struct { /// Deep copy of the struct. Required by Config. pub fn clone(self: *const Self, alloc: Allocator) !Self { - // TODO(fontmem): clone the codemap descriptors - - return .{ - .map = .{ .list = try self.map.list.clone(alloc) }, - }; + return .{ .map = try self.map.clone(alloc) }; } /// Compare if two of our value are requal. Required by Config. diff --git a/src/font/CodepointMap.zig b/src/font/CodepointMap.zig index c5b5b1ffb..8c9ded402 100644 --- a/src/font/CodepointMap.zig +++ b/src/font/CodepointMap.zig @@ -30,6 +30,18 @@ pub fn deinit(self: *CodepointMap, alloc: Allocator) void { self.list.deinit(alloc); } +/// Deep copy of the struct. The given allocator is expected to +/// be an arena allocator of some sort since the struct itself +/// doesn't support fine-grained deallocation of fields. +pub fn clone(self: *const CodepointMap, alloc: Allocator) !CodepointMap { + var list = try self.list.clone(alloc); + for (list.items(.descriptor)) |*d| { + d.* = try d.clone(alloc); + } + + return .{ .list = list }; +} + /// Add an entry to the map. /// /// For conflicting codepoints, entries added later take priority over diff --git a/src/font/discovery.zig b/src/font/discovery.zig index 13a994f76..4371909ba 100644 --- a/src/font/discovery.zig +++ b/src/font/discovery.zig @@ -86,6 +86,21 @@ pub const Descriptor = struct { return hasher.final(); } + /// Deep copy of the struct. The given allocator is expected to + /// be an arena allocator of some sort since the descriptor + /// itself doesn't support fine-grained deallocation of fields. + pub fn clone(self: *const Descriptor, alloc: Allocator) !Descriptor { + // We can't do any errdefer cleanup in here. As documented we + // expect the allocator to be an arena so any errors should be + // cleaned up somewhere else. + + var copy = self.*; + copy.family = if (self.family) |src| try alloc.dupeZ(u8, src) else null; + copy.style = if (self.style) |src| try alloc.dupeZ(u8, src) else null; + copy.variations = try alloc.dupe(Variation, self.variations); + return copy; + } + /// Convert to Fontconfig pattern to use for lookup. The pattern does /// not have defaults filled/substituted (Fontconfig thing) so callers /// must still do this.