如何在gtkmm绘图区域中绘制poppler文档

如何在gtkmm绘图区域中绘制poppler文档,gtk,cairo,gtkmm,poppler,Gtk,Cairo,Gtkmm,Poppler,我正在尝试用poppler gtk和gtkmm DrawingArea绘制PDF,但它不起作用,我不确定出了什么问题。绘图区域不会绘制文档。我知道绘图区域在Cairo::Context::stroke()中工作。我是否需要使用更gtk的方法并将小部件包装到gtkmm? 代码: 增加 之后 您在哪一点绘制/呈现poppler页面?假设我正确地看到了这一点,您只需要使用页面来获取其大小。因此,cairo图像表面保持其默认内容(完全透明)。@UliSchlachter您是对的。我用呈现poppler页

我正在尝试用poppler gtk和gtkmm DrawingArea绘制PDF,但它不起作用,我不确定出了什么问题。绘图区域不会绘制文档。我知道绘图区域在Cairo::Context::stroke()中工作。我是否需要使用更gtk的方法并将小部件包装到gtkmm? 代码:

增加

之后


您在哪一点绘制/呈现poppler页面?假设我正确地看到了这一点,您只需要使用页面来获取其大小。因此,cairo图像表面保持其默认内容(完全透明)。@UliSchlachter您是对的。我用呈现poppler页面的线条更新了帖子。
// PdfViewer.h    
#include <gtkmm.h>
#include <poppler.h>
#include "DrawingAreaFoo.h"

class PdfViewer: public Gtk::Box
{
public:
   PdfViewer();
   virtual ~PdfViewer();
private:
   PopplerDocument *m_document;
   PopplerPage *m_page;
   DrawingAreaFoo m_drawingArea;

 };


// PdfViewer.cpp
#include "PdfViewer.h"

 PdfViewer::PdfViewer():
 {
    const char * uri = "file:////path/to/file/pdf.pdf";
    m_document = poppler_document_new_from_file (uri, NULL, NULL);
    auto total_pages = poppler_document_get_n_pages (m_document);

    pack_start(m_drawingArea, TRUE, TRUE);

    int w, h;
    double width, height;

    m_page = poppler_document_get_page (m_document, 0);
    poppler_page_get_size (m_page, &width, &height);
    w = (int) ceil(width);
    h = (int) ceil(height);
    cairo_surface_t * surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);

    m_drawingArea.drawSurface(surface);
}

PdfViewer::~PdfViewer(){}

// DrawinAreFoo.h
#include <gtkmm.h>

 class DrawingAreaFoo : public Gtk::DrawingArea
 {
 public:
    DrawingAreaFoo();
    virtual ~DrawingAreaFoo();
    void drawSurface (cairo_surface_t * surface);
 protected:
    bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;
    Cairo::RefPtr<Cairo::Surface> m_refSurface;
 };

 // DrawinAreFoo.cpp
 #include "DrawingAreaFoo.h"

 DrawingAreaFoo::DrawingAreaFoo() {}

 DrawingAreaFoo::~DrawingAreaFoo() {}

 bool DrawingAreaFoo::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
 {
    if (m_refSurface)
    {
       cr->set_source(m_refSurface, 0, 0);
       cr->paint();
    }
    return true;
 }

 void DrawingAreaFoo::drawSurface (cairo_surface_t * surface)
 {
    m_refSurface = Cairo::RefPtr<Cairo::Surface>{new Cairo::Surface(surface)} ;
    Glib::RefPtr<Gdk::Window> win = get_window();
    if (win)
    {
       Gdk::Rectangle r(0, 0, get_allocation().get_width(), get_allocation().get_height());
       win->invalidate_rect(r, false);
     }
  }
cairo_t *cr = cairo_create (surface);
poppler_page_render (m_page, cr);
cairo_destroy (cr);
cairo_t *cr = cairo_create (surface);
poppler_page_render (m_page, cr);
cairo_destroy (cr);
    cairo_surface_t * surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);