Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDF display prototype #78

Open
Compro-Prasad opened this issue Sep 26, 2019 · 2 comments
Open

PDF display prototype #78

Compro-Prasad opened this issue Sep 26, 2019 · 2 comments
Assignees

Comments

@Compro-Prasad
Copy link
Contributor

Compro-Prasad commented Sep 26, 2019

No step by step guide available

I was looking for Getting Started with Poppler and wasted a lot of time in not looking into the actual documentation itself. The problem is that there is hardly any step by step guide to get started with poppler.

What is poppler?

For people not aware of Poppler; Poppler is basically a very common library I have seen while installing packages in Linux. I hardly had any idea of what it was until I saw that many apps use poppler to display PDFs.

Getting started

  1. There are three sets of APIs available for poppler (as given here):
    a. CPP
    b. Glib
    c. qt5
  2. The test I have done is using poppler-cpp. So, make sure it(libraries and headers) is installed on your system.
  3. Since it is in C++, you need to have a C++ compiler installed. I would be using g++ for this example.
  4. Finding and linking specific libraries and headers manually is a hard task. I will be using pkg-config to get that information.
  5. The program:
#include <poppler/cpp/poppler-document.h>
#include <poppler/cpp/poppler-image.h>
#include <poppler/cpp/poppler-page-renderer.h>

int main(int argc, char **argv) {
  // argv[1] should have the file you want to read from
  poppler::document *d = poppler::document::load_from_file(argv[1]);

  // This creates the first page in the memory
  poppler::page *p = d->create_page(0);

  // This will create an image off the first page in memory of 200xDPI and 200yDPI
  // You can get further documentation online
  poppler::page_renderer pr;
  poppler::image img = pr.render_page(p, 200, 200);

  // This will save the image from memory to a file
  img.save(argv[2], "png");

  // This will free up the memory
  delete d;

  return 0;
}
  1. Compile it using the following command:
g++ `pkg-config --cflags --libs poppler-cpp` x.cpp
  1. When running the executable, give two arguments:
./a.out ~/Downloads/pdf/resume.pdf test2.png

While working on this I will be updating about this issue in the comments. If you want you can start a PR since it might take time for me to put up a proper version. I will try my best though.

@Compro-Prasad
Copy link
Contributor Author

From my current research I found out that poppler-cpp is good for processing PDFs and showing images. But if we want to render it to a GTK window we will need poppler-glib. Good thing is that I found out the specific function in Evince that renders a page to the screen. It is by using a cairo surface.
https://github.com/GNOME/evince/blob/613826e6cafa93301942388d79a4c6e405474511/backend/pdf/ev-poppler.cc#L396
To show cairo surface in a GTK window there is a stackoverflow answer: https://stackoverflow.com/questions/21102622/how-to-create-a-cairo-t-on-a-gtk-2-window#21109557

@Compro-Prasad
Copy link
Contributor Author

Compro-Prasad commented Oct 6, 2019

A simple version to show the first page from a PDF on a Gtk window:

#include <poppler.h>
#include <gtk/gtk.h>
#include <glib/gprintf.h>

gboolean on_draw_event(GtkWidget *widget, cairo_t *cr) {
  GError *e = NULL;
  const char *filename = "file:///home/compro/AnnexureE.pdf";
  PopplerDocument *doc = poppler_document_new_from_file (filename, NULL, &e);
  if (doc == NULL) {
    g_fprintf(stderr, "Some error occurred:\n%s", e->message);
    exit(1);
  }
  PopplerPage *doc_page_1 = poppler_document_get_page (doc, 0);
  poppler_page_render (doc_page_1, cr);
  return FALSE;
}

int main(int argc, char *argv[]) {

  GtkWidget *window;
  GtkWidget *darea;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  darea = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(window), darea);

  g_signal_connect(darea, "draw",
                   G_CALLBACK(on_draw_event), NULL);
  g_signal_connect(window, "destroy",
                   G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

  gtk_window_set_title(GTK_WINDOW(window), "Draw 1st page from PDF");
  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

To compile and run:

gcc `pkg-config --cflags --libs cairo poppler-glib gtk+-3.0` test.c -o test && ./test

This is a modified version of the code taken from http://zetcode.com/gui/gtk2/gtkevents/ .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant