1 /*
2 Copyright © 2008-13 Qtrac Ltd. All rights reserved.
3 This program or module is free software: you can redistribute it
4 and/or modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation, either version 2 of
6 the License, or (at your option) any later version. This program is
7 distributed in the hope that it will be useful, but WITHOUT ANY
8 WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10 for more details.
11 */
12
13 #include "generic.hpp"
14 #include <QMimeData>
15 #include <QRectF>
16 #include <QPainter>
17 #include <QPen>
18 #include <QPixmapCache>
19 #include <QUrl>
20
21 const QSize SwatchSize(24, 24);
22
23
scaleRect(int dpi,QRectF * rect)24 void scaleRect(int dpi, QRectF *rect)
25 {
26 if (dpi == POINTS_PER_INCH)
27 return;
28 qreal x1;
29 qreal y1;
30 qreal x2;
31 qreal y2;
32 rect->getCoords(&x1, &y1, &x2, &y2);
33 qreal factor = dpi / static_cast<qreal>(POINTS_PER_INCH);
34 x1 *= factor;
35 y1 *= factor;
36 x2 *= factor;
37 y2 *= factor;
38 rect->setCoords(x1, y1, x2, y2);
39 }
40
41
pointValueForPixelOffset(const double dpi,int px)42 int pointValueForPixelOffset(const double dpi, int px)
43 {
44 const double inches = px / dpi;
45 return qRound(inches * POINTS_PER_INCH);
46 }
47
48
pixelOffsetForPointValue(const double dpi,int pt)49 int pixelOffsetForPointValue(const double dpi, int pt)
50 {
51 const double inches = pt / static_cast<double>(POINTS_PER_INCH);
52 return qRound(inches * dpi);
53 }
54
55
rectForMargins(const int width,const int height,const int top,const int bottom,const int left,const int right)56 QRectF rectForMargins(const int width, const int height, const int top,
57 const int bottom, const int left, const int right)
58 {
59 return QRectF(QPointF(left, top),
60 QPointF(width - right, height - bottom));
61 }
62
63
unorderedRange(int end,int start)64 Ranges unorderedRange(int end, int start)
65 {
66 Q_ASSERT(end >= start);
67 Ranges ranges;
68 while (start < end)
69 ranges.insert(start++);
70 return ranges;
71 }
72
73
colorSwatch(const QColor & color)74 QPixmap colorSwatch(const QColor &color)
75 {
76 QString key = QString("COLORSWATCH:%1").arg(color.name());
77 QPixmap pixmap(SwatchSize);
78 #if QT_VERSION >= 0x040600
79 if (!QPixmapCache::find(key, &pixmap)) {
80 #else
81 if (!QPixmapCache::find(key, pixmap)) {
82 #endif
83 pixmap.fill(Qt::transparent);
84 {
85 QPainter painter(&pixmap);
86 painter.setRenderHints(QPainter::Antialiasing);
87 painter.setPen(Qt::NoPen);
88 painter.setBrush(color);
89 painter.drawEllipse(0, 0, SwatchSize.width(),
90 SwatchSize.height());
91 }
92 QPixmapCache::insert(key, pixmap);
93 }
94 return pixmap;
95 }
96
97
98 QPixmap brushSwatch(const Qt::BrushStyle style, const QColor &color)
99 {
100 QString key = QString("BRUSHSTYLESWATCH:%1:%2:%3")
101 .arg(static_cast<int>(style)).arg(color.name()).arg(color.alpha());
102 QPixmap pixmap(SwatchSize);
103 #if QT_VERSION >= 0x040600
104 if (!QPixmapCache::find(key, &pixmap)) {
105 #else
106 if (!QPixmapCache::find(key, pixmap)) {
107 #endif
108 pixmap.fill(Qt::transparent);
109 {
110 QPainter painter(&pixmap);
111 painter.setRenderHint(QPainter::Antialiasing);
112 painter.setPen(Qt::NoPen);
113 painter.setBrush(QBrush(color, style));
114 painter.drawRect(0, 0, SwatchSize.width(),
115 SwatchSize.height());
116 }
117 QPixmapCache::insert(key, pixmap);
118 }
119 return pixmap;
120 }
121
122
123 QPixmap penStyleSwatch(const Qt::PenStyle style, const QColor &color)
124 {
125 QString key = QString("PENSTYLESWATCH:%1:%2")
126 .arg(static_cast<int>(style)).arg(color.name());
127 QPixmap pixmap(SwatchSize);
128 #if QT_VERSION >= 0x040600
129 if (!QPixmapCache::find(key, &pixmap)) {
130 #else
131 if (!QPixmapCache::find(key, pixmap)) {
132 #endif
133 pixmap.fill(Qt::transparent);
134 {
135 QPainter painter(&pixmap);
136 QPen pen(style);
137 pen.setColor(color);
138 pen.setWidth(2);
139 painter.setPen(pen);
140 const int Y = SwatchSize.height() / 2;
141 painter.drawLine(0, Y, SwatchSize.width(), Y);
142 }
143 QPixmapCache::insert(key, pixmap);
144 }
145 return pixmap;
146 }
147
148
149 const TextBoxList getTextBoxes(PdfPage page, const QRectF &rect)
150 {
151 TextBoxList boxes;
152 foreach (Poppler::TextBox *box, page->textList()) {
153 PdfTextBox box_ptr(box);
154 if (rect.isEmpty() || rect.contains(box_ptr->boundingBox()))
155 boxes.append(box_ptr);
156 }
157 return boxes;
158 }
159
160
161 const QString strippedFilename(const QString &filename)
162 {
163 const QString FilePrefix("file://");
164 QString filename_ = filename;
165 if (filename_.startsWith(FilePrefix))
166 filename_ = filename_.mid(FilePrefix.length());
167 #ifdef Q_WS_WIN
168 if (filename_.startsWith("/"))
169 filename_ = filename_.mid(1);
170 #endif
171 return filename_.trimmed();
172 }
173
174
175 const QStringList droppedFilenames(const QMimeData *mimeData)
176 {
177 QStringList filenames;
178 QString text = mimeData->text();
179 if (!text.isEmpty()) {
180 filenames = text.split("\n");
181 for (int i = 0; i < filenames.count(); ++i)
182 filenames[i] = strippedFilename(filenames.at(i));
183 }
184 else {
185 foreach (const QUrl &url, mimeData->urls())
186 filenames << strippedFilename(url.toString());
187 }
188 return filenames;
189 }
190
191 // Returns a copy of pageRect reduced if necessary to have the same
192 // aspect ratio as pixmapSize.
193 const QRect resizeRect(const QRect &pageRect, const QSize &pixmapSize)
194 {
195 double ratio = pixmapSize.width() /
196 static_cast<double>(pixmapSize.height());
197 double height = pageRect.height();
198 double width = ratio * height;
199 if (width > pageRect.width()) {
200 width = pageRect.width();
201 height = width / ratio;
202 }
203 QRect rect(pageRect);
204 rect.setWidth(width);
205 rect.setHeight(height);
206 return rect;
207 }
208