From be8b3a6c35ab5a75b02a4d3264b0384c322417e3 Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Mon, 2 Sep 2013 16:05:31 +1000 Subject: [PATCH 01/10] Add the ability to set page width, height, and margins. --- CutyCapt.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--- CutyCapt.hpp | 9 ++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index c732cb9..eda61e9 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -162,12 +162,15 @@ CutyPage::setAttribute(QWebSettings::WebAttribute option, CutyCapt::CutyCapt(CutyPage* page, const QString& output, int delay, OutputFormat format, const QString& scriptProp, const QString& scriptCode, bool insecure, - bool smooth) { + bool smooth, int pageWidth, int pageHeight, QRectF margins) { mPage = page; mOutput = output; mDelay = delay; mInsecure = insecure; mSmooth = smooth; + mPageWidth = pageWidth; + mPageHeight = pageHeight; + mMargins = margins; mSawInitialLayout = false; mSawDocumentComplete = false; mFormat = format; @@ -283,7 +286,14 @@ CutyCapt::saveSnapshot() { case PdfFormat: case PsFormat: { QPrinter printer; - printer.setPageSize(QPrinter::A4); + if (mPageWidth != 0 && mPageHeight != 0) { + printer.setPaperSize(QSizeF(mPageWidth, mPageHeight), QPrinter::Point); + } else { + printer.setPageSize(QPrinter::A4); + } + if (mMargins.left() >= 0 && mMargins.top() >= 0 && mMargins.right() >= 0 && mMargins.bottom() >= 0) { + printer.setPageMargins(mMargins.left(), mMargins.top(), mMargins.right(), mMargins.bottom(), QPrinter::Point); + } printer.setOutputFileName(mOutput); // TODO: change quality here? mainFrame->print(&printer); @@ -361,6 +371,12 @@ CaptHelp(void) { " --auto-load-images= Automatic image loading (default: on) \n" " --js-can-open-windows= Script can open windows? (default: unknown) \n" " --js-can-access-clipboard= Script clipboard privs (default: unknown)\n" + " --page-width= Sets the page width in points (default: A4 width)\n" + " --page-height= Sets the page height in points (default: A4 height)\n" + " --margin-left= Sets the left margin in points (default: unknown)\n" + " --margin-top= Sets the top margin in points (default: unknown)\n" + " --margin-bottom= Sets the bottom margin in points (default: unknown)\n" #if QT_VERSION >= 0x040500 " --print-backgrounds= Backgrounds in PDF/PS output (default: off) \n" " --zoom-factor= Page zoom factor (default: no zooming) \n" @@ -407,6 +423,12 @@ main(int argc, char *argv[]) { int argMaxWait = 90000; int argVerbosity = 0; int argSmooth = 0; + int argPageWidth = 0; + int argPageHeight = 0; + int argMarginLeft = -1; + int argMarginTop = -1; + int argMarginRight = -1; + int argMarginBottom = -1; const char* argUrl = NULL; const char* argUserStyle = NULL; @@ -495,6 +517,30 @@ main(int argc, char *argv[]) { // TODO: see above argMaxWait = (unsigned int)atoi(value); + } else if (strncmp("--page-width", s, nlen) == 0) { + // TODO: see above + argPageWidth = (unsigned int)atoi(value); + + } else if (strncmp("--page-height", s, nlen) == 0) { + // TODO: see above + argPageHeight = (unsigned int)atoi(value); + + } else if (strncmp("--margin-left", s, nlen) == 0) { + // TODO: see above + argMarginLeft = (unsigned int)atoi(value); + + } else if (strncmp("--margin-top", s, nlen) == 0) { + // TODO: see above + argMarginTop = (unsigned int)atoi(value); + + } else if (strncmp("--margin-right", s, nlen) == 0) { + // TODO: see above + argMarginRight = (unsigned int)atoi(value); + + } else if (strncmp("--margin-bottom", s, nlen) == 0) { + // TODO: see above + argMarginBottom = (unsigned int)atoi(value); + } else if (strncmp("--out", s, nlen) == 0) { argOut = value; @@ -651,7 +697,8 @@ main(int argc, char *argv[]) { } CutyCapt main(&page, argOut, argDelay, format, scriptProp, scriptCode, - !!argInsecure, !!argSmooth); + !!argInsecure, !!argSmooth, argPageWidth, argPageHeight, + QRectF(argMarginLeft, argMarginTop, argMarginRight, argMarginBottom)); app.connect(&page, SIGNAL(loadFinished(bool)), diff --git a/CutyCapt.hpp b/CutyCapt.hpp index 15f3864..04c223a 100755 --- a/CutyCapt.hpp +++ b/CutyCapt.hpp @@ -1,4 +1,5 @@ #include +#include #if QT_VERSION >= 0x050000 #include @@ -46,7 +47,10 @@ class CutyCapt : public QObject { const QString& scriptProp, const QString& scriptCode, bool insecure, - bool smooth); + bool smooth, + int pageWidth, + int pageHeight, + QRectF margins); private slots: void DocumentComplete(bool ok); @@ -72,4 +76,7 @@ private slots: QString mScriptCode; bool mInsecure; bool mSmooth; + int mPageWidth; + int mPageHeight; + QRectF mMargins; }; From 4049bb887d0649b1f42c9ed93a40ceff4e18b0bd Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Wed, 4 Sep 2013 11:07:15 +1000 Subject: [PATCH 02/10] Add in a command line option to disable fetching remote resources. --- CutyCapt.cpp | 33 ++++++++++++++++++++++++++++++--- CutyCapt.hpp | 12 ++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index eda61e9..2de856a 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -76,6 +76,24 @@ static struct _CutyExtMap { { CutyCapt::OtherFormat, "", "" } }; +CutyNetworkAccessManager::CutyNetworkAccessManager() { + mAllowRemoteResources = true; +} + +void CutyNetworkAccessManager::setAllowRemoteResources(bool allowRemoteResources) { + mAllowRemoteResources = allowRemoteResources; +} + +QNetworkReply * CutyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) { + if (req.url().scheme() != "file" && !mAllowRemoteResources) { + QNetworkRequest adjusted = req; + adjusted.setUrl(QUrl("about:invalid")); + return QNetworkAccessManager::createRequest(op, adjusted, outgoingData); + } + + return QNetworkAccessManager::createRequest(op, req, outgoingData); +} + QString CutyPage::chooseFile(QWebFrame* /*frame*/, const QString& /*suggestedFile*/) { return QString::null; @@ -369,6 +387,7 @@ CaptHelp(void) { " --plugins= Plugin execution (default: unknown) \n" " --private-browsing= Private browsing (default: unknown) \n" " --auto-load-images= Automatic image loading (default: on) \n" + " --allow-remote-resources= Allow loading remote resources (default: on)n" " --js-can-open-windows= Script can open windows? (default: unknown) \n" " --js-can-access-clipboard= Script clipboard privs (default: unknown)\n" " --page-width= Sets the page width in points (default: A4 width)\n" @@ -443,12 +462,14 @@ main(int argc, char *argv[]) { QApplication app(argc, argv, true); CutyPage page; - + QNetworkAccessManager::Operation method = QNetworkAccessManager::GetOperation; QByteArray body; QNetworkRequest req; - QNetworkAccessManager manager; + CutyNetworkAccessManager manager; + + page.setNetworkAccessManager(&manager); // Parse command line parameters for (int ax = 1; ax < argc; ++ax) { @@ -565,6 +586,13 @@ main(int argc, char *argv[]) { } else if (strncmp("--auto-load-images", s, nlen) == 0) { page.setAttribute(QWebSettings::AutoLoadImages, value); + } else if (strncmp("--allow-remote-resources", s, nlen) == 0) { + if (strcmp("on", value) == 0) { + manager.setAllowRemoteResources(true); + } else if (strcmp("off", value) == 0) { + manager.setAllowRemoteResources(false); + } + } else if (strncmp("--javascript", s, nlen) == 0) { page.setAttribute(QWebSettings::JavascriptEnabled, value); @@ -604,7 +632,6 @@ main(int argc, char *argv[]) { QNetworkProxy proxy = QNetworkProxy(QNetworkProxy::HttpProxy, p.host(), p.port(80), p.userName(), p.password()); manager.setProxy(proxy); - page.setNetworkAccessManager(&manager); #endif #if CUTYCAPT_SCRIPT diff --git a/CutyCapt.hpp b/CutyCapt.hpp index 04c223a..5c21a55 100755 --- a/CutyCapt.hpp +++ b/CutyCapt.hpp @@ -5,6 +5,18 @@ #include #endif +class CutyNetworkAccessManager : public QNetworkAccessManager { + Q_OBJECT + +public: + CutyNetworkAccessManager(); + void setAllowRemoteResources(bool allowRemoteResources); + QNetworkReply * createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0); + +protected: + bool mAllowRemoteResources; +}; + class CutyCapt; class CutyPage : public QWebPage { Q_OBJECT From d2995537674b2736ff24d0643a7be0264803dccb Mon Sep 17 00:00:00 2001 From: "Trejkaz (pen name)" Date: Wed, 22 Jan 2014 16:58:38 +1100 Subject: [PATCH 03/10] Create Info.plist --- Info.plist | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Info.plist diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..c40e338 --- /dev/null +++ b/Info.plist @@ -0,0 +1,12 @@ + + + + + CFBundleExecutable + CutyCapt + CFBundleIdentifier + net.sf.cutycapt + LSUIElement + 1 + + From c0df50b46cdb30c0fa844b52189295f921701436 Mon Sep 17 00:00:00 2001 From: "Trejkaz (pen name)" Date: Wed, 22 Jan 2014 16:59:59 +1100 Subject: [PATCH 04/10] Remove .app wrapping for Mac OS X Employ a trick to embed Info.plist into the executable so that we can turn off the dock icon, and set the Qt build flag to tell it not to create a wrapper. --- CutyCapt.pro | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CutyCapt.pro b/CutyCapt.pro index 10dda79..715a9ac 100755 --- a/CutyCapt.pro +++ b/CutyCapt.pro @@ -12,3 +12,8 @@ contains(CONFIG, static): { DEFINES += STATIC_PLUGINS } +mac { + QMAKE_CXXFLAGS += -fvisibility=hidden + QMAKE_LFLAGS += '-sectcreate __TEXT __info_plist Info.plist' + CONFIG -= app_bundle +} From cc8491ce11407674d77a93d1e592418ea81504a7 Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Mon, 10 Mar 2014 14:15:22 +1100 Subject: [PATCH 05/10] Switch to an empty data URL instead of about:invalid for blocked resources. It turns out that QT webkit will try to resolve 'about:invalid' as a file on disk. --- CutyCapt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index 2de856a..7e6ddb0 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -87,7 +87,7 @@ void CutyNetworkAccessManager::setAllowRemoteResources(bool allowRemoteResources QNetworkReply * CutyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) { if (req.url().scheme() != "file" && !mAllowRemoteResources) { QNetworkRequest adjusted = req; - adjusted.setUrl(QUrl("about:invalid")); + adjusted.setUrl(QUrl("data:")); return QNetworkAccessManager::createRequest(op, adjusted, outgoingData); } From ec5b4f246a0f5eb1f2aa3802c15b859d30349c74 Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Thu, 31 Jul 2014 12:15:08 +1000 Subject: [PATCH 06/10] Fix the data URL for blocked resources. --- CutyCapt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index 7e6ddb0..6be2920 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -87,7 +87,7 @@ void CutyNetworkAccessManager::setAllowRemoteResources(bool allowRemoteResources QNetworkReply * CutyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) { if (req.url().scheme() != "file" && !mAllowRemoteResources) { QNetworkRequest adjusted = req; - adjusted.setUrl(QUrl("data:")); + adjusted.setUrl(QUrl("data:,")); return QNetworkAccessManager::createRequest(op, adjusted, outgoingData); } From 35e662a7af4c997a4bae388a56861e6d95424b24 Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Thu, 31 Jul 2014 16:15:56 +1000 Subject: [PATCH 07/10] Make the text inside PDFs on Mac OSX selectable. --- CutyCapt.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index 6be2920..f6d05ca 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -313,6 +313,12 @@ CutyCapt::saveSnapshot() { printer.setPageMargins(mMargins.left(), mMargins.top(), mMargins.right(), mMargins.bottom(), QPrinter::Point); } printer.setOutputFileName(mOutput); +#ifdef Q_WS_MACX + if (mFormat == PdfFormat) { + // Set the output format to native on Mac OSX otherwise the PDF text isn't selectable + printer.setOutputFormat(QPrinter::NativeFormat); + } +#endif // TODO: change quality here? mainFrame->print(&printer); break; From 17022c01649965c8cf9e6b0032661c9a831eb678 Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Thu, 31 Jul 2014 16:17:17 +1000 Subject: [PATCH 08/10] Kill off some tabs. --- CutyCapt.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index f6d05ca..6b23358 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -85,7 +85,7 @@ void CutyNetworkAccessManager::setAllowRemoteResources(bool allowRemoteResources } QNetworkReply * CutyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) { - if (req.url().scheme() != "file" && !mAllowRemoteResources) { + if (req.url().scheme() != "file" && !mAllowRemoteResources) { QNetworkRequest adjusted = req; adjusted.setUrl(QUrl("data:,")); return QNetworkAccessManager::createRequest(op, adjusted, outgoingData); @@ -304,14 +304,14 @@ CutyCapt::saveSnapshot() { case PdfFormat: case PsFormat: { QPrinter printer; - if (mPageWidth != 0 && mPageHeight != 0) { - printer.setPaperSize(QSizeF(mPageWidth, mPageHeight), QPrinter::Point); - } else { - printer.setPageSize(QPrinter::A4); - } + if (mPageWidth != 0 && mPageHeight != 0) { + printer.setPaperSize(QSizeF(mPageWidth, mPageHeight), QPrinter::Point); + } else { + printer.setPageSize(QPrinter::A4); + } if (mMargins.left() >= 0 && mMargins.top() >= 0 && mMargins.right() >= 0 && mMargins.bottom() >= 0) { - printer.setPageMargins(mMargins.left(), mMargins.top(), mMargins.right(), mMargins.bottom(), QPrinter::Point); - } + printer.setPageMargins(mMargins.left(), mMargins.top(), mMargins.right(), mMargins.bottom(), QPrinter::Point); + } printer.setOutputFileName(mOutput); #ifdef Q_WS_MACX if (mFormat == PdfFormat) { From ace151d9bd67c79062cdc2c820ce6869073838fc Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Wed, 22 Oct 2014 11:00:06 +1100 Subject: [PATCH 09/10] Fix a problem rendering images from a data url. --- CutyCapt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index 7e6ddb0..089ce1e 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -85,7 +85,7 @@ void CutyNetworkAccessManager::setAllowRemoteResources(bool allowRemoteResources } QNetworkReply * CutyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) { - if (req.url().scheme() != "file" && !mAllowRemoteResources) { + if (req.url().scheme() != "file" && req.url().scheme() != "data" && !mAllowRemoteResources) { QNetworkRequest adjusted = req; adjusted.setUrl(QUrl("data:")); return QNetworkAccessManager::createRequest(op, adjusted, outgoingData); From c4eca6b92d2af1f1c8a2e94725a9618930f2d85c Mon Sep 17 00:00:00 2001 From: Luke Quinane Date: Wed, 22 Oct 2014 11:55:02 +1100 Subject: [PATCH 10/10] Add some ifdefs for when SVG is not enabled. --- CutyCapt.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CutyCapt.cpp b/CutyCapt.cpp index 2d6c137..9d466ad 100755 --- a/CutyCapt.cpp +++ b/CutyCapt.cpp @@ -26,7 +26,9 @@ #include #include #include +#ifndef QT_NO_SVG #include +#endif #if QT_VERSION < 0x050000 #include @@ -46,7 +48,9 @@ Q_IMPORT_PLUGIN(qjpeg) Q_IMPORT_PLUGIN(qgif) Q_IMPORT_PLUGIN(qtiff) +#ifndef QT_NO_SVG Q_IMPORT_PLUGIN(qsvg) +#endif Q_IMPORT_PLUGIN(qmng) Q_IMPORT_PLUGIN(qico) #endif @@ -56,7 +60,9 @@ static struct _CutyExtMap { const char* extension; const char* identifier; } const CutyExtMap[] = { +#ifndef QT_NO_SVG { CutyCapt::SvgFormat, ".svg", "svg" }, +#endif { CutyCapt::PdfFormat, ".pdf", "pdf" }, { CutyCapt::PsFormat, ".ps", "ps" }, { CutyCapt::InnerTextFormat, ".txt", "itext" }, @@ -292,6 +298,7 @@ CutyCapt::saveSnapshot() { mPage->setViewportSize( mainFrame->contentsSize() ); switch (mFormat) { +#ifndef QT_NO_SVG case SvgFormat: { QSvgGenerator svg; svg.setFileName(mOutput); @@ -301,6 +308,7 @@ CutyCapt::saveSnapshot() { painter.end(); break; } +#endif case PdfFormat: case PsFormat: { QPrinter printer;