Idiomatic Rust bindings for Pdfium

Overview

Idiomatic Rust bindings for Pdfium

pdfium-render provides an idiomatic high-level Rust interface around the low-level bindings to Pdfium exposed by the excellent pdfium-sys crate.

    // Iterates over each page in the given test PDF file and renders each page
    // as a separate JPEG image in the current working directory.

    use pdfium_render::{Pdfium, PdfBitmapConfig, PdfBitmapRotation, PdfiumError};
    use image::ImageFormat;
    
    fn export_pages() -> Result<(), PdfiumError> {
        let document = Pdfium::new(Pdfium::bind_to_system_library()?)
            .load_pdf_from_file("test.pdf", None)?;
            
        for page in document.pages() {
            page.get_bitmap_with_config(&PdfBitmapConfig::new()
                    .set_target_width(2000)
                    .set_maximum_height(2000)
                    .rotate_if_landscape(PdfBitmapRotation::Degrees90, true))?
                .as_image() // Renders this page to an Image::DynamicImage
                .as_bgra8()?
                .save_with_format(format!("test-page-{}.jpg", page.index()), ImageFormat::Jpeg)?;
        }
        
        Ok(())
    }

In addition to providing a more natural interface to Pdfium, pdfium-render differs from pdfium-sys in several other important ways:

  • pdfium-render uses libloading to late bind to a Pdfium library at run-time, whereas pdfium-sys binds to a library at compile-time. Not only can compile-time binding be a bit fiddly to configure, but it precludes compiling pdfium-sys to WASM. By binding to Pdfium at run-time instead of compile-time, pdfium-render can dynamically switch between bundled libraries and system libraries and offer idiomatic Rust error handling in situations where a Pdfium library is not available.
  • Late binding to Pdfium means that pdfium-render can be compiled to WASM for running in a browser; this is not possible with pdfium-sys.
  • Pages rendered by Pdfium can be exported as instances of Image::DynamicImage for easy, idiomatic post-processing.

Porting existing Pdfium code from other languages

The high-level idiomatic Rust interface provided by the Pdfium struct is entirely optional; the Pdfium struct wraps around raw FFI bindings defined in the PdfiumLibraryBindings trait, and it is completely feasible to simply use those raw FFI bindings directly rather than the high level interface. This makes porting existing code that calls FPDF_* functions very straight-forward, while still gaining the benefits of late binding and WASM compatibility. For instance, the following code snippet (taken from a C++ sample):

    string test_doc = "test.pdf";

    FPDF_InitLibrary();
    FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
    // ... do something with doc
    FPDF_CloseDocument(doc);
    FPDF_DestroyLibrary();

would translate to the following Rust code:

    let bindings = Pdfium::bind_to_system_library()?;
    
    let test_doc = "test.pdf";

    bindings.FPDF_InitLibrary();
    let doc = bindings.FPDF_LoadDocument(test_doc, None);
    // ... do something with doc
    bindings.FPDF_CloseDocument(doc);
    bindings.FPDF_DestroyLibrary();

External Pdfium builds

pdfium-render does not bundle Pdfium at all. You can either bind to a system-provided library or package an external build of Pdfium alongside your Rust application. When compiling to WASM, packaging an external build of Pdfium as a WASM module is essential.

  • Native builds of Pdfium for all major platforms:
  • WASM builds of Pdfium, suitable for deploying alongside pdfium-render:

Compiling to WASM

See for a full example that shows how to bundle a Rust application using pdfium-render alongside a pre-built Pdfium WASM module for in-browser introspection and rendering of PDF files.

Development status

The initial focus of this crate has been on rendering pages in a PDF file; consequently, FPDF_* functions related to bitmaps and rendering have been prioritised. By 1.0, the functionality of all FPDF_* functions exported by Pdfium will be available.

If you need a function that is not currently exposed, just raise an issue.

Comments
  • Allow reuse of PdfBitmap when rendering pages

    Allow reuse of PdfBitmap when rendering pages

    get_bitmap_with_config is quite slow on WASM. For a 2000x2000 bitmap, it takes ~11ms on my machine.
    Most of that time is spent in create_empty_bitmap_handle. I will explore what optimizations can be done to improve this, especially on WASM.

    After #32, which made the actual rendering process much faster, here is the crude flamegraph I generated.
    Unlike the graphs in #32, this test is more realistic, rendering a real page with a lot of content: image

    "TOTAL" is the whole rendering process, starting with getting a specific page from a document, and ending with drawing the bitmap to a canvas. image

    opened by NyxCode 26
  • Add text objects editing functionality

    Add text objects editing functionality

    The easiest way IMO to edit a text object in a pdf file is if we can directly edit the raw object

    BT /F13 12 Tf 288 720 Td (ABC) Tj ET As a side effect we can easily edit many other properties of the text object, however I don't know how easy it is to implement this or if it's even possible. especially that I don't exactly understand how are document level objects and cross references tables and other stuff that I may not know about relate to the content of the text object

    opened by AbdesamedBendjeddou 21
  • lifetime problems with self-referential struct

    lifetime problems with self-referential struct

    Hi, first off thanks for this library. It's really nice to be able to use such a good pdf renderer like pdfium in rust. I'm integrating pdfium into my digital pen note taking application, which needs to re-render the pdf potentially every frame (when scaling, rotating or translating the page).

    I have major issues with the API that is provided by pdfium-render. There are lifetimes everywhere (which in itself might be justified) but the most function signatures don't have explicit lifetimes and as a consequence all lifetimes are the same, which is overly restrictive. This is probably rather easy to solve.

    Furthermore the PdfDocument requires a bytes slice when loading from bytes. This means the document can't own the bytes and I have to store them separately from the document. This results in a self referential struct that contains bot the document and the bytes. It's not a solution to re-parse the document every time from the bytes as this is too slow. Do you have a solution for this problem?

    I would be willing to do some contributions to this project as I heavily rely on it and need it for my own project.

    Edit: After giving this all some more thought and taking a look at some functions in pdfium-render, I now think that these restrictions are from the C++ pdfium library. That's just how it is designed, right? It just happens to not align very well with the way the borrow checker would like you to write rust code.

    opened by LU15W1R7H 18
  • Add support for setting and retrieving page object transforms for more accurate text placement.

    Add support for setting and retrieving page object transforms for more accurate text placement.

    using the sample pdf #17 I got the desired output, however using other pdfs, the text is not placed correctly even without any change in the text formatting, just extracting the text deleting the original, and placing the same text will result in a wrongly placed text. I'm thinking that there are some other objects' properties that may have been lost and must be preserved to get the desired output.

    opened by AbdesamedBendjeddou 13
  • Loading library once for optimum performance

    Loading library once for optimum performance

    Hi, we are working on a project that needs maximum performance for bulk pdf preview generation on an android JNI bridge. Currently, we're loading the library bindings on every call to the library and we're not sure if it's performance efficient. Could you please give me an example demonstrating loading the library once and then using it on each call? https://github.com/ARK-Builders/ARK-Navigator/pull/271

    opened by hhio618 12
  • `get_processed_image` gives reversed byte order

    `get_processed_image` gives reversed byte order

    So I tried the following:

        let document = pdfium.load_pdf_from_file(&args.file, None)?;
    
        for (page_n, page) in document.pages().iter().enumerate() {
            for (object_n, object) in page.objects().iter().enumerate() {
                match &object {
                    PdfPageObject::Text(_) => println!("Got Text object"),
                    PdfPageObject::Path(_) => println!("Got Path object"),
                    PdfPageObject::Image(image_obj) => {
                        println!("Got Image object");
                        let image = image_obj.get_processed_image(&document)?;
                        image.save(format!("{page_n:0>3}_{object_n:0>3}.jpeg"))?;
                    }
                    PdfPageObject::Shading(_) => println!("Got Shading object"),
                    PdfPageObject::FormFragment(_) => println!("Got FormFragment object"),
                    PdfPageObject::Unsupported(_) => println!("Got Unsupported object"),
                }
            }
        }
    

    This worked on the first image of a PDF I tried it on, after which I got an error Error: Pdfium(PdfiumLibraryInternalError(Unknown)). But the important point is that the image that did manage to get extracted had the colours all wrong - a mostly red image turned blue. I'm guessing this is due to #9 and that this doesn't use the set_reverse_byte_order flag?

    opened by Victor-N-Suadicani 12
  • Support higher performance bitmap retrieval when compiling to WASM.

    Support higher performance bitmap retrieval when compiling to WASM.

    Hey! Great crate, had a blast playing around with it!
    I tried to beat PDF.js for rendering a page to a canvas, but I can't seem to get the performance any better than PDF.js.

    It seems like it always creates a new buffer when calling the get_bitmap_* functions. Would it be possible to introduce a variant which takes a mutable reference to a buffer and renders to that? I am not sure how much performance is left on the table here, but it's probably not nothing.

    opened by NyxCode 12
  • Can't get static compilation to work

    Can't get static compilation to work

    I've tried building pdfium locally to get a libpdfium.a. I then instruct cargo to link with a build.rs like this:

    fn main() {
        println!("cargo:rustc-link-search=native=./");
        println!("cargo:rustc-link-lib=static=pdfium");
    }
    

    And it does find my library. All good so far.

    However I still get all these undefined reference errors when building. Here's a snippet of it (it filled more than my terminal could handle):

              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `bool v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::Register>::RecursivelyEmitMoveChainTargets<unsigned int>(unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::Register>::GapMoveTargets&)':
              ./../../v8/src/maglev/maglev-code-generator.cc:(.text+0x56f): undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::PopTargets(v8::internal::XMMRegister)':
              ./../../buildtools/third_party/libc++/trunk/include/array:218: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `bool v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::RecursivelyEmitMoveChainTargets<v8::internal::XMMRegister>(v8::internal::XMMRegister, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets&)':
              ./../../v8/src/maglev/maglev-code-generator.cc:(.text+0x4e9): undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::EmitMovesFromSource(v8::internal::XMMRegister, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets const&)':
              ./../../buildtools/third_party/libc++/trunk/include/array:218: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&>(std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&>(std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&>(std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&>(std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, std::Cr::__hash_map_iterator<std::Cr::__hash_iterator<std::Cr::__hash_node<std::Cr::__hash_value_type<unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets>, void*>*> > const&, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/new:(.text+0x471): undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(maglev-code-generator.o): in function `bool v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::RecursivelyEmitMoveChainTargets<unsigned int>(unsigned int, v8::internal::maglev::(anonymous namespace)::ParallelMoveResolver<v8::internal::XMMRegister>::GapMoveTargets&)':
              ./../../v8/src/maglev/maglev-code-generator.cc:(.text+0x57a): undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `v8::internal::SharedTurboAssemblerBase<v8::internal::TurboAssembler>::F64x2ConvertLowI32x4U(v8::internal::XMMRegister, v8::internal::XMMRegister, v8::internal::Register)':
              ./../../buildtools/third_party/libc++/trunk/include/__string/char_traits.h:236: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `v8::internal::SharedTurboAssemblerBase<v8::internal::TurboAssembler>::I32x4TruncSatF64x2SZero(v8::internal::XMMRegister, v8::internal::XMMRegister, v8::internal::XMMRegister, v8::internal::Register)':
              ./../../buildtools/third_party/libc++/trunk/include/__string/char_traits.h:236: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `v8::internal::SharedTurboAssemblerBase<v8::internal::TurboAssembler>::I32x4TruncSatF64x2UZero(v8::internal::XMMRegister, v8::internal::XMMRegister, v8::internal::XMMRegister, v8::internal::Register)':
              ./../../buildtools/third_party/libc++/trunk/include/__string/char_traits.h:236: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o):./../../buildtools/third_party/libc++/trunk/include/__string/char_traits.h:236: more undefined references to `std::Cr::__libcpp_verbose_abort(char const*, ...)' follow
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<int, v8::internal::compiler::CallDescriptor::Flag>(int, v8::internal::compiler::CallDescriptor::Flag, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<int, v8::internal::compiler::CallDescriptor::Flag>(int, v8::internal::compiler::CallDescriptor::Flag, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<int, v8::internal::compiler::CallDescriptor::Flag>(int, v8::internal::compiler::CallDescriptor::Flag, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::CallDescriptor::Flag&>(v8::internal::compiler::CallDescriptor::Flag&)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::CallDescriptor::Flag&>(v8::internal::compiler::CallDescriptor::Flag&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::CallDescriptor::Flag&>(v8::internal::compiler::CallDescriptor::Flag&)':
              ./../../v8/src/base/logging.h:141: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::operator<<(int)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::CallDescriptor::Flag&>(v8::internal::compiler::CallDescriptor::Flag&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::CallDescriptor::Flag&>(v8::internal::compiler::CallDescriptor::Flag&)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode>(v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode>(v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode>(v8::internal::compiler::MemoryAccessMode, v8::internal::compiler::MemoryAccessMode, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::MemoryAccessMode&>(v8::internal::compiler::MemoryAccessMode&)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::MemoryAccessMode&>(v8::internal::compiler::MemoryAccessMode&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::MemoryAccessMode&>(v8::internal::compiler::MemoryAccessMode&)':
              ./../../v8/src/base/logging.h:141: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::operator<<(int)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::MemoryAccessMode&>(v8::internal::compiler::MemoryAccessMode&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::MemoryAccessMode&>(v8::internal::compiler::MemoryAccessMode&)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::XMMRegister const&, v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&, v8::internal::XMMRegister const&, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::XMMRegister const&, v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&, v8::internal::XMMRegister const&, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::XMMRegister const&, v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&, v8::internal::XMMRegister const&, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::XMMRegister const&>(v8::internal::XMMRegister const&)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth>(v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth>(v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth>(v8::internal::compiler::AtomicWidth, v8::internal::compiler::AtomicWidth, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition>(v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition>(v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition>(v8::internal::compiler::FlagsCondition, v8::internal::compiler::FlagsCondition, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsCondition&>(v8::internal::compiler::FlagsCondition&)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsCondition&>(v8::internal::compiler::FlagsCondition&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(code-generator-x64.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsCondition&>(v8::internal::compiler::FlagsCondition&)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(unwinding-info-writer-x64.o): in function `v8::internal::compiler::UnwindingInfoWriter::BeginInstructionBlock(int, v8::internal::compiler::InstructionBlock const*)':
              ./../../buildtools/third_party/libc++/trunk/include/vector:1457: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(unwinding-info-writer-x64.o): in function `v8::internal::compiler::UnwindingInfoWriter::EndInstructionBlock(v8::internal::compiler::InstructionBlock const*)':
              ./../../v8/src/zone/zone.h:(.text+0x3a6): undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `v8::internal::compiler::InstructionScheduler::StressSchedulerQueue::PopBestCandidate(int)':
              ./../../buildtools/third_party/libc++/trunk/include/list:1708: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode>(v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode>(v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode, char const*)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >* v8::base::MakeCheckOpString<v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode>(v8::internal::compiler::FlagsMode, v8::internal::compiler::FlagsMode, char const*)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsMode&>(v8::internal::compiler::FlagsMode&)':
              ./../../buildtools/third_party/libc++/trunk/include/ios:709: undefined reference to `std::Cr::ios_base::init(void*)'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsMode&>(v8::internal::compiler::FlagsMode&)':
              ./../../buildtools/third_party/libc++/trunk/include/sstream:230: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:231: undefined reference to `vtable for std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:766: undefined reference to `std::Cr::basic_stringbuf<char, std::Cr::char_traits<char>, std::Cr::allocator<char> >::str() const'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:864: undefined reference to `std::Cr::basic_streambuf<char, std::Cr::char_traits<char> >::~basic_streambuf()'
              /usr/bin/ld: ./../../buildtools/third_party/libc++/trunk/include/sstream:866: undefined reference to `std::Cr::basic_ostream<char, std::Cr::char_traits<char> >::~basic_ostream()'
              /usr/bin/ld: .//libpdfium.a(instruction-scheduler.o): in function `std::Cr::basic_string<char, std::Cr::char_traits<char>, std::Cr::allocator<char> > v8::base::detail::PrintToString<v8::internal::compiler::FlagsMode&>(v8::internal::compiler::FlagsMode&)':
              ./../../v8/src/base/logging.h:54: undefined reference to `std::Cr::basic_ios<char, std::Cr::char_traits<char> >::~basic_ios()'
              /usr/bin/ld: .//libpdfium.a(memory-lowering.o): in function `v8::internal::compiler::MemoryLowering::AllocationGroup* v8::internal::Zone::New<v8::internal::compiler::MemoryLowering::AllocationGroup, v8::internal::compiler::Node*&, v8::internal::AllocationType&, v8::internal::compiler::Node*&, v8::internal::Zone*>(v8::internal::compiler::Node*&, v8::internal::AllocationType&, v8::internal::compiler::Node*&, v8::internal::Zone*&&)':
              ./../../buildtools/third_party/libc++/trunk/include/__tree:294: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(memory-lowering.o): in function `v8::internal::compiler::MemoryLowering::AllocationGroup* v8::internal::Zone::New<v8::internal::compiler::MemoryLowering::AllocationGroup, v8::internal::compiler::Node*&, v8::internal::AllocationType&, v8::internal::Zone*>(v8::internal::compiler::Node*&, v8::internal::AllocationType&, v8::internal::Zone*&&)':
              ./../../buildtools/third_party/libc++/trunk/include/__tree:294: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(cfx_xmldocument.o): in function `std::Cr::vector<std::Cr::unique_ptr<CFX_XMLNode, std::Cr::default_delete<CFX_XMLNode> >, std::Cr::allocator<std::Cr::unique_ptr<CFX_XMLNode, std::Cr::default_delete<CFX_XMLNode> > > >::back[abi:v16000]()':
              ./../../buildtools/third_party/libc++/trunk/include/vector:563: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(cfx_xmldocument.o): in function `void std::Cr::advance[abi:v16000]<std::Cr::move_iterator<std::Cr::__wrap_iter<std::Cr::unique_ptr<CFX_XMLNode, std::Cr::default_delete<CFX_XMLNode> >*> >, long, long, void>(std::Cr::move_iterator<std::Cr::__wrap_iter<std::Cr::unique_ptr<CFX_XMLNode, std::Cr::default_delete<CFX_XMLNode> >*> >&, long)':
              ./../../buildtools/third_party/libc++/trunk/include/__iterator/advance.h:64: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(cfx_xmlelement.o): in function `std::Cr::__tree_node_base<void*>* std::Cr::__tree_leaf[abi:v16000]<std::Cr::__tree_node_base<void*>*>(std::Cr::__tree_node_base<void*>*)':
              ./../../buildtools/third_party/libc++/trunk/include/__tree:223: undefined reference to `std::Cr::__libcpp_verbose_abort(char const*, ...)'
              /usr/bin/ld: .//libpdfium.a(cfx_xmlparser.o):./../../buildtools/third_party/libc++/trunk/include/__iterator/advance.h:64: more undefined references to `std::Cr::__libcpp_verbose_abort(char const*, ...)' follow
              collect2: error: ld returned 1 exit status
              
      = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
      = note: use the `-l` flag to specify native libraries to link
      = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
    
    error: could not compile `internal` due to previous error
    

    Any ideas how I might fix this? Any help would be greatly appreciated.

    opened by Victor-N-Suadicani 10
  • Latest release of pdfium-lib wasm binary does not work

    Latest release of pdfium-lib wasm binary does not work

    https://github.com/paulocoutinhox/pdfium-lib/releases/tag/5407 changes how the PDFium module is defined. I was able to get the example working by replacing

    Module.onRuntimeInitialized = async _ => {
    

    with

    PDFiumModule().then(async mod => {
        Module = mod;
        wasmTable = Module.asm.__indirect_function_table;
    

    I also noticed that the Reflect::get calls don't seem to return an error when the result is undefined, instead they just return JsValue::UNDEFINED. I'm not entirely sure about this, but without defining the wasmTable variable I got an error in table.length() because table is undefined. So maybe the return values of Reflect::get always have to be checked for .is_undefined()?

    opened by DorianRudolph 9
  • Complete implementation of PdfiumRenderWasmState::copy_file_access_to_pdfium().

    Complete implementation of PdfiumRenderWasmState::copy_file_access_to_pdfium().

    File access functions in Pdfium use the FPDF_FILEACCESS struct which contains a pointer to a callback function that Pdfium repeatedly calls to load (or save) blocks of data from (or to) a file. That function pointer points to a location in pdfium-render's local WASM memory heap, but Pdfium needs a pointer to a function in its own WASM memory heap. Simply copying the function to Pdfium's WASM heap is not sufficient, since the function will no longer have access to any data it expects to find in our local WASM heap.

    opened by ajrcarey 9
  • Add bindings and functions to access segments of page path objects, font glyphs, and clip paths.

    Add bindings and functions to access segments of page path objects, font glyphs, and clip paths.

    PDFIUM allows access to Path's points to extract vector data Base API are:

    FPDFPathObj_CountPoints
    FPDFPathObj_GetPointType
    FPDFPathObj_GetPointX
    FPDFPathObj_GetPointY
    

    Would be very nice to have access to this in pdfium-render, in an API that can look like this:

    for i in 0..path.points_count() {
        let type = path.get_point_type(i);
        match type {
            PdfPagePathObject::POINT_TYPE_MOVETO => {
                let x = path.get_point_x(i, 0);
                let y = path.get_point_y(i, 0);
            },
            PdfPagePathObject::POINT_TYPE_LINETO => {
                let x = path.get_point_x(i, 0);
                let y = path.get_point_y(i, 0);
            },
            PdfPagePathObject::POINT_TYPE_BEZIERTO => {
                let x1 = path.get_point_x(i, 0);
                let y1 = path.get_point_y(i, 0);
                let x2 = path.get_point_x(i, 1);
                let y2 = path.get_point_y(i, 1);
                let x3 = path.get_point_x(i, 2);
                let y3 = path.get_point_y(i, 2);
            },
            ...
        }
    }
    

    Or even better:

    for point in path.points() {
        match point {
            PdfPagePathObjectPoint::MoveTo(x, y) => {},
            PdfPagePathObjectPoint::LineTo(x, y) => {},
            PdfPagePathObjectPoint::BezierTo(x1, y1, x2, y2, x3, y3) => {},
            ...
        }
    }
    
    opened by chingham 7
  • Moving `PdfPageObject`s from one `PdfPage` to another

    Moving `PdfPageObject`s from one `PdfPage` to another

    Hi there.

    I've been trying hard to get moving objects from one page to another to work, without success.

    On the one hand, using PdfPageObjects::remove_object gives borrow checker errors because getting a PdfPage object borrows PdfPageObjectsimmutable and then you can't borrow the samePdfPageObjectsmutably to call theremove_object` function.

    I've also tried it with good old index access and with that I can remove them fine, but re-adding them to another PdfPage produces segfaults.

    For example:

            let mut objs = page.objects();
            let new_objs = new_page.objects_mut();
            let mut i = 0;
            while i < objs.len() {
                let obj = objs.get(i).map_err(PdfiumErr)?;
                let Ok(bounds) = obj.bounds() else {continue};
                if bounds.bottom >= y {
                    log::debug!("item = {:?}", obj.object_type());
                    new_objs.take_object_from_page(&mut page, I); // <-- segfault here
                    objs = page.objects();
                } else {
                    i += 1;
                }
            }
    

    produces segfaults.

    There is also the PdfPageGroupObject, but this doesn't help since calling remove_objects_from_page also deletes the objects (and somehow mirrors the source page horizontally).

    So, am I doing this wrong? Is it even possible?

    Either way, many thanks for your great work.

    opened by N3xed 6
  • Consider options for offering automated building of Pdfium as part of pdfium-render.

    Consider options for offering automated building of Pdfium as part of pdfium-render.

    Follow-on from #12, #51. Look into options for offering automated building of Pdfium as part of pdfium-render, and in the meantime document the process for building Pdfium manually based on a sample build script provided by Victor-N-Suadicani as part of #51.

    opened by ajrcarey 4
  • Standardise lifetime and reference handling for child objects inside PdfDocument.

    Standardise lifetime and reference handling for child objects inside PdfDocument.

    As of 0.7.19, the child objects inside PdfDocument are created and returned using a variety of different approaches:

    • Some immutable-only collections (with no mutable equivalent) are created fresh each time the accessor function is called, and always return a new object instance, e.g. PdfDocument::bookmarks(), PdfDocument::metadata(), PdfDocument::permissions(), PdfDocument::signatures().
    • Some collections that support both immutable and mutable access, and distinguish between mutable and immutable references, create a private owned collection instance inside the containing object as part of the object's new() constructor, then hand out mutable or immutable references to that owned collection as necessary, e.g. PdfDocument::attachments(), PdfDocument::attachments_mut().
    • PdfPages, which supports both immutable and mutable access but does not distinguish between mutable and immutable references, instead handing out a new object instance each time it is called from PdfDocument::pages().

    Standardise the approach. All collections should create private owned collection instances inside the containing object as part of the object's new() constructor, function, then hand out mutable or immutable references as necessary. New object instances should never be handed out.

    opened by ajrcarey 13
  • Add PdfParagraph to allow for more natural processing of multi-line text.

    Add PdfParagraph to allow for more natural processing of multi-line text.

    Follow-on from #17, #22, #25. Add a PdfParagraph object that allows for easier handling of multi-line text with embedded character formatting changes.

    Ideally, it would be possible to generate a PdfParagraph from an existing set of PdfPageTextObject objects, each one containing a formatted fragment of a paragraph.

    opened by ajrcarey 1
Owner
Alastair Carey
Alastair Carey
Rust bindings for GDNative

GDNative bindings for Rust Rust bindings to the Godot game engine. Website | User Guide | API Documentation Stability The bindings cover most of the e

null 3.2k Jan 9, 2023
SDL bindings for Rust

Rust-SDL Bindings for SDL in Rust Overview Rust-SDL is a library for talking to SDL from Rust. Low-level C components are wrapped in Rust code to make

Brian Anderson 174 Nov 22, 2022
SDL2 bindings for Rust

Rust-SDL2 Bindings for SDL2 in Rust Changelog for 0.34.2 Overview Rust-SDL2 is a library for talking to the new SDL2.0 libraries from Rust. Low-level

null 2.2k Jan 5, 2023
SFML bindings for Rust

rust-sfml Rust bindings for SFML, the Simple and Fast Multimedia Library. Requirements Linux, Windows, or OS X Rust 1.42 or later SFML 2.5 CSFML 2.5 D

Jeremy Letang 567 Jan 7, 2023
Rust bindings for libtcod 1.6.3 (the Doryen library/roguelike toolkit)

Warning: Not Maintained This project is no longer actively developed or maintained. Please accept our apologies. Open pull requests may still get merg

Tomas Sedovic 226 Nov 17, 2022
Some Rust bindings for Binary Ninja

Binary Ninja Rust Bindings Work in progress Rust bindings geared towards analysis. Features added as they come up. No promises anything works at this

Cory Duplantis 21 May 5, 2022
Qt Quick / QML bindings for Rust

qmlrsng Qt Quick bindings for Rust, based on libqmlbind. The crate libqmlbind-sys wraps libqmlbind C library in Rust and exposes an unsafe API. The go

Nicolas Bigaouette 5 Jul 13, 2017
Wein2D.js bindings for creating browser games in Rust using WebAssembly.

Wein2D.js-WASM Wein2D.js bindings for creating browser games in Rust using WebAssembly. Wein2D.js-WASM requires Wein2d.js to be loaded in the same doc

DevTaube 1 Apr 14, 2022
A simple Verlet integration solver written using the Rust SDL2 bindings.

Rust Verlet Solver A simple Verlet integration solver written using the Rust SDL2 bindings. Where's the friction?! Building cargo-vcpkg is required in

Will 8 Jun 6, 2022
MMDeploy bindings for Rust.

rust-mmdeploy-sys MMDeploy bindings for Rust. ?? THIS REPO IS STILL UNDER CONSTRUCTION! Prerequisites NOTICE: Linux only. Onnxruntime only. In order t

梦阳 2 Sep 29, 2022
Rust bindings for googleprojectzero/TinyInst

tinyinst-rs FFI to TinyInst. Created for LibAFL. Dependencies cxxbridge cargo-make python3 git Running the test Open a terminal and set up your build

Advanced Fuzzing League ++ 12 Jan 20, 2023
Rust bindings for entity-gym.

EntityGym for Rust EntityGym is a Python library that defines a novel entity-based abstraction for reinforcement learning environments which enables h

null 18 Apr 15, 2023
A simple Verlet integration solver written using the Rust SDL2 bindings.

Rust Verlet Solver A simple Verlet integration solver written using the Rust SDL2 bindings. Where's the friction?! Building cargo-vcpkg is required in

Will 8 Jun 6, 2022
corange-rs CorangeCorange lucidscape/corange-rs — Corange bindings

CORANGE-RS This crate provides an interface to the Corange game engine, written in Pure C, SDL and OpenGL by Daniel Holden. Features include: deferred

null 43 Jul 22, 2022
Pure and simple Vulkan bindings generated from Vulkan-Headers!

mira Pure and simple Vulkan bindings generated from Vulkan-Headers! Mira provides a simple and straightforward way to interact with Vulkan. Everything

maresia 3 Mar 3, 2022
Python bindings for egg

Python bindings for egg Installing Install maturin, a cool Rust/Python builder thingy. Download from their site or just pip install maturin. Type make

null 28 Dec 25, 2022
Bindings to TinyGL, a Small, Free and Fast Subset of OpenGL

TinyGL is a very lightweight partial OpenGL implementation. Its small size makes it ideal for static linking.

null 12 Oct 13, 2022
Safe, fully-featured bindings to the Tracy profiler

Complete Rust bindings for the Tracy profiler. Getting Started Just add the following to your Cargo.toml: [dependencies.tracy] package = "tracy_full"

Shaye Garg 12 May 6, 2023
Rust-raytracer - 🔭 A simple ray tracer in Rust 🦀

rust-raytracer An implementation of a very simple raytracer based on Ray Tracing in One Weekend by Peter Shirley in Rust. I used this project to learn

David Singleton 159 Nov 28, 2022