【发布时间】:2019-10-19 21:48:37
【问题描述】:
我正在尝试使用 poppler gtk 和 gtkmm DrawingArea 绘制 PDF,但它无法正常工作,我不确定出了什么问题。绘图区域不绘制文档。我知道绘图区域可以与 Cairo::Context::stroke() 一起使用。我是否需要使用更多的 gtk 方法并将小部件包装到 gtkmm? 代码:
// 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_image_surface_create 之后的以下代码使代码工作。
cairo_t *cr = cairo_create (surface);
poppler_page_render (m_page, cr);
cairo_destroy (cr);
【问题讨论】:
-
你在什么时候绘制/渲染 poppler 页面?假设我没看错,你只是使用页面来获取它的大小。因此,cairo 图像表面保持其默认内容(完全透明)。
-
@UliSchlachter 你是对的。我用呈现 poppler 页面的行更新了帖子。