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.
178 lines
5.4 KiB
178 lines
5.4 KiB
/* |
|
SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "generator_plucker.h" |
|
|
|
#include <QAbstractTextDocumentLayout> |
|
#include <QFile> |
|
#include <QPainter> |
|
#include <QPrinter> |
|
#include <QTextDocument> |
|
|
|
#include <KAboutData> |
|
#include <KLocalizedString> |
|
|
|
#include <core/page.h> |
|
|
|
OKULAR_EXPORT_PLUGIN(PluckerGenerator, "libokularGenerator_plucker.json") |
|
|
|
static void calculateBoundingRect(QTextDocument *document, int startPosition, int endPosition, QRectF &rect) |
|
{ |
|
const QTextBlock startBlock = document->findBlock(startPosition); |
|
const QRectF startBoundingRect = document->documentLayout()->blockBoundingRect(startBlock); |
|
|
|
const QTextBlock endBlock = document->findBlock(endPosition); |
|
const QRectF endBoundingRect = document->documentLayout()->blockBoundingRect(endBlock); |
|
|
|
QTextLayout *startLayout = startBlock.layout(); |
|
QTextLayout *endLayout = endBlock.layout(); |
|
|
|
int startPos = startPosition - startBlock.position(); |
|
int endPos = endPosition - endBlock.position(); |
|
const QTextLine startLine = startLayout->lineForTextPosition(startPos); |
|
const QTextLine endLine = endLayout->lineForTextPosition(endPos); |
|
|
|
double x = startBoundingRect.x() + startLine.cursorToX(startPos); |
|
double y = startBoundingRect.y() + startLine.y(); |
|
double r = endBoundingRect.x() + endLine.cursorToX(endPos); |
|
double b = endBoundingRect.y() + endLine.y() + endLine.height(); |
|
|
|
const QSizeF size = document->size(); |
|
rect = QRectF(x / size.width(), y / size.height(), (r - x) / size.width(), (b - y) / size.height()); |
|
} |
|
|
|
PluckerGenerator::PluckerGenerator(QObject *parent, const QVariantList &args) |
|
: Generator(parent, args) |
|
{ |
|
} |
|
|
|
PluckerGenerator::~PluckerGenerator() |
|
{ |
|
} |
|
|
|
bool PluckerGenerator::loadDocument(const QString &fileName, QVector<Okular::Page *> &pagesVector) |
|
{ |
|
QUnpluck unpluck; |
|
|
|
if (!unpluck.open(fileName)) |
|
return false; |
|
|
|
mPages = unpluck.pages(); |
|
mLinks = unpluck.links(); |
|
|
|
const QMap<QString, QString> infos = unpluck.infos(); |
|
QMapIterator<QString, QString> it(infos); |
|
while (it.hasNext()) { |
|
it.next(); |
|
if (!it.value().isEmpty()) { |
|
if (it.key() == QLatin1String("name")) |
|
mDocumentInfo.set(QStringLiteral("name"), it.value(), i18n("Name")); |
|
else if (it.key() == QLatin1String("title")) |
|
mDocumentInfo.set(Okular::DocumentInfo::Title, it.value()); |
|
else if (it.key() == QLatin1String("author")) |
|
mDocumentInfo.set(Okular::DocumentInfo::Author, it.value()); |
|
else if (it.key() == QLatin1String("time")) |
|
mDocumentInfo.set(Okular::DocumentInfo::CreationDate, it.value()); |
|
} |
|
} |
|
|
|
pagesVector.resize(mPages.count()); |
|
|
|
for (int i = 0; i < mPages.count(); ++i) { |
|
QSizeF size = mPages[i]->size(); |
|
Okular::Page *page = new Okular::Page(i, size.width(), size.height(), Okular::Rotation0); |
|
pagesVector[i] = page; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
bool PluckerGenerator::doCloseDocument() |
|
{ |
|
mLinkAdded.clear(); |
|
mLinks.clear(); |
|
|
|
qDeleteAll(mPages); |
|
mPages.clear(); |
|
|
|
// do not use clear() for the following, otherwise its type is changed |
|
mDocumentInfo = Okular::DocumentInfo(); |
|
|
|
return true; |
|
} |
|
|
|
Okular::DocumentInfo PluckerGenerator::generateDocumentInfo(const QSet<Okular::DocumentInfo::Key> & /*keys*/) const |
|
{ |
|
return mDocumentInfo; |
|
} |
|
|
|
QImage PluckerGenerator::image(Okular::PixmapRequest *request) |
|
{ |
|
const QSizeF size = mPages[request->pageNumber()]->size(); |
|
|
|
QImage image(request->width(), request->height(), QImage::Format_ARGB32_Premultiplied); |
|
image.fill(Qt::white); |
|
|
|
QPainter p; |
|
p.begin(&image); |
|
|
|
qreal width = request->width(); |
|
qreal height = request->height(); |
|
|
|
p.scale(width / (qreal)size.width(), height / (qreal)size.height()); |
|
mPages[request->pageNumber()]->drawContents(&p); |
|
p.end(); |
|
|
|
if (!mLinkAdded.contains(request->pageNumber())) { |
|
QLinkedList<Okular::ObjectRect *> objects; |
|
for (int i = 0; i < mLinks.count(); ++i) { |
|
if (mLinks[i].page == request->pageNumber()) { |
|
QTextDocument *document = mPages[request->pageNumber()]; |
|
|
|
QRectF rect; |
|
calculateBoundingRect(document, mLinks[i].start, mLinks[i].end, rect); |
|
|
|
objects.append(new Okular::ObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, mLinks[i].link)); |
|
} |
|
} |
|
|
|
if (!objects.isEmpty()) |
|
request->page()->setObjectRects(objects); |
|
|
|
mLinkAdded.insert(request->pageNumber()); |
|
} |
|
|
|
return image; |
|
} |
|
|
|
Okular::ExportFormat::List PluckerGenerator::exportFormats() const |
|
{ |
|
static Okular::ExportFormat::List formats; |
|
if (formats.isEmpty()) |
|
formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText)); |
|
|
|
return formats; |
|
} |
|
|
|
bool PluckerGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format) |
|
{ |
|
if (format.mimeType().name() == QLatin1String("text/plain")) { |
|
QFile file(fileName); |
|
if (!file.open(QIODevice::WriteOnly)) |
|
return false; |
|
|
|
QTextStream out(&file); |
|
for (int i = 0; i < mPages.count(); ++i) { |
|
out << mPages[i]->toPlainText(); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
#include "generator_plucker.moc"
|
|
|