source: terepaima/terepaima-0.4.16/sources/fitzmodel.cpp

desarrollostretch
Last change on this file was 1f4adec, checked in by aosorio <aosorio@…>, 8 years ago

Agregado proyecto base, esto luego del dh_make -f

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2
3Copyright 2015 Martin Banky
4Copyright 2014-2015 Adam Reichold
5
6This file is part of qpdfview.
7
8qpdfview is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 2 of the License, or
11(at your option) any later version.
12
13qpdfview is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
20
21*/
22
23#include "fitzmodel.h"
24
25#include <QFile>
26#include <qmath.h>
27
28extern "C"
29{
30
31#include <mupdf/fitz/display-list.h>
32#include <mupdf/fitz/document.h>
33
34typedef struct pdf_document_s pdf_document;
35
36pdf_document* pdf_specifics(fz_context*, fz_document*);
37
38}
39
40namespace
41{
42
43using namespace qpdfview;
44using namespace qpdfview::Model;
45
46void loadOutline(fz_outline* outline, QStandardItem* parent)
47{
48    QStandardItem* item = new QStandardItem(QString::fromUtf8(outline->title));
49    item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
50
51    if(outline->dest.kind != FZ_LINK_NONE)
52    {
53        const int page = outline->dest.ld.gotor.page + 1;
54
55        item->setData(page, Document::PageRole);
56
57        QStandardItem* pageItem = item->clone();
58        pageItem->setText(QString::number(page));
59        pageItem->setTextAlignment(Qt::AlignRight);
60
61        parent->appendRow(QList< QStandardItem* >() << item << pageItem);
62    }
63    else
64    {
65        parent->appendRow(item);
66    }
67
68    if(outline->next != 0)
69    {
70        loadOutline(outline->next, parent);
71    }
72
73    if(outline->down != 0)
74    {
75        loadOutline(outline->down, item);
76    }
77}
78
79} // anonymous
80
81namespace qpdfview
82{
83
84namespace Model
85{
86
87FitzPage::FitzPage(const FitzDocument* parent, fz_page* page) :
88    m_parent(parent),
89    m_page(page)
90{
91}
92
93FitzPage::~FitzPage()
94{
95    fz_drop_page(m_parent->m_context, m_page);
96}
97
98QSizeF FitzPage::size() const
99{
100    QMutexLocker mutexLocker(&m_parent->m_mutex);
101
102    fz_rect rect;
103    fz_bound_page(m_parent->m_context, m_page, &rect);
104
105    return QSizeF(rect.x1 - rect.x0, rect.y1 - rect.y0);
106}
107
108QImage FitzPage::render(qreal horizontalResolution, qreal verticalResolution, Rotation rotation, const QRect& boundingRect) const
109{
110    QMutexLocker mutexLocker(&m_parent->m_mutex);
111
112    fz_matrix matrix;
113
114    fz_scale(&matrix, horizontalResolution / 72.0f, verticalResolution / 72.0f);
115
116    switch(rotation)
117    {
118    default:
119    case RotateBy0:
120        fz_pre_rotate(&matrix, 0.0);
121        break;
122    case RotateBy90:
123        fz_pre_rotate(&matrix, 90.0);
124        break;
125    case RotateBy180:
126        fz_pre_rotate(&matrix, 180.0);
127        break;
128    case RotateBy270:
129        fz_pre_rotate(&matrix, 270.0);
130        break;
131    }
132
133    fz_rect rect;
134    fz_bound_page(m_parent->m_context, m_page, &rect);
135    fz_transform_rect(&rect, &matrix);
136
137    fz_irect irect;
138    fz_round_rect(&irect, &rect);
139
140
141    fz_context* context = fz_clone_context(m_parent->m_context);
142    fz_display_list* display_list = fz_new_display_list(context);
143
144    fz_device* device = fz_new_list_device(context, display_list);
145    fz_run_page(m_parent->m_context, m_page, device, &matrix, 0);
146    fz_drop_device(m_parent->m_context, device);
147
148
149    mutexLocker.unlock();
150
151
152    fz_matrix tileMatrix;
153    fz_translate(&tileMatrix, -rect.x0, -rect.y0);
154
155    fz_rect tileRect = fz_infinite_rect;
156
157    int tileWidth = irect.x1 - irect.x0;
158    int tileHeight = irect.y1 - irect.y0;
159
160    if(!boundingRect.isNull())
161    {
162        fz_pre_translate(&tileMatrix, -boundingRect.x(), -boundingRect.y());
163
164        tileRect.x0 = tileRect.y0 = 0.0;
165
166        tileWidth = tileRect.x1 = boundingRect.width();
167        tileHeight = tileRect.y1 = boundingRect.height();
168    }
169
170
171    QImage image(tileWidth, tileHeight, QImage::Format_RGB32);
172    image.fill(m_parent->m_paperColor);
173
174    fz_pixmap* pixmap = fz_new_pixmap_with_data(context, fz_device_bgr(context), image.width(), image.height(), image.bits());
175
176    device = fz_new_draw_device(context, pixmap);
177    fz_run_display_list(context, display_list, device, &tileMatrix, &tileRect, 0);
178    fz_drop_device(context, device);
179
180    fz_drop_pixmap(context, pixmap);
181    fz_drop_display_list(context, display_list);
182    fz_drop_context(context);
183
184    return image;
185}
186
187QList< Link* > FitzPage::links() const
188{
189    QMutexLocker mutexLocker(&m_parent->m_mutex);
190
191    QList< Link* > links;
192
193    fz_rect rect;
194    fz_bound_page(m_parent->m_context, m_page, &rect);
195
196    const qreal width = qAbs(rect.x1 - rect.x0);
197    const qreal height = qAbs(rect.y1 - rect.y0);
198
199    fz_link* first_link = fz_load_links(m_parent->m_context, m_page);
200
201    for(fz_link* link = first_link; link != 0; link = link->next)
202    {
203        const QRectF boundary = QRectF(link->rect.x0 / width, link->rect.y0 / height, (link->rect.x1 - link->rect.x0) / width, (link->rect.y1 - link->rect.y0) / height).normalized();
204
205        if(link->dest.kind == FZ_LINK_GOTO)
206        {
207            const int page = link->dest.ld.gotor.page + 1;
208
209            links.append(new Link(boundary, page));
210        }
211        else if(link->dest.kind == FZ_LINK_GOTOR)
212        {
213            const int page = link->dest.ld.gotor.page + 1;
214
215            if(link->dest.ld.gotor.file_spec != 0)
216            {
217                links.append(new Link(boundary, QString::fromUtf8(link->dest.ld.gotor.file_spec), page));
218            }
219            else
220            {
221                links.append(new Link(boundary, page));
222            }
223        }
224        else if(link->dest.kind == FZ_LINK_URI)
225        {
226            const QString url = QString::fromUtf8(link->dest.ld.uri.uri);
227
228            links.append(new Link(boundary, url));
229        }
230        else if(link->dest.kind == FZ_LINK_LAUNCH)
231        {
232            const QString url = QString::fromUtf8(link->dest.ld.launch.file_spec);
233
234            links.append(new Link(boundary, url));
235        }
236    }
237
238    fz_drop_link(m_parent->m_context, first_link);
239
240    return links;
241}
242
243FitzDocument::FitzDocument(fz_context* context, fz_document* document) :
244    m_mutex(),
245    m_context(context),
246    m_document(document),
247    m_paperColor(Qt::white)
248{
249}
250
251FitzDocument::~FitzDocument()
252{
253    fz_drop_document(m_context, m_document);
254    fz_drop_context(m_context);
255}
256
257int FitzDocument::numberOfPages() const
258{
259    QMutexLocker mutexLocker(&m_mutex);
260
261    return fz_count_pages(m_context, m_document);
262}
263
264Page* FitzDocument::page(int index) const
265{
266    QMutexLocker mutexLocker(&m_mutex);
267
268    fz_page* page = fz_load_page(m_context, m_document, index);
269
270    return page != 0 ? new FitzPage(this, page) : 0;
271}
272
273bool FitzDocument::canBePrintedUsingCUPS() const
274{
275    QMutexLocker mutexLocker(&m_mutex);
276
277    return pdf_specifics(m_context, m_document) != 0;
278}
279
280void FitzDocument::setPaperColor(const QColor& paperColor)
281{
282    m_paperColor = paperColor;
283}
284
285void FitzDocument::loadOutline(QStandardItemModel* outlineModel) const
286{
287    Document::loadOutline(outlineModel);
288
289    QMutexLocker mutexLocker(&m_mutex);
290
291    fz_outline* outline = fz_load_outline(m_context, m_document);
292
293    if(outline != 0)
294    {
295        ::loadOutline(outline, outlineModel->invisibleRootItem());
296
297        fz_drop_outline(m_context, outline);
298    }
299}
300
301} // Model
302
303FitzPlugin::FitzPlugin(QObject* parent) : QObject(parent)
304{
305    setObjectName("FitzPlugin");
306
307    m_locks_context.user = this;
308    m_locks_context.lock = FitzPlugin::lock;
309    m_locks_context.unlock = FitzPlugin::unlock;
310
311    m_context = fz_new_context(0, &m_locks_context, FZ_STORE_DEFAULT);
312
313    fz_register_document_handlers(m_context);
314}
315
316FitzPlugin::~FitzPlugin()
317{
318    fz_drop_context(m_context);
319}
320
321Model::Document* FitzPlugin::loadDocument(const QString& filePath) const
322{
323    fz_context* context = fz_clone_context(m_context);
324
325    if(context == 0)
326    {
327        return 0;
328    }
329
330#ifdef _MSC_VER
331
332    fz_document* document = fz_open_document(context, filePath.toUtf8());
333
334#else
335
336    fz_document* document = fz_open_document(context, QFile::encodeName(filePath));
337
338#endif // _MSC_VER
339
340    if(document == 0)
341    {
342        fz_drop_context(context);
343
344        return 0;
345    }
346
347    return new Model::FitzDocument(context, document);
348}
349
350void FitzPlugin::lock(void* user, int lock)
351{
352    static_cast< FitzPlugin* >(user)->m_mutex[lock].lock();
353}
354
355void FitzPlugin::unlock(void* user, int lock)
356{
357    static_cast< FitzPlugin* >(user)->m_mutex[lock].unlock();
358}
359
360} // qpdfview
361
362#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
363
364Q_EXPORT_PLUGIN2(qpdfview_fitz, qpdfview::FitzPlugin)
365
366#endif // QT_VERSION
Note: See TracBrowser for help on using the repository browser.