Add "hello world" to existing pdf in rust?

Viewed 137

Can anyone write up a small code snippet where a a text is added to an existing pdf. I am currently using lopdf but I am willing to look at other crates.

let bytes = include_bytes!("example.pdf");
let mut doc = Document::load_mem(bytes).unwrap();
doc.save("test.pdf").unwrap();

I have been trying for a couple of hours, but I've only been able to add text to a new pdf; if I try to add the text to the existing pdf, the text never shows up.


let bytes = include_bytes!("example.pdf");
let mut doc = Document::load_mem(bytes).unwrap();

let pages_id = doc.new_object_id();
let font_id = doc.add_object(dictionary! {
    "Type" => "Font",
    "Subtype" => "Type1",
    "BaseFont" => "Courier",
});
let resources_id = doc.add_object(dictionary! {
    "Font" => dictionary! {
        "F1" => font_id,
    },
});

let content = Content {
    operations: vec![
        Operation::new("BT", vec![]),
        Operation::new("Tf", vec!["F1".into(), 100.into()]),
        Operation::new("Td", vec![80.into(), 400.into()]),
        Operation::new("Tj", vec![Object::string_literal("hello")]),
        Operation::new("ET", vec![]),
        Operation::new("BT", vec![]),
        Operation::new("Tf", vec!["F1".into(), 12.into()]),
        Operation::new("Td", vec![10.into(), 800.into()]),
        Operation::new(
            "Tj",
            vec![Object::string_literal(
                "hello world.",
            )],
        ),
        Operation::new("ET", vec![]),
        Operation::new("BT", vec![]),
        Operation::new("Tf", vec!["F1".into(), 10.into()]),
        Operation::new("Td", vec![10.into(), 780.into()]),
        Operation::new(
            "Tj",
            vec![Object::string_literal("to")],
        ),
        Operation::new("ET", vec![]),
    ],
};
let content_id = doc.add_object(Stream::new(dictionary! {}, content.encode().unwrap()));
let mut kids = vec![];
for (page_number, page_id) in doc.get_pages() {
    let page_id = doc.add_object(dictionary! {
        "Type" => "Page",
        "Parent" => pages_id,
        "Contents" => content_id,
    });
    kids.push(page_id.into());
}
let pages = dictionary! {
    "Type" => "Pages",
    "Kids" => kids,
    "Count" => 1,
    "Resources" => resources_id,
    "MediaBox" => vec![0.into(), 0.into(), 595.into(), 842.into()],
};
doc.objects.insert(pages_id, Object::Dictionary(pages));
let catalog_id = doc.add_object(dictionary! {
    "Type" => "Catalog",
    "Pages" => pages_id,
});
doc.trailer.set("Root", catalog_id);

doc.save("test.pdf").unwrap();

Example pdf file I am using:

https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf

0 Answers
Related