1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*
SPDX-FileCopyrightText: 2006 Luigi Toscano <luigi.toscano@tiscali.it>
SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "utils.h"
#include "utils_p.h"
#include "debug_p.h"
#include "settings_core.h"
#include <QApplication>
#include <QIODevice>
#include <QImage>
#include <QRect>
#include <QScreen>
#include <QWidget>
#include <QWindow>
using namespace Okular;
QRect Utils::rotateRect(const QRect source, int width, int height, int orientation)
{
QRect ret;
// adapt the coordinates of the boxes to the rotation
switch (orientation) {
case 1:
ret = QRect(width - source.y() - source.height(), source.x(), source.height(), source.width());
break;
case 2:
ret = QRect(width - source.x() - source.width(), height - source.y() - source.height(), source.width(), source.height());
break;
case 3:
ret = QRect(source.y(), height - source.x() - source.width(), source.height(), source.width());
break;
case 0: // no modifications
default: // other cases
ret = source;
}
return ret;
}
QSizeF Utils::realDpi(const QWindow *windowOnScreen)
{
const QScreen *screen = windowOnScreen ? windowOnScreen->screen() : qGuiApp->primaryScreen();
if (screen) {
const QSizeF res(screen->physicalDotsPerInchX(), screen->physicalDotsPerInchY());
if (res.width() > 0 && res.height() > 0) {
if (qAbs(res.width() - res.height()) / qMin(res.height(), res.width()) < 0.15) {
return res;
} else {
qCDebug(OkularCoreDebug) << "QScreen calculation returned a non square dpi." << res << ". Falling back";
}
}
}
return QSizeF(72, 72);
}
inline static bool isPaperColor(QRgb argb, QRgb paperColor)
{
return (argb & 0xFFFFFF) == (paperColor & 0xFFFFFF); // ignore alpha
}
NormalizedRect Utils::imageBoundingBox(const QImage *image)
{
if (!image) {
return NormalizedRect();
}
const int width = image->width();
const int height = image->height();
const QRgb paperColor = SettingsCore::paperColor().rgb();
int left, top, bottom, right, x, y;
#ifdef BBOX_DEBUG
QTime time;
time.start();
#endif
// Scan pixels for top non-white
for (top = 0; top < height; ++top) {
for (x = 0; x < width; ++x) {
if (!isPaperColor(image->pixel(x, top), paperColor)) {
goto got_top;
}
}
}
return NormalizedRect(0, 0, 0, 0); // the image is blank
got_top:
left = right = x;
// Scan pixels for bottom non-white
for (bottom = height - 1; bottom >= top; --bottom) {
for (x = width - 1; x >= 0; --x) {
if (!isPaperColor(image->pixel(x, bottom), paperColor)) {
goto got_bottom;
}
}
}
Q_ASSERT(0); // image changed?!
got_bottom:
if (x < left) {
left = x;
}
if (x > right) {
right = x;
}
// Scan for leftmost and rightmost (we already found some bounds on these):
for (y = top; y <= bottom && (left > 0 || right < width - 1); ++y) {
for (x = 0; x < left; ++x) {
if (!isPaperColor(image->pixel(x, y), paperColor)) {
left = x;
}
}
for (x = width - 1; x > right + 1; --x) {
if (!isPaperColor(image->pixel(x, y), paperColor)) {
right = x;
}
}
}
NormalizedRect bbox(QRect(left, top, (right - left + 1), (bottom - top + 1)), image->width(), image->height());
#ifdef BBOX_DEBUG
qCDebug(OkularCoreDebug) << "Computed bounding box" << bbox << "in" << time.elapsed() << "ms";
#endif
return bbox;
}
void Okular::copyQIODevice(QIODevice *from, QIODevice *to)
{
QByteArray buffer(65536, '\0');
qint64 read = 0;
while ((read = from->read(buffer.data(), buffer.size())) > 0) {
qint64 written = to->write(buffer.constData(), read);
if (read != written) {
break;
}
}
}
QTransform Okular::buildRotationMatrix(Rotation rotation)
{
QTransform matrix;
matrix.rotate((int)rotation * 90);
switch (rotation) {
case Rotation90:
matrix.translate(0, -1);
break;
case Rotation180:
matrix.translate(-1, -1);
break;
case Rotation270:
matrix.translate(-1, 0);
break;
default:;
}
return matrix;
}
/* kate: replace-tabs on; indent-width 4; */
|