| /* 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(0), |
| pageConvertedPayload(0) |
| { |
| } |
| |
| |
| 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 GBool annotDisplayDecideCbk(Annot *annot, void *user_data) |
| { |
| if (annot->getType() == Annot::typeWidget) |
| return gTrue; // Never hide forms |
| else |
| return *(GBool*)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 = 0; |
| |
| 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, |
| gFalse, |
| gFalse, |
| 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()) |
| { |
| GBool isPrinting = (d->opts & Printing) ? gTrue : gFalse; |
| GBool showAnnotations = (d->opts & HideAnnotations) ? gFalse : gTrue; |
| foreach(int page, d->pageList) |
| { |
| d->document->doc->displayPage(psOut, |
| page, |
| d->hDPI, |
| d->vDPI, |
| d->rotate, |
| gFalse, |
| gTrue, |
| isPrinting, |
| NULL, |
| NULL, |
| annotDisplayDecideCbk, |
| &showAnnotations, gTrue); |
| if (d->pageConvertedCallback) |
| (*d->pageConvertedCallback)(page, d->pageConvertedPayload); |
| } |
| delete psOut; |
| d->closeDevice(); |
| return true; |
| } |
| else |
| { |
| delete psOut; |
| d->closeDevice(); |
| return false; |
| } |
| } |
| |
| } |