Skip to content
This repository was archived by the owner on May 30, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions examples/rasterize.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
if (phantom.state.length === 0) {
if (phantom.args.length !== 2) {
console.log('Usage: rasterize.js URL filename');
if (phantom.args.length < 2 || phantom.args.length > 3) {
console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]');
console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
phantom.exit();
} else {
var address = phantom.args[0];
phantom.state = 'rasterize';
phantom.viewportSize = { width: 600, height: 600 };
if (phantom.args.length === 3 && phantom.args[1].substr(-4) === ".pdf") {
var size = phantom.args[2].split('*');
phantom.paperSize = size.length === 2 ? { width: size[0], height: size[1], border: '0px' }
: { format: phantom.args[2], orientation: 'portrait', border: '1cm' };
}
phantom.open(address);
}
} else {
Expand Down
103 changes: 96 additions & 7 deletions src/phantomjs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#define PHANTOMJS_VERSION_PATCH 0
#define PHANTOMJS_VERSION_STRING "1.1.0"

#define PHANTOMJS_PDF_DPI 72 // Different defaults. OSX: 72, X11: 75(?), Windows: 96

void showUsage()
{
std::cerr << "Usage: phantomjs [options] script.js [argument [argument ...]]" << std::endl << std::endl;
Expand Down Expand Up @@ -127,6 +129,7 @@ class Phantom: public QObject
Q_PROPERTY(QString userAgent READ userAgent WRITE setUserAgent)
Q_PROPERTY(QVariantMap version READ version)
Q_PROPERTY(QVariantMap viewportSize READ viewportSize WRITE setViewportSize)
Q_PROPERTY(QVariantMap paperSize READ paperSize WRITE setPaperSize)

public:
Phantom(QObject *parent = 0);
Expand All @@ -152,6 +155,9 @@ class Phantom: public QObject
void setViewportSize(const QVariantMap &size);
QVariantMap viewportSize() const;

void setPaperSize(const QVariantMap &size);
QVariantMap paperSize() const;

public slots:
void exit(int code = 0);
void open(const QString &address);
Expand All @@ -162,6 +168,7 @@ public slots:
private slots:
void inject();
void finish(bool);
bool renderPdf(const QString &fileName);

private:
QString m_scriptFile;
Expand All @@ -174,6 +181,7 @@ private slots:
QString m_script;
QString m_state;
CSConverter *m_converter;
QVariantMap m_paperSize; // For PDF output via render()
};

Phantom::Phantom(QObject *parent)
Expand Down Expand Up @@ -370,13 +378,8 @@ bool Phantom::render(const QString &fileName)
QDir dir;
dir.mkpath(fileInfo.absolutePath());

if (fileName.toLower().endsWith(".pdf")) {
QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
m_page.mainFrame()->print(&printer);
return true;
}
if (fileName.endsWith(".pdf", Qt::CaseInsensitive))
return renderPdf(fileName);

QSize viewportSize = m_page.viewportSize();
QSize pageSize = m_page.mainFrame()->contentsSize();
Expand Down Expand Up @@ -474,6 +477,92 @@ QVariantMap Phantom::viewportSize() const
return result;
}

void Phantom::setPaperSize(const QVariantMap &size)
{
m_paperSize = size;
}

QVariantMap Phantom::paperSize() const
{
return m_paperSize;
}

static qreal stringToPointSize(const QString &string)
{
static const struct {
QString unit;
qreal factor;
} units[] = {
{ "mm", 72 / 25.4 },
{ "cm", 72 / 2.54 },
{ "in", 72 },
{ "px", 72.0 / PHANTOMJS_PDF_DPI / 2.54 },
{ "", 72.0 / PHANTOMJS_PDF_DPI / 2.54 }
};
for (uint i = 0; i < sizeof(units) / sizeof(units[0]); ++i) {
if (string.endsWith(units[i].unit)) {
QString value = string;
value.chop(units[i].unit.length());
return value.toDouble() * units[i].factor;
}
}
return 0;
}

bool Phantom::renderPdf(const QString &fileName)
{
QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
printer.setResolution(PHANTOMJS_PDF_DPI);
QVariantMap paperSize = m_paperSize;

if (paperSize.isEmpty()) {
const QSize pageSize = m_page.mainFrame()->contentsSize();
paperSize.insert("width", QString::number(pageSize.width()) + "px");
paperSize.insert("height", QString::number(pageSize.height()) + "px");
paperSize.insert("border", "0px");
}

if (paperSize.contains("width") && paperSize.contains("height")) {
const QSizeF sizePt(ceil(stringToPointSize(paperSize.value("width").toString())),
ceil(stringToPointSize(paperSize.value("height").toString())));
printer.setPaperSize(sizePt, QPrinter::Point);
} else if (paperSize.contains("format")) {
const QPrinter::Orientation orientation = paperSize.contains("orientation")
&& paperSize.value("orientation").toString().compare("landscape", Qt::CaseInsensitive) == 0 ?
QPrinter::Landscape : QPrinter::Portrait;
printer.setOrientation(orientation);
static const struct {
QString format;
QPrinter::PaperSize paperSize;
} formats[] = {
{ "A3", QPrinter::A3 },
{ "A4", QPrinter::A4 },
{ "A5", QPrinter::A5 },
{ "Legal", QPrinter::Legal },
{ "Letter", QPrinter::Letter },
{ "Tabloid", QPrinter::Tabloid }
};
printer.setPaperSize(QPrinter::A4); // Fallback
for (uint i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) {
if (paperSize.value("format").toString().compare(formats[i].format, Qt::CaseInsensitive) == 0) {
printer.setPaperSize(formats[i].paperSize);
break;
}
}
} else {
return false;
}

const qreal border = paperSize.contains("border") ?
floor(stringToPointSize(paperSize.value("border").toString())) : 0;
printer.setPageMargins(border, border, border, border, QPrinter::Point);

m_page.mainFrame()->print(&printer);
return true;
}

#include "phantomjs.moc"

int main(int argc, char** argv)
Expand Down