You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.5 KiB
157 lines
4.5 KiB
/* |
|
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) // clazy:exclude=function-args-by-value TODO remove the & when we do a BIC change elsewhere |
|
{ |
|
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(QWidget *widgetOnScreen) |
|
{ |
|
const QScreen *screen = widgetOnScreen && widgetOnScreen->window() && widgetOnScreen->window()->windowHandle() ? widgetOnScreen->window()->windowHandle()->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.05) { |
|
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; |
|
qint64 written = 0; |
|
while ((read = from->read(buffer.data(), buffer.size())) > 0) { |
|
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; */
|
|
|