lib/pdf/src/font.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 const cmap = @import("cmap.zig");
 4 
 5 pub const Font = struct {
 6     map: ?cmap.Map = null,
 7 };
 8 
 9 pub const Entry = struct {
10     name: []const u8,
11     font: *const Font,
12 };
13 
14 pub const Set = struct {
15     entries: []const Entry = &.{},
16 
17     pub fn get(self: Set, name: []const u8) ?*const Font {
18         for (self.entries) |entry| {
19             if (std.mem.eql(u8, entry.name, name)) return entry.font;
20         }
21         return null;
22     }
23 };
24 
25 pub fn appendText(current: ?*const Font, allocator: std.mem.Allocator, out: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory}!void {
26     if (current) |selected| {
27         if (selected.map) |map| return map.appendDecoded(allocator, out, bytes);
28     }
29     out.appendSlice(allocator, bytes) catch return error.OutOfMemory;
30 }
31 
32 test "font set resolves names and unmapped fonts pass bytes through" {
33     const plain = Font{};
34     const set = Set{ .entries = &.{.{ .name = "F1", .font = &plain }} };
35     try std.testing.expect(set.get("F1") != null);
36     try std.testing.expect(set.get("F2") == null);
37     var out = std.ArrayList(u8).empty;
38     defer out.deinit(std.testing.allocator);
39     try appendText(set.get("F1"), std.testing.allocator, &out, "raw bytes");
40     try appendText(null, std.testing.allocator, &out, "!");
41     try std.testing.expectEqualStrings("raw bytes!", out.items);
42 }