Skip to documentation
SLOP

tiny.pdf.Document

Reference tiny.pdf Document

Defined in tiny.pdf.

API (15)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callstiny.pdfDocument
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/pdf/src/document.zig:52

zig
pub const Document = struct {    document_allocator: std.mem.Allocator,    arena_state: alloc_arena.Arena,    filter_storage: *filter.Storage,    bytes: []const u8,    table: xref.Table,    containers: std.AutoHashMapUnmanaged(u32, Container),    fonts: std.AutoHashMapUnmanaged(u32, *const font.Font),    pub fn init(        document_allocator: std.mem.Allocator,        filter_storage: *filter.Storage,        bytes: []const u8,    ) DocumentError!Document {        var arena_state = alloc_arena.Arena.init(document_allocator);        errdefer arena_state.deinit();        var table = try xref.parse(            document_allocator,            arena_state.allocator(),            filter_storage,            bytes,        );        errdefer table.deinit(document_allocator);        return .{            .document_allocator = document_allocator,            .arena_state = arena_state,            .filter_storage = filter_storage,            .bytes = bytes,            .table = table,            .containers = .empty,            .fonts = .empty,        };    }    pub fn deinit(self: *Document) void {        self.fonts.deinit(self.document_allocator);        self.containers.deinit(self.document_allocator);        self.table.deinit(self.document_allocator);        self.arena_state.deinit();    }    pub fn objectValue(self: *Document, reference: object.Reference) DocumentError!object.Value {        return ObjectAccess.init(self).objectValue(reference);    }    pub fn objectStream(self: *Document, reference: object.Reference) DocumentError!Stream {        return ObjectAccess.init(self).objectStream(reference);    }    pub fn resolve(self: *Document, value: object.Value) DocumentError!object.Value {        return ObjectAccess.init(self).resolve(value);    }    pub fn decodeStream(self: *Document, stream: Stream) DocumentError![]u8 {        return ObjectAccess.init(self).decodeStream(stream);    }    pub fn pagesAppend(self: *Document, list_allocator: std.mem.Allocator, pages: *std.ArrayList(Page)) DocumentError!void {        const catalog = switch (try self.objectValue(self.table.root)) {            .dict => |dict| dict,            else => return error.NotADictionary,        };        const pages_value = catalog.get("Pages") orelse return error.MissingPages;        const pages_ref = switch (pages_value) {            .reference => |reference| reference,            else => return error.MissingPages,        };        try self.walkPages(list_allocator, pages, pages_ref, null, 0);    }    fn walkPages(self: *Document, list_allocator: std.mem.Allocator, pages: *std.ArrayList(Page), reference: object.Reference, inherited: ?object.Dict, depth: usize) DocumentError!void {        if (depth > 64) return error.ResolveDepth;        const node = switch (try self.objectValue(reference)) {            .dict => |dict| dict,            else => return error.NotADictionary,        };        const kind = node.get("Type") orelse return error.NotADictionary;        const kind_name = switch (kind) {            .name => |name| name,            else => return error.NotADictionary,        };        const resources: ?object.Dict = blk: {            const value = node.get("Resources") orelse break :blk inherited;            break :blk switch (try self.resolve(value)) {                .dict => |dict| dict,                else => inherited,            };        };        if (std.mem.eql(u8, kind_name, "Pages")) {            const kids = node.get("Kids") orelse return;            const items = switch (try self.resolve(kids)) {                .array => |array| array,                else => return,            };            for (items) |item| {                switch (item) {                    .reference => |kid| try self.walkPages(list_allocator, pages, kid, resources, depth + 1),                    else => {},                }            }            return;        }        if (!std.mem.eql(u8, kind_name, "Page")) return;        const arena = self.arena_state.allocator();        var refs: std.ArrayList(object.Reference) = .empty;        if (node.get("Contents")) |contents| {            switch (contents) {                .reference => |stream_ref| refs.append(arena, stream_ref) catch return error.OutOfMemory,                .array => |items| {                    for (items) |item| {                        switch (item) {                            .reference => |stream_ref| refs.append(arena, stream_ref) catch return error.OutOfMemory,                            else => {},                        }                    }                },                else => {},            }        }        const owned = refs.toOwnedSlice(arena) catch return error.OutOfMemory;        pages.append(list_allocator, .{ .contents = owned, .resources = resources }) catch return error.OutOfMemory;    }    pub fn fontSetAlloc(self: *Document, resources: ?object.Dict) DocumentError!font.Set {        const resources_dict = resources orelse return .{};        const fonts_value = resources_dict.get("Font") orelse return .{};        const fonts_dict = switch (try self.resolve(fonts_value)) {            .dict => |dict| dict,            else => return .{},        };        const arena = self.arena_state.allocator();        const entries = arena.alloc(font.Entry, fonts_dict.entries.len) catch return error.OutOfMemory;        var count: usize = 0;        for (fonts_dict.entries) |entry| {            switch (entry.value) {                .reference => |reference| {                    entries[count] = .{ .name = entry.key, .font = try self.loadFont(reference) };                    count += 1;                },                else => {},            }        }        return .{ .entries = entries[0..count] };    }    fn loadFont(self: *Document, reference: object.Reference) DocumentError!*const font.Font {        if (self.fonts.get(reference.number)) |cached| return cached;        const arena = self.arena_state.allocator();        const created = arena.create(font.Font) catch return error.OutOfMemory;        created.* = .{ .map = self.fontMapAlloc(reference) catch |err| switch (err) {            error.OutOfMemory => return error.OutOfMemory,            else => null,        } };        self.fonts.put(self.document_allocator, reference.number, created) catch return error.OutOfMemory;        return created;    }    fn fontMapAlloc(self: *Document, reference: object.Reference) DocumentError!?cmap.Map {        const dict = switch (try self.objectValue(reference)) {            .dict => |dict| dict,            else => return null,        };        const to_unicode = dict.get("ToUnicode") orelse return null;        const stream_ref = switch (to_unicode) {            .reference => |stream_ref| stream_ref,            else => return null,        };        const stream = try self.objectStream(stream_ref);        const arena = self.arena_state.allocator();        const decoded = try self.decodeStream(stream);        defer self.filter_storage.reset();        return cmap.parseAlloc(arena, decoded) catch |err| switch (err) {            error.OutOfMemory => return error.OutOfMemory,            error.BadCMap => null,        };    }};

Source: lib/pdf/src/root.zig:19

zig
pub const Document = @import("document.zig").Document;
Called byCallsprivate sourcelib.pdf.src.document.DocumentfontMapAlloctiny.pdfextractTextAllocprivate sourcelib.pdf.src.document.ObjectAccessinitDocumentdecodeStream
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstiny.pdfextractTextAllocxref.TabledeinitDocumentdeinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstiny.pdfextractTextAllocprivate sourcelib.pdf.src.document.DocumentloadFontDocumentresolveDocumentfontSetAlloc
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallstiny.pdfextractTextAllocxrefparseDocumentinit
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallsprivate sourcelib.pdf.src.document.DocumentfontMapAlloctiny.pdfextractTextAllocprivate sourcelib.pdf.src.document.ObjectAccessinitDocumentobjectStream
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.pdf.src.document.DocumentfontMapAllocDocumentpagesAppendprivate sourcelib.pdf.src.document.DocumentwalkPagesprivate sourcelib.pdf.src.document.ObjectAccessinitDocumentobjectValue
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstiny.pdfextractTextAllocDocumentobjectValueprivate sourcelib.pdf.src.document.DocumentwalkPagesDocumentpagesAppend
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsDocumentfontSetAllocprivate sourcelib.pdf.src.document.DocumentwalkPagesprivate sourcelib.pdf.src.document.ObjectAccessinitDocumentresolve
Static calls · unresolved targets: 0 · external targets: 0.

Audit

Definitions9
Public names9
Members7
Version26.7.0
Revisiondaab053ee433