ajrcarey / pdfium-render

A high-level idiomatic Rust wrapper around Pdfium, the C++ PDF library used by the Google Chromium project.
https://crates.io/crates/pdfium-render
Other
363 stars 59 forks source link

Error when compiling on Windows #24

Closed AbdesamedBendjeddou closed 2 years ago

AbdesamedBendjeddou commented 2 years ago

running these two programs seems to give a compile error on windows

use pdfium_render::prelude::*;

fn main()   {
    let pdfium = Pdfium::new(
        Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./"))
            .or_else(|_| Pdfium::bind_to_system_library()).unwrap(),
    );

    // Create a new document containing a single page with the desired sample text.

    let document = pdfium.create_new_pdf().unwrap();

    let mut pages = document.pages();

    let mut page = pages.create_page_at_start(PdfPagePaperSize::a4()).unwrap();

    // Desired sample text:

    let sample_text = vec!(
            "TITLE HERE",
            "",
            "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum",
            "has been the industry's standard dummy text ever since the 1500s, when an unknown",
            "printer took a galley of type and scrambled it to make a type specimen book. It has",
            "survived not only five centuries, but also the leap into electronic typesetting, remaining",
            "essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets",
            "containing Lorem Ipsum passages, and more recently with desktop publishing software like",
            "Aldus PageMaker including versions of Lorem Ipsum.",
        );

    // Add the sample text to the page. We create a separate text object
    // for each line in the sample text.

    let regular_font = PdfFont::helvetica(&document);

    let bold_font = PdfFont::helvetica_bold(&document);

    let font_size = PdfPoints::new(12.0);

    let line_spacing = font_size * 1.5;

    let line_left = PdfPoints::new(50.0);

    let mut line_top = PdfPoints::new(700.0);

    for (index, line) in sample_text.iter().enumerate() {
        let font = {
            // Make the first line bold, all other lines regular.

            if index == 0 {
                &bold_font
            } else {
                &regular_font
            }
        };

        page.objects_mut()
            .create_text_object(line_left, line_top, line, font, font_size).unwrap();

        line_top -= line_spacing;
    }

    document.save_to_file("before.pdf").unwrap();

}
// this just a part of the program I included only the part where the error seems to occur
 let mut bold_word = PdfPageTextObject::new(
                                &document,
                                child_object.bold.clone(),
                                &object_txt.font(),
                                object_txt.font_size(),
                            )
                            .unwrap();
/* line 67 */         bold_part.translate(word_left, line_top).unwrap();
                            word_left += bold_part.width().unwrap();
//the error:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PdfiumLibraryInternalError(Unknown)', src\place.rs:67:70  

since create_text_object() use translate() method in its definition I'm assuming that both errors are in fact the same. both programs compile fine on WSL It is worth mentioning that opening a file, removing text objects from it and saving the edited version worked fine. probably because we didn't need to use translate() method.

ajrcarey commented 2 years ago

I can reproduce the problem on a Windows 11 x64 virtual machine with rustc 1.60.0 and Pdfium 105.0.5117.0.

You are right that the underlying problem is the same, although it's not specific to translate(). There are a number of FPDF_* functions that return void rather than any particular return value; the FPDFPageObj_Transform() function used in translate() is one of those, but there are others. The idea is that, after calling these void-returning FPDF_* functions, you then call FPDF_GetLastError() to see if there was any problem with the previous call.

It's these calls to FPDF_GetLastError() that are failing on Windows. If I comment out those calls to FPDF_GetLastError(), the sample works fine and the before.pdf file is created correctly, so there aren't any actual errors occurring, but FPDF_GetLastError() is reporting that there are. Working on it.

ajrcarey commented 2 years ago

On Linux and macOS, a call to FPDF_GetLastError() after a successful operation consistently returns 0 (which is defined in the library as the constant FPDF_ERR_SUCCESS), but on Windows the return value on success is undefined; in my testing, the return value was usually 487. In fairness, the documentation for FPDF_GetLastError() at https://pdfium.googlesource.com/pdfium/+/refs/heads/main/public/fpdfview.h does state that "... if the previous SDK call succeeded, the return value of this function is not defined".

Adjusted PdfiumLibraryBindings::get_pdfium_last_error() in bindings.rs to assume success on an undefined return value rather than failure.

ajrcarey commented 2 years ago

Updated documentation. Bumped crate version to 0.7.5. Published to crates.io.

ajrcarey commented 2 years ago

Please update to crate version 0.7.5 and confirm that the problem persists.

AbdesamedBendjeddou commented 2 years ago

Yes, the problem is fixed! Thank you very much for your work

ajrcarey commented 2 years ago

Excellent. Hopefully this gives you everything you need to complete your project.

AbdesamedBendjeddou commented 2 years ago

There is one more problem, I'm opening an issue for it now