source: terepaima/terepaima-0.4.16/sources/rendertask.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.5 KB
Line 
1/*
2
3Copyright 2013-2015 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 "rendertask.h"
23
24#include <qmath.h>
25#include <QPainter>
26#include <QThreadPool>
27
28#include "model.h"
29#include "settings.h"
30
31namespace
32{
33
34using namespace qpdfview;
35
36qreal scaledResolutionX(const RenderParam& renderParam)
37{
38    return renderParam.devicePixelRatio()
39            * renderParam.resolutionX()
40            * renderParam.scaleFactor();
41}
42
43qreal scaledResolutionY(const RenderParam& renderParam)
44{
45    return renderParam.devicePixelRatio()
46            * renderParam.resolutionY()
47            * renderParam.scaleFactor();
48}
49
50const QRgb alphaMask = 0xff << 24;
51
52bool columnHasPaperColor(int x, QRgb paperColor, const QImage& image)
53{
54    const int height = image.height();
55
56    for(int y = 0; y < height; ++y)
57    {
58        const QRgb color = image.pixel(x, y);
59
60        if(qAlpha(color) != 0 && paperColor != (color | alphaMask))
61        {
62            return false;
63        }
64    }
65
66    return true;
67}
68
69bool rowHasPaperColor(int y, QRgb paperColor, const QImage& image)
70{
71    const int width = image.width();
72
73    for(int x = 0; x < width; ++x)
74    {
75        const QRgb color = image.pixel(x, y);
76
77        if(qAlpha(color) != 0 && paperColor != (color | alphaMask))
78        {
79            return false;
80        }
81    }
82
83    return true;
84}
85
86QRectF trimMargins(QRgb paperColor, const QImage& image)
87{
88    if(image.isNull())
89    {
90        return QRectF(0.0, 0.0, 1.0, 1.0);
91    }
92
93    const int width = image.width();
94    const int height = image.height();
95
96    int left;
97    for(left = 0; left < width; ++left)
98    {
99        if(!columnHasPaperColor(left, paperColor, image))
100        {
101            break;
102        }
103    }
104    left = qMin(left, width / 3);
105
106    int right;
107    for(right = width - 1; right >= left; --right)
108    {
109        if(!columnHasPaperColor(right, paperColor, image))
110        {
111            break;
112        }
113    }
114    right = qMax(right, 2 * width / 3);
115
116    int top;
117    for(top = 0; top < height; ++top)
118    {
119        if(!rowHasPaperColor(top, paperColor, image))
120        {
121            break;
122        }
123    }
124    top = qMin(top, height / 3);
125
126    int bottom;
127    for(bottom = height - 1; bottom >= top; --bottom)
128    {
129        if(!rowHasPaperColor(bottom, paperColor, image))
130        {
131            break;
132        }
133    }
134    bottom = qMax(bottom, 2 * height / 3);
135
136    left = qMax(left - width / 100, 0);
137    top = qMax(top - height / 100, 0);
138
139    right = qMin(right + width / 100, width);
140    bottom = qMin(bottom + height / 100, height);
141
142    return QRectF(static_cast< qreal >(left) / width,
143                  static_cast< qreal >(top) / height,
144                  static_cast< qreal >(right - left) / width,
145                  static_cast< qreal >(bottom - top) / height);
146}
147
148void convertToGrayscale(QImage& image)
149{
150    QRgb* const begin = reinterpret_cast< QRgb* >(image.bits());
151    QRgb* const end = reinterpret_cast< QRgb* >(image.bits() + image.byteCount());
152
153    for(QRgb* pointer = begin; pointer != end; ++pointer)
154    {
155        const int gray = qGray(*pointer);
156        const int alpha = qAlpha(*pointer);
157
158        *pointer = qRgba(gray, gray, gray, alpha);
159    }
160}
161
162void composeWithColor(QPainter::CompositionMode mode, const QColor& color, QImage& image)
163{
164    QPainter painter(&image);
165
166    painter.setCompositionMode(mode);
167    painter.fillRect(image.rect(), color);
168}
169
170} // anonymous
171
172namespace qpdfview
173{
174
175Settings* RenderTask::s_settings = 0;
176
177RenderParam RenderTask::s_defaultRenderParam;
178
179RenderTask::RenderTask(Model::Page* page, QObject* parent) : QObject(parent), QRunnable(),
180    m_isRunning(false),
181    m_wasCanceled(NotCanceled),
182    m_page(page),
183    m_renderParam(s_defaultRenderParam),
184    m_rect(),
185    m_prefetch(false)
186{
187    if(s_settings == 0)
188    {
189        s_settings = Settings::instance();
190    }
191
192    setAutoDelete(false);
193}
194
195void RenderTask::wait()
196{
197    QMutexLocker mutexLocker(&m_mutex);
198
199    while(m_isRunning)
200    {
201        m_waitCondition.wait(&m_mutex);
202    }
203}
204
205bool RenderTask::isRunning() const
206{
207    QMutexLocker mutexLocker(&m_mutex);
208
209    return m_isRunning;
210}
211
212void RenderTask::run()
213{
214#define CANCELLATION_POINT if(testCancellation()) { finish(); return; }
215
216    CANCELLATION_POINT
217
218    QImage image;
219    QRectF cropRect;
220
221    image = m_page->render(scaledResolutionX(m_renderParam), scaledResolutionY(m_renderParam),
222                           m_renderParam.rotation(), m_rect);
223
224#if QT_VERSION >= QT_VERSION_CHECK(5,1,0)
225
226    image.setDevicePixelRatio(m_renderParam.devicePixelRatio());
227
228#endif // QT_VERSION
229
230    if(m_renderParam.darkenWithPaperColor())
231    {
232        CANCELLATION_POINT
233
234        composeWithColor(QPainter::CompositionMode_Darken, s_settings->pageItem().paperColor(), image);
235    }
236    else if(m_renderParam.lightenWithPaperColor())
237    {
238        CANCELLATION_POINT
239
240        composeWithColor(QPainter::CompositionMode_Lighten, s_settings->pageItem().paperColor(), image);
241    }
242
243    if(m_renderParam.trimMargins())
244    {
245        CANCELLATION_POINT
246
247        cropRect = trimMargins(s_settings->pageItem().paperColor().rgb() | alphaMask, image);
248    }
249
250    if(m_renderParam.convertToGrayscale())
251    {
252        CANCELLATION_POINT
253
254        convertToGrayscale(image);
255    }
256
257    if(m_renderParam.invertColors())
258    {
259        CANCELLATION_POINT
260
261        image.invertPixels();
262    }
263
264    CANCELLATION_POINT
265
266    emit imageReady(m_renderParam,
267                    m_rect, m_prefetch,
268                    image, cropRect);
269
270    finish();
271
272#undef CANCELLATION_POINT
273}
274
275void RenderTask::start(const RenderParam& renderParam,
276                       const QRect& rect, bool prefetch)
277{
278    m_renderParam = renderParam;
279
280    m_rect = rect;
281    m_prefetch = prefetch;
282
283    m_mutex.lock();
284    m_isRunning = true;
285    m_mutex.unlock();
286
287    resetCancellation();
288
289    QThreadPool::globalInstance()->start(this, prefetch ? 0 : 1);
290}
291
292void RenderTask::finish()
293{
294    m_renderParam = s_defaultRenderParam;
295
296    emit finished();
297
298    m_mutex.lock();
299    m_isRunning = false;
300    m_mutex.unlock();
301
302    m_waitCondition.wakeAll();
303}
304
305} // qpdfview
Note: See TracBrowser for help on using the repository browser.