source: terepaima/terepaima-0.4.16/sources/tileitem.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: 6.0 KB
Line 
1/*
2
3Copyright 2012-2014 Adam Reichold
4
5This file is part of qpdfview.
6
7qpdfview is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12qpdfview is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22#include "tileitem.h"
23
24#include <QPainter>
25
26#include "settings.h"
27#include "rendertask.h"
28#include "pageitem.h"
29
30namespace qpdfview
31{
32
33Settings* TileItem::s_settings = 0;
34
35QCache< TileItem::CacheKey, TileItem::CacheObject > TileItem::s_cache;
36
37TileItem::TileItem(PageItem* page) : QObject(page),
38    m_page(page),
39    m_rect(),
40    m_cropRect(),
41    m_pixmapError(false),
42    m_pixmap(),
43    m_obsoletePixmap(),
44    m_deleteAfterRender(false),
45    m_renderTask(0)
46{
47    if(s_settings == 0)
48    {
49        s_settings = Settings::instance();
50    }
51
52    s_cache.setMaxCost(s_settings->pageItem().cacheSize());
53
54    m_renderTask = new RenderTask(m_page->m_page, this);
55
56    connect(m_renderTask, SIGNAL(finished()), SLOT(on_renderTask_finished()));
57    connect(m_renderTask, SIGNAL(imageReady(RenderParam,QRect,bool,QImage,QRectF)), SLOT(on_renderTask_imageReady(RenderParam,QRect,bool,QImage,QRectF)));
58}
59
60TileItem::~TileItem()
61{
62    m_renderTask->cancel(true);
63    m_renderTask->wait();
64}
65
66void TileItem::setCropRect(const QRectF& cropRect)
67{
68    if(!m_page->m_renderParam.trimMargins())
69    {
70        return;
71    }
72
73    if(m_cropRect.isNull() && !cropRect.isNull())
74    {
75        m_cropRect = cropRect;
76
77        m_page->updateCropRect();
78    }
79}
80
81void TileItem::dropCachedPixmaps(PageItem* page)
82{
83    foreach(CacheKey key, s_cache.keys())
84    {
85        if(key.first == page)
86        {
87            s_cache.remove(key);
88        }
89    }
90}
91
92bool TileItem::paint(QPainter* painter, const QPointF& topLeft)
93{
94    const QPixmap& pixmap = takePixmap();
95
96    if(!pixmap.isNull())
97    {
98        // pixmap
99
100        painter->drawPixmap(m_rect.topLeft() + topLeft, pixmap);
101
102        return true;
103    }
104    else if(!m_obsoletePixmap.isNull())
105    {
106        // obsolete pixmap
107
108        painter->drawPixmap(QRectF(m_rect).translated(topLeft), m_obsoletePixmap, QRectF());
109
110        return false;
111    }
112    else
113    {
114        const qreal iconExtent = qMin(0.1 * m_rect.width(), 0.1 * m_rect.height());
115        const QRect iconRect(topLeft.x() + m_rect.left() + 0.01 * m_rect.width(),
116                             topLeft.y() + m_rect.top() + 0.01 * m_rect.height(),
117                             iconExtent, iconExtent);
118
119        if(!m_pixmapError)
120        {
121            // progress icon
122
123            s_settings->pageItem().progressIcon().paint(painter, iconRect);
124
125            return false;
126        }
127        else
128        {
129            // error icon
130
131            s_settings->pageItem().errorIcon().paint(painter, iconRect);
132
133            return true;
134        }
135    }
136}
137
138void TileItem::refresh(bool keepObsoletePixmaps)
139{
140    if(keepObsoletePixmaps && s_settings->pageItem().keepObsoletePixmaps())
141    {
142        if(const CacheObject* object = s_cache.object(cacheKey()))
143        {
144            m_obsoletePixmap = object->first;
145        }
146    }
147    else
148    {
149        m_obsoletePixmap = QPixmap();
150    }
151
152    if(!keepObsoletePixmaps)
153    {
154        m_cropRect = QRectF();
155    }
156
157    m_renderTask->cancel(true);
158
159    m_pixmapError = false;
160    m_pixmap = QPixmap();
161}
162
163int TileItem::startRender(bool prefetch)
164{
165    if(m_pixmapError || m_renderTask->isRunning() || (prefetch && s_cache.contains(cacheKey())))
166    {
167        return 0;
168    }
169
170    m_renderTask->start(m_page->m_renderParam, m_rect, prefetch);
171
172    return 1;
173}
174
175void TileItem::cancelRender()
176{
177    m_renderTask->cancel();
178
179    m_pixmap = QPixmap();
180    m_obsoletePixmap = QPixmap();
181}
182
183void TileItem::deleteAfterRender()
184{
185    if(!m_renderTask->isRunning())
186    {
187        deleteLater();
188    }
189    else
190    {
191        m_renderTask->cancel(true);
192
193        m_deleteAfterRender = true;
194    }
195}
196
197void TileItem::on_renderTask_finished()
198{
199    if(m_deleteAfterRender)
200    {
201        deleteLater();
202    }
203    else if(!m_page->useTiling() || m_page->m_exposedTileItems.contains(this))
204    {
205        m_page->update();
206    }
207}
208
209void TileItem::on_renderTask_imageReady(const RenderParam& renderParam,
210                                        const QRect& rect, bool prefetch,
211                                        const QImage& image, const QRectF& cropRect)
212{
213    if(m_page->m_renderParam != renderParam || m_rect != rect)
214    {
215        return;
216    }
217
218    m_obsoletePixmap = QPixmap();
219
220    if(image.isNull())
221    {
222        m_pixmapError = true;
223
224        return;
225    }
226
227    if(prefetch && !m_renderTask->wasCanceledForcibly())
228    {
229        const int cost = qMax(1, image.width() * image.height() * image.depth() / 8);
230        s_cache.insert(cacheKey(), new CacheObject(QPixmap::fromImage(image), cropRect), cost);
231
232        setCropRect(cropRect);
233    }
234    else if(!m_renderTask->wasCanceled())
235    {
236        m_pixmap = QPixmap::fromImage(image);
237
238        setCropRect(cropRect);
239    }
240}
241
242inline TileItem::CacheKey TileItem::cacheKey() const
243{
244    QByteArray key;
245    QDataStream stream(&key, QIODevice::WriteOnly);
246
247    stream << m_page->m_renderParam << m_rect;
248
249    return qMakePair(m_page, key);
250}
251
252QPixmap TileItem::takePixmap()
253{
254    const CacheKey key = cacheKey();
255
256    if(const CacheObject* object = s_cache.object(key))
257    {
258        m_obsoletePixmap = QPixmap();
259
260        setCropRect(object->second);
261        return object->first;
262    }
263
264    QPixmap pixmap;
265
266    if(!m_pixmap.isNull())
267    {
268        const int cost = qMax(1, m_pixmap.width() * m_pixmap.height() * m_pixmap.depth() / 8);
269        s_cache.insert(key, new CacheObject(m_pixmap, m_cropRect), cost);
270
271        pixmap = m_pixmap;
272    }
273    else
274    {
275        startRender();
276    }
277
278    return pixmap;
279}
280
281} // qpdfview
Note: See TracBrowser for help on using the repository browser.