blob: c4dec24cb9576ff9d1a55834e12cd9a1e5f1ab67 [file] [log] [blame]
/* poppler-ps-converter.cc: qt interface to poppler
* Copyright (C) 2007, 2009, 2010, 2015, 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>
*
* 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-qt5.h"
#include "poppler-private.h"
#include "poppler-converter-private.h"
#include "PSOutputDev.h"
static void outputToQIODevice(void *stream, const char *data, int len)
{
static_cast<QIODevice*>(stream)->write(data, len);
}
namespace Poppler {
class PSConverterPrivate : public BaseConverterPrivate
{
public:
PSConverterPrivate();
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)
{
}
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));
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;
}
}
}