mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-04-10 19:15:13 +00:00
265 lines
6.8 KiB
Plaintext
265 lines
6.8 KiB
Plaintext
|
|
/* poppler-ps-converter.cc: qt interface to poppler
|
||
|
|
* Copyright (C) 2007, 2009, 2010, 2015, 2020, 2022, Albert Astals Cid <aacid@kde.org>
|
||
|
|
* Copyright (C) 2008, Pino Toscano <pino@kde.org>
|
||
|
|
* Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
|
||
|
|
* Copyright (C) 2011 Glad Deschrijver <glad.deschrijver@gmail.com>
|
||
|
|
* Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
|
||
|
|
* Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
|
||
|
|
* Copyright (C) 2014 Adrian Johnson <ajohnson@redneon.com>
|
||
|
|
* Copyright (C) 2020 William Bader <williambader@hotmail.com>
|
||
|
|
*
|
||
|
|
* This program is free software; you can redistribute it and/or modify
|
||
|
|
* it under the terms of the GNU General Public License as published by
|
||
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
||
|
|
* any later version.
|
||
|
|
*
|
||
|
|
* This program is distributed in the hope that it will be useful,
|
||
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
* GNU General Public License for more details.
|
||
|
|
*
|
||
|
|
* You should have received a copy of the GNU General Public License
|
||
|
|
* along with this program; if not, write to the Free Software
|
||
|
|
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "poppler-qt6.h"
|
||
|
|
|
||
|
|
#include "poppler-private.h"
|
||
|
|
#include "poppler-converter-private.h"
|
||
|
|
|
||
|
|
#include "PSOutputDev.h"
|
||
|
|
|
||
|
|
static void outputToQIODevice(void *stream, const char *data, size_t len)
|
||
|
|
{
|
||
|
|
static_cast<QIODevice *>(stream)->write(data, len);
|
||
|
|
}
|
||
|
|
|
||
|
|
namespace Poppler {
|
||
|
|
|
||
|
|
class PSConverterPrivate : public BaseConverterPrivate
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
PSConverterPrivate();
|
||
|
|
~PSConverterPrivate() override;
|
||
|
|
|
||
|
|
QList<int> pageList;
|
||
|
|
QString title;
|
||
|
|
double hDPI;
|
||
|
|
double vDPI;
|
||
|
|
int rotate;
|
||
|
|
int paperWidth;
|
||
|
|
int paperHeight;
|
||
|
|
int marginRight;
|
||
|
|
int marginBottom;
|
||
|
|
int marginLeft;
|
||
|
|
int marginTop;
|
||
|
|
PSConverter::PSOptions opts;
|
||
|
|
void (*pageConvertedCallback)(int page, void *payload);
|
||
|
|
void *pageConvertedPayload;
|
||
|
|
};
|
||
|
|
|
||
|
|
PSConverterPrivate::PSConverterPrivate()
|
||
|
|
: BaseConverterPrivate(),
|
||
|
|
hDPI(72),
|
||
|
|
vDPI(72),
|
||
|
|
rotate(0),
|
||
|
|
paperWidth(-1),
|
||
|
|
paperHeight(-1),
|
||
|
|
marginRight(0),
|
||
|
|
marginBottom(0),
|
||
|
|
marginLeft(0),
|
||
|
|
marginTop(0),
|
||
|
|
opts(PSConverter::Printing),
|
||
|
|
pageConvertedCallback(nullptr),
|
||
|
|
pageConvertedPayload(nullptr)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
PSConverterPrivate::~PSConverterPrivate() = default;
|
||
|
|
|
||
|
|
PSConverter::PSConverter(DocumentData *document) : BaseConverter(*new PSConverterPrivate())
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->document = document;
|
||
|
|
}
|
||
|
|
|
||
|
|
PSConverter::~PSConverter() { }
|
||
|
|
|
||
|
|
void PSConverter::setPageList(const QList<int> &pageList)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->pageList = pageList;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setTitle(const QString &title)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->title = title;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setHDPI(double hDPI)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->hDPI = hDPI;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setVDPI(double vDPI)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->vDPI = vDPI;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setRotate(int rotate)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->rotate = rotate;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setPaperWidth(int paperWidth)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->paperWidth = paperWidth;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setPaperHeight(int paperHeight)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->paperHeight = paperHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setRightMargin(int marginRight)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->marginRight = marginRight;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setBottomMargin(int marginBottom)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->marginBottom = marginBottom;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setLeftMargin(int marginLeft)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->marginLeft = marginLeft;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setTopMargin(int marginTop)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->marginTop = marginTop;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setStrictMargins(bool strictMargins)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
if (strictMargins) {
|
||
|
|
d->opts |= StrictMargins;
|
||
|
|
} else {
|
||
|
|
d->opts &= ~StrictMargins;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setForceRasterize(bool forceRasterize)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
if (forceRasterize) {
|
||
|
|
d->opts |= ForceRasterization;
|
||
|
|
} else {
|
||
|
|
d->opts &= ~ForceRasterization;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setPSOptions(PSConverter::PSOptions options)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->opts = options;
|
||
|
|
}
|
||
|
|
|
||
|
|
PSConverter::PSOptions PSConverter::psOptions() const
|
||
|
|
{
|
||
|
|
Q_D(const PSConverter);
|
||
|
|
return d->opts;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PSConverter::setPageConvertedCallback(void (*callback)(int page, void *payload), void *payload)
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->pageConvertedCallback = callback;
|
||
|
|
d->pageConvertedPayload = payload;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool annotDisplayDecideCbk(Annot *annot, void *user_data)
|
||
|
|
{
|
||
|
|
if (annot->getType() == Annot::typeWidget) {
|
||
|
|
return true; // Never hide forms
|
||
|
|
} else {
|
||
|
|
return *(bool *)user_data;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool PSConverter::convert()
|
||
|
|
{
|
||
|
|
Q_D(PSConverter);
|
||
|
|
d->lastError = NoError;
|
||
|
|
|
||
|
|
Q_ASSERT(!d->pageList.isEmpty());
|
||
|
|
Q_ASSERT(d->paperWidth != -1);
|
||
|
|
Q_ASSERT(d->paperHeight != -1);
|
||
|
|
|
||
|
|
if (d->document->locked) {
|
||
|
|
d->lastError = FileLockedError;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
QIODevice *dev = d->openDevice();
|
||
|
|
if (!dev) {
|
||
|
|
d->lastError = OpenOutputError;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray pstitle8Bit = d->title.toLocal8Bit();
|
||
|
|
char *pstitlechar;
|
||
|
|
if (!d->title.isEmpty()) {
|
||
|
|
pstitlechar = pstitle8Bit.data();
|
||
|
|
} else {
|
||
|
|
pstitlechar = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<int> pages;
|
||
|
|
foreach (int page, d->pageList) {
|
||
|
|
pages.push_back(page);
|
||
|
|
}
|
||
|
|
|
||
|
|
PSOutputDev *psOut = new PSOutputDev(outputToQIODevice, dev, pstitlechar, d->document->doc, pages, (d->opts & PrintToEPS) ? psModeEPS : psModePS, d->paperWidth, d->paperHeight, false, false, d->marginLeft, d->marginBottom,
|
||
|
|
d->paperWidth - d->marginRight, d->paperHeight - d->marginTop, (d->opts & ForceRasterization) ? psAlwaysRasterize : psRasterizeWhenNeeded);
|
||
|
|
|
||
|
|
if (d->opts & StrictMargins) {
|
||
|
|
double xScale = ((double)d->paperWidth - (double)d->marginLeft - (double)d->marginRight) / (double)d->paperWidth;
|
||
|
|
double yScale = ((double)d->paperHeight - (double)d->marginBottom - (double)d->marginTop) / (double)d->paperHeight;
|
||
|
|
psOut->setScale(xScale, yScale);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (psOut->isOk()) {
|
||
|
|
bool isPrinting = (d->opts & Printing) ? true : false;
|
||
|
|
bool showAnnotations = (d->opts & HideAnnotations) ? false : true;
|
||
|
|
foreach (int page, d->pageList) {
|
||
|
|
d->document->doc->displayPage(psOut, page, d->hDPI, d->vDPI, d->rotate, false, true, isPrinting, nullptr, nullptr, annotDisplayDecideCbk, &showAnnotations, true);
|
||
|
|
if (d->pageConvertedCallback) {
|
||
|
|
(*d->pageConvertedCallback)(page, d->pageConvertedPayload);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
delete psOut;
|
||
|
|
d->closeDevice();
|
||
|
|
return true;
|
||
|
|
} else {
|
||
|
|
delete psOut;
|
||
|
|
d->closeDevice();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|