summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2020-07-03 23:51:42 +0200
committerAlbert Astals Cid <aacid@kde.org>2020-07-03 23:51:42 +0200
commit814fbda28cc8a37fed3134c2db8da28f86fb5ee0 (patch)
tree77872b408199925ebba6a68b0dccaa0d29274c3f /utils
parent0d48722746b9702e219df58ad14cee6184a62bef (diff)
Run clang-format
find . \( -name "*.cpp" -or -name "*.h" -or -name "*.c" -or -name "*.cc" \) -exec clang-format -i {} \; If you reached this file doing a git blame, please see README.contributors (instructions added 2 commits in the future to this one)
Diffstat (limited to 'utils')
-rw-r--r--utils/HtmlFonts.cc496
-rw-r--r--utils/HtmlFonts.h146
-rw-r--r--utils/HtmlLinks.cc174
-rw-r--r--utils/HtmlLinks.h64
-rw-r--r--utils/HtmlOutputDev.cc2742
-rw-r--r--utils/HtmlOutputDev.h443
-rw-r--r--utils/HtmlUtils.h27
-rw-r--r--utils/ImageOutputDev.cc1138
-rw-r--r--utils/ImageOutputDev.h232
-rw-r--r--utils/InMemoryFile.cc42
-rw-r--r--utils/InMemoryFile.h18
-rw-r--r--utils/Win32Console.cc211
-rw-r--r--utils/Win32Console.h39
-rw-r--r--utils/numberofcharacters.h13
-rw-r--r--utils/parseargs.cc332
-rw-r--r--utils/parseargs.h48
-rw-r--r--utils/pdfattach.cc145
-rw-r--r--utils/pdfdetach.cc517
-rw-r--r--utils/pdffonts.cc244
-rw-r--r--utils/pdfimages.cc289
-rw-r--r--utils/pdfinfo.cc1588
-rw-r--r--utils/pdfseparate.cc240
-rw-r--r--utils/pdfsig.cc282
-rw-r--r--utils/pdftocairo-win32.cc847
-rw-r--r--utils/pdftocairo-win32.h9
-rw-r--r--utils/pdftocairo.cc1853
-rw-r--r--utils/pdftohtml.cc791
-rw-r--r--utils/pdftoppm.cc988
-rw-r--r--utils/pdftops.cc581
-rw-r--r--utils/pdftotext.cc836
-rw-r--r--utils/pdfunite.cc656
-rw-r--r--utils/printencodings.cc16
32 files changed, 7709 insertions, 8338 deletions
diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc
index 964ab018..bb46c152 100644
--- a/utils/HtmlFonts.cc
+++ b/utils/HtmlFonts.cc
@@ -44,29 +44,23 @@
#include "GfxFont.h"
#include <cstdio>
-namespace
-{
+namespace {
-const char* const defaultFamilyName = "Times";
+const char *const defaultFamilyName = "Times";
-const char* const styleSuffixes[] = {
- "-Regular",
- "-Bold",
- "-BoldOblique",
- "-BoldItalic",
- "-Oblique",
- "-Italic",
- "-Roman",
+const char *const styleSuffixes[] = {
+ "-Regular", "-Bold", "-BoldOblique", "-BoldItalic", "-Oblique", "-Italic", "-Roman",
};
-void removeStyleSuffix(std::string& familyName) {
- for (const char* const styleSuffix : styleSuffixes) {
- auto pos = familyName.rfind(styleSuffix);
- if (pos != std::string::npos) {
- familyName.resize(pos);
- return;
+void removeStyleSuffix(std::string &familyName)
+{
+ for (const char *const styleSuffix : styleSuffixes) {
+ auto pos = familyName.rfind(styleSuffix);
+ if (pos != std::string::npos) {
+ familyName.resize(pos);
+ return;
+ }
}
- }
}
}
@@ -75,266 +69,284 @@ void removeStyleSuffix(std::string& familyName) {
extern bool xml;
extern bool fontFullName;
-HtmlFontColor::HtmlFontColor(GfxRGB rgb){
- r=static_cast<int>(rgb.r/65535.0*255.0);
- g=static_cast<int>(rgb.g/65535.0*255.0);
- b=static_cast<int>(rgb.b/65535.0*255.0);
- if (!(Ok(r)&&Ok(b)&&Ok(g))) {
- if (!globalParams->getErrQuiet()) fprintf(stderr, "Error : Bad color (%d,%d,%d) reset to (0,0,0)\n", r, g, b);
- r=0;g=0;b=0;
- }
+HtmlFontColor::HtmlFontColor(GfxRGB rgb)
+{
+ r = static_cast<int>(rgb.r / 65535.0 * 255.0);
+ g = static_cast<int>(rgb.g / 65535.0 * 255.0);
+ b = static_cast<int>(rgb.b / 65535.0 * 255.0);
+ if (!(Ok(r) && Ok(b) && Ok(g))) {
+ if (!globalParams->getErrQuiet())
+ fprintf(stderr, "Error : Bad color (%d,%d,%d) reset to (0,0,0)\n", r, g, b);
+ r = 0;
+ g = 0;
+ b = 0;
+ }
}
-GooString *HtmlFontColor::convtoX(unsigned int xcol) const{
- GooString *xret=new GooString();
- char tmp;
- unsigned int k;
- k = (xcol/16);
- if (k<10) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
- xret->append(tmp);
- k = (xcol%16);
- if (k<10) tmp=(char) ('0'+k); else tmp=(char)('a'+k-10);
- xret->append(tmp);
- return xret;
+GooString *HtmlFontColor::convtoX(unsigned int xcol) const
+{
+ GooString *xret = new GooString();
+ char tmp;
+ unsigned int k;
+ k = (xcol / 16);
+ if (k < 10)
+ tmp = (char)('0' + k);
+ else
+ tmp = (char)('a' + k - 10);
+ xret->append(tmp);
+ k = (xcol % 16);
+ if (k < 10)
+ tmp = (char)('0' + k);
+ else
+ tmp = (char)('a' + k - 10);
+ xret->append(tmp);
+ return xret;
}
-GooString *HtmlFontColor::toString() const{
- GooString *tmp=new GooString("#");
- GooString *tmpr=convtoX(r);
- GooString *tmpg=convtoX(g);
- GooString *tmpb=convtoX(b);
- tmp->append(tmpr);
- tmp->append(tmpg);
- tmp->append(tmpb);
- delete tmpr;
- delete tmpg;
- delete tmpb;
- return tmp;
-}
-
-HtmlFont::HtmlFont(GfxFont *font, int _size, GfxRGB rgb){
- color=HtmlFontColor(rgb);
-
- lineSize = -1;
-
- size=_size;
- italic = false;
- bold = false;
- rotOrSkewed = false;
-
- if (font->isBold() || font->getWeight() >= GfxFont::W700) bold=true;
- if (font->isItalic()) italic=true;
-
- if (const GooString *fontname = font->getName()){
- FontName = new GooString(fontname);
-
- GooString fontnameLower(fontname);
- fontnameLower.lowerCase();
-
- if (!bold && strstr(fontnameLower.c_str(),"bold")) {
- bold=true;
- }
+GooString *HtmlFontColor::toString() const
+{
+ GooString *tmp = new GooString("#");
+ GooString *tmpr = convtoX(r);
+ GooString *tmpg = convtoX(g);
+ GooString *tmpb = convtoX(b);
+ tmp->append(tmpr);
+ tmp->append(tmpg);
+ tmp->append(tmpb);
+ delete tmpr;
+ delete tmpg;
+ delete tmpb;
+ return tmp;
+}
+
+HtmlFont::HtmlFont(GfxFont *font, int _size, GfxRGB rgb)
+{
+ color = HtmlFontColor(rgb);
- if (!italic &&
- (strstr(fontnameLower.c_str(),"italic")||
- strstr(fontnameLower.c_str(),"oblique"))) {
- italic=true;
+ lineSize = -1;
+
+ size = _size;
+ italic = false;
+ bold = false;
+ rotOrSkewed = false;
+
+ if (font->isBold() || font->getWeight() >= GfxFont::W700)
+ bold = true;
+ if (font->isItalic())
+ italic = true;
+
+ if (const GooString *fontname = font->getName()) {
+ FontName = new GooString(fontname);
+
+ GooString fontnameLower(fontname);
+ fontnameLower.lowerCase();
+
+ if (!bold && strstr(fontnameLower.c_str(), "bold")) {
+ bold = true;
+ }
+
+ if (!italic && (strstr(fontnameLower.c_str(), "italic") || strstr(fontnameLower.c_str(), "oblique"))) {
+ italic = true;
+ }
+
+ familyName = fontname->c_str();
+ removeStyleSuffix(familyName);
+ } else {
+ FontName = new GooString(defaultFamilyName);
+ familyName = defaultFamilyName;
}
- familyName = fontname->c_str();
- removeStyleSuffix(familyName);
- } else {
- FontName = new GooString(defaultFamilyName);
- familyName = defaultFamilyName;
- }
+ rotSkewMat[0] = rotSkewMat[1] = rotSkewMat[2] = rotSkewMat[3] = 0;
+}
- rotSkewMat[0] = rotSkewMat[1] = rotSkewMat[2] = rotSkewMat[3] = 0;
+HtmlFont::HtmlFont(const HtmlFont &x)
+{
+ size = x.size;
+ lineSize = x.lineSize;
+ italic = x.italic;
+ bold = x.bold;
+ familyName = x.familyName;
+ color = x.color;
+ FontName = new GooString(x.FontName);
+ rotOrSkewed = x.rotOrSkewed;
+ memcpy(rotSkewMat, x.rotSkewMat, sizeof(rotSkewMat));
}
-
-HtmlFont::HtmlFont(const HtmlFont& x){
- size=x.size;
- lineSize=x.lineSize;
- italic=x.italic;
- bold=x.bold;
- familyName=x.familyName;
- color=x.color;
- FontName=new GooString(x.FontName);
- rotOrSkewed = x.rotOrSkewed;
- memcpy(rotSkewMat, x.rotSkewMat, sizeof(rotSkewMat));
- }
-
-
-HtmlFont::~HtmlFont(){
- delete FontName;
+
+HtmlFont::~HtmlFont()
+{
+ delete FontName;
}
-HtmlFont& HtmlFont::operator=(const HtmlFont& x){
- if (this==&x) return *this;
- size=x.size;
- lineSize=x.lineSize;
- italic=x.italic;
- bold=x.bold;
- familyName=x.familyName;
- color=x.color;
- delete FontName;
- FontName=new GooString(x.FontName);
- return *this;
+HtmlFont &HtmlFont::operator=(const HtmlFont &x)
+{
+ if (this == &x)
+ return *this;
+ size = x.size;
+ lineSize = x.lineSize;
+ italic = x.italic;
+ bold = x.bold;
+ familyName = x.familyName;
+ color = x.color;
+ delete FontName;
+ FontName = new GooString(x.FontName);
+ return *this;
}
/*
This function is used to compare font uniquely for insertion into
the list of all encountered fonts
*/
-bool HtmlFont::isEqual(const HtmlFont& x) const{
- return (size==x.size) &&
- (lineSize==x.lineSize) &&
- (FontName->cmp(x.FontName) == 0) && (bold==x.bold) && (italic==x.italic) &&
- (color.isEqual(x.getColor())) && isRotOrSkewed() == x.isRotOrSkewed() &&
- (!isRotOrSkewed() || rot_matrices_equal(getRotMat(), x.getRotMat()));
+bool HtmlFont::isEqual(const HtmlFont &x) const
+{
+ return (size == x.size) && (lineSize == x.lineSize) && (FontName->cmp(x.FontName) == 0) && (bold == x.bold) && (italic == x.italic) && (color.isEqual(x.getColor())) && isRotOrSkewed() == x.isRotOrSkewed()
+ && (!isRotOrSkewed() || rot_matrices_equal(getRotMat(), x.getRotMat()));
}
/*
This one is used to decide whether two pieces of text can be joined together
and therefore we don't care about bold/italics properties
*/
-bool HtmlFont::isEqualIgnoreBold(const HtmlFont& x) const{
- return ((size==x.size) &&
- (familyName == x.familyName) &&
- (color.isEqual(x.getColor())));
+bool HtmlFont::isEqualIgnoreBold(const HtmlFont &x) const
+{
+ return ((size == x.size) && (familyName == x.familyName) && (color.isEqual(x.getColor())));
}
-GooString* HtmlFont::getFontName(){
- return new GooString(familyName);
+GooString *HtmlFont::getFontName()
+{
+ return new GooString(familyName);
}
-GooString* HtmlFont::getFullName(){
- return new GooString(FontName);
+GooString *HtmlFont::getFullName()
+{
+ return new GooString(FontName);
}
// this method if plain wrong todo
-GooString* HtmlFont::HtmlFilter(const Unicode* u, int uLen) {
- GooString *tmp = new GooString();
- const UnicodeMap *uMap;
- char buf[8];
- int n;
-
- // get the output encoding
- if (!(uMap = globalParams->getTextEncoding())) {
- return tmp;
- }
-
- for (int i = 0; i < uLen; ++i) {
- // skip control characters. W3C disallows them and they cause a warning
- // with PHP.
- if (u[i] <= 31 && u[i] != '\t')
- continue;
-
- switch (u[i])
- {
- case '"': tmp->append("&#34;"); break;
- case '&': tmp->append("&amp;"); break;
- case '<': tmp->append("&lt;"); break;
- case '>': tmp->append("&gt;"); break;
- case ' ': case '\t': tmp->append( !xml && ( i+1 >= uLen || !tmp->getLength() || tmp->getChar( tmp->getLength()-1 ) == ' ' ) ? "&#160;" : " " );
- break;
- default:
- {
- // convert unicode to string
- if ((n = uMap->mapUnicode(u[i], buf, sizeof(buf))) > 0) {
- tmp->append(buf, n);
- }
- }
+GooString *HtmlFont::HtmlFilter(const Unicode *u, int uLen)
+{
+ GooString *tmp = new GooString();
+ const UnicodeMap *uMap;
+ char buf[8];
+ int n;
+
+ // get the output encoding
+ if (!(uMap = globalParams->getTextEncoding())) {
+ return tmp;
}
- }
- return tmp;
-}
+ for (int i = 0; i < uLen; ++i) {
+ // skip control characters. W3C disallows them and they cause a warning
+ // with PHP.
+ if (u[i] <= 31 && u[i] != '\t')
+ continue;
+
+ switch (u[i]) {
+ case '"':
+ tmp->append("&#34;");
+ break;
+ case '&':
+ tmp->append("&amp;");
+ break;
+ case '<':
+ tmp->append("&lt;");
+ break;
+ case '>':
+ tmp->append("&gt;");
+ break;
+ case ' ':
+ case '\t':
+ tmp->append(!xml && (i + 1 >= uLen || !tmp->getLength() || tmp->getChar(tmp->getLength() - 1) == ' ') ? "&#160;" : " ");
+ break;
+ default: {
+ // convert unicode to string
+ if ((n = uMap->mapUnicode(u[i], buf, sizeof(buf))) > 0) {
+ tmp->append(buf, n);
+ }
+ }
+ }
+ }
-HtmlFontAccu::HtmlFontAccu(){
+ return tmp;
}
-HtmlFontAccu::~HtmlFontAccu(){
-}
+HtmlFontAccu::HtmlFontAccu() { }
-int HtmlFontAccu::AddFont(const HtmlFont& font){
- std::vector<HtmlFont>::iterator i;
- for (i=accu.begin();i!=accu.end();++i)
- {
- if (font.isEqual(*i))
- {
- return (int)(i-(accu.begin()));
- }
- }
-
- accu.push_back(font);
- return (accu.size()-1);
-}
+HtmlFontAccu::~HtmlFontAccu() { }
-// get CSS font definition for font #i
-GooString* HtmlFontAccu::CSStyle(int i, int j){
- GooString *tmp=new GooString();
-
- std::vector<HtmlFont>::iterator g=accu.begin();
- g+=i;
- HtmlFont font=*g;
- GooString *colorStr=font.getColor().toString();
- GooString *fontName=(fontFullName ? font.getFullName() : font.getFontName());
-
- if(!xml){
- tmp->append(".ft");
- tmp->append(std::to_string(j));
- tmp->append(std::to_string(i));
- tmp->append("{font-size:");
- tmp->append(std::to_string(font.getSize()));
- if( font.getLineSize() != -1 && font.getLineSize() != 0 )
- {
- tmp->append("px;line-height:");
- tmp->append(std::to_string(font.getLineSize()));
- }
- tmp->append("px;font-family:");
- tmp->append(fontName); //font.getFontName());
- tmp->append(";color:");
- tmp->append(colorStr);
- // if there is rotation or skew, include the matrix
- if (font.isRotOrSkewed()) {
- const double * const text_mat = font.getRotMat();
- GooString matrix_str(" matrix(");
- matrix_str.appendf("{0:10.10g}, {1:10.10g}, {2:10.10g}, {3:10.10g}, 0, 0)",
- text_mat[0], text_mat[1], text_mat[2], text_mat[3]);
- tmp->append(";-moz-transform:");
- tmp->append(&matrix_str);
- tmp->append(";-webkit-transform:");
- tmp->append(&matrix_str);
- tmp->append(";-o-transform:");
- tmp->append(&matrix_str);
- tmp->append(";-ms-transform:");
- tmp->append(&matrix_str);
- // Todo: 75% is a wild guess that seems to work pretty well;
- // We probably need to calculate the real percentage
- // Based on the characteristic baseline and bounding box of current font
- // PDF origin is at baseline
- tmp->append(";-moz-transform-origin: left 75%");
- tmp->append(";-webkit-transform-origin: left 75%");
- tmp->append(";-o-transform-origin: left 75%");
- tmp->append(";-ms-transform-origin: left 75%");
- }
- tmp->append(";}");
- }
- if (xml) {
- tmp->append("<fontspec id=\"");
- tmp->append(std::to_string(i));
- tmp->append("\" size=\"");
- tmp->append(std::to_string(font.getSize()));
- tmp->append("\" family=\"");
- tmp->append(fontName);
- tmp->append("\" color=\"");
- tmp->append(colorStr);
- tmp->append("\"/>");
- }
-
- delete fontName;
- delete colorStr;
- return tmp;
+int HtmlFontAccu::AddFont(const HtmlFont &font)
+{
+ std::vector<HtmlFont>::iterator i;
+ for (i = accu.begin(); i != accu.end(); ++i) {
+ if (font.isEqual(*i)) {
+ return (int)(i - (accu.begin()));
+ }
+ }
+
+ accu.push_back(font);
+ return (accu.size() - 1);
}
-
+// get CSS font definition for font #i
+GooString *HtmlFontAccu::CSStyle(int i, int j)
+{
+ GooString *tmp = new GooString();
+
+ std::vector<HtmlFont>::iterator g = accu.begin();
+ g += i;
+ HtmlFont font = *g;
+ GooString *colorStr = font.getColor().toString();
+ GooString *fontName = (fontFullName ? font.getFullName() : font.getFontName());
+
+ if (!xml) {
+ tmp->append(".ft");
+ tmp->append(std::to_string(j));
+ tmp->append(std::to_string(i));
+ tmp->append("{font-size:");
+ tmp->append(std::to_string(font.getSize()));
+ if (font.getLineSize() != -1 && font.getLineSize() != 0) {
+ tmp->append("px;line-height:");
+ tmp->append(std::to_string(font.getLineSize()));
+ }
+ tmp->append("px;font-family:");
+ tmp->append(fontName); // font.getFontName());
+ tmp->append(";color:");
+ tmp->append(colorStr);
+ // if there is rotation or skew, include the matrix
+ if (font.isRotOrSkewed()) {
+ const double *const text_mat = font.getRotMat();
+ GooString matrix_str(" matrix(");
+ matrix_str.appendf("{0:10.10g}, {1:10.10g}, {2:10.10g}, {3:10.10g}, 0, 0)", text_mat[0], text_mat[1], text_mat[2], text_mat[3]);
+ tmp->append(";-moz-transform:");
+ tmp->append(&matrix_str);
+ tmp->append(";-webkit-transform:");
+ tmp->append(&matrix_str);
+ tmp->append(";-o-transform:");
+ tmp->append(&matrix_str);
+ tmp->append(";-ms-transform:");
+ tmp->append(&matrix_str);
+ // Todo: 75% is a wild guess that seems to work pretty well;
+ // We probably need to calculate the real percentage
+ // Based on the characteristic baseline and bounding box of current font
+ // PDF origin is at baseline
+ tmp->append(";-moz-transform-origin: left 75%");
+ tmp->append(";-webkit-transform-origin: left 75%");
+ tmp->append(";-o-transform-origin: left 75%");
+ tmp->append(";-ms-transform-origin: left 75%");
+ }
+ tmp->append(";}");
+ }
+ if (xml) {
+ tmp->append("<fontspec id=\"");
+ tmp->append(std::to_string(i));
+ tmp->append("\" size=\"");
+ tmp->append(std::to_string(font.getSize()));
+ tmp->append("\" family=\"");
+ tmp->append(fontName);
+ tmp->append("\" color=\"");
+ tmp->append(colorStr);
+ tmp->append("\"/>");
+ }
+
+ delete fontName;
+ delete colorStr;
+ return tmp;
+}
diff --git a/utils/HtmlFonts.h b/utils/HtmlFonts.h
index c44ce6a1..6f410262 100644
--- a/utils/HtmlFonts.h
+++ b/utils/HtmlFonts.h
@@ -36,79 +36,87 @@
#include "CharTypes.h"
#include <vector>
-class HtmlFontColor{
- private:
- unsigned int r;
- unsigned int g;
- unsigned int b;
- bool Ok(unsigned int xcol){ return xcol<=255;}
- GooString *convtoX(unsigned int xcol) const;
- public:
- HtmlFontColor():r(0),g(0),b(0){}
- HtmlFontColor(GfxRGB rgb);
- HtmlFontColor(const HtmlFontColor& x){r=x.r;g=x.g;b=x.b;}
- HtmlFontColor& operator=(const HtmlFontColor &x){
- r=x.r;g=x.g;b=x.b;
- return *this;
- }
- ~HtmlFontColor(){};
- GooString* toString() const;
- bool isEqual(const HtmlFontColor& col) const{
- return ((r==col.r)&&(g==col.g)&&(b==col.b));
- }
-} ;
-
+class HtmlFontColor
+{
+private:
+ unsigned int r;
+ unsigned int g;
+ unsigned int b;
+ bool Ok(unsigned int xcol) { return xcol <= 255; }
+ GooString *convtoX(unsigned int xcol) const;
-class HtmlFont{
- private:
- int size;
- int lineSize;
- bool italic;
- bool bold;
- bool rotOrSkewed;
- std::string familyName;
- GooString *FontName;
- HtmlFontColor color;
- double rotSkewMat[4]; // only four values needed for rotation and skew
-public:
+public:
+ HtmlFontColor() : r(0), g(0), b(0) { }
+ HtmlFontColor(GfxRGB rgb);
+ HtmlFontColor(const HtmlFontColor &x)
+ {
+ r = x.r;
+ g = x.g;
+ b = x.b;
+ }
+ HtmlFontColor &operator=(const HtmlFontColor &x)
+ {
+ r = x.r;
+ g = x.g;
+ b = x.b;
+ return *this;
+ }
+ ~HtmlFontColor() {};
+ GooString *toString() const;
+ bool isEqual(const HtmlFontColor &col) const { return ((r == col.r) && (g == col.g) && (b == col.b)); }
+};
- HtmlFont(GfxFont *font,int _size, GfxRGB rgb);
- HtmlFont(const HtmlFont& x);
- HtmlFont& operator=(const HtmlFont& x);
- HtmlFontColor getColor() const {return color;}
- ~HtmlFont();
- GooString* getFullName();
- bool isItalic() const {return italic;}
- bool isBold() const {return bold;}
- bool isRotOrSkewed() const { return rotOrSkewed; }
- int getSize() const {return size;}
- int getLineSize() const {return lineSize;}
- void setLineSize(int _lineSize) { lineSize = _lineSize; }
- void setRotMat(const double * const mat)
- { rotOrSkewed = true; memcpy(rotSkewMat, mat, sizeof(rotSkewMat)); }
- const double *getRotMat() const { return rotSkewMat; }
- GooString* getFontName();
- static GooString* HtmlFilter(const Unicode* u, int uLen); //char* s);
- bool isEqual(const HtmlFont& x) const;
- bool isEqualIgnoreBold(const HtmlFont& x) const;
- void print() const {printf("font: %s (%s) %d %s%s\n", FontName->c_str(), familyName.c_str(), size, bold ? "bold " : "", italic ? "italic " : "");};
+class HtmlFont
+{
+private:
+ int size;
+ int lineSize;
+ bool italic;
+ bool bold;
+ bool rotOrSkewed;
+ std::string familyName;
+ GooString *FontName;
+ HtmlFontColor color;
+ double rotSkewMat[4]; // only four values needed for rotation and skew
+public:
+ HtmlFont(GfxFont *font, int _size, GfxRGB rgb);
+ HtmlFont(const HtmlFont &x);
+ HtmlFont &operator=(const HtmlFont &x);
+ HtmlFontColor getColor() const { return color; }
+ ~HtmlFont();
+ GooString *getFullName();
+ bool isItalic() const { return italic; }
+ bool isBold() const { return bold; }
+ bool isRotOrSkewed() const { return rotOrSkewed; }
+ int getSize() const { return size; }
+ int getLineSize() const { return lineSize; }
+ void setLineSize(int _lineSize) { lineSize = _lineSize; }
+ void setRotMat(const double *const mat)
+ {
+ rotOrSkewed = true;
+ memcpy(rotSkewMat, mat, sizeof(rotSkewMat));
+ }
+ const double *getRotMat() const { return rotSkewMat; }
+ GooString *getFontName();
+ static GooString *HtmlFilter(const Unicode *u, int uLen); // char* s);
+ bool isEqual(const HtmlFont &x) const;
+ bool isEqualIgnoreBold(const HtmlFont &x) const;
+ void print() const { printf("font: %s (%s) %d %s%s\n", FontName->c_str(), familyName.c_str(), size, bold ? "bold " : "", italic ? "italic " : ""); };
};
-class HtmlFontAccu{
+class HtmlFontAccu
+{
private:
- std::vector<HtmlFont> accu;
-
+ std::vector<HtmlFont> accu;
+
public:
- HtmlFontAccu();
- ~HtmlFontAccu();
- HtmlFontAccu(const HtmlFontAccu &) = delete;
- HtmlFontAccu& operator=(const HtmlFontAccu &) = delete;
- int AddFont(const HtmlFont& font);
- const HtmlFont *Get(int i) const {
- return &accu[i];
- }
- GooString* CSStyle(int i, int j = 0);
- int size() const {return accu.size();}
-
-};
+ HtmlFontAccu();
+ ~HtmlFontAccu();
+ HtmlFontAccu(const HtmlFontAccu &) = delete;
+ HtmlFontAccu &operator=(const HtmlFontAccu &) = delete;
+ int AddFont(const HtmlFont &font);
+ const HtmlFont *Get(int i) const { return &accu[i]; }
+ GooString *CSStyle(int i, int j = 0);
+ int size() const { return accu.size(); }
+};
#endif
diff --git a/utils/HtmlLinks.cc b/utils/HtmlLinks.cc
index 5738ad6b..b505e37c 100644
--- a/utils/HtmlLinks.cc
+++ b/utils/HtmlLinks.cc
@@ -30,79 +30,96 @@
extern bool xml;
-HtmlLink::HtmlLink(const HtmlLink& x){
- Xmin=x.Xmin;
- Ymin=x.Ymin;
- Xmax=x.Xmax;
- Ymax=x.Ymax;
- dest=new GooString(x.dest);
+HtmlLink::HtmlLink(const HtmlLink &x)
+{
+ Xmin = x.Xmin;
+ Ymin = x.Ymin;
+ Xmax = x.Xmax;
+ Ymax = x.Ymax;
+ dest = new GooString(x.dest);
}
-HtmlLink::HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString * _dest)
+HtmlLink::HtmlLink(double xmin, double ymin, double xmax, double ymax, GooString *_dest)
{
- if (xmin < xmax) {
- Xmin=xmin;
- Xmax=xmax;
- } else {
- Xmin=xmax;
- Xmax=xmin;
- }
- if (ymin < ymax) {
- Ymin=ymin;
- Ymax=ymax;
- } else {
- Ymin=ymax;
- Ymax=ymin;
- }
- dest=new GooString(_dest);
+ if (xmin < xmax) {
+ Xmin = xmin;
+ Xmax = xmax;
+ } else {
+ Xmin = xmax;
+ Xmax = xmin;
+ }
+ if (ymin < ymax) {
+ Ymin = ymin;
+ Ymax = ymax;
+ } else {
+ Ymin = ymax;
+ Ymax = ymin;
+ }
+ dest = new GooString(_dest);
}
-HtmlLink::~HtmlLink(){
- delete dest;
+HtmlLink::~HtmlLink()
+{
+ delete dest;
}
-bool HtmlLink::isEqualDest(const HtmlLink& x) const{
- return (!strcmp(dest->c_str(), x.dest->c_str()));
+bool HtmlLink::isEqualDest(const HtmlLink &x) const
+{
+ return (!strcmp(dest->c_str(), x.dest->c_str()));
}
-bool HtmlLink::inLink(double xmin,double ymin,double xmax,double ymax) const {
- double y=(ymin+ymax)/2;
- if (y>Ymax) return false;
- return (y>Ymin)&&(xmin<Xmax)&&(xmax>Xmin);
- }
-
-static GooString* EscapeSpecialChars( GooString* s )
+bool HtmlLink::inLink(double xmin, double ymin, double xmax, double ymax) const
{
- GooString* tmp = nullptr;
- for( int i = 0, j = 0; i < s->getLength(); i++, j++ ){
+ double y = (ymin + ymax) / 2;
+ if (y > Ymax)
+ return false;
+ return (y > Ymin) && (xmin < Xmax) && (xmax > Xmin);
+}
+
+static GooString *EscapeSpecialChars(GooString *s)
+{
+ GooString *tmp = nullptr;
+ for (int i = 0, j = 0; i < s->getLength(); i++, j++) {
const char *replace = nullptr;
- switch ( s->getChar(i) ){
- case '"': replace = "&quot;"; break;
- case '&': replace = "&amp;"; break;
- case '<': replace = "&lt;"; break;
- case '>': replace = "&gt;"; break;
- default: continue;
- }
- if( replace ){
- if( !tmp ) tmp = new GooString( s );
- if( tmp ){
- tmp->del( j, 1 );
- int l = strlen( replace );
- tmp->insert( j, replace, l );
- j += l - 1;
- }
- }
- }
- return tmp ? tmp : s;
+ switch (s->getChar(i)) {
+ case '"':
+ replace = "&quot;";
+ break;
+ case '&':
+ replace = "&amp;";
+ break;
+ case '<':
+ replace = "&lt;";
+ break;
+ case '>':
+ replace = "&gt;";
+ break;
+ default:
+ continue;
+ }
+ if (replace) {
+ if (!tmp)
+ tmp = new GooString(s);
+ if (tmp) {
+ tmp->del(j, 1);
+ int l = strlen(replace);
+ tmp->insert(j, replace, l);
+ j += l - 1;
+ }
+ }
+ }
+ return tmp ? tmp : s;
}
-GooString* HtmlLink::getLinkStart() {
- GooString *res = new GooString("<a href=\"");
- GooString *d = xml ? EscapeSpecialChars(dest) : dest;
- res->append( d );
- if( d != dest ) delete d;
- res->append("\">");
- return res;
+GooString *HtmlLink::getLinkStart()
+{
+ GooString *res = new GooString("<a href=\"");
+ GooString *d = xml ? EscapeSpecialChars(dest) : dest;
+ res->append(d);
+ if (d != dest)
+ delete d;
+ res->append("\">");
+ return res;
}
/*GooString* HtmlLink::Link(GooString* content){
@@ -116,29 +133,30 @@ GooString* HtmlLink::getLinkStart() {
return tmp;
}*/
-
-
-HtmlLinks::HtmlLinks(){
- accu=new std::vector<HtmlLink>();
+HtmlLinks::HtmlLinks()
+{
+ accu = new std::vector<HtmlLink>();
}
-HtmlLinks::~HtmlLinks(){
- delete accu;
- accu=nullptr;
+HtmlLinks::~HtmlLinks()
+{
+ delete accu;
+ accu = nullptr;
}
-bool HtmlLinks::inLink(double xmin,double ymin,double xmax,double ymax,int& p)const {
-
- for(std::vector<HtmlLink>::iterator i=accu->begin();i!=accu->end();++i){
- if (i->inLink(xmin,ymin,xmax,ymax)) {
- p=(i - accu->begin());
- return true;
+bool HtmlLinks::inLink(double xmin, double ymin, double xmax, double ymax, int &p) const
+{
+
+ for (std::vector<HtmlLink>::iterator i = accu->begin(); i != accu->end(); ++i) {
+ if (i->inLink(xmin, ymin, xmax, ymax)) {
+ p = (i - accu->begin());
+ return true;
+ }
}
- }
- return false;
+ return false;
}
-HtmlLink* HtmlLinks::getLink(int i) const{
- return &(*accu)[i];
+HtmlLink *HtmlLinks::getLink(int i) const
+{
+ return &(*accu)[i];
}
-
diff --git a/utils/HtmlLinks.h b/utils/HtmlLinks.h
index 78bbb11e..fa4fb2a3 100644
--- a/utils/HtmlLinks.h
+++ b/utils/HtmlLinks.h
@@ -32,45 +32,45 @@
#include <vector>
#include "goo/GooString.h"
-class HtmlLink{
+class HtmlLink
+{
-private:
- double Xmin;
- double Ymin;
- double Xmax;
- double Ymax;
- GooString* dest;
+private:
+ double Xmin;
+ double Ymin;
+ double Xmax;
+ double Ymax;
+ GooString *dest;
public:
- HtmlLink(const HtmlLink& x);
- HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString *_dest);
- ~HtmlLink();
- HtmlLink& operator=(const HtmlLink &) = delete;
- bool isEqualDest(const HtmlLink& x) const;
- GooString *getDest(){return new GooString(dest);}
- double getX1() const {return Xmin;}
- double getX2() const {return Xmax;}
- double getY1() const {return Ymin;}
- double getY2() const {return Ymax;}
- bool inLink(double xmin,double ymin,double xmax,double ymax) const ;
- //GooString *Link(GooString *content);
- GooString* getLinkStart();
-
+ HtmlLink(const HtmlLink &x);
+ HtmlLink(double xmin, double ymin, double xmax, double ymax, GooString *_dest);
+ ~HtmlLink();
+ HtmlLink &operator=(const HtmlLink &) = delete;
+ bool isEqualDest(const HtmlLink &x) const;
+ GooString *getDest() { return new GooString(dest); }
+ double getX1() const { return Xmin; }
+ double getX2() const { return Xmax; }
+ double getY1() const { return Ymin; }
+ double getY2() const { return Ymax; }
+ bool inLink(double xmin, double ymin, double xmax, double ymax) const;
+ // GooString *Link(GooString *content);
+ GooString *getLinkStart();
};
-class HtmlLinks{
+class HtmlLinks
+{
private:
- std::vector<HtmlLink> *accu;
-public:
- HtmlLinks();
- ~HtmlLinks();
- HtmlLinks(const HtmlLinks &) = delete;
- HtmlLinks& operator=(const HtmlLinks &) = delete;
- void AddLink(const HtmlLink& x) {accu->push_back(x);}
- bool inLink(double xmin,double ymin,double xmax,double ymax,int& p) const;
- HtmlLink* getLink(int i) const;
+ std::vector<HtmlLink> *accu;
+public:
+ HtmlLinks();
+ ~HtmlLinks();
+ HtmlLinks(const HtmlLinks &) = delete;
+ HtmlLinks &operator=(const HtmlLinks &) = delete;
+ void AddLink(const HtmlLink &x) { accu->push_back(x); }
+ bool inLink(double xmin, double ymin, double xmax, double ymax, int &p) const;
+ HtmlLink *getLink(int i) const;
};
#endif
-
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index b0f562ad..27a7f11a 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -78,7 +78,7 @@
#include "PDFDoc.h"
#ifdef ENABLE_LIBPNG
-#include <png.h>
+# include <png.h>
#endif
#define DEBUG __FILE__ << ": " << __LINE__ << ": DEBUG: "
@@ -86,22 +86,25 @@
class HtmlImage
{
public:
- HtmlImage(GooString *_fName, GfxState *state)
- : fName(_fName) {
- state->transform(0, 0, &xMin, &yMax);
- state->transform(1, 1, &xMax, &yMin);
- }
- ~HtmlImage() { delete fName; }
- HtmlImage(const HtmlImage &) = delete;
- HtmlImage& operator=(const HtmlImage &) = delete;
+ HtmlImage(GooString *_fName, GfxState *state) : fName(_fName)
+ {
+ state->transform(0, 0, &xMin, &yMax);
+ state->transform(1, 1, &xMax, &yMin);
+ }
+ ~HtmlImage() { delete fName; }
+ HtmlImage(const HtmlImage &) = delete;
+ HtmlImage &operator=(const HtmlImage &) = delete;
- double xMin, xMax; // image x coordinates
- double yMin, yMax; // image y coordinates
- GooString *fName; // image file name
+ double xMin, xMax; // image x coordinates
+ double yMin, yMax; // image y coordinates
+ GooString *fName; // image file name
};
// returns true if x is closer to y than x is to z
-static inline bool IS_CLOSER(float x, float y, float z) { return std::fabs((x)-(y)) < std::fabs((x)-(z)); }
+static inline bool IS_CLOSER(float x, float y, float z)
+{
+ return std::fabs((x) - (y)) < std::fabs((x) - (z));
+}
extern bool complexMode;
extern bool singleHtml;
@@ -130,290 +133,291 @@ static GooString* Dirname(GooString* str){
if (*(p+i)==SLASH)
return new GooString(p,i+1);
return new GooString();
-}
+}
#endif
-static const char *print_matrix(const double *mat) {
- delete gstr_buff0;
+static const char *print_matrix(const double *mat)
+{
+ delete gstr_buff0;
- gstr_buff0 = GooString::format("[{0:g} {1:g} {2:g} {3:g} {4:g} {5:g}]",
- *mat, mat[1], mat[2], mat[3], mat[4], mat[5]);
- return gstr_buff0->c_str();
+ gstr_buff0 = GooString::format("[{0:g} {1:g} {2:g} {3:g} {4:g} {5:g}]", *mat, mat[1], mat[2], mat[3], mat[4], mat[5]);
+ return gstr_buff0->c_str();
}
-static const char *print_uni_str(const Unicode *u, const unsigned uLen) {
- GooString *gstr_buff1 = nullptr;
-
- delete gstr_buff0;
-
- if (!uLen) return "";
- gstr_buff0 = GooString::format("{0:c}", (*u < 0x7F ? *u & 0xFF : '?'));
- for (unsigned i = 1; i < uLen; i++) {
- if (u[i] < 0x7F) {
- gstr_buff1 = gstr_buff0->append(u[i] < 0x7F ? static_cast<char>(u[i]) & 0xFF : '?');
- delete gstr_buff0;
- gstr_buff0 = gstr_buff1;
+static const char *print_uni_str(const Unicode *u, const unsigned uLen)
+{
+ GooString *gstr_buff1 = nullptr;
+
+ delete gstr_buff0;
+
+ if (!uLen)
+ return "";
+ gstr_buff0 = GooString::format("{0:c}", (*u < 0x7F ? *u & 0xFF : '?'));
+ for (unsigned i = 1; i < uLen; i++) {
+ if (u[i] < 0x7F) {
+ gstr_buff1 = gstr_buff0->append(u[i] < 0x7F ? static_cast<char>(u[i]) & 0xFF : '?');
+ delete gstr_buff0;
+ gstr_buff0 = gstr_buff1;
+ }
}
- }
- return gstr_buff0->c_str();
+ return gstr_buff0->c_str();
}
//------------------------------------------------------------------------
// HtmlString
//------------------------------------------------------------------------
-HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu* _fonts) : fonts(_fonts) {
- GfxFont *font;
- double x, y;
-
- state->transform(state->getCurX(), state->getCurY(), &x, &y);
- if ((font = state->getFont())) {
- double ascent = font->getAscent();
- double descent = font->getDescent();
- if( ascent > 1.05 ){
- //printf( "ascent=%.15g is too high, descent=%.15g\n", ascent, descent );
- ascent = 1.05;
- }
- if( descent < -0.4 ){
- //printf( "descent %.15g is too low, ascent=%.15g\n", descent, ascent );
- descent = -0.4;
- }
- yMin = y - ascent * fontSize;
- yMax = y - descent * fontSize;
- GfxRGB rgb;
- state->getFillRGB(&rgb);
- HtmlFont hfont=HtmlFont(font, static_cast<int>(fontSize), rgb);
- if (isMatRotOrSkew(state->getTextMat())) {
- double normalizedMatrix[4];
- memcpy(normalizedMatrix, state->getTextMat(), sizeof(normalizedMatrix));
- // browser rotates the opposite way
- // so flip the sign of the angle -> sin() components change sign
- if (debug)
- std::cerr << DEBUG << "before transform: " << print_matrix(normalizedMatrix) << std::endl;
- normalizedMatrix[1] *= -1;
- normalizedMatrix[2] *= -1;
- if (debug)
- std::cerr << DEBUG << "after reflecting angle: " << print_matrix(normalizedMatrix) << std::endl;
- normalizeRotMat(normalizedMatrix);
- if (debug)
- std::cerr << DEBUG << "after norm: " << print_matrix(normalizedMatrix) << std::endl;
- hfont.setRotMat(normalizedMatrix);
- }
- fontpos = fonts->AddFont(hfont);
- } else {
- // this means that the PDF file draws text without a current font,
- // which should never happen
- yMin = y - 0.95 * fontSize;
- yMax = y + 0.35 * fontSize;
- fontpos=0;
- }
- if (yMin == yMax) {
- // this is a sanity check for a case that shouldn't happen -- but
- // if it does happen, we want to avoid dividing by zero later
- yMin = y;
- yMax = y + 1;
- }
- col = 0;
- text = nullptr;
- xRight = nullptr;
- link = nullptr;
- len = size = 0;
- yxNext = nullptr;
- xyNext = nullptr;
- htext=new GooString();
- dir = textDirUnknown;
+HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu *_fonts) : fonts(_fonts)
+{
+ GfxFont *font;
+ double x, y;
+
+ state->transform(state->getCurX(), state->getCurY(), &x, &y);
+ if ((font = state->getFont())) {
+ double ascent = font->getAscent();
+ double descent = font->getDescent();
+ if (ascent > 1.05) {
+ // printf( "ascent=%.15g is too high, descent=%.15g\n", ascent, descent );
+ ascent = 1.05;
+ }
+ if (descent < -0.4) {
+ // printf( "descent %.15g is too low, ascent=%.15g\n", descent, ascent );
+ descent = -0.4;
+ }
+ yMin = y - ascent * fontSize;
+ yMax = y - descent * fontSize;
+ GfxRGB rgb;
+ state->getFillRGB(&rgb);
+ HtmlFont hfont = HtmlFont(font, static_cast<int>(fontSize), rgb);
+ if (isMatRotOrSkew(state->getTextMat())) {
+ double normalizedMatrix[4];
+ memcpy(normalizedMatrix, state->getTextMat(), sizeof(normalizedMatrix));
+ // browser rotates the opposite way
+ // so flip the sign of the angle -> sin() components change sign
+ if (debug)
+ std::cerr << DEBUG << "before transform: " << print_matrix(normalizedMatrix) << std::endl;
+ normalizedMatrix[1] *= -1;
+ normalizedMatrix[2] *= -1;
+ if (debug)
+ std::cerr << DEBUG << "after reflecting angle: " << print_matrix(normalizedMatrix) << std::endl;
+ normalizeRotMat(normalizedMatrix);
+ if (debug)
+ std::cerr << DEBUG << "after norm: " << print_matrix(normalizedMatrix) << std::endl;
+ hfont.setRotMat(normalizedMatrix);
+ }
+ fontpos = fonts->AddFont(hfont);
+ } else {
+ // this means that the PDF file draws text without a current font,
+ // which should never happen
+ yMin = y - 0.95 * fontSize;
+ yMax = y + 0.35 * fontSize;
+ fontpos = 0;
+ }
+ if (yMin == yMax) {
+ // this is a sanity check for a case that shouldn't happen -- but
+ // if it does happen, we want to avoid dividing by zero later
+ yMin = y;
+ yMax = y + 1;
+ }
+ col = 0;
+ text = nullptr;
+ xRight = nullptr;
+ link = nullptr;
+ len = size = 0;
+ yxNext = nullptr;
+ xyNext = nullptr;
+ htext = new GooString();
+ dir = textDirUnknown;
}
-
-HtmlString::~HtmlString() {
- gfree(text);
- delete htext;
- gfree(xRight);
+HtmlString::~HtmlString()
+{
+ gfree(text);
+ delete htext;
+ gfree(xRight);
}
-void HtmlString::addChar(GfxState *state, double x, double y,
- double dx, double dy, Unicode u) {
- if (dir == textDirUnknown) {
- //dir = UnicodeMap::getDirection(u);
- dir = textDirLeftRight;
- }
-
- if (len == size) {
- size += 16;
- text = (Unicode *)grealloc(text, size * sizeof(Unicode));
- xRight = (double *)grealloc(xRight, size * sizeof(double));
- }
- text[len] = u;
- if (len == 0) {
- xMin = x;
- }
- xMax = xRight[len] = x + dx;
-//printf("added char: %f %f xright = %f\n", x, dx, x+dx);
- ++len;
+void HtmlString::addChar(GfxState *state, double x, double y, double dx, double dy, Unicode u)
+{
+ if (dir == textDirUnknown) {
+ // dir = UnicodeMap::getDirection(u);
+ dir = textDirLeftRight;
+ }
+
+ if (len == size) {
+ size += 16;
+ text = (Unicode *)grealloc(text, size * sizeof(Unicode));
+ xRight = (double *)grealloc(xRight, size * sizeof(double));
+ }
+ text[len] = u;
+ if (len == 0) {
+ xMin = x;
+ }
+ xMax = xRight[len] = x + dx;
+ // printf("added char: %f %f xright = %f\n", x, dx, x+dx);
+ ++len;
}
void HtmlString::endString()
{
- if( dir == textDirRightLeft && len > 1 )
- {
- //printf("will reverse!\n");
- for (int i = 0; i < len / 2; i++)
- {
- Unicode ch = text[i];
- text[i] = text[len - i - 1];
- text[len - i - 1] = ch;
+ if (dir == textDirRightLeft && len > 1) {
+ // printf("will reverse!\n");
+ for (int i = 0; i < len / 2; i++) {
+ Unicode ch = text[i];
+ text[i] = text[len - i - 1];
+ text[len - i - 1] = ch;
+ }
}
- }
}
//------------------------------------------------------------------------
// HtmlPage
//------------------------------------------------------------------------
-HtmlPage::HtmlPage(bool rawOrderA) {
- rawOrder = rawOrderA;
- curStr = nullptr;
- yxStrings = nullptr;
- xyStrings = nullptr;
- yxCur1 = yxCur2 = nullptr;
- fonts=new HtmlFontAccu();
- links=new HtmlLinks();
- imgList=new std::vector<HtmlImage*>();
- pageWidth=0;
- pageHeight=0;
- fontsPageMarker = 0;
- DocName=nullptr;
- firstPage = -1;
+HtmlPage::HtmlPage(bool rawOrderA)
+{
+ rawOrder = rawOrderA;
+ curStr = nullptr;
+ yxStrings = nullptr;
+ xyStrings = nullptr;
+ yxCur1 = yxCur2 = nullptr;
+ fonts = new HtmlFontAccu();
+ links = new HtmlLinks();
+ imgList = new std::vector<HtmlImage *>();
+ pageWidth = 0;
+ pageHeight = 0;
+ fontsPageMarker = 0;
+ DocName = nullptr;
+ firstPage = -1;
}
-HtmlPage::~HtmlPage() {
- clear();
- delete DocName;
- delete fonts;
- delete links;
- for (auto entry : *imgList) {
- delete entry;
- }
- delete imgList;
+HtmlPage::~HtmlPage()
+{
+ clear();
+ delete DocName;
+ delete fonts;
+ delete links;
+ for (auto entry : *imgList) {
+ delete entry;
+ }
+ delete imgList;
}
-void HtmlPage::updateFont(GfxState *state) {
- GfxFont *font;
- const char *name;
- int code;
- double w;
-
- // adjust the font size
- fontSize = state->getTransformedFontSize();
- if ((font = state->getFont()) && font->getType() == fontType3) {
- // This is a hack which makes it possible to deal with some Type 3
- // fonts. The problem is that it's impossible to know what the
- // base coordinate system used in the font is without actually
- // rendering the font. This code tries to guess by looking at the
- // width of the character 'm' (which breaks if the font is a
- // subset that doesn't contain 'm').
- for (code = 0; code < 256; ++code) {
- if ((name = ((Gfx8BitFont *)font)->getCharName(code)) &&
- name[0] == 'm' && name[1] == '\0') {
- break;
- }
- }
- if (code < 256) {
- w = ((Gfx8BitFont *)font)->getWidth(code);
- if (w != 0) {
- // 600 is a generic average 'm' width -- yes, this is a hack
- fontSize *= w / 0.6;
- }
- }
- const double *fm = font->getFontMatrix();
- if (fm[0] != 0) {
- fontSize *= fabs(fm[3] / fm[0]);
+void HtmlPage::updateFont(GfxState *state)
+{
+ GfxFont *font;
+ const char *name;
+ int code;
+ double w;
+
+ // adjust the font size
+ fontSize = state->getTransformedFontSize();
+ if ((font = state->getFont()) && font->getType() == fontType3) {
+ // This is a hack which makes it possible to deal with some Type 3
+ // fonts. The problem is that it's impossible to know what the
+ // base coordinate system used in the font is without actually
+ // rendering the font. This code tries to guess by looking at the
+ // width of the character 'm' (which breaks if the font is a
+ // subset that doesn't contain 'm').
+ for (code = 0; code < 256; ++code) {
+ if ((name = ((Gfx8BitFont *)font)->getCharName(code)) && name[0] == 'm' && name[1] == '\0') {
+ break;
+ }
+ }
+ if (code < 256) {
+ w = ((Gfx8BitFont *)font)->getWidth(code);
+ if (w != 0) {
+ // 600 is a generic average 'm' width -- yes, this is a hack
+ fontSize *= w / 0.6;
+ }
+ }
+ const double *fm = font->getFontMatrix();
+ if (fm[0] != 0) {
+ fontSize *= fabs(fm[3] / fm[0]);
+ }
}
- }
}
-void HtmlPage::beginString(GfxState *state, const GooString *s) {
- curStr = new HtmlString(state, fontSize, fonts);
+void HtmlPage::beginString(GfxState *state, const GooString *s)
+{
+ curStr = new HtmlString(state, fontSize, fonts);
}
+void HtmlPage::conv()
+{
+ for (HtmlString *tmp = yxStrings; tmp; tmp = tmp->yxNext) {
+ delete tmp->htext;
+ tmp->htext = HtmlFont::HtmlFilter(tmp->text, tmp->len);
-void HtmlPage::conv(){
- for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){
- delete tmp->htext;
- tmp->htext=HtmlFont::HtmlFilter(tmp->text,tmp->len);
-
- int linkIndex = 0;
- if (links->inLink(tmp->xMin,tmp->yMin,tmp->xMax,tmp->yMax, linkIndex)){
- tmp->link = links->getLink(linkIndex);
- }
- }
+ int linkIndex = 0;
+ if (links->inLink(tmp->xMin, tmp->yMin, tmp->xMax, tmp->yMax, linkIndex)) {
+ tmp->link = links->getLink(linkIndex);
+ }
+ }
}
-
-void HtmlPage::addChar(GfxState *state, double x, double y,
- double dx, double dy,
- double ox, double oy, const Unicode *u, int uLen) {
- double x1, y1, w1, h1, dx2, dy2;
- int n, i;
- state->transform(x, y, &x1, &y1);
- n = curStr->len;
-
- // check that new character is in the same direction as current string
- // and is not too far away from it before adding
- //if ((UnicodeMap::getDirection(u[0]) != curStr->dir) ||
- // XXX
- if (debug) {
- const double *text_mat = state->getTextMat();
- // rotation is (cos q, sin q, -sin q, cos q, 0, 0)
- // sin q is zero iff there is no rotation, or 180 deg. rotation;
- // for 180 rotation, cos q will be negative
- if (text_mat[0] < 0 || !is_within(text_mat[1], .1, 0)) {
- std::cerr << DEBUG << "rotation matrix for \"" << print_uni_str(u, uLen) << '"' << std::endl;
- std::cerr << "text " << print_matrix(state->getTextMat());
+void HtmlPage::addChar(GfxState *state, double x, double y, double dx, double dy, double ox, double oy, const Unicode *u, int uLen)
+{
+ double x1, y1, w1, h1, dx2, dy2;
+ int n, i;
+ state->transform(x, y, &x1, &y1);
+ n = curStr->len;
+
+ // check that new character is in the same direction as current string
+ // and is not too far away from it before adding
+ // if ((UnicodeMap::getDirection(u[0]) != curStr->dir) ||
+ // XXX
+ if (debug) {
+ const double *text_mat = state->getTextMat();
+ // rotation is (cos q, sin q, -sin q, cos q, 0, 0)
+ // sin q is zero iff there is no rotation, or 180 deg. rotation;
+ // for 180 rotation, cos q will be negative
+ if (text_mat[0] < 0 || !is_within(text_mat[1], .1, 0)) {
+ std::cerr << DEBUG << "rotation matrix for \"" << print_uni_str(u, uLen) << '"' << std::endl;
+ std::cerr << "text " << print_matrix(state->getTextMat());
+ }
+ }
+ if (n > 0 && // don't start a new string, unless there is already a string
+ // TODO: the following line assumes that text is flowing left to
+ // right, which will not necessarily be the case, e.g. if rotated;
+ // It assesses whether or not two characters are close enough to
+ // be part of the same string
+ fabs(x1 - curStr->xRight[n - 1]) > wordBreakThreshold * (curStr->yMax - curStr->yMin) &&
+ // rotation is (cos q, sin q, -sin q, cos q, 0, 0)
+ // sin q is zero iff there is no rotation, or 180 deg. rotation;
+ // for 180 rotation, cos q will be negative
+ !rot_matrices_equal(curStr->getFont().getRotMat(), state->getTextMat())) {
+ endString();
+ beginString(state, nullptr);
+ }
+ state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(), 0, &dx2, &dy2);
+ dx -= dx2;
+ dy -= dy2;
+ state->transformDelta(dx, dy, &w1, &h1);
+ if (uLen != 0) {
+ w1 /= uLen;
+ h1 /= uLen;
+ }
+ for (i = 0; i < uLen; ++i) {
+ curStr->addChar(state, x1 + i * w1, y1 + i * h1, w1, h1, u[i]);
}
- }
- if (n > 0 && // don't start a new string, unless there is already a string
- // TODO: the following line assumes that text is flowing left to
- // right, which will not necessarily be the case, e.g. if rotated;
- // It assesses whether or not two characters are close enough to
- // be part of the same string
- fabs(x1 - curStr->xRight[n-1]) > wordBreakThreshold * (curStr->yMax - curStr->yMin) &&
- // rotation is (cos q, sin q, -sin q, cos q, 0, 0)
- // sin q is zero iff there is no rotation, or 180 deg. rotation;
- // for 180 rotation, cos q will be negative
- !rot_matrices_equal(curStr->getFont().getRotMat(), state->getTextMat()))
- {
- endString();
- beginString(state, nullptr);
- }
- state->textTransformDelta(state->getCharSpace() * state->getHorizScaling(),
- 0, &dx2, &dy2);
- dx -= dx2;
- dy -= dy2;
- state->transformDelta(dx, dy, &w1, &h1);
- if (uLen != 0) {
- w1 /= uLen;
- h1 /= uLen;
- }
- for (i = 0; i < uLen; ++i) {
- curStr->addChar(state, x1 + i*w1, y1 + i*h1, w1, h1, u[i]);
- }
}
-void HtmlPage::endString() {
- HtmlString *p1, *p2;
- double h, y1, y2;
-
- // throw away zero-length strings -- they don't have valid xMin/xMax
- // values, and they're useless anyway
- if (curStr->len == 0) {
- delete curStr;
- curStr = nullptr;
- return;
- }
+void HtmlPage::endString()
+{
+ HtmlString *p1, *p2;
+ double h, y1, y2;
+
+ // throw away zero-length strings -- they don't have valid xMin/xMax
+ // values, and they're useless anyway
+ if (curStr->len == 0) {
+ delete curStr;
+ curStr = nullptr;
+ return;
+ }
- curStr->endString();
+ curStr->endString();
#if 0 //~tmp
if (curStr->yMax - curStr->yMin > 20) {
@@ -423,76 +427,72 @@ void HtmlPage::endString() {
}
#endif
- // insert string in y-major list
- h = curStr->yMax - curStr->yMin;
- y1 = curStr->yMin + 0.5 * h;
- y2 = curStr->yMin + 0.8 * h;
- if (rawOrder) {
- p1 = yxCur1;
- p2 = nullptr;
- } else if ((!yxCur1 ||
- (y1 >= yxCur1->yMin &&
- (y2 >= yxCur1->yMax || curStr->xMax >= yxCur1->xMin))) &&
- (!yxCur2 ||
- (y1 < yxCur2->yMin ||
- (y2 < yxCur2->yMax && curStr->xMax < yxCur2->xMin)))) {
- p1 = yxCur1;
- p2 = yxCur2;
- } else {
- for (p1 = nullptr, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) {
- if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin))
- break;
- }
- yxCur2 = p2;
- }
- yxCur1 = curStr;
- if (p1)
- p1->yxNext = curStr;
- else
- yxStrings = curStr;
- curStr->yxNext = p2;
- curStr = nullptr;
+ // insert string in y-major list
+ h = curStr->yMax - curStr->yMin;
+ y1 = curStr->yMin + 0.5 * h;
+ y2 = curStr->yMin + 0.8 * h;
+ if (rawOrder) {
+ p1 = yxCur1;
+ p2 = nullptr;
+ } else if ((!yxCur1 || (y1 >= yxCur1->yMin && (y2 >= yxCur1->yMax || curStr->xMax >= yxCur1->xMin))) && (!yxCur2 || (y1 < yxCur2->yMin || (y2 < yxCur2->yMax && curStr->xMax < yxCur2->xMin)))) {
+ p1 = yxCur1;
+ p2 = yxCur2;
+ } else {
+ for (p1 = nullptr, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) {
+ if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin))
+ break;
+ }
+ yxCur2 = p2;
+ }
+ yxCur1 = curStr;
+ if (p1)
+ p1->yxNext = curStr;
+ else
+ yxStrings = curStr;
+ curStr->yxNext = p2;
+ curStr = nullptr;
}
-static const char *strrstr( const char *s, const char *ss )
+static const char *strrstr(const char *s, const char *ss)
{
- const char *p = strstr( s, ss );
- for( const char *pp = p; pp != nullptr; pp = strstr( p+1, ss ) ){
- p = pp;
- }
- return p;
+ const char *p = strstr(s, ss);
+ for (const char *pp = p; pp != nullptr; pp = strstr(p + 1, ss)) {
+ p = pp;
+ }
+ return p;
}
-static void CloseTags( GooString *htext, bool &finish_a, bool &finish_italic, bool &finish_bold )
+static void CloseTags(GooString *htext, bool &finish_a, bool &finish_italic, bool &finish_bold)
{
- const char *last_italic = finish_italic && ( finish_bold || finish_a ) ? strrstr( htext->c_str(), "<i>" ) : nullptr;
- const char *last_bold = finish_bold && ( finish_italic || finish_a ) ? strrstr( htext->c_str(), "<b>" ) : nullptr;
- const char *last_a = finish_a && ( finish_italic || finish_bold ) ? strrstr( htext->c_str(), "<a " ) : nullptr;
- if( finish_a && ( finish_italic || finish_bold ) && last_a > ( last_italic > last_bold ? last_italic : last_bold ) ){
- htext->append("</a>", 4);
- finish_a = false;
- }
- if( finish_italic && finish_bold && last_italic > last_bold ){
- htext->append("</i>", 4);
- finish_italic = false;
- }
- if( finish_bold )
- htext->append("</b>", 4);
- if( finish_italic )
- htext->append("</i>", 4);
- if( finish_a )
- htext->append("</a>");
+ const char *last_italic = finish_italic && (finish_bold || finish_a) ? strrstr(htext->c_str(), "<i>") : nullptr;
+ const char *last_bold = finish_bold && (finish_italic || finish_a) ? strrstr(htext->c_str(), "<b>") : nullptr;
+ const char *last_a = finish_a && (finish_italic || finish_bold) ? strrstr(htext->c_str(), "<a ") : nullptr;
+ if (finish_a && (finish_italic || finish_bold) && last_a > (last_italic > last_bold ? last_italic : last_bold)) {
+ htext->append("</a>", 4);
+ finish_a = false;
+ }
+ if (finish_italic && finish_bold && last_italic > last_bold) {
+ htext->append("</i>", 4);
+ finish_italic = false;
+ }
+ if (finish_bold)
+ htext->append("</b>", 4);
+ if (finish_italic)
+ htext->append("</i>", 4);
+ if (finish_a)
+ htext->append("</a>");
}
// Strings are lines of text;
// This function aims to combine strings into lines and paragraphs if !noMerge
// It may also strip out duplicate strings (if they are on top of each other); sometimes they are to create a font effect
-void HtmlPage::coalesce() {
- HtmlString *str1, *str2;
- double space, horSpace, vertSpace, vertOverlap;
- bool addSpace, addLineBreak;
- int n, i;
- double curX, curY;
+void HtmlPage::coalesce()
+{
+ HtmlString *str1, *str2;
+ double space, horSpace, vertSpace, vertOverlap;
+ bool addSpace, addLineBreak;
+ int n, i;
+ double curX, curY;
#if 0 //~ for debugging
for (str1 = yxStrings; str1; str1 = str1->yxNext) {
@@ -506,216 +506,189 @@ void HtmlPage::coalesce() {
}
printf("\n------------------------------------------------------------\n\n");
#endif
- str1 = yxStrings;
-
- if( !str1 ) return;
-
- //----- discard duplicated text (fake boldface, drop shadows)
- if( !complexMode )
- { /* if not in complex mode get rid of duplicate strings */
- HtmlString *str3;
- bool found;
- while (str1)
- {
- double size = str1->yMax - str1->yMin;
- double xLimit = str1->xMin + size * 0.2;
- found = false;
- for (str2 = str1, str3 = str1->yxNext;
- str3 && str3->xMin < xLimit;
- str2 = str3, str3 = str2->yxNext)
- {
- if (str3->len == str1->len &&
- !memcmp(str3->text, str1->text, str1->len * sizeof(Unicode)) &&
- fabs(str3->yMin - str1->yMin) < size * 0.2 &&
- fabs(str3->yMax - str1->yMax) < size * 0.2 &&
- fabs(str3->xMax - str1->xMax) < size * 0.2)
- {
- found = true;
- //printf("found duplicate!\n");
- break;
- }
- }
- if (found)
- {
- str2->xyNext = str3->xyNext;
- str2->yxNext = str3->yxNext;
- delete str3;
- }
- else
- {
- str1 = str1->yxNext;
- }
- }
- } /*- !complexMode */
-
- str1 = yxStrings;
-
- const HtmlFont *hfont1 = getFont(str1);
- if( hfont1->isBold() )
- str1->htext->insert(0,"<b>",3);
- if( hfont1->isItalic() )
- str1->htext->insert(0,"<i>",3);
- if( str1->getLink() != nullptr ) {
- GooString *ls = str1->getLink()->getLinkStart();
- str1->htext->insert(0, ls);
- delete ls;
- }
- curX = str1->xMin; curY = str1->yMin;
-
- while (str1 && (str2 = str1->yxNext)) {
- const HtmlFont *hfont2 = getFont(str2);
- space = str1->yMax - str1->yMin; // the height of the font's bounding box
- horSpace = str2->xMin - str1->xMax;
- // if strings line up on left-hand side AND they are on subsequent lines, we need a line break
- addLineBreak = !noMerge && (fabs(str1->xMin - str2->xMin) < 0.4) && IS_CLOSER(str2->yMax, str1->yMax + space, str1->yMax);
- vertSpace = str2->yMin - str1->yMax;
-
-//printf("coalesce %d %d %f? ", str1->dir, str2->dir, d);
+ str1 = yxStrings;
- if (str2->yMin >= str1->yMin && str2->yMin <= str1->yMax)
- {
- vertOverlap = str1->yMax - str2->yMin;
- } else
- if (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax)
- {
- vertOverlap = str2->yMax - str1->yMin;
- } else
- {
- vertOverlap = 0;
- }
-
- // Combine strings if:
- // They appear to be the same font (complex mode only) && going in the same direction AND at least one of the following:
- // 1. They appear to be part of the same line of text
- // 2. They appear to be subsequent lines of a paragraph
- // We assume (1) or (2) above, respectively, based on:
- // (1) strings overlap vertically AND
- // horizontal space between end of str1 and start of str2 is consistent with a single space or less;
- // when rawOrder, the strings have to overlap vertically by at least 50%
- // (2) Strings flow down the page, but the space between them is not too great, and they are lined up on the left
- if (
- (
- (
- (
- (rawOrder && vertOverlap > 0.5 * space)
- ||
- (!rawOrder && str2->yMin < str1->yMax)
- ) &&
- (horSpace > -0.5 * space && horSpace < space)
- ) ||
- (vertSpace >= 0 && vertSpace < 0.5 * space && addLineBreak)
- ) &&
- (!complexMode || (hfont1->isEqualIgnoreBold(*hfont2))) && // in complex mode fonts must be the same, in other modes fonts do not metter
- str1->dir == str2->dir // text direction the same
- )
- {
-// printf("yes\n");
- n = str1->len + str2->len;
- if ((addSpace = horSpace > wordBreakThreshold * space)) {
- ++n;
- }
- if (addLineBreak) {
- ++n;
- }
-
- str1->size = (n + 15) & ~15;
- str1->text = (Unicode *)grealloc(str1->text,
- str1->size * sizeof(Unicode));
- str1->xRight = (double *)grealloc(str1->xRight,
- str1->size * sizeof(double));
- if (addSpace) {
- str1->text[str1->len] = 0x20;
- str1->htext->append(xml?" ":"&#160;");
- str1->xRight[str1->len] = str2->xMin;
- ++str1->len;
- }
- if (addLineBreak) {
- str1->text[str1->len] = '\n';
- str1->htext->append("<br/>");
- str1->xRight[str1->len] = str2->xMin;
- ++str1->len;
- str1->yMin = str2->yMin;
- str1->yMax = str2->yMax;
- str1->xMax = str2->xMax;
- int fontLineSize = hfont1->getLineSize();
- int curLineSize = (int)(vertSpace + space);
- if( curLineSize != fontLineSize )
- {
- HtmlFont *newfnt = new HtmlFont(*hfont1);
- newfnt->setLineSize(curLineSize);
- str1->fontpos = fonts->AddFont(*newfnt);
- delete newfnt;
- hfont1 = getFont(str1);
- // we have to reget hfont2 because it's location could have
- // changed on resize
- hfont2 = getFont(str2);
- }
- }
- for (i = 0; i < str2->len; ++i) {
- str1->text[str1->len] = str2->text[i];
- str1->xRight[str1->len] = str2->xRight[i];
- ++str1->len;
- }
+ if (!str1)
+ return;
- /* fix <i>, <b> if str1 and str2 differ and handle switch of links */
- HtmlLink *hlink1 = str1->getLink();
- HtmlLink *hlink2 = str2->getLink();
- bool switch_links = !hlink1 || !hlink2 || !hlink1->isEqualDest(*hlink2);
- bool finish_a = switch_links && hlink1 != nullptr;
- bool finish_italic = hfont1->isItalic() && ( !hfont2->isItalic() || finish_a );
- bool finish_bold = hfont1->isBold() && ( !hfont2->isBold() || finish_a || finish_italic );
- CloseTags( str1->htext, finish_a, finish_italic, finish_bold );
- if( switch_links && hlink2 != nullptr ) {
- GooString *ls = hlink2->getLinkStart();
- str1->htext->append(ls);
+ //----- discard duplicated text (fake boldface, drop shadows)
+ if (!complexMode) { /* if not in complex mode get rid of duplicate strings */
+ HtmlString *str3;
+ bool found;
+ while (str1) {
+ double size = str1->yMax - str1->yMin;
+ double xLimit = str1->xMin + size * 0.2;
+ found = false;
+ for (str2 = str1, str3 = str1->yxNext; str3 && str3->xMin < xLimit; str2 = str3, str3 = str2->yxNext) {
+ if (str3->len == str1->len && !memcmp(str3->text, str1->text, str1->len * sizeof(Unicode)) && fabs(str3->yMin - str1->yMin) < size * 0.2 && fabs(str3->yMax - str1->yMax) < size * 0.2
+ && fabs(str3->xMax - str1->xMax) < size * 0.2) {
+ found = true;
+ // printf("found duplicate!\n");
+ break;
+ }
+ }
+ if (found) {
+ str2->xyNext = str3->xyNext;
+ str2->yxNext = str3->yxNext;
+ delete str3;
+ } else {
+ str1 = str1->yxNext;
+ }
+ }
+ } /*- !complexMode */
+
+ str1 = yxStrings;
+
+ const HtmlFont *hfont1 = getFont(str1);
+ if (hfont1->isBold())
+ str1->htext->insert(0, "<b>", 3);
+ if (hfont1->isItalic())
+ str1->htext->insert(0, "<i>", 3);
+ if (str1->getLink() != nullptr) {
+ GooString *ls = str1->getLink()->getLinkStart();
+ str1->htext->insert(0, ls);
delete ls;
- }
- if( ( !hfont1->isItalic() || finish_italic ) && hfont2->isItalic() )
- str1->htext->append("<i>", 3);
- if( ( !hfont1->isBold() || finish_bold ) && hfont2->isBold() )
- str1->htext->append("<b>", 3);
-
-
- str1->htext->append(str2->htext);
- // str1 now contains href for link of str2 (if it is defined)
- str1->link = str2->link;
- hfont1 = hfont2;
- if (str2->xMax > str1->xMax) {
- str1->xMax = str2->xMax;
- }
- if (str2->yMax > str1->yMax) {
- str1->yMax = str2->yMax;
- }
- str1->yxNext = str2->yxNext;
- delete str2;
- } else { // keep strings separate
-// printf("no\n");
- bool finish_a = str1->getLink() != nullptr;
- bool finish_bold = hfont1->isBold();
- bool finish_italic = hfont1->isItalic();
- CloseTags( str1->htext, finish_a, finish_italic, finish_bold );
-
- str1->xMin = curX; str1->yMin = curY;
- str1 = str2;
- curX = str1->xMin; curY = str1->yMin;
- hfont1 = hfont2;
- if( hfont1->isBold() )
- str1->htext->insert(0,"<b>",3);
- if( hfont1->isItalic() )
- str1->htext->insert(0,"<i>",3);
- if( str1->getLink() != nullptr ) {
- GooString *ls = str1->getLink()->getLinkStart();
- str1->htext->insert(0, ls);
- delete ls;
- }
}
- }
- str1->xMin = curX; str1->yMin = curY;
+ curX = str1->xMin;
+ curY = str1->yMin;
+
+ while (str1 && (str2 = str1->yxNext)) {
+ const HtmlFont *hfont2 = getFont(str2);
+ space = str1->yMax - str1->yMin; // the height of the font's bounding box
+ horSpace = str2->xMin - str1->xMax;
+ // if strings line up on left-hand side AND they are on subsequent lines, we need a line break
+ addLineBreak = !noMerge && (fabs(str1->xMin - str2->xMin) < 0.4) && IS_CLOSER(str2->yMax, str1->yMax + space, str1->yMax);
+ vertSpace = str2->yMin - str1->yMax;
+
+ // printf("coalesce %d %d %f? ", str1->dir, str2->dir, d);
+
+ if (str2->yMin >= str1->yMin && str2->yMin <= str1->yMax) {
+ vertOverlap = str1->yMax - str2->yMin;
+ } else if (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax) {
+ vertOverlap = str2->yMax - str1->yMin;
+ } else {
+ vertOverlap = 0;
+ }
- bool finish_bold = hfont1->isBold();
- bool finish_italic = hfont1->isItalic();
- bool finish_a = str1->getLink() != nullptr;
- CloseTags( str1->htext, finish_a, finish_italic, finish_bold );
+ // Combine strings if:
+ // They appear to be the same font (complex mode only) && going in the same direction AND at least one of the following:
+ // 1. They appear to be part of the same line of text
+ // 2. They appear to be subsequent lines of a paragraph
+ // We assume (1) or (2) above, respectively, based on:
+ // (1) strings overlap vertically AND
+ // horizontal space between end of str1 and start of str2 is consistent with a single space or less;
+ // when rawOrder, the strings have to overlap vertically by at least 50%
+ // (2) Strings flow down the page, but the space between them is not too great, and they are lined up on the left
+ if (((((rawOrder && vertOverlap > 0.5 * space) || (!rawOrder && str2->yMin < str1->yMax)) && (horSpace > -0.5 * space && horSpace < space)) || (vertSpace >= 0 && vertSpace < 0.5 * space && addLineBreak))
+ && (!complexMode || (hfont1->isEqualIgnoreBold(*hfont2))) && // in complex mode fonts must be the same, in other modes fonts do not metter
+ str1->dir == str2->dir // text direction the same
+ ) {
+ // printf("yes\n");
+ n = str1->len + str2->len;
+ if ((addSpace = horSpace > wordBreakThreshold * space)) {
+ ++n;
+ }
+ if (addLineBreak) {
+ ++n;
+ }
+
+ str1->size = (n + 15) & ~15;
+ str1->text = (Unicode *)grealloc(str1->text, str1->size * sizeof(Unicode));
+ str1->xRight = (double *)grealloc(str1->xRight, str1->size * sizeof(double));
+ if (addSpace) {
+ str1->text[str1->len] = 0x20;
+ str1->htext->append(xml ? " " : "&#160;");
+ str1->xRight[str1->len] = str2->xMin;
+ ++str1->len;
+ }
+ if (addLineBreak) {
+ str1->text[str1->len] = '\n';
+ str1->htext->append("<br/>");
+ str1->xRight[str1->len] = str2->xMin;
+ ++str1->len;
+ str1->yMin = str2->yMin;
+ str1->yMax = str2->yMax;
+ str1->xMax = str2->xMax;
+ int fontLineSize = hfont1->getLineSize();
+ int curLineSize = (int)(vertSpace + space);
+ if (curLineSize != fontLineSize) {
+ HtmlFont *newfnt = new HtmlFont(*hfont1);
+ newfnt->setLineSize(curLineSize);
+ str1->fontpos = fonts->AddFont(*newfnt);
+ delete newfnt;
+ hfont1 = getFont(str1);
+ // we have to reget hfont2 because it's location could have
+ // changed on resize
+ hfont2 = getFont(str2);
+ }
+ }
+ for (i = 0; i < str2->len; ++i) {
+ str1->text[str1->len] = str2->text[i];
+ str1->xRight[str1->len] = str2->xRight[i];
+ ++str1->len;
+ }
+
+ /* fix <i>, <b> if str1 and str2 differ and handle switch of links */
+ HtmlLink *hlink1 = str1->getLink();
+ HtmlLink *hlink2 = str2->getLink();
+ bool switch_links = !hlink1 || !hlink2 || !hlink1->isEqualDest(*hlink2);
+ bool finish_a = switch_links && hlink1 != nullptr;
+ bool finish_italic = hfont1->isItalic() && (!hfont2->isItalic() || finish_a);
+ bool finish_bold = hfont1->isBold() && (!hfont2->isBold() || finish_a || finish_italic);
+ CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
+ if (switch_links && hlink2 != nullptr) {
+ GooString *ls = hlink2->getLinkStart();
+ str1->htext->append(ls);
+ delete ls;
+ }
+ if ((!hfont1->isItalic() || finish_italic) && hfont2->isItalic())
+ str1->htext->append("<i>", 3);
+ if ((!hfont1->isBold() || finish_bold) && hfont2->isBold())
+ str1->htext->append("<b>", 3);
+
+ str1->htext->append(str2->htext);
+ // str1 now contains href for link of str2 (if it is defined)
+ str1->link = str2->link;
+ hfont1 = hfont2;
+ if (str2->xMax > str1->xMax) {
+ str1->xMax = str2->xMax;
+ }
+ if (str2->yMax > str1->yMax) {
+ str1->yMax = str2->yMax;
+ }
+ str1->yxNext = str2->yxNext;
+ delete str2;
+ } else { // keep strings separate
+ // printf("no\n");
+ bool finish_a = str1->getLink() != nullptr;
+ bool finish_bold = hfont1->isBold();
+ bool finish_italic = hfont1->isItalic();
+ CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
+
+ str1->xMin = curX;
+ str1->yMin = curY;
+ str1 = str2;
+ curX = str1->xMin;
+ curY = str1->yMin;
+ hfont1 = hfont2;
+ if (hfont1->isBold())
+ str1->htext->insert(0, "<b>", 3);
+ if (hfont1->isItalic())
+ str1->htext->insert(0, "<i>", 3);
+ if (str1->getLink() != nullptr) {
+ GooString *ls = str1->getLink()->getLinkStart();
+ str1->htext->insert(0, ls);
+ delete ls;
+ }
+ }
+ }
+ str1->xMin = curX;
+ str1->yMin = curY;
+
+ bool finish_bold = hfont1->isBold();
+ bool finish_italic = hfont1->isItalic();
+ bool finish_a = str1->getLink() != nullptr;
+ CloseTags(str1->htext, finish_a, finish_italic, finish_bold);
#if 0 //~ for debugging
for (str1 = yxStrings; str1; str1 = str1->yxNext) {
@@ -726,270 +699,282 @@ void HtmlPage::coalesce() {
}
printf("\n------------------------------------------------------------\n\n");
#endif
-
}
-void HtmlPage::dumpAsXML(FILE* f,int page){
- fprintf(f, "<page number=\"%d\" position=\"absolute\"", page);
- fprintf(f," top=\"0\" left=\"0\" height=\"%d\" width=\"%d\">\n", pageHeight,pageWidth);
-
- for(int i=fontsPageMarker;i < fonts->size();i++) {
- GooString *fontCSStyle = fonts->CSStyle(i);
- fprintf(f,"\t%s\n",fontCSStyle->c_str());
- delete fontCSStyle;
- }
+void HtmlPage::dumpAsXML(FILE *f, int page)
+{
+ fprintf(f, "<page number=\"%d\" position=\"absolute\"", page);
+ fprintf(f, " top=\"0\" left=\"0\" height=\"%d\" width=\"%d\">\n", pageHeight, pageWidth);
- for (auto ptr : *imgList) {
- auto img = static_cast<HtmlImage *>(ptr);
- if (!noRoundedCoordinates) {
- fprintf(f, "<image top=\"%d\" left=\"%d\" ", xoutRound(img->yMin), xoutRound(img->xMin));
- fprintf(f, "width=\"%d\" height=\"%d\" ", xoutRound(img->xMax - img->xMin), xoutRound(img->yMax - img->yMin));
+ for (int i = fontsPageMarker; i < fonts->size(); i++) {
+ GooString *fontCSStyle = fonts->CSStyle(i);
+ fprintf(f, "\t%s\n", fontCSStyle->c_str());
+ delete fontCSStyle;
}
- else {
- fprintf(f, "<image top=\"%f\" left=\"%f\" ", img->yMin, img->xMin);
- fprintf(f, "width=\"%f\" height=\"%f\" ", img->xMax - img->xMin, img->yMax - img->yMin);
+
+ for (auto ptr : *imgList) {
+ auto img = static_cast<HtmlImage *>(ptr);
+ if (!noRoundedCoordinates) {
+ fprintf(f, "<image top=\"%d\" left=\"%d\" ", xoutRound(img->yMin), xoutRound(img->xMin));
+ fprintf(f, "width=\"%d\" height=\"%d\" ", xoutRound(img->xMax - img->xMin), xoutRound(img->yMax - img->yMin));
+ } else {
+ fprintf(f, "<image top=\"%f\" left=\"%f\" ", img->yMin, img->xMin);
+ fprintf(f, "width=\"%f\" height=\"%f\" ", img->xMax - img->xMin, img->yMax - img->yMin);
+ }
+ fprintf(f, "src=\"%s\"/>\n", img->fName->c_str());
+ delete img;
}
- fprintf(f,"src=\"%s\"/>\n",img->fName->c_str());
- delete img;
- }
- imgList->clear();
+ imgList->clear();
- for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){
- if (tmp->htext){
- if (!noRoundedCoordinates) {
- fprintf(f, "<text top=\"%d\" left=\"%d\" ", xoutRound(tmp->yMin), xoutRound(tmp->xMin));
- fprintf(f, "width=\"%d\" height=\"%d\" ", xoutRound(tmp->xMax - tmp->xMin), xoutRound(tmp->yMax - tmp->yMin));
- }
- else {
- fprintf(f, "<text top=\"%f\" left=\"%f\" ", tmp->yMin, tmp->xMin);
- fprintf(f, "width=\"%f\" height=\"%f\" ", tmp->xMax - tmp->xMin, tmp->yMax - tmp->yMin);
- }
- fprintf(f,"font=\"%d\">", tmp->fontpos);
- fputs(tmp->htext->c_str(),f);
- fputs("</text>\n",f);
+ for (HtmlString *tmp = yxStrings; tmp; tmp = tmp->yxNext) {
+ if (tmp->htext) {
+ if (!noRoundedCoordinates) {
+ fprintf(f, "<text top=\"%d\" left=\"%d\" ", xoutRound(tmp->yMin), xoutRound(tmp->xMin));
+ fprintf(f, "width=\"%d\" height=\"%d\" ", xoutRound(tmp->xMax - tmp->xMin), xoutRound(tmp->yMax - tmp->yMin));
+ } else {
+ fprintf(f, "<text top=\"%f\" left=\"%f\" ", tmp->yMin, tmp->xMin);
+ fprintf(f, "width=\"%f\" height=\"%f\" ", tmp->xMax - tmp->xMin, tmp->yMax - tmp->yMin);
+ }
+ fprintf(f, "font=\"%d\">", tmp->fontpos);
+ fputs(tmp->htext->c_str(), f);
+ fputs("</text>\n", f);
+ }
}
- }
- fputs("</page>\n",f);
+ fputs("</page>\n", f);
}
static void printCSS(FILE *f)
{
- // Image flip/flop CSS
- // Source:
- // http://stackoverflow.com/questions/1309055/cross-browser-way-to-flip-html-image-via-javascript-css
- // tested in Chrome, Fx (Linux) and IE9 (W7)
- static const char css[] =
- "<style type=\"text/css\">" "\n"
- "<!--" "\n"
- ".xflip {" "\n"
- " -moz-transform: scaleX(-1);" "\n"
- " -webkit-transform: scaleX(-1);" "\n"
- " -o-transform: scaleX(-1);" "\n"
- " transform: scaleX(-1);" "\n"
- " filter: fliph;" "\n"
- "}" "\n"
- ".yflip {" "\n"
- " -moz-transform: scaleY(-1);" "\n"
- " -webkit-transform: scaleY(-1);" "\n"
- " -o-transform: scaleY(-1);" "\n"
- " transform: scaleY(-1);" "\n"
- " filter: flipv;" "\n"
- "}" "\n"
- ".xyflip {" "\n"
- " -moz-transform: scaleX(-1) scaleY(-1);" "\n"
- " -webkit-transform: scaleX(-1) scaleY(-1);" "\n"
- " -o-transform: scaleX(-1) scaleY(-1);" "\n"
- " transform: scaleX(-1) scaleY(-1);" "\n"
- " filter: fliph + flipv;" "\n"
- "}" "\n"
- "-->" "\n"
- "</style>" "\n";
-
- fwrite( css, sizeof(css)-1, 1, f );
+ // Image flip/flop CSS
+ // Source:
+ // http://stackoverflow.com/questions/1309055/cross-browser-way-to-flip-html-image-via-javascript-css
+ // tested in Chrome, Fx (Linux) and IE9 (W7)
+ static const char css[] = "<style type=\"text/css\">"
+ "\n"
+ "<!--"
+ "\n"
+ ".xflip {"
+ "\n"
+ " -moz-transform: scaleX(-1);"
+ "\n"
+ " -webkit-transform: scaleX(-1);"
+ "\n"
+ " -o-transform: scaleX(-1);"
+ "\n"
+ " transform: scaleX(-1);"
+ "\n"
+ " filter: fliph;"
+ "\n"
+ "}"
+ "\n"
+ ".yflip {"
+ "\n"
+ " -moz-transform: scaleY(-1);"
+ "\n"
+ " -webkit-transform: scaleY(-1);"
+ "\n"
+ " -o-transform: scaleY(-1);"
+ "\n"
+ " transform: scaleY(-1);"
+ "\n"
+ " filter: flipv;"
+ "\n"
+ "}"
+ "\n"
+ ".xyflip {"
+ "\n"
+ " -moz-transform: scaleX(-1) scaleY(-1);"
+ "\n"
+ " -webkit-transform: scaleX(-1) scaleY(-1);"
+ "\n"
+ " -o-transform: scaleX(-1) scaleY(-1);"
+ "\n"
+ " transform: scaleX(-1) scaleY(-1);"
+ "\n"
+ " filter: fliph + flipv;"
+ "\n"
+ "}"
+ "\n"
+ "-->"
+ "\n"
+ "</style>"
+ "\n";
+
+ fwrite(css, sizeof(css) - 1, 1, f);
}
-int HtmlPage::dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page) {
+int HtmlPage::dumpComplexHeaders(FILE *const file, FILE *&pageFile, int page)
+{
- if( !noframes )
- {
- const std::string pgNum = std::to_string(page);
- std::string pageFileName(DocName->toStr());
- if (!singleHtml){
+ if (!noframes) {
+ const std::string pgNum = std::to_string(page);
+ std::string pageFileName(DocName->toStr());
+ if (!singleHtml) {
pageFileName += '-' + pgNum + ".html";
pageFile = fopen(pageFileName.c_str(), "w");
- } else {
+ } else {
pageFileName += "-html.html";
pageFile = fopen(pageFileName.c_str(), "a");
- }
+ }
- if (!pageFile) {
- error(errIO, -1, "Couldn't open html file '{0:t}'", pageFileName.c_str());
- return 1;
- }
-
- if (!singleHtml)
- fprintf(pageFile,"%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>Page %d</title>\n\n", DOCTYPE, page);
- else
- fprintf(pageFile,"%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>%s</title>\n\n", DOCTYPE, pageFileName.c_str());
-
- const std::string htmlEncoding = HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName());
- if (!singleHtml)
- fprintf(pageFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
- else
- fprintf(pageFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n <br/>\n", htmlEncoding.c_str());
- }
- else
- {
- pageFile = file;
- fprintf(pageFile,"<!-- Page %d -->\n", page);
- fprintf(pageFile,"<a name=\"%d\"></a>\n", page);
- }
-
- return 0;
-}
+ if (!pageFile) {
+ error(errIO, -1, "Couldn't open html file '{0:t}'", pageFileName.c_str());
+ return 1;
+ }
-void HtmlPage::dumpComplex(FILE *file, int page, const std::vector<std::string>& backgroundImages) {
- FILE* pageFile;
+ if (!singleHtml)
+ fprintf(pageFile, "%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>Page %d</title>\n\n", DOCTYPE, page);
+ else
+ fprintf(pageFile, "%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>%s</title>\n\n", DOCTYPE, pageFileName.c_str());
- if( firstPage == -1 ) firstPage = page;
-
- if (dumpComplexHeaders(file, pageFile, page)) { error(errIO, -1, "Couldn't write headers."); return; }
-
- fputs("<style type=\"text/css\">\n<!--\n",pageFile);
- fputs("\tp {margin: 0; padding: 0;}",pageFile);
- for(int i=fontsPageMarker;i!=fonts->size();i++) {
- GooString *fontCSStyle;
- if (!singleHtml)
- fontCSStyle = fonts->CSStyle(i);
- else
- fontCSStyle = fonts->CSStyle(i,page);
- fprintf(pageFile,"\t%s\n",fontCSStyle->c_str());
- delete fontCSStyle;
- }
-
- fputs("-->\n</style>\n",pageFile);
-
- if( !noframes )
- {
- fputs("</head>\n<body bgcolor=\"#A0A0A0\" vlink=\"blue\" link=\"blue\">\n",pageFile);
- }
-
- fprintf(pageFile,"<div id=\"page%d-div\" style=\"position:relative;width:%dpx;height:%dpx;\">\n",
- page, pageWidth, pageHeight);
-
- if(!ignore && (size_t) (page - firstPage) < backgroundImages.size())
- {
- fprintf(pageFile,
- "<img width=\"%d\" height=\"%d\" src=\"%s\" alt=\"background image\"/>\n",
- pageWidth, pageHeight, backgroundImages[page - firstPage].c_str());
- }
-
- for(HtmlString *tmp1=yxStrings;tmp1;tmp1=tmp1->yxNext){
- if (tmp1->htext){
- fprintf(pageFile,
- "<p style=\"position:absolute;top:%dpx;left:%dpx;white-space:nowrap\" class=\"ft",
- xoutRound(tmp1->yMin),
- xoutRound(tmp1->xMin));
- if (!singleHtml) {
- fputc('0', pageFile);
- } else {
- fprintf(pageFile, "%d", page);
- }
- fprintf(pageFile,"%d\">", tmp1->fontpos);
- fputs(tmp1->htext->c_str(), pageFile);
- fputs("</p>\n", pageFile);
+ const std::string htmlEncoding = HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName());
+ if (!singleHtml)
+ fprintf(pageFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
+ else
+ fprintf(pageFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n <br/>\n", htmlEncoding.c_str());
+ } else {
+ pageFile = file;
+ fprintf(pageFile, "<!-- Page %d -->\n", page);
+ fprintf(pageFile, "<a name=\"%d\"></a>\n", page);
}
- }
- fputs("</div>\n", pageFile);
-
- if( !noframes )
- {
- fputs("</body>\n</html>\n",pageFile);
- fclose(pageFile);
- }
+ return 0;
}
-
-void HtmlPage::dump(FILE *f, int pageNum, const std::vector<std::string>& backgroundImages)
+void HtmlPage::dumpComplex(FILE *file, int page, const std::vector<std::string> &backgroundImages)
{
- if (complexMode || singleHtml)
- {
- if (xml) dumpAsXML(f, pageNum);
- if (!xml) dumpComplex(f, pageNum, backgroundImages);
- }
- else
- {
- fprintf(f,"<a name=%d></a>",pageNum);
- // Loop over the list of image names on this page
- for (auto ptr : *imgList) {
- auto img = static_cast<HtmlImage *>(ptr);
+ FILE *pageFile;
- // see printCSS() for class names
- const char *styles[4] = { "", " class=\"xflip\"", " class=\"yflip\"", " class=\"xyflip\"" };
- int style_index=0;
- if (img->xMin > img->xMax) style_index += 1; // xFlip
- if (img->yMin > img->yMax) style_index += 2; // yFlip
+ if (firstPage == -1)
+ firstPage = page;
- fprintf(f,"<img%s src=\"%s\"/><br/>\n",styles[style_index],img->fName->c_str());
- delete img;
+ if (dumpComplexHeaders(file, pageFile, page)) {
+ error(errIO, -1, "Couldn't write headers.");
+ return;
}
- imgList->clear();
- GooString* str;
- for(HtmlString *tmp=yxStrings;tmp;tmp=tmp->yxNext){
- if (tmp->htext){
- str=new GooString(tmp->htext);
- fputs(str->c_str(),f);
- delete str;
- fputs("<br/>\n",f);
- }
+ fputs("<style type=\"text/css\">\n<!--\n", pageFile);
+ fputs("\tp {margin: 0; padding: 0;}", pageFile);
+ for (int i = fontsPageMarker; i != fonts->size(); i++) {
+ GooString *fontCSStyle;
+ if (!singleHtml)
+ fontCSStyle = fonts->CSStyle(i);
+ else
+ fontCSStyle = fonts->CSStyle(i, page);
+ fprintf(pageFile, "\t%s\n", fontCSStyle->c_str());
+ delete fontCSStyle;
}
- fputs("<hr/>\n",f);
- }
-}
+ fputs("-->\n</style>\n", pageFile);
+ if (!noframes) {
+ fputs("</head>\n<body bgcolor=\"#A0A0A0\" vlink=\"blue\" link=\"blue\">\n", pageFile);
+ }
-void HtmlPage::clear() {
- HtmlString *p1, *p2;
+ fprintf(pageFile, "<div id=\"page%d-div\" style=\"position:relative;width:%dpx;height:%dpx;\">\n", page, pageWidth, pageHeight);
- if (curStr) {
- delete curStr;
- curStr = nullptr;
- }
- for (p1 = yxStrings; p1; p1 = p2) {
- p2 = p1->yxNext;
- delete p1;
- }
- yxStrings = nullptr;
- xyStrings = nullptr;
- yxCur1 = yxCur2 = nullptr;
-
- if( !noframes )
- {
- delete fonts;
- fonts=new HtmlFontAccu();
- fontsPageMarker = 0;
- }
- else
- {
- fontsPageMarker = fonts->size();
- }
+ if (!ignore && (size_t)(page - firstPage) < backgroundImages.size()) {
+ fprintf(pageFile, "<img width=\"%d\" height=\"%d\" src=\"%s\" alt=\"background image\"/>\n", pageWidth, pageHeight, backgroundImages[page - firstPage].c_str());
+ }
+
+ for (HtmlString *tmp1 = yxStrings; tmp1; tmp1 = tmp1->yxNext) {
+ if (tmp1->htext) {
+ fprintf(pageFile, "<p style=\"position:absolute;top:%dpx;left:%dpx;white-space:nowrap\" class=\"ft", xoutRound(tmp1->yMin), xoutRound(tmp1->xMin));
+ if (!singleHtml) {
+ fputc('0', pageFile);
+ } else {
+ fprintf(pageFile, "%d", page);
+ }
+ fprintf(pageFile, "%d\">", tmp1->fontpos);
+ fputs(tmp1->htext->c_str(), pageFile);
+ fputs("</p>\n", pageFile);
+ }
+ }
+
+ fputs("</div>\n", pageFile);
+
+ if (!noframes) {
+ fputs("</body>\n</html>\n", pageFile);
+ fclose(pageFile);
+ }
+}
+
+void HtmlPage::dump(FILE *f, int pageNum, const std::vector<std::string> &backgroundImages)
+{
+ if (complexMode || singleHtml) {
+ if (xml)
+ dumpAsXML(f, pageNum);
+ if (!xml)
+ dumpComplex(f, pageNum, backgroundImages);
+ } else {
+ fprintf(f, "<a name=%d></a>", pageNum);
+ // Loop over the list of image names on this page
+ for (auto ptr : *imgList) {
+ auto img = static_cast<HtmlImage *>(ptr);
+
+ // see printCSS() for class names
+ const char *styles[4] = { "", " class=\"xflip\"", " class=\"yflip\"", " class=\"xyflip\"" };
+ int style_index = 0;
+ if (img->xMin > img->xMax)
+ style_index += 1; // xFlip
+ if (img->yMin > img->yMax)
+ style_index += 2; // yFlip
+
+ fprintf(f, "<img%s src=\"%s\"/><br/>\n", styles[style_index], img->fName->c_str());
+ delete img;
+ }
+ imgList->clear();
+
+ GooString *str;
+ for (HtmlString *tmp = yxStrings; tmp; tmp = tmp->yxNext) {
+ if (tmp->htext) {
+ str = new GooString(tmp->htext);
+ fputs(str->c_str(), f);
+ delete str;
+ fputs("<br/>\n", f);
+ }
+ }
+ fputs("<hr/>\n", f);
+ }
+}
- delete links;
- links=new HtmlLinks();
-
+void HtmlPage::clear()
+{
+ HtmlString *p1, *p2;
+
+ if (curStr) {
+ delete curStr;
+ curStr = nullptr;
+ }
+ for (p1 = yxStrings; p1; p1 = p2) {
+ p2 = p1->yxNext;
+ delete p1;
+ }
+ yxStrings = nullptr;
+ xyStrings = nullptr;
+ yxCur1 = yxCur2 = nullptr;
+
+ if (!noframes) {
+ delete fonts;
+ fonts = new HtmlFontAccu();
+ fontsPageMarker = 0;
+ } else {
+ fontsPageMarker = fonts->size();
+ }
+ delete links;
+ links = new HtmlLinks();
}
-void HtmlPage::setDocName(const char *fname){
- DocName=new GooString(fname);
+void HtmlPage::setDocName(const char *fname)
+{
+ DocName = new GooString(fname);
}
-void HtmlPage::addImage(GooString *fname, GfxState *state) {
- HtmlImage *img = new HtmlImage(fname, state);
- imgList->push_back(img);
+void HtmlPage::addImage(GooString *fname, GfxState *state)
+{
+ HtmlImage *img = new HtmlImage(fname, state);
+ imgList->push_back(img);
}
//------------------------------------------------------------------------
@@ -1004,11 +989,11 @@ HtmlMetaVar::HtmlMetaVar(const char *_name, const char *_content)
HtmlMetaVar::~HtmlMetaVar()
{
- delete name;
- delete content;
-}
-
-GooString* HtmlMetaVar::toString() const
+ delete name;
+ delete content;
+}
+
+GooString *HtmlMetaVar::toString() const
{
GooString *result = new GooString("<meta name=\"");
result->append(name);
@@ -1022,201 +1007,192 @@ GooString* HtmlMetaVar::toString() const
// HtmlOutputDev
//------------------------------------------------------------------------
-static const char* HtmlEncodings[][2] = {
- {"Latin1", "ISO-8859-1"},
- {nullptr, nullptr}
-};
+static const char *HtmlEncodings[][2] = { { "Latin1", "ISO-8859-1" }, { nullptr, nullptr } };
std::string HtmlOutputDev::mapEncodingToHtml(const std::string &encoding)
{
- for(int i = 0; HtmlEncodings[i][0] != nullptr; i++)
- {
- if( encoding == HtmlEncodings[i][0] )
- {
- return HtmlEncodings[i][1];
+ for (int i = 0; HtmlEncodings[i][0] != nullptr; i++) {
+ if (encoding == HtmlEncodings[i][0]) {
+ return HtmlEncodings[i][1];
+ }
}
- }
- return encoding;
+ return encoding;
}
-void HtmlOutputDev::doFrame(int firstPage){
- GooString* fName=new GooString(Docname);
- fName->append(".html");
+void HtmlOutputDev::doFrame(int firstPage)
+{
+ GooString *fName = new GooString(Docname);
+ fName->append(".html");
+
+ if (!(fContentsFrame = fopen(fName->c_str(), "w"))) {
+ error(errIO, -1, "Couldn't open html file '{0:t}'", fName);
+ delete fName;
+ return;
+ }
- if (!(fContentsFrame = fopen(fName->c_str(), "w"))){
- error(errIO, -1, "Couldn't open html file '{0:t}'", fName);
delete fName;
- return;
- }
-
- delete fName;
-
- const std::string baseName = gbasename(Docname->c_str());
- fputs(DOCTYPE, fContentsFrame);
- fputs("\n<html>",fContentsFrame);
- fputs("\n<head>",fContentsFrame);
- fprintf(fContentsFrame,"\n<title>%s</title>",docTitle->c_str());
- const std::string htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName());
- fprintf(fContentsFrame, "\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
- dumpMetaVars(fContentsFrame);
- fprintf(fContentsFrame, "</head>\n");
- fputs("<frameset cols=\"100,*\">\n",fContentsFrame);
- fprintf(fContentsFrame,"<frame name=\"links\" src=\"%s_ind.html\"/>\n", baseName.c_str());
- fputs("<frame name=\"contents\" src=",fContentsFrame);
- if (complexMode)
- fprintf(fContentsFrame,"\"%s-%d.html\"", baseName.c_str(), firstPage);
- else
- fprintf(fContentsFrame,"\"%ss.html\"", baseName.c_str());
-
- fputs("/>\n</frameset>\n</html>\n",fContentsFrame);
-
- fclose(fContentsFrame);
+
+ const std::string baseName = gbasename(Docname->c_str());
+ fputs(DOCTYPE, fContentsFrame);
+ fputs("\n<html>", fContentsFrame);
+ fputs("\n<head>", fContentsFrame);
+ fprintf(fContentsFrame, "\n<title>%s</title>", docTitle->c_str());
+ const std::string htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName());
+ fprintf(fContentsFrame, "\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
+ dumpMetaVars(fContentsFrame);
+ fprintf(fContentsFrame, "</head>\n");
+ fputs("<frameset cols=\"100,*\">\n", fContentsFrame);
+ fprintf(fContentsFrame, "<frame name=\"links\" src=\"%s_ind.html\"/>\n", baseName.c_str());
+ fputs("<frame name=\"contents\" src=", fContentsFrame);
+ if (complexMode)
+ fprintf(fContentsFrame, "\"%s-%d.html\"", baseName.c_str(), firstPage);
+ else
+ fprintf(fContentsFrame, "\"%ss.html\"", baseName.c_str());
+
+ fputs("/>\n</frameset>\n</html>\n", fContentsFrame);
+
+ fclose(fContentsFrame);
}
-HtmlOutputDev::HtmlOutputDev(Catalog *catalogA, const char *fileName, const char *title,
- const char *author, const char *keywords, const char *subject, const char *date,
- bool rawOrderA, int firstPage, bool outline)
+HtmlOutputDev::HtmlOutputDev(Catalog *catalogA, const char *fileName, const char *title, const char *author, const char *keywords, const char *subject, const char *date, bool rawOrderA, int firstPage, bool outline)
{
- catalog = catalogA;
- fContentsFrame = nullptr;
- page = nullptr;
- docTitle = new GooString(title);
- pages = nullptr;
- dumpJPEG=true;
- //write = true;
- rawOrder = rawOrderA;
- this->doOutline = outline;
- ok = false;
- //this->firstPage = firstPage;
- //pageNum=firstPage;
- // open file
- needClose = false;
- pages = new HtmlPage(rawOrder);
-
- glMetaVars = new std::vector<HtmlMetaVar*>();
- glMetaVars->push_back(new HtmlMetaVar("generator", "pdftohtml 0.36"));
- if( author ) glMetaVars->push_back(new HtmlMetaVar("author", author));
- if( keywords ) glMetaVars->push_back(new HtmlMetaVar("keywords", keywords));
- if( date ) glMetaVars->push_back(new HtmlMetaVar("date", date));
- if( subject ) glMetaVars->push_back(new HtmlMetaVar("subject", subject));
-
- maxPageWidth = 0;
- maxPageHeight = 0;
-
- pages->setDocName(fileName);
- Docname=new GooString (fileName);
-
- // for non-xml output (complex or simple) with frames generate the left frame
- if(!xml && !noframes)
- {
- if (!singleHtml)
- {
- GooString* left=new GooString(fileName);
- left->append("_ind.html");
-
- doFrame(firstPage);
-
- if (!(fContentsFrame = fopen(left->c_str(), "w")))
- {
- error(errIO, -1, "Couldn't open html file '{0:t}'", left);
- delete left;
- return;
- }
- delete left;
- fputs(DOCTYPE, fContentsFrame);
- fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title></title>\n</head>\n<body>\n", fContentsFrame);
-
- if (doOutline)
- {
- fprintf(fContentsFrame, "<a href=\"%s%s\" target=\"contents\">Outline</a><br/>",
- gbasename(Docname->c_str()).c_str(),
- complexMode ? "-outline.html" : "s.html#outline");
- }
- }
- if (!complexMode)
- { /* not in complex mode */
-
- GooString* right=new GooString(fileName);
- right->append("s.html");
-
- if (!(page=fopen(right->c_str(),"w"))){
- error(errIO, -1, "Couldn't open html file '{0:t}'", right);
- delete right;
- return;
- }
- delete right;
- fputs(DOCTYPE, page);
- fputs("<html>\n<head>\n<title></title>\n",page);
- printCSS(page);
- fputs("</head>\n<body>\n",page);
- }
- }
-
- if (noframes) {
- if (stout) page=stdout;
- else {
- GooString* right=new GooString(fileName);
- if (!xml) right->append(".html");
- if (xml) right->append(".xml");
- if (!(page=fopen(right->c_str(),"w"))){
- error(errIO, -1, "Couldn't open html file '{0:t}'", right);
- delete right;
- return;
- }
- delete right;
+ catalog = catalogA;
+ fContentsFrame = nullptr;
+ page = nullptr;
+ docTitle = new GooString(title);
+ pages = nullptr;
+ dumpJPEG = true;
+ // write = true;
+ rawOrder = rawOrderA;
+ this->doOutline = outline;
+ ok = false;
+ // this->firstPage = firstPage;
+ // pageNum=firstPage;
+ // open file
+ needClose = false;
+ pages = new HtmlPage(rawOrder);
+
+ glMetaVars = new std::vector<HtmlMetaVar *>();
+ glMetaVars->push_back(new HtmlMetaVar("generator", "pdftohtml 0.36"));
+ if (author)
+ glMetaVars->push_back(new HtmlMetaVar("author", author));
+ if (keywords)
+ glMetaVars->push_back(new HtmlMetaVar("keywords", keywords));
+ if (date)
+ glMetaVars->push_back(new HtmlMetaVar("date", date));
+ if (subject)
+ glMetaVars->push_back(new HtmlMetaVar("subject", subject));
+
+ maxPageWidth = 0;
+ maxPageHeight = 0;
+
+ pages->setDocName(fileName);
+ Docname = new GooString(fileName);
+
+ // for non-xml output (complex or simple) with frames generate the left frame
+ if (!xml && !noframes) {
+ if (!singleHtml) {
+ GooString *left = new GooString(fileName);
+ left->append("_ind.html");
+
+ doFrame(firstPage);
+
+ if (!(fContentsFrame = fopen(left->c_str(), "w"))) {
+ error(errIO, -1, "Couldn't open html file '{0:t}'", left);
+ delete left;
+ return;
+ }
+ delete left;
+ fputs(DOCTYPE, fContentsFrame);
+ fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title></title>\n</head>\n<body>\n", fContentsFrame);
+
+ if (doOutline) {
+ fprintf(fContentsFrame, "<a href=\"%s%s\" target=\"contents\">Outline</a><br/>", gbasename(Docname->c_str()).c_str(), complexMode ? "-outline.html" : "s.html#outline");
+ }
+ }
+ if (!complexMode) { /* not in complex mode */
+
+ GooString *right = new GooString(fileName);
+ right->append("s.html");
+
+ if (!(page = fopen(right->c_str(), "w"))) {
+ error(errIO, -1, "Couldn't open html file '{0:t}'", right);
+ delete right;
+ return;
+ }
+ delete right;
+ fputs(DOCTYPE, page);
+ fputs("<html>\n<head>\n<title></title>\n", page);
+ printCSS(page);
+ fputs("</head>\n<body>\n", page);
+ }
}
- const std::string htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName());
- if (xml)
- {
- fprintf(page, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", htmlEncoding.c_str());
- fputs("<!DOCTYPE pdf2xml SYSTEM \"pdf2xml.dtd\">\n\n", page);
- fprintf(page,"<pdf2xml producer=\"%s\" version=\"%s\">\n", PACKAGE_NAME, PACKAGE_VERSION);
- }
- else
- {
- fprintf(page,"%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>%s</title>\n", DOCTYPE, docTitle->c_str());
-
- fprintf(page, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
-
- dumpMetaVars(page);
- printCSS(page);
- fprintf(page,"</head>\n");
- fprintf(page,"<body bgcolor=\"#A0A0A0\" vlink=\"blue\" link=\"blue\">\n");
+ if (noframes) {
+ if (stout)
+ page = stdout;
+ else {
+ GooString *right = new GooString(fileName);
+ if (!xml)
+ right->append(".html");
+ if (xml)
+ right->append(".xml");
+ if (!(page = fopen(right->c_str(), "w"))) {
+ error(errIO, -1, "Couldn't open html file '{0:t}'", right);
+ delete right;
+ return;
+ }
+ delete right;
+ }
+
+ const std::string htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName());
+ if (xml) {
+ fprintf(page, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", htmlEncoding.c_str());
+ fputs("<!DOCTYPE pdf2xml SYSTEM \"pdf2xml.dtd\">\n\n", page);
+ fprintf(page, "<pdf2xml producer=\"%s\" version=\"%s\">\n", PACKAGE_NAME, PACKAGE_VERSION);
+ } else {
+ fprintf(page, "%s\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<head>\n<title>%s</title>\n", DOCTYPE, docTitle->c_str());
+
+ fprintf(page, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding.c_str());
+
+ dumpMetaVars(page);
+ printCSS(page);
+ fprintf(page, "</head>\n");
+ fprintf(page, "<body bgcolor=\"#A0A0A0\" vlink=\"blue\" link=\"blue\">\n");
+ }
}
- }
- ok = true;
+ ok = true;
}
-HtmlOutputDev::~HtmlOutputDev() {
+HtmlOutputDev::~HtmlOutputDev()
+{
delete Docname;
delete docTitle;
for (auto entry : *glMetaVars) {
- delete entry;
+ delete entry;
}
delete glMetaVars;
- if (fContentsFrame){
- fputs("</body>\n</html>\n",fContentsFrame);
- fclose(fContentsFrame);
+ if (fContentsFrame) {
+ fputs("</body>\n</html>\n", fContentsFrame);
+ fclose(fContentsFrame);
}
if (page != nullptr) {
- if (xml) {
- fputs("</pdf2xml>\n",page);
- fclose(page);
- } else
- if ( !complexMode || xml || noframes )
- {
- fputs("</body>\n</html>\n",page);
- fclose(page);
- }
+ if (xml) {
+ fputs("</pdf2xml>\n", page);
+ fclose(page);
+ } else if (!complexMode || xml || noframes) {
+ fputs("</body>\n</html>\n", page);
+ fclose(page);
+ }
}
if (pages)
- delete pages;
+ delete pages;
}
-void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref) {
+void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref)
+{
#if 0
if (mode&&!xml){
if (write){
@@ -1236,610 +1212,568 @@ void HtmlOutputDev::startPage(int pageNumA, GfxState *state, XRef *xref) {
}
#endif
- pageNum = pageNumA;
- const std::string str = gbasename(Docname->c_str());
- pages->clear();
- if(!noframes)
- {
- if (fContentsFrame)
- {
- if (complexMode)
- fprintf(fContentsFrame,"<a href=\"%s-%d.html\"", str.c_str(), pageNum);
- else
- fprintf(fContentsFrame,"<a href=\"%ss.html#%d\"", str.c_str(), pageNum);
- fprintf(fContentsFrame," target=\"contents\" >Page %d</a><br/>\n",pageNum);
+ pageNum = pageNumA;
+ const std::string str = gbasename(Docname->c_str());
+ pages->clear();
+ if (!noframes) {
+ if (fContentsFrame) {
+ if (complexMode)
+ fprintf(fContentsFrame, "<a href=\"%s-%d.html\"", str.c_str(), pageNum);
+ else
+ fprintf(fContentsFrame, "<a href=\"%ss.html#%d\"", str.c_str(), pageNum);
+ fprintf(fContentsFrame, " target=\"contents\" >Page %d</a><br/>\n", pageNum);
+ }
}
- }
- pages->pageWidth=static_cast<int>(state->getPageWidth());
- pages->pageHeight=static_cast<int>(state->getPageHeight());
-}
+ pages->pageWidth = static_cast<int>(state->getPageWidth());
+ pages->pageHeight = static_cast<int>(state->getPageHeight());
+}
+
+void HtmlOutputDev::endPage()
+{
+ Links *linksList = docPage->getLinks();
+ for (int i = 0; i < linksList->getNumLinks(); ++i) {
+ doProcessLink(linksList->getLink(i));
+ }
+ delete linksList;
+ pages->conv();
+ pages->coalesce();
+ pages->dump(page, pageNum, backgroundImages);
-void HtmlOutputDev::endPage() {
- Links *linksList = docPage->getLinks();
- for (int i = 0; i < linksList->getNumLinks(); ++i)
- {
- doProcessLink(linksList->getLink(i));
- }
- delete linksList;
+ // I don't yet know what to do in the case when there are pages of different
+ // sizes and we want complex output: running ghostscript many times
+ // seems very inefficient. So for now I'll just use last page's size
+ maxPageWidth = pages->pageWidth;
+ maxPageHeight = pages->pageHeight;
- pages->conv();
- pages->coalesce();
- pages->dump(page, pageNum, backgroundImages);
-
- // I don't yet know what to do in the case when there are pages of different
- // sizes and we want complex output: running ghostscript many times
- // seems very inefficient. So for now I'll just use last page's size
- maxPageWidth = pages->pageWidth;
- maxPageHeight = pages->pageHeight;
-
- //if(!noframes&&!xml) fputs("<br/>\n", fContentsFrame);
- if(!stout && !globalParams->getErrQuiet()) printf("Page-%d\n",(pageNum));
+ // if(!noframes&&!xml) fputs("<br/>\n", fContentsFrame);
+ if (!stout && !globalParams->getErrQuiet())
+ printf("Page-%d\n", (pageNum));
}
-void HtmlOutputDev::addBackgroundImage(const std::string& img) {
- backgroundImages.push_back(img);
+void HtmlOutputDev::addBackgroundImage(const std::string &img)
+{
+ backgroundImages.push_back(img);
}
-void HtmlOutputDev::updateFont(GfxState *state) {
- pages->updateFont(state);
+void HtmlOutputDev::updateFont(GfxState *state)
+{
+ pages->updateFont(state);
}
-void HtmlOutputDev::beginString(GfxState *state, const GooString *s) {
- pages->beginString(state, s);
+void HtmlOutputDev::beginString(GfxState *state, const GooString *s)
+{
+ pages->beginString(state, s);
}
-void HtmlOutputDev::endString(GfxState *state) {
- pages->endString();
+void HtmlOutputDev::endString(GfxState *state)
+{
+ pages->endString();
}
-void HtmlOutputDev::drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, int /*nBytes*/, const Unicode *u, int uLen)
+void HtmlOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int /*nBytes*/, const Unicode *u, int uLen)
{
- if ( !showHidden && (state->getRender() & 3) == 3) {
- return;
- }
- pages->addChar(state, x, y, dx, dy, originX, originY, u, uLen);
+ if (!showHidden && (state->getRender() & 3) == 3) {
+ return;
+ }
+ pages->addChar(state, x, y, dx, dy, originX, originY, u, uLen);
}
void HtmlOutputDev::drawJpegImage(GfxState *state, Stream *str)
{
- InMemoryFile ims;
- FILE *f1 = nullptr;
- int c;
-
- // open the image file
- GooString *fName = createImageFileName("jpg");
- f1 = dataUrls ? ims.open("wb") : fopen(fName->c_str(), "wb");
- if (!f1) {
- error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
- delete fName;
- return;
- }
+ InMemoryFile ims;
+ FILE *f1 = nullptr;
+ int c;
+
+ // open the image file
+ GooString *fName = createImageFileName("jpg");
+ f1 = dataUrls ? ims.open("wb") : fopen(fName->c_str(), "wb");
+ if (!f1) {
+ error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
+ delete fName;
+ return;
+ }
- // initialize stream
- str = str->getNextStream();
- str->reset();
+ // initialize stream
+ str = str->getNextStream();
+ str->reset();
- // copy the stream
- while ((c = str->getChar()) != EOF)
- fputc(c, f1);
+ // copy the stream
+ while ((c = str->getChar()) != EOF)
+ fputc(c, f1);
- fclose(f1);
+ fclose(f1);
- if (dataUrls) {
- delete fName;
- fName = new GooString(std::string("data:image/jpeg;base64,") + gbase64Encode(ims.getBuffer()));
- }
- pages->addImage(fName, state);
+ if (dataUrls) {
+ delete fName;
+ fName = new GooString(std::string("data:image/jpeg;base64,") + gbase64Encode(ims.getBuffer()));
+ }
+ pages->addImage(fName, state);
}
-void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int height,
- GfxImageColorMap *colorMap, bool isMask)
+void HtmlOutputDev::drawPngImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool isMask)
{
#ifdef ENABLE_LIBPNG
- FILE *f1;
- InMemoryFile ims;
-
- if (!colorMap && !isMask) {
- error(errInternal, -1, "Can't have color image without a color map");
- return;
- }
-
- // open the image file
- GooString *fName=createImageFileName("png");
- f1 = dataUrls ? ims.open("wb") : fopen(fName->c_str(), "wb");
- if (!f1) {
- error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
- delete fName;
- return;
- }
+ FILE *f1;
+ InMemoryFile ims;
- PNGWriter *writer = new PNGWriter( isMask ? PNGWriter::MONOCHROME : PNGWriter::RGB );
- // TODO can we calculate the resolution of the image?
- if (!writer->init(f1, width, height, 72, 72)) {
- error(errInternal, -1, "Can't init PNG for image '{0:t}'", fName);
- delete writer;
- fclose(f1);
- return;
- }
-
- if (!isMask) {
- unsigned char *p;
- GfxRGB rgb;
- png_byte *row = (png_byte *) gmalloc(3 * width); // 3 bytes/pixel: RGB
- png_bytep *row_pointer= &row;
-
- // Initialize the image stream
- ImageStream *imgStr = new ImageStream(str, width,
- colorMap->getNumPixelComps(), colorMap->getBits());
- imgStr->reset();
-
- // For each line...
- for (int y = 0; y < height; y++) {
+ if (!colorMap && !isMask) {
+ error(errInternal, -1, "Can't have color image without a color map");
+ return;
+ }
- // Convert into a PNG row
- p = imgStr->getLine();
- if (!p) {
- error(errIO, -1, "Failed to read PNG. '{0:t}' will be incorrect", fName);
+ // open the image file
+ GooString *fName = createImageFileName("png");
+ f1 = dataUrls ? ims.open("wb") : fopen(fName->c_str(), "wb");
+ if (!f1) {
+ error(errIO, -1, "Couldn't open image file '{0:t}'", fName);
delete fName;
- gfree(row);
- delete writer;
- delete imgStr;
- fclose(f1);
return;
- }
- for (int x = 0; x < width; x++) {
- colorMap->getRGB(p, &rgb);
- // Write the RGB pixels into the row
- row[3*x]= colToByte(rgb.r);
- row[3*x+1]= colToByte(rgb.g);
- row[3*x+2]= colToByte(rgb.b);
- p += colorMap->getNumPixelComps();
- }
+ }
- if (!writer->writeRow(row_pointer)) {
- error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
+ PNGWriter *writer = new PNGWriter(isMask ? PNGWriter::MONOCHROME : PNGWriter::RGB);
+ // TODO can we calculate the resolution of the image?
+ if (!writer->init(f1, width, height, 72, 72)) {
+ error(errInternal, -1, "Can't init PNG for image '{0:t}'", fName);
delete writer;
- delete imgStr;
fclose(f1);
return;
- }
- }
- gfree(row);
- imgStr->close();
- delete imgStr;
- }
- else { // isMask == true
- int size = (width + 7)/8;
-
- // PDF masks use 0 = draw current color, 1 = leave unchanged.
- // We invert this to provide the standard interpretation of alpha
- // (0 = transparent, 1 = opaque). If the colorMap already inverts
- // the mask we leave the data unchanged.
- int invert_bits = 0xff;
- if (colorMap) {
- GfxGray gray;
- unsigned char zero[gfxColorMaxComps];
- memset(zero, 0, sizeof(zero));
- colorMap->getGray(zero, &gray);
- if (colToByte(gray) == 0)
- invert_bits = 0x00;
}
- str->reset();
- unsigned char *png_row = (unsigned char *)gmalloc(size);
+ if (!isMask) {
+ unsigned char *p;
+ GfxRGB rgb;
+ png_byte *row = (png_byte *)gmalloc(3 * width); // 3 bytes/pixel: RGB
+ png_bytep *row_pointer = &row;
+
+ // Initialize the image stream
+ ImageStream *imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
+ imgStr->reset();
+
+ // For each line...
+ for (int y = 0; y < height; y++) {
+
+ // Convert into a PNG row
+ p = imgStr->getLine();
+ if (!p) {
+ error(errIO, -1, "Failed to read PNG. '{0:t}' will be incorrect", fName);
+ delete fName;
+ gfree(row);
+ delete writer;
+ delete imgStr;
+ fclose(f1);
+ return;
+ }
+ for (int x = 0; x < width; x++) {
+ colorMap->getRGB(p, &rgb);
+ // Write the RGB pixels into the row
+ row[3 * x] = colToByte(rgb.r);
+ row[3 * x + 1] = colToByte(rgb.g);
+ row[3 * x + 2] = colToByte(rgb.b);
+ p += colorMap->getNumPixelComps();
+ }
+
+ if (!writer->writeRow(row_pointer)) {
+ error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
+ delete writer;
+ delete imgStr;
+ fclose(f1);
+ return;
+ }
+ }
+ gfree(row);
+ imgStr->close();
+ delete imgStr;
+ } else { // isMask == true
+ int size = (width + 7) / 8;
+
+ // PDF masks use 0 = draw current color, 1 = leave unchanged.
+ // We invert this to provide the standard interpretation of alpha
+ // (0 = transparent, 1 = opaque). If the colorMap already inverts
+ // the mask we leave the data unchanged.
+ int invert_bits = 0xff;
+ if (colorMap) {
+ GfxGray gray;
+ unsigned char zero[gfxColorMaxComps];
+ memset(zero, 0, sizeof(zero));
+ colorMap->getGray(zero, &gray);
+ if (colToByte(gray) == 0)
+ invert_bits = 0x00;
+ }
- for (int ri = 0; ri < height; ++ri)
- {
- for(int i = 0; i < size; i++)
- png_row[i] = str->getChar() ^ invert_bits;
+ str->reset();
+ unsigned char *png_row = (unsigned char *)gmalloc(size);
- if (!writer->writeRow( &png_row ))
- {
- error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
- delete writer;
- fclose(f1);
+ for (int ri = 0; ri < height; ++ri) {
+ for (int i = 0; i < size; i++)
+ png_row[i] = str->getChar() ^ invert_bits;
+
+ if (!writer->writeRow(&png_row)) {
+ error(errIO, -1, "Failed to write into PNG '{0:t}'", fName);
+ delete writer;
+ fclose(f1);
+ gfree(png_row);
+ return;
+ }
+ }
+ str->close();
gfree(png_row);
- return;
- }
}
- str->close();
- gfree(png_row);
- }
- str->close();
+ str->close();
- writer->close();
- delete writer;
- fclose(f1);
+ writer->close();
+ delete writer;
+ fclose(f1);
- if (dataUrls) {
- delete fName;
- fName = new GooString(std::string("data:image/png;base64,") + gbase64Encode(ims.getBuffer()));
- }
- pages->addImage(fName, state);
+ if (dataUrls) {
+ delete fName;
+ fName = new GooString(std::string("data:image/png;base64,") + gbase64Encode(ims.getBuffer()));
+ }
+ pages->addImage(fName, state);
#else
- return;
+ return;
#endif
}
GooString *HtmlOutputDev::createImageFileName(const char *ext)
{
- return GooString::format("{0:s}-{1:d}_{2:d}.{3:s}", Docname->c_str(), pageNum, pages->getNumImages() + 1, ext);
+ return GooString::format("{0:s}-{1:d}_{2:d}.{3:s}", Docname->c_str(), pageNum, pages->getNumImages() + 1, ext);
}
-void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, bool invert,
- bool interpolate, bool inlineImg) {
+void HtmlOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg)
+{
- if (ignore||(complexMode && !xml)) {
- OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
- return;
- }
-
- // dump JPEG file
- if (dumpJPEG && str->getKind() == strDCT) {
- drawJpegImage(state, str);
- }
- else {
+ if (ignore || (complexMode && !xml)) {
+ OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
+ return;
+ }
+
+ // dump JPEG file
+ if (dumpJPEG && str->getKind() == strDCT) {
+ drawJpegImage(state, str);
+ } else {
#ifdef ENABLE_LIBPNG
- drawPngImage(state, str, width, height, nullptr, true);
+ drawPngImage(state, str, width, height, nullptr, true);
#else
- OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
+ OutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
#endif
- }
+ }
}
-void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
- bool interpolate, const int *maskColors, bool inlineImg) {
+void HtmlOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg)
+{
- if (ignore||(complexMode && !xml)) {
- OutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate,
- maskColors, inlineImg);
- return;
- }
-
- /*if( !globalParams->getErrQuiet() )
- printf("image stream of kind %d\n", str->getKind());*/
- // dump JPEG file
- if (dumpJPEG && str->getKind() == strDCT && (colorMap->getNumPixelComps() == 1 ||
- colorMap->getNumPixelComps() == 3) && !inlineImg) {
- drawJpegImage(state, str);
- }
- else {
+ if (ignore || (complexMode && !xml)) {
+ OutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate, maskColors, inlineImg);
+ return;
+ }
+
+ /*if( !globalParams->getErrQuiet() )
+ printf("image stream of kind %d\n", str->getKind());*/
+ // dump JPEG file
+ if (dumpJPEG && str->getKind() == strDCT && (colorMap->getNumPixelComps() == 1 || colorMap->getNumPixelComps() == 3) && !inlineImg) {
+ drawJpegImage(state, str);
+ } else {
#ifdef ENABLE_LIBPNG
- drawPngImage(state, str, width, height, colorMap );
+ drawPngImage(state, str, width, height, colorMap);
#else
- OutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate,
- maskColors, inlineImg);
+ OutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate, maskColors, inlineImg);
#endif
- }
+ }
}
+void HtmlOutputDev::doProcessLink(AnnotLink *link)
+{
+ double _x1, _y1, _x2, _y2;
+ int x1, y1, x2, y2;
+ link->getRect(&_x1, &_y1, &_x2, &_y2);
+ cvtUserToDev(_x1, _y1, &x1, &y1);
-void HtmlOutputDev::doProcessLink(AnnotLink* link){
- double _x1,_y1,_x2,_y2;
- int x1,y1,x2,y2;
-
- link->getRect(&_x1,&_y1,&_x2,&_y2);
- cvtUserToDev(_x1,_y1,&x1,&y1);
-
- cvtUserToDev(_x2,_y2,&x2,&y2);
-
+ cvtUserToDev(_x2, _y2, &x2, &y2);
- GooString* _dest=getLinkDest(link);
- HtmlLink t((double) x1,(double) y2,(double) x2,(double) y1,_dest);
- pages->AddLink(t);
- delete _dest;
+ GooString *_dest = getLinkDest(link);
+ HtmlLink t((double)x1, (double)y2, (double)x2, (double)y1, _dest);
+ pages->AddLink(t);
+ delete _dest;
}
-GooString* HtmlOutputDev::getLinkDest(AnnotLink *link){
- if (!link->getAction())
- return new GooString();
- switch(link->getAction()->getKind())
- {
- case actionGoTo:
- {
- int destPage=1;
- LinkGoTo *ha=(LinkGoTo *)link->getAction();
- std::unique_ptr<LinkDest> dest;
- if (ha->getDest()!=nullptr)
- dest=std::unique_ptr<LinkDest>(ha->getDest()->copy());
- else if (ha->getNamedDest()!=nullptr)
- dest=catalog->findDest(ha->getNamedDest());
-
- if (dest){
- GooString* file = new GooString(gbasename(Docname->c_str()));
-
- if (dest->isPageRef()){
- const Ref pageref=dest->getPageRef();
- destPage=catalog->findPage(pageref);
- }
- else {
- destPage=dest->getPageNum();
- }
-
- /* complex simple
- frames file-4.html files.html#4
- noframes file.html#4 file.html#4
- */
- if (noframes)
- {
- file->append(".html#");
- file->append(std::to_string(destPage));
- }
- else
- {
- if( complexMode )
- {
- file->append("-");
- file->append(std::to_string(destPage));
- file->append(".html");
- }
- else
- {
- file->append("s.html#");
- file->append(std::to_string(destPage));
- }
- }
-
- if (printCommands) printf(" link to page %d ",destPage);
- return file;
- }
- else
- {
- return new GooString();
- }
- }
- case actionGoToR:
- {
- LinkGoToR *ha=(LinkGoToR *) link->getAction();
- LinkDest *dest=nullptr;
- int destPage=1;
- GooString *file=new GooString();
- if (ha->getFileName()){
- delete file;
- file=new GooString(ha->getFileName()->c_str());
- }
- if (ha->getDest()!=nullptr) dest=ha->getDest()->copy();
- if (dest&&file){
- if (!(dest->isPageRef())) destPage=dest->getPageNum();
- delete dest;
-
- if (printCommands) printf(" link to page %d ",destPage);
- if (printHtml){
- const char *p=file->c_str()+file->getLength()-4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")){
- file->del(file->getLength()-4,4);
- file->append(".html");
- }
- file->append('#');
- file->append(std::to_string(destPage));
- }
- }
- if (printCommands && file) printf("filename %s\n",file->c_str());
- return file;
- }
- case actionURI:
- {
- LinkURI *ha=(LinkURI *) link->getAction();
- GooString* file=new GooString(ha->getURI());
- // printf("uri : %s\n",file->c_str());
- return file;
- }
- case actionLaunch:
- if (printHtml) {
- LinkLaunch *ha=(LinkLaunch *) link->getAction();
- GooString* file=new GooString(ha->getFileName()->c_str());
- const char *p=file->c_str()+file->getLength()-4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")){
- file->del(file->getLength()-4,4);
- file->append(".html");
- }
- if (printCommands) printf("filename %s",file->c_str());
-
- return file;
-
- }
- // fallthrough
- default:
- return new GooString();
- }
+GooString *HtmlOutputDev::getLinkDest(AnnotLink *link)
+{
+ if (!link->getAction())
+ return new GooString();
+ switch (link->getAction()->getKind()) {
+ case actionGoTo: {
+ int destPage = 1;
+ LinkGoTo *ha = (LinkGoTo *)link->getAction();
+ std::unique_ptr<LinkDest> dest;
+ if (ha->getDest() != nullptr)
+ dest = std::unique_ptr<LinkDest>(ha->getDest()->copy());
+ else if (ha->getNamedDest() != nullptr)
+ dest = catalog->findDest(ha->getNamedDest());
+
+ if (dest) {
+ GooString *file = new GooString(gbasename(Docname->c_str()));
+
+ if (dest->isPageRef()) {
+ const Ref pageref = dest->getPageRef();
+ destPage = catalog->findPage(pageref);
+ } else {
+ destPage = dest->getPageNum();
+ }
+
+ /* complex simple
+ frames file-4.html files.html#4
+ noframes file.html#4 file.html#4
+ */
+ if (noframes) {
+ file->append(".html#");
+ file->append(std::to_string(destPage));
+ } else {
+ if (complexMode) {
+ file->append("-");
+ file->append(std::to_string(destPage));
+ file->append(".html");
+ } else {
+ file->append("s.html#");
+ file->append(std::to_string(destPage));
+ }
+ }
+
+ if (printCommands)
+ printf(" link to page %d ", destPage);
+ return file;
+ } else {
+ return new GooString();
+ }
+ }
+ case actionGoToR: {
+ LinkGoToR *ha = (LinkGoToR *)link->getAction();
+ LinkDest *dest = nullptr;
+ int destPage = 1;
+ GooString *file = new GooString();
+ if (ha->getFileName()) {
+ delete file;
+ file = new GooString(ha->getFileName()->c_str());
+ }
+ if (ha->getDest() != nullptr)
+ dest = ha->getDest()->copy();
+ if (dest && file) {
+ if (!(dest->isPageRef()))
+ destPage = dest->getPageNum();
+ delete dest;
+
+ if (printCommands)
+ printf(" link to page %d ", destPage);
+ if (printHtml) {
+ const char *p = file->c_str() + file->getLength() - 4;
+ if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
+ file->del(file->getLength() - 4, 4);
+ file->append(".html");
+ }
+ file->append('#');
+ file->append(std::to_string(destPage));
+ }
+ }
+ if (printCommands && file)
+ printf("filename %s\n", file->c_str());
+ return file;
+ }
+ case actionURI: {
+ LinkURI *ha = (LinkURI *)link->getAction();
+ GooString *file = new GooString(ha->getURI());
+ // printf("uri : %s\n",file->c_str());
+ return file;
+ }
+ case actionLaunch:
+ if (printHtml) {
+ LinkLaunch *ha = (LinkLaunch *)link->getAction();
+ GooString *file = new GooString(ha->getFileName()->c_str());
+ const char *p = file->c_str() + file->getLength() - 4;
+ if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
+ file->del(file->getLength() - 4, 4);
+ file->append(".html");
+ }
+ if (printCommands)
+ printf("filename %s", file->c_str());
+
+ return file;
+ }
+ // fallthrough
+ default:
+ return new GooString();
+ }
}
void HtmlOutputDev::dumpMetaVars(FILE *file)
{
- GooString *var;
+ GooString *var;
- for(const HtmlMetaVar *t : *glMetaVars)
- {
- var = t->toString();
- fprintf(file, "%s\n", var->c_str());
- delete var;
- }
+ for (const HtmlMetaVar *t : *glMetaVars) {
+ var = t->toString();
+ fprintf(file, "%s\n", var->c_str());
+ delete var;
+ }
}
-bool HtmlOutputDev::dumpDocOutline(PDFDoc* doc)
-{
- FILE * output = nullptr;
- bool bClose = false;
-
- if (!ok)
+bool HtmlOutputDev::dumpDocOutline(PDFDoc *doc)
+{
+ FILE *output = nullptr;
+ bool bClose = false;
+
+ if (!ok)
+ return false;
+
+ Outline *outline = doc->getOutline();
+ if (!outline)
+ return false;
+
+ const std::vector<OutlineItem *> *outlines = outline->getItems();
+ if (!outlines)
+ return false;
+
+ if (!complexMode || xml) {
+ output = page;
+ } else if (complexMode && !xml) {
+ if (noframes) {
+ output = page;
+ fputs("<hr/>\n", output);
+ } else {
+ GooString *str = Docname->copy();
+ str->append("-outline.html");
+ output = fopen(str->c_str(), "w");
+ delete str;
+ if (output == nullptr)
return false;
-
- Outline *outline = doc->getOutline();
- if (!outline)
- return false;
+ bClose = true;
+
+ const std::string htmlEncoding = HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName());
+
+ fprintf(output,
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
+ "lang=\"\" xml:lang=\"\">\n"
+ "<head>\n"
+ "<title>Document Outline</title>\n"
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; "
+ "charset=%s\"/>\n"
+ "</head>\n<body>\n",
+ htmlEncoding.c_str());
+ }
+ }
- const std::vector<OutlineItem*> *outlines = outline->getItems();
- if (!outlines)
- return false;
-
- if (!complexMode || xml)
- {
- output = page;
- }
- else if (complexMode && !xml)
- {
- if (noframes)
- {
- output = page;
- fputs("<hr/>\n", output);
- }
- else
- {
- GooString *str = Docname->copy();
- str->append("-outline.html");
- output = fopen(str->c_str(), "w");
- delete str;
- if (output == nullptr)
- return false;
- bClose = true;
-
- const std::string htmlEncoding =
- HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName());
-
- fprintf(output, "<html xmlns=\"http://www.w3.org/1999/xhtml\" " \
- "lang=\"\" xml:lang=\"\">\n" \
- "<head>\n" \
- "<title>Document Outline</title>\n" \
- "<meta http-equiv=\"Content-Type\" content=\"text/html; " \
- "charset=%s\"/>\n" \
- "</head>\n<body>\n", htmlEncoding.c_str());
- }
- }
-
- if (!xml)
- {
- bool done = newHtmlOutlineLevel(output, outlines);
- if (done && !complexMode)
- fputs("<hr/>\n", output);
-
- if (bClose)
- {
- fputs("</body>\n</html>\n", output);
- fclose(output);
- }
- }
- else
- newXmlOutlineLevel(output, outlines);
-
- return true;
+ if (!xml) {
+ bool done = newHtmlOutlineLevel(output, outlines);
+ if (done && !complexMode)
+ fputs("<hr/>\n", output);
+
+ if (bClose) {
+ fputs("</body>\n</html>\n", output);
+ fclose(output);
+ }
+ } else
+ newXmlOutlineLevel(output, outlines);
+
+ return true;
}
-bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines, int level)
+bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const std::vector<OutlineItem *> *outlines, int level)
{
- bool atLeastOne = false;
+ bool atLeastOne = false;
- if (level == 1)
- {
- fputs("<a name=\"outline\"></a>", output);
- fputs("<h1>Document Outline</h1>\n", output);
- }
- fputs("<ul>\n",output);
+ if (level == 1) {
+ fputs("<a name=\"outline\"></a>", output);
+ fputs("<h1>Document Outline</h1>\n", output);
+ }
+ fputs("<ul>\n", output);
- for (OutlineItem *item : *outlines)
- {
- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(),
- item->getTitleLength());
+ for (OutlineItem *item : *outlines) {
+ GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength());
- GooString *linkName = nullptr;;
+ GooString *linkName = nullptr;
+ ;
const int itemPage = getOutlinePageNum(item);
- if (itemPage > 0)
- {
- /* complex simple
- frames file-4.html files.html#4
- noframes file.html#4 file.html#4
- */
- linkName = new GooString(gbasename(Docname->c_str()));
- if (noframes) {
- linkName->append(".html#");
- linkName->append(std::to_string(itemPage));
- } else {
- if( complexMode ) {
- linkName->append("-");
- linkName->append(std::to_string(itemPage));
- linkName->append(".html");
- } else {
- linkName->append("s.html#");
- linkName->append(std::to_string(itemPage));
- }
- }
- }
-
- fputs("<li>",output);
- if (linkName)
- fprintf(output,"<a href=\"%s\">", linkName->c_str());
- fputs(titleStr->c_str(),output);
- if (linkName) {
- fputs("</a>",output);
- delete linkName;
- }
- delete titleStr;
- atLeastOne = true;
-
- item->open();
- if (item->hasKids() && item->getKids())
- {
- fputs("\n",output);
- newHtmlOutlineLevel(output, item->getKids(), level+1);
- }
- item->close();
- fputs("</li>\n",output);
- }
- fputs("</ul>\n",output);
-
- return atLeastOne;
+ if (itemPage > 0) {
+ /* complex simple
+ frames file-4.html files.html#4
+ noframes file.html#4 file.html#4
+ */
+ linkName = new GooString(gbasename(Docname->c_str()));
+ if (noframes) {
+ linkName->append(".html#");
+ linkName->append(std::to_string(itemPage));
+ } else {
+ if (complexMode) {
+ linkName->append("-");
+ linkName->append(std::to_string(itemPage));
+ linkName->append(".html");
+ } else {
+ linkName->append("s.html#");
+ linkName->append(std::to_string(itemPage));
+ }
+ }
+ }
+
+ fputs("<li>", output);
+ if (linkName)
+ fprintf(output, "<a href=\"%s\">", linkName->c_str());
+ fputs(titleStr->c_str(), output);
+ if (linkName) {
+ fputs("</a>", output);
+ delete linkName;
+ }
+ delete titleStr;
+ atLeastOne = true;
+
+ item->open();
+ if (item->hasKids() && item->getKids()) {
+ fputs("\n", output);
+ newHtmlOutlineLevel(output, item->getKids(), level + 1);
+ }
+ item->close();
+ fputs("</li>\n", output);
+ }
+ fputs("</ul>\n", output);
+
+ return atLeastOne;
}
-void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines)
+void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const std::vector<OutlineItem *> *outlines)
{
fputs("<outline>\n", output);
- for (OutlineItem *item : *outlines)
- {
- GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(),
- item->getTitleLength());
+ for (OutlineItem *item : *outlines) {
+ GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), item->getTitleLength());
const int itemPage = getOutlinePageNum(item);
- if (itemPage > 0)
- {
- fprintf(output, "<item page=\"%d\">%s</item>\n",
- itemPage, titleStr->c_str());
- }
- else
- {
+ if (itemPage > 0) {
+ fprintf(output, "<item page=\"%d\">%s</item>\n", itemPage, titleStr->c_str());
+ } else {
fprintf(output, "<item>%s</item>\n", titleStr->c_str());
}
delete titleStr;
item->open();
- if (item->hasKids() && item->getKids())
- {
+ if (item->hasKids() && item->getKids()) {
newXmlOutlineLevel(output, item->getKids());
}
item->close();
- }
+ }
fputs("</outline>\n", output);
}
int HtmlOutputDev::getOutlinePageNum(OutlineItem *item)
{
- const LinkAction *action = item->getAction();
- const LinkGoTo *link = nullptr;
+ const LinkAction *action = item->getAction();
+ const LinkGoTo *link = nullptr;
std::unique_ptr<LinkDest> linkdest;
- int pagenum = -1;
+ int pagenum = -1;
if (!action || action->getKind() != actionGoTo)
return pagenum;
- link = static_cast<const LinkGoTo*>(action);
+ link = static_cast<const LinkGoTo *>(action);
if (!link || !link->isOk())
return pagenum;
diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h
index b724ec18..8ad8ebf1 100644
--- a/utils/HtmlOutputDev.h
+++ b/utils/HtmlOutputDev.h
@@ -58,160 +58,150 @@ class OutlineItem;
// HtmlString
//------------------------------------------------------------------------
-enum UnicodeTextDirection {
- textDirUnknown,
- textDirLeftRight,
- textDirRightLeft,
- textDirTopBottom
+enum UnicodeTextDirection
+{
+ textDirUnknown,
+ textDirLeftRight,
+ textDirRightLeft,
+ textDirTopBottom
};
-class HtmlString {
+class HtmlString
+{
public:
+ // Constructor.
+ HtmlString(GfxState *state, double fontSize, HtmlFontAccu *fonts);
- // Constructor.
- HtmlString(GfxState *state, double fontSize, HtmlFontAccu* fonts);
+ // Destructor.
+ ~HtmlString();
- // Destructor.
- ~HtmlString();
+ HtmlString(const HtmlString &) = delete;
+ HtmlString &operator=(const HtmlString &) = delete;
- HtmlString(const HtmlString &) = delete;
- HtmlString& operator=(const HtmlString &) = delete;
-
- // Add a character to the string.
- void addChar(GfxState *state, double x, double y,
- double dx, double dy,
- Unicode u);
- HtmlLink* getLink() { return link; }
- const HtmlFont &getFont() const { return *fonts->Get(fontpos); }
- void endString(); // postprocessing
+ // Add a character to the string.
+ void addChar(GfxState *state, double x, double y, double dx, double dy, Unicode u);
+ HtmlLink *getLink() { return link; }
+ const HtmlFont &getFont() const { return *fonts->Get(fontpos); }
+ void endString(); // postprocessing
private:
-// aender die text variable
- HtmlLink *link;
- double xMin, xMax; // bounding box x coordinates
- double yMin, yMax; // bounding box y coordinates
- int col; // starting column
- Unicode *text; // the text
- double *xRight; // right-hand x coord of each char
- HtmlString *yxNext; // next string in y-major order
- HtmlString *xyNext; // next string in x-major order
- int fontpos;
- GooString* htext;
- int len; // length of text and xRight
- int size; // size of text and xRight arrays
- UnicodeTextDirection dir; // direction (left to right/right to left)
- HtmlFontAccu *fonts;
-
- friend class HtmlPage;
-
+ // aender die text variable
+ HtmlLink *link;
+ double xMin, xMax; // bounding box x coordinates
+ double yMin, yMax; // bounding box y coordinates
+ int col; // starting column
+ Unicode *text; // the text
+ double *xRight; // right-hand x coord of each char
+ HtmlString *yxNext; // next string in y-major order
+ HtmlString *xyNext; // next string in x-major order
+ int fontpos;
+ GooString *htext;
+ int len; // length of text and xRight
+ int size; // size of text and xRight arrays
+ UnicodeTextDirection dir; // direction (left to right/right to left)
+ HtmlFontAccu *fonts;
+
+ friend class HtmlPage;
};
-
//------------------------------------------------------------------------
// HtmlPage
//------------------------------------------------------------------------
-
-
-class HtmlPage {
+class HtmlPage
+{
public:
+ // Constructor.
+ HtmlPage(bool rawOrder);
+
+ // Destructor.
+ ~HtmlPage();
- // Constructor.
- HtmlPage(bool rawOrder);
+ HtmlPage(const HtmlPage &) = delete;
+ HtmlPage &operator=(const HtmlPage &) = delete;
- // Destructor.
- ~HtmlPage();
+ // Begin a new string.
+ void beginString(GfxState *state, const GooString *s);
- HtmlPage(const HtmlPage &) = delete;
- HtmlPage& operator=(const HtmlPage &) = delete;
+ // Add a character to the current string.
+ void addChar(GfxState *state, double x, double y, double dx, double dy, double ox, double oy, const Unicode *u, int uLen); // unsigned char c);
- // Begin a new string.
- void beginString(GfxState *state, const GooString *s);
+ void updateFont(GfxState *state);
- // Add a character to the current string.
- void addChar(GfxState *state, double x, double y,
- double dx, double dy,
- double ox, double oy,
- const Unicode *u, int uLen); //unsigned char c);
+ // End the current string, sorting it into the list of strings.
+ void endString();
- void updateFont(GfxState *state);
+ // Coalesce strings that look like parts of the same line.
+ void coalesce();
- // End the current string, sorting it into the list of strings.
- void endString();
+ // Find a string. If <top> is true, starts looking at top of page;
+ // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true,
+ // stops looking at bottom of page; otherwise stops looking at
+ // <xMax>,<yMax>. If found, sets the text bounding rectangle and
+ // returns true; otherwise returns false.
- // Coalesce strings that look like parts of the same line.
- void coalesce();
+ // new functions
+ void AddLink(const HtmlLink &x) { links->AddLink(x); }
- // Find a string. If <top> is true, starts looking at top of page;
- // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true,
- // stops looking at bottom of page; otherwise stops looking at
- // <xMax>,<yMax>. If found, sets the text bounding rectangle and
- // returns true; otherwise returns false.
-
+ // add an image to the current page
+ void addImage(GooString *fname, GfxState *state);
- // new functions
- void AddLink(const HtmlLink& x){
- links->AddLink(x);
- }
+ // number of images on the current page
+ int getNumImages() { return imgList->size(); }
- // add an image to the current page
- void addImage(GooString *fname, GfxState *state);
+ void dump(FILE *f, int pageNum, const std::vector<std::string> &backgroundImages);
- // number of images on the current page
- int getNumImages() { return imgList->size(); }
+ // Clear the page.
+ void clear();
- void dump(FILE *f, int pageNum, const std::vector<std::string>& backgroundImages);
+ void conv();
- // Clear the page.
- void clear();
-
- void conv();
private:
- const HtmlFont* getFont(HtmlString *hStr) const { return fonts->Get(hStr->fontpos); }
-
- double fontSize; // current font size
- bool rawOrder; // keep strings in content stream order
-
- HtmlString *curStr; // currently active string
-
- HtmlString *yxStrings; // strings in y-major order
- HtmlString *xyStrings; // strings in x-major order
- HtmlString *yxCur1, *yxCur2; // cursors for yxStrings list
-
- void setDocName(const char* fname);
- void dumpAsXML(FILE* f,int page);
- void dumpComplex(FILE* f, int page, const std::vector<std::string>& backgroundImages);
- int dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page);
-
- // marks the position of the fonts that belong to current page (for noframes)
- int fontsPageMarker;
- HtmlFontAccu *fonts;
- HtmlLinks *links;
- std::vector<HtmlImage*> *imgList;
-
- GooString *DocName;
- int pageWidth;
- int pageHeight;
- int firstPage; // used to begin the numeration of pages
-
- friend class HtmlOutputDev;
+ const HtmlFont *getFont(HtmlString *hStr) const { return fonts->Get(hStr->fontpos); }
+
+ double fontSize; // current font size
+ bool rawOrder; // keep strings in content stream order
+
+ HtmlString *curStr; // currently active string
+
+ HtmlString *yxStrings; // strings in y-major order
+ HtmlString *xyStrings; // strings in x-major order
+ HtmlString *yxCur1, *yxCur2; // cursors for yxStrings list
+
+ void setDocName(const char *fname);
+ void dumpAsXML(FILE *f, int page);
+ void dumpComplex(FILE *f, int page, const std::vector<std::string> &backgroundImages);
+ int dumpComplexHeaders(FILE *const file, FILE *&pageFile, int page);
+
+ // marks the position of the fonts that belong to current page (for noframes)
+ int fontsPageMarker;
+ HtmlFontAccu *fonts;
+ HtmlLinks *links;
+ std::vector<HtmlImage *> *imgList;
+
+ GooString *DocName;
+ int pageWidth;
+ int pageHeight;
+ int firstPage; // used to begin the numeration of pages
+
+ friend class HtmlOutputDev;
};
//------------------------------------------------------------------------
// HtmlMetaVar
//------------------------------------------------------------------------
-class HtmlMetaVar {
+class HtmlMetaVar
+{
public:
HtmlMetaVar(const char *_name, const char *_content);
- ~HtmlMetaVar();
-
+ ~HtmlMetaVar();
+
HtmlMetaVar(const HtmlMetaVar &) = delete;
- HtmlMetaVar& operator=(const HtmlMetaVar &) = delete;
+ HtmlMetaVar &operator=(const HtmlMetaVar &) = delete;
- GooString* toString() const;
+ GooString *toString() const;
private:
-
GooString *name;
GooString *content;
};
@@ -220,135 +210,112 @@ private:
// HtmlOutputDev
//------------------------------------------------------------------------
-class HtmlOutputDev: public OutputDev {
+class HtmlOutputDev : public OutputDev
+{
public:
+ // Open a text output file. If <fileName> is nullptr, no file is written
+ // (this is useful, e.g., for searching text). If <useASCII7> is true,
+ // text is converted to 7-bit ASCII; otherwise, text is converted to
+ // 8-bit ISO Latin-1. <useASCII7> should also be set for Japanese
+ // (EUC-JP) text. If <rawOrder> is true, the text is kept in content
+ // stream order.
+ HtmlOutputDev(Catalog *catalogA, const char *fileName, const char *title, const char *author, const char *keywords, const char *subject, const char *date, bool rawOrder, int firstPage = 1, bool outline = false);
+
+ // Destructor.
+ ~HtmlOutputDev() override;
+
+ // Check if file was successfully created.
+ virtual bool isOk() { return ok; }
+
+ //---- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ bool upsideDown() override { return true; }
+
+ // Does this device use drawChar() or drawString()?
+ bool useDrawChar() override { return true; }
+
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ bool interpretType3Chars() override { return false; }
+
+ // Does this device need non-text content?
+ bool needNonText() override { return true; }
+
+ //----- initialization and control
+
+ bool checkPageSlice(Page *p, double hDPI, double vDPI, int rotate, bool useMediaBox, bool crop, int sliceX, int sliceY, int sliceW, int sliceH, bool printing, bool (*abortCheckCbk)(void *data) = nullptr,
+ void *abortCheckCbkData = nullptr, bool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = nullptr, void *annotDisplayDecideCbkData = nullptr) override
+ {
+ docPage = p;
+ return true;
+ }
+
+ // Start a page.
+ void startPage(int pageNum, GfxState *state, XRef *xref) override;
+
+ // End a page.
+ void endPage() override;
+
+ // add a background image to the list of background images,
+ // as this seems to be done outside other processing. takes ownership of img.
+ void addBackgroundImage(const std::string &img);
+
+ //----- update text state
+ void updateFont(GfxState *state) override;
+
+ //----- text drawing
+ void beginString(GfxState *state, const GooString *s) override;
+ void endString(GfxState *state) override;
+ void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen) override;
+
+ void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override;
+ void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override;
+
+ // new feature
+ virtual int DevType() { return 1234; }
+
+ int getPageWidth() { return maxPageWidth; }
+ int getPageHeight() { return maxPageHeight; }
- // Open a text output file. If <fileName> is nullptr, no file is written
- // (this is useful, e.g., for searching text). If <useASCII7> is true,
- // text is converted to 7-bit ASCII; otherwise, text is converted to
- // 8-bit ISO Latin-1. <useASCII7> should also be set for Japanese
- // (EUC-JP) text. If <rawOrder> is true, the text is kept in content
- // stream order.
- HtmlOutputDev(Catalog *catalogA, const char *fileName, const char *title,
- const char *author,
- const char *keywords,
- const char *subject,
- const char *date,
- bool rawOrder,
- int firstPage = 1,
- bool outline = false);
-
- // Destructor.
- ~HtmlOutputDev() override;
-
- // Check if file was successfully created.
- virtual bool isOk() { return ok; }
-
- //---- get info about output device
-
- // Does this device use upside-down coordinates?
- // (Upside-down means (0,0) is the top left corner of the page.)
- bool upsideDown() override { return true; }
-
- // Does this device use drawChar() or drawString()?
- bool useDrawChar() override { return true; }
-
- // Does this device use beginType3Char/endType3Char? Otherwise,
- // text in Type 3 fonts will be drawn with drawChar/drawString.
- bool interpretType3Chars() override { return false; }
-
- // Does this device need non-text content?
- bool needNonText() override { return true; }
-
- //----- initialization and control
-
- bool checkPageSlice(Page *p, double hDPI, double vDPI,
- int rotate, bool useMediaBox, bool crop,
- int sliceX, int sliceY, int sliceW, int sliceH,
- bool printing,
- bool (* abortCheckCbk)(void *data) = nullptr,
- void * abortCheckCbkData = nullptr,
- bool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = nullptr,
- void *annotDisplayDecideCbkData = nullptr) override
- {
- docPage = p;
- return true;
- }
-
-
- // Start a page.
- void startPage(int pageNum, GfxState *state, XRef *xref) override;
-
- // End a page.
- void endPage() override;
-
- // add a background image to the list of background images,
- // as this seems to be done outside other processing. takes ownership of img.
- void addBackgroundImage(const std::string& img);
-
- //----- update text state
- void updateFont(GfxState *state) override;
-
- //----- text drawing
- void beginString(GfxState *state, const GooString *s) override;
- void endString(GfxState *state) override;
- void drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, int nBytes, const Unicode *u, int uLen) override;
-
- void drawImageMask(GfxState *state, Object *ref,
- Stream *str,
- int width, int height, bool invert,
- bool interpolate, bool inlineImg) override;
- void drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
- bool interpolate, const int *maskColors, bool inlineImg) override;
-
- //new feature
- virtual int DevType() {return 1234;}
-
- int getPageWidth() { return maxPageWidth; }
- int getPageHeight() { return maxPageHeight; }
-
- bool dumpDocOutline(PDFDoc* doc);
+ bool dumpDocOutline(PDFDoc *doc);
private:
- // convert encoding into a HTML standard, or encoding->c_str if not
- // recognized.
- static std::string mapEncodingToHtml(const std::string &encoding);
- void doProcessLink(AnnotLink *link);
- GooString* getLinkDest(AnnotLink *link);
- void dumpMetaVars(FILE *);
- void doFrame(int firstPage);
- bool newHtmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines, int level = 1);
- void newXmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines);
- int getOutlinePageNum(OutlineItem *item);
- void drawJpegImage(GfxState *state, Stream *str);
- void drawPngImage(GfxState *state, Stream *str, int width, int height,
- GfxImageColorMap *colorMap, bool isMask = false);
- GooString *createImageFileName(const char *ext);
-
- FILE *fContentsFrame;
- FILE *page; // html file
- //FILE *tin; // image log file
- //bool write;
- bool needClose; // need to close the file?
- HtmlPage *pages; // text for the current page
- bool rawOrder; // keep text in content stream order
- bool doOutline; // output document outline
- bool ok; // set up ok?
- bool dumpJPEG;
- int pageNum;
- int maxPageWidth;
- int maxPageHeight;
- GooString *Docname;
- GooString *docTitle;
- std::vector<HtmlMetaVar*> *glMetaVars;
- Catalog *catalog;
- Page *docPage;
- std::vector<std::string> backgroundImages;
- friend class HtmlPage;
+ // convert encoding into a HTML standard, or encoding->c_str if not
+ // recognized.
+ static std::string mapEncodingToHtml(const std::string &encoding);
+ void doProcessLink(AnnotLink *link);
+ GooString *getLinkDest(AnnotLink *link);
+ void dumpMetaVars(FILE *);
+ void doFrame(int firstPage);
+ bool newHtmlOutlineLevel(FILE *output, const std::vector<OutlineItem *> *outlines, int level = 1);
+ void newXmlOutlineLevel(FILE *output, const std::vector<OutlineItem *> *outlines);
+ int getOutlinePageNum(OutlineItem *item);
+ void drawJpegImage(GfxState *state, Stream *str);
+ void drawPngImage(GfxState *state, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool isMask = false);
+ GooString *createImageFileName(const char *ext);
+
+ FILE *fContentsFrame;
+ FILE *page; // html file
+ // FILE *tin; // image log file
+ // bool write;
+ bool needClose; // need to close the file?
+ HtmlPage *pages; // text for the current page
+ bool rawOrder; // keep text in content stream order
+ bool doOutline; // output document outline
+ bool ok; // set up ok?
+ bool dumpJPEG;
+ int pageNum;
+ int maxPageWidth;
+ int maxPageHeight;
+ GooString *Docname;
+ GooString *docTitle;
+ std::vector<HtmlMetaVar *> *glMetaVars;
+ Catalog *catalog;
+ Page *docPage;
+ std::vector<std::string> backgroundImages;
+ friend class HtmlPage;
};
#endif
diff --git a/utils/HtmlUtils.h b/utils/HtmlUtils.h
index c6ccdc12..019e9873 100644
--- a/utils/HtmlUtils.h
+++ b/utils/HtmlUtils.h
@@ -22,29 +22,34 @@
// Returns true iff the difference between a and b is less than the threshold
// We always use fuzzy math when comparing decimal numbers due to imprecision
-inline bool is_within(double a, double thresh, double b) {
- return fabs(a-b) < thresh;
+inline bool is_within(double a, double thresh, double b)
+{
+ return fabs(a - b) < thresh;
}
-inline bool rot_matrices_equal(const double * const mat0, const double * const mat1) {
- return is_within(mat0[0], .1, mat1[0]) && is_within(mat0[1], .1, mat1[1]) &&
- is_within(mat0[2], .1, mat1[2]) && is_within(mat0[3], .1, mat1[3]);
+inline bool rot_matrices_equal(const double *const mat0, const double *const mat1)
+{
+ return is_within(mat0[0], .1, mat1[0]) && is_within(mat0[1], .1, mat1[1]) && is_within(mat0[2], .1, mat1[2]) && is_within(mat0[3], .1, mat1[3]);
}
// rotation is (cos q, sin q, -sin q, cos q, 0, 0)
// sin q is zero iff there is no rotation, or 180 deg. rotation;
// for 180 rotation, cos q will be negative
-inline bool isMatRotOrSkew(const double * const mat) {
- return mat[0] < 0 || !is_within(mat[1], .1, 0);
+inline bool isMatRotOrSkew(const double *const mat)
+{
+ return mat[0] < 0 || !is_within(mat[1], .1, 0);
}
// Alters the matrix so that it does not scale a vector's x component;
// If the matrix does not skew, then that will also normalize the y
// component, keeping any rotation, but removing scaling.
-inline void normalizeRotMat(double *mat) {
- double scale = fabs(mat[0] + mat[1]);
- if (!scale) return;
- for (int i = 0; i < 4; i++) mat[i] /= scale;
+inline void normalizeRotMat(double *mat)
+{
+ double scale = fabs(mat[0] + mat[1]);
+ if (!scale)
+ return;
+ for (int i = 0; i < 4; i++)
+ mat[i] /= scale;
}
#endif /* HTMLUTILS_H_ */
diff --git a/utils/ImageOutputDev.cc b/utils/ImageOutputDev.cc
index 02684467..552a3b15 100644
--- a/utils/ImageOutputDev.cc
+++ b/utils/ImageOutputDev.cc
@@ -50,45 +50,46 @@
#include "JBIG2Stream.h"
#include "ImageOutputDev.h"
-ImageOutputDev::ImageOutputDev(char *fileRootA, bool pageNamesA, bool listImagesA) {
- listImages = listImagesA;
- if (!listImages) {
- fileRoot = copyString(fileRootA);
- fileName = (char *)gmalloc(strlen(fileRoot) + 45);
- }
- outputPNG = false;
- outputTiff = false;
- dumpJPEG = false;
- dumpJP2 = false;
- dumpJBIG2 = false;
- dumpCCITT = false;
- pageNames = pageNamesA;
- imgNum = 0;
- pageNum = 0;
- ok = true;
- if (listImages) {
- printf("page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio\n");
- printf("--------------------------------------------------------------------------------------------\n");
- }
+ImageOutputDev::ImageOutputDev(char *fileRootA, bool pageNamesA, bool listImagesA)
+{
+ listImages = listImagesA;
+ if (!listImages) {
+ fileRoot = copyString(fileRootA);
+ fileName = (char *)gmalloc(strlen(fileRoot) + 45);
+ }
+ outputPNG = false;
+ outputTiff = false;
+ dumpJPEG = false;
+ dumpJP2 = false;
+ dumpJBIG2 = false;
+ dumpCCITT = false;
+ pageNames = pageNamesA;
+ imgNum = 0;
+ pageNum = 0;
+ ok = true;
+ if (listImages) {
+ printf("page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio\n");
+ printf("--------------------------------------------------------------------------------------------\n");
+ }
}
-
-ImageOutputDev::~ImageOutputDev() {
- if (!listImages) {
- gfree(fileName);
- gfree(fileRoot);
- }
+ImageOutputDev::~ImageOutputDev()
+{
+ if (!listImages) {
+ gfree(fileName);
+ gfree(fileRoot);
+ }
}
-void ImageOutputDev::setFilename(const char *fileExt) {
- if (pageNames) {
- sprintf(fileName, "%s-%03d-%03d.%s", fileRoot, pageNum, imgNum, fileExt);
- } else {
- sprintf(fileName, "%s-%03d.%s", fileRoot, imgNum, fileExt);
- }
+void ImageOutputDev::setFilename(const char *fileExt)
+{
+ if (pageNames) {
+ sprintf(fileName, "%s-%03d-%03d.%s", fileRoot, pageNum, imgNum, fileExt);
+ } else {
+ sprintf(fileName, "%s-%03d.%s", fileRoot, imgNum, fileExt);
+ }
}
-
// Print a floating point number between 0 - 9999 using 4 characters
// eg '1.23', '12.3', ' 123', '1234'
//
@@ -97,634 +98,607 @@ void ImageOutputDev::setFilename(const char *fileExt) {
// outputs "10.00" instead of "9.99".
static void printNumber(double d)
{
- char buf[10];
-
- if (d < 10.0) {
- sprintf(buf, "%4.2f", d);
- buf[4] = 0;
- printf("%s", buf);
- } else if (d < 100.0) {
- sprintf(buf, "%4.1f", d);
- if (!isdigit(buf[3])) {
- buf[3] = 0;
- printf(" %s", buf);
+ char buf[10];
+
+ if (d < 10.0) {
+ sprintf(buf, "%4.2f", d);
+ buf[4] = 0;
+ printf("%s", buf);
+ } else if (d < 100.0) {
+ sprintf(buf, "%4.1f", d);
+ if (!isdigit(buf[3])) {
+ buf[3] = 0;
+ printf(" %s", buf);
+ } else {
+ printf("%s", buf);
+ }
} else {
- printf("%s", buf);
+ printf("%4.0f", d);
}
- } else {
- printf("%4.0f", d);
- }
}
-void ImageOutputDev::listImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- bool interpolate, bool inlineImg,
- ImageType imageType) {
- const char *type;
- const char *colorspace;
- const char *enc;
- int components, bpc;
-
- printf("%4d %5d ", pageNum, imgNum);
- type = "";
- switch (imageType) {
- case imgImage:
- type = "image";
- break;
- case imgStencil:
- type = "stencil";
- break;
- case imgMask:
- type = "mask";
- break;
- case imgSmask:
- type = "smask";
- break;
- }
- printf("%-7s %5d %5d ", type, width, height);
-
- colorspace = "-";
- /* masks and stencils default to ncomps = 1 and bpc = 1 */
- components = 1;
- bpc = 1;
- if (colorMap && colorMap->isOk()) {
- switch (colorMap->getColorSpace()->getMode()) {
- case csDeviceGray:
- case csCalGray:
- colorspace = "gray";
+void ImageOutputDev::listImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, bool inlineImg, ImageType imageType)
+{
+ const char *type;
+ const char *colorspace;
+ const char *enc;
+ int components, bpc;
+
+ printf("%4d %5d ", pageNum, imgNum);
+ type = "";
+ switch (imageType) {
+ case imgImage:
+ type = "image";
break;
- case csDeviceRGB:
- case csCalRGB:
- colorspace = "rgb";
+ case imgStencil:
+ type = "stencil";
break;
- case csDeviceCMYK:
- colorspace = "cmyk";
+ case imgMask:
+ type = "mask";
break;
- case csLab:
- colorspace = "lab";
+ case imgSmask:
+ type = "smask";
break;
- case csICCBased:
- colorspace = "icc";
+ }
+ printf("%-7s %5d %5d ", type, width, height);
+
+ colorspace = "-";
+ /* masks and stencils default to ncomps = 1 and bpc = 1 */
+ components = 1;
+ bpc = 1;
+ if (colorMap && colorMap->isOk()) {
+ switch (colorMap->getColorSpace()->getMode()) {
+ case csDeviceGray:
+ case csCalGray:
+ colorspace = "gray";
+ break;
+ case csDeviceRGB:
+ case csCalRGB:
+ colorspace = "rgb";
+ break;
+ case csDeviceCMYK:
+ colorspace = "cmyk";
+ break;
+ case csLab:
+ colorspace = "lab";
+ break;
+ case csICCBased:
+ colorspace = "icc";
+ break;
+ case csIndexed:
+ colorspace = "index";
+ break;
+ case csSeparation:
+ colorspace = "sep";
+ break;
+ case csDeviceN:
+ colorspace = "devn";
+ break;
+ case csPattern:
+ default:
+ colorspace = "-";
+ break;
+ }
+ components = colorMap->getNumPixelComps();
+ bpc = colorMap->getBits();
+ }
+ printf("%-5s %2d %2d ", colorspace, components, bpc);
+
+ switch (str->getKind()) {
+ case strCCITTFax:
+ enc = "ccitt";
break;
- case csIndexed:
- colorspace = "index";
+ case strDCT:
+ enc = "jpeg";
break;
- case csSeparation:
- colorspace = "sep";
+ case strJPX:
+ enc = "jpx";
break;
- case csDeviceN:
- colorspace = "devn";
+ case strJBIG2:
+ enc = "jbig2";
break;
- case csPattern:
- default:
- colorspace = "-";
+ case strFile:
+ case strFlate:
+ case strCachedFile:
+ case strASCIIHex:
+ case strASCII85:
+ case strLZW:
+ case strRunLength:
+ case strWeird:
+ default:
+ enc = "image";
break;
}
- components = colorMap->getNumPixelComps();
- bpc = colorMap->getBits();
- }
- printf("%-5s %2d %2d ", colorspace, components, bpc);
-
- switch (str->getKind()) {
- case strCCITTFax:
- enc = "ccitt";
- break;
- case strDCT:
- enc = "jpeg";
- break;
- case strJPX:
- enc = "jpx";
- break;
- case strJBIG2:
- enc = "jbig2";
- break;
- case strFile:
- case strFlate:
- case strCachedFile:
- case strASCIIHex:
- case strASCII85:
- case strLZW:
- case strRunLength:
- case strWeird:
- default:
- enc = "image";
- break;
- }
- printf("%-5s ", enc);
-
- printf("%-3s ", interpolate ? "yes" : "no");
-
- if (inlineImg) {
- printf("[inline] ");
- } else if (ref->isRef()) {
- const Ref imageRef = ref->getRef();
- if (imageRef.gen >= 100000) {
- printf("[none] ");
- } else {
- printf(" %6d %2d ", imageRef.num, imageRef.gen);
- }
- } else {
- printf("[none] ");
- }
-
- const double *mat = state->getCTM();
- double width2 = mat[0] + mat[2];
- double height2 = mat[1] + mat[3];
- double xppi = fabs(width*72.0/width2) + 0.5;
- double yppi = fabs(height*72.0/height2) + 0.5;
- if (xppi < 1.0)
- printf("%5.3f ", xppi);
- else
- printf("%5.0f ", xppi);
- if (yppi < 1.0)
- printf("%5.3f ", yppi);
- else
- printf("%5.0f ", yppi);
-
- Goffset embedSize = -1;
- if (inlineImg)
- embedSize = getInlineImageLength(str, width, height, colorMap);
- else
- embedSize = str->getBaseStream()->getLength();
-
- long long imageSize = 0;
- if (colorMap && colorMap->isOk())
- imageSize = ((long long)width * height * colorMap->getNumPixelComps() * colorMap->getBits())/8;
- else
- imageSize = (long long)width*height/8; // mask
-
- double ratio = -1.0;
- if (imageSize > 0)
- ratio = 100.0*embedSize/imageSize;
-
- if (embedSize < 0) {
- printf(" - ");
- } else if (embedSize <= 9999) {
- printf("%4lldB", embedSize);
- } else {
- double d = embedSize/1024.0;
- if (d <= 9999.0) {
- printNumber(d);
- putchar('K');
+ printf("%-5s ", enc);
+
+ printf("%-3s ", interpolate ? "yes" : "no");
+
+ if (inlineImg) {
+ printf("[inline] ");
+ } else if (ref->isRef()) {
+ const Ref imageRef = ref->getRef();
+ if (imageRef.gen >= 100000) {
+ printf("[none] ");
+ } else {
+ printf(" %6d %2d ", imageRef.num, imageRef.gen);
+ }
} else {
- d /= 1024.0;
- if (d <= 9999.0) {
- printNumber(d);
- putchar('M');
- } else {
- d /= 1024.0;
- printNumber(d);
- putchar('G');
- }
+ printf("[none] ");
}
- }
- if (ratio > 9.9)
- printf(" %3.0f%%\n", ratio);
- else if (ratio >= 0.0)
- printf(" %3.1f%%\n", ratio);
- else
- printf(" - \n");
-
- ++imgNum;
+ const double *mat = state->getCTM();
+ double width2 = mat[0] + mat[2];
+ double height2 = mat[1] + mat[3];
+ double xppi = fabs(width * 72.0 / width2) + 0.5;
+ double yppi = fabs(height * 72.0 / height2) + 0.5;
+ if (xppi < 1.0)
+ printf("%5.3f ", xppi);
+ else
+ printf("%5.0f ", xppi);
+ if (yppi < 1.0)
+ printf("%5.3f ", yppi);
+ else
+ printf("%5.0f ", yppi);
-}
+ Goffset embedSize = -1;
+ if (inlineImg)
+ embedSize = getInlineImageLength(str, width, height, colorMap);
+ else
+ embedSize = str->getBaseStream()->getLength();
-long ImageOutputDev::getInlineImageLength(Stream *str, int width, int height,
- GfxImageColorMap *colorMap) {
- long len;
+ long long imageSize = 0;
+ if (colorMap && colorMap->isOk())
+ imageSize = ((long long)width * height * colorMap->getNumPixelComps() * colorMap->getBits()) / 8;
+ else
+ imageSize = (long long)width * height / 8; // mask
- if (colorMap) {
- ImageStream *imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgStr->reset();
- for (int y = 0; y < height; y++)
- imgStr->getLine();
+ double ratio = -1.0;
+ if (imageSize > 0)
+ ratio = 100.0 * embedSize / imageSize;
- imgStr->close();
- delete imgStr;
- } else {
- str->reset();
- for (int y = 0; y < height; y++) {
- int size = (width + 7)/8;
- for (int x = 0; x < size; x++)
- str->getChar();
+ if (embedSize < 0) {
+ printf(" - ");
+ } else if (embedSize <= 9999) {
+ printf("%4lldB", embedSize);
+ } else {
+ double d = embedSize / 1024.0;
+ if (d <= 9999.0) {
+ printNumber(d);
+ putchar('K');
+ } else {
+ d /= 1024.0;
+ if (d <= 9999.0) {
+ printNumber(d);
+ putchar('M');
+ } else {
+ d /= 1024.0;
+ printNumber(d);
+ putchar('G');
+ }
+ }
}
- }
-
- EmbedStream *embedStr = (EmbedStream *) (str->getBaseStream());
- embedStr->rewind();
- len = 0;
- while (embedStr->getChar() != EOF)
- len++;
- embedStr->restore();
+ if (ratio > 9.9)
+ printf(" %3.0f%%\n", ratio);
+ else if (ratio >= 0.0)
+ printf(" %3.1f%%\n", ratio);
+ else
+ printf(" - \n");
- return len;
+ ++imgNum;
}
-void ImageOutputDev::writeRawImage(Stream *str, const char *ext) {
- FILE *f;
- int c;
+long ImageOutputDev::getInlineImageLength(Stream *str, int width, int height, GfxImageColorMap *colorMap)
+{
+ long len;
+
+ if (colorMap) {
+ ImageStream *imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
+ imgStr->reset();
+ for (int y = 0; y < height; y++)
+ imgStr->getLine();
- // open the image file
- setFilename(ext);
- ++imgNum;
- if (!(f = fopen(fileName, "wb"))) {
- error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
- return;
- }
+ imgStr->close();
+ delete imgStr;
+ } else {
+ str->reset();
+ for (int y = 0; y < height; y++) {
+ int size = (width + 7) / 8;
+ for (int x = 0; x < size; x++)
+ str->getChar();
+ }
+ }
- // initialize stream
- str = str->getNextStream();
- str->reset();
+ EmbedStream *embedStr = (EmbedStream *)(str->getBaseStream());
+ embedStr->rewind();
+ len = 0;
+ while (embedStr->getChar() != EOF)
+ len++;
- // copy the stream
- while ((c = str->getChar()) != EOF)
- fputc(c, f);
+ embedStr->restore();
- str->close();
- fclose(f);
+ return len;
}
-void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const char *ext,
- Stream *str, int width, int height, GfxImageColorMap *colorMap) {
- FILE *f = nullptr; /* squelch bogus compiler warning */
- ImageStream *imgStr = nullptr;
- unsigned char *row;
- unsigned char *rowp;
- unsigned char *p;
- GfxRGB rgb;
- GfxCMYK cmyk;
- GfxGray gray;
- unsigned char zero[gfxColorMaxComps];
- int invert_bits;
-
- if (writer) {
+void ImageOutputDev::writeRawImage(Stream *str, const char *ext)
+{
+ FILE *f;
+ int c;
+
+ // open the image file
setFilename(ext);
++imgNum;
if (!(f = fopen(fileName, "wb"))) {
- error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
- return;
- }
-
- if (!writer->init(f, width, height, 72, 72)) {
- error(errIO, -1, "Error writing '{0:s}'", fileName);
- return;
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
}
- }
- if (format != imgMonochrome) {
- // initialize stream
- imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgStr->reset();
- } else {
// initialize stream
+ str = str->getNextStream();
str->reset();
- }
-
- int pixelSize = sizeof(unsigned int);
- if (format == imgRGB48)
- pixelSize = 2*sizeof(unsigned int);
-
- row = (unsigned char *) gmallocn(width, pixelSize);
-
- // PDF masks use 0 = draw current color, 1 = leave unchanged.
- // We invert this to provide the standard interpretation of alpha
- // (0 = transparent, 1 = opaque). If the colorMap already inverts
- // the mask we leave the data unchanged.
- invert_bits = 0xff;
- if (colorMap) {
- memset(zero, 0, sizeof(zero));
- colorMap->getGray(zero, &gray);
- if (colToByte(gray) == 0)
- invert_bits = 0x00;
- }
-
- // for each line...
- for (int y = 0; y < height; y++) {
- switch (format) {
- case imgRGB:
- p = imgStr->getLine();
- rowp = row;
- for (int x = 0; x < width; ++x) {
- if (p) {
- colorMap->getRGB(p, &rgb);
- *rowp++ = colToByte(rgb.r);
- *rowp++ = colToByte(rgb.g);
- *rowp++ = colToByte(rgb.b);
- p += colorMap->getNumPixelComps();
- } else {
- *rowp++ = 0;
- *rowp++ = 0;
- *rowp++ = 0;
+
+ // copy the stream
+ while ((c = str->getChar()) != EOF)
+ fputc(c, f);
+
+ str->close();
+ fclose(f);
+}
+
+void ImageOutputDev::writeImageFile(ImgWriter *writer, ImageFormat format, const char *ext, Stream *str, int width, int height, GfxImageColorMap *colorMap)
+{
+ FILE *f = nullptr; /* squelch bogus compiler warning */
+ ImageStream *imgStr = nullptr;
+ unsigned char *row;
+ unsigned char *rowp;
+ unsigned char *p;
+ GfxRGB rgb;
+ GfxCMYK cmyk;
+ GfxGray gray;
+ unsigned char zero[gfxColorMaxComps];
+ int invert_bits;
+
+ if (writer) {
+ setFilename(ext);
+ ++imgNum;
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+
+ if (!writer->init(f, width, height, 72, 72)) {
+ error(errIO, -1, "Error writing '{0:s}'", fileName);
+ return;
}
- }
- if (writer)
- writer->writeRow(&row);
- break;
-
- case imgRGB48: {
- p = imgStr->getLine();
- unsigned short *rowp16 = reinterpret_cast<unsigned short*>(row);
- for (int x = 0; x < width; ++x) {
- if (p) {
- colorMap->getRGB(p, &rgb);
- *rowp16++ = colToShort(rgb.r);
- *rowp16++ = colToShort(rgb.g);
- *rowp16++ = colToShort(rgb.b);
- p += colorMap->getNumPixelComps();
- } else {
- *rowp16++ = 0;
- *rowp16++ = 0;
- *rowp16++ = 0;
- }
- }
- if (writer)
- writer->writeRow(&row);
- break;
}
- case imgCMYK:
- p = imgStr->getLine();
- rowp = row;
- for (int x = 0; x < width; ++x) {
- if (p) {
- colorMap->getCMYK(p, &cmyk);
- *rowp++ = colToByte(cmyk.c);
- *rowp++ = colToByte(cmyk.m);
- *rowp++ = colToByte(cmyk.y);
- *rowp++ = colToByte(cmyk.k);
- p += colorMap->getNumPixelComps();
- } else {
- *rowp++ = 0;
- *rowp++ = 0;
- *rowp++ = 0;
- *rowp++ = 0;
+ if (format != imgMonochrome) {
+ // initialize stream
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
+ imgStr->reset();
+ } else {
+ // initialize stream
+ str->reset();
+ }
+
+ int pixelSize = sizeof(unsigned int);
+ if (format == imgRGB48)
+ pixelSize = 2 * sizeof(unsigned int);
+
+ row = (unsigned char *)gmallocn(width, pixelSize);
+
+ // PDF masks use 0 = draw current color, 1 = leave unchanged.
+ // We invert this to provide the standard interpretation of alpha
+ // (0 = transparent, 1 = opaque). If the colorMap already inverts
+ // the mask we leave the data unchanged.
+ invert_bits = 0xff;
+ if (colorMap) {
+ memset(zero, 0, sizeof(zero));
+ colorMap->getGray(zero, &gray);
+ if (colToByte(gray) == 0)
+ invert_bits = 0x00;
+ }
+
+ // for each line...
+ for (int y = 0; y < height; y++) {
+ switch (format) {
+ case imgRGB:
+ p = imgStr->getLine();
+ rowp = row;
+ for (int x = 0; x < width; ++x) {
+ if (p) {
+ colorMap->getRGB(p, &rgb);
+ *rowp++ = colToByte(rgb.r);
+ *rowp++ = colToByte(rgb.g);
+ *rowp++ = colToByte(rgb.b);
+ p += colorMap->getNumPixelComps();
+ } else {
+ *rowp++ = 0;
+ *rowp++ = 0;
+ *rowp++ = 0;
+ }
+ }
+ if (writer)
+ writer->writeRow(&row);
+ break;
+
+ case imgRGB48: {
+ p = imgStr->getLine();
+ unsigned short *rowp16 = reinterpret_cast<unsigned short *>(row);
+ for (int x = 0; x < width; ++x) {
+ if (p) {
+ colorMap->getRGB(p, &rgb);
+ *rowp16++ = colToShort(rgb.r);
+ *rowp16++ = colToShort(rgb.g);
+ *rowp16++ = colToShort(rgb.b);
+ p += colorMap->getNumPixelComps();
+ } else {
+ *rowp16++ = 0;
+ *rowp16++ = 0;
+ *rowp16++ = 0;
+ }
+ }
+ if (writer)
+ writer->writeRow(&row);
+ break;
}
- }
- if (writer)
- writer->writeRow(&row);
- break;
-
- case imgGray:
- p = imgStr->getLine();
- rowp = row;
- for (int x = 0; x < width; ++x) {
- if (p) {
- colorMap->getGray(p, &gray);
- *rowp++ = colToByte(gray);
- p += colorMap->getNumPixelComps();
- } else {
- *rowp++ = 0;
+
+ case imgCMYK:
+ p = imgStr->getLine();
+ rowp = row;
+ for (int x = 0; x < width; ++x) {
+ if (p) {
+ colorMap->getCMYK(p, &cmyk);
+ *rowp++ = colToByte(cmyk.c);
+ *rowp++ = colToByte(cmyk.m);
+ *rowp++ = colToByte(cmyk.y);
+ *rowp++ = colToByte(cmyk.k);
+ p += colorMap->getNumPixelComps();
+ } else {
+ *rowp++ = 0;
+ *rowp++ = 0;
+ *rowp++ = 0;
+ *rowp++ = 0;
+ }
+ }
+ if (writer)
+ writer->writeRow(&row);
+ break;
+
+ case imgGray:
+ p = imgStr->getLine();
+ rowp = row;
+ for (int x = 0; x < width; ++x) {
+ if (p) {
+ colorMap->getGray(p, &gray);
+ *rowp++ = colToByte(gray);
+ p += colorMap->getNumPixelComps();
+ } else {
+ *rowp++ = 0;
+ }
+ }
+ if (writer)
+ writer->writeRow(&row);
+ break;
+
+ case imgMonochrome:
+ int size = (width + 7) / 8;
+ for (int x = 0; x < size; x++)
+ row[x] = str->getChar() ^ invert_bits;
+ if (writer)
+ writer->writeRow(&row);
+ break;
}
- }
- if (writer)
- writer->writeRow(&row);
- break;
-
- case imgMonochrome:
- int size = (width + 7)/8;
- for (int x = 0; x < size; x++)
- row[x] = str->getChar() ^ invert_bits;
- if (writer)
- writer->writeRow(&row);
- break;
}
- }
-
- gfree(row);
- if (format != imgMonochrome) {
- imgStr->close();
- delete imgStr;
- }
- str->close();
- if (writer) {
- writer->close();
- fclose(f);
- }
+
+ gfree(row);
+ if (format != imgMonochrome) {
+ imgStr->close();
+ delete imgStr;
+ }
+ str->close();
+ if (writer) {
+ writer->close();
+ fclose(f);
+ }
}
-void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap, bool inlineImg) {
- ImageFormat format;
- EmbedStream *embedStr;
-
- if (inlineImg) {
- embedStr = (EmbedStream *) (str->getBaseStream());
- // Record the stream. This determines the size.
- getInlineImageLength(str, width, height, colorMap);
- // Reading the stream again will return EOF at end of recording.
- embedStr->rewind();
- }
-
- if (dumpJPEG && str->getKind() == strDCT) {
- // dump JPEG file
- writeRawImage(str, "jpg");
-
- } else if (dumpJP2 && str->getKind() == strJPX && !inlineImg) {
- // dump JPEG2000 file
- writeRawImage(str, "jp2");
-
- } else if (dumpJBIG2 && str->getKind() == strJBIG2 && !inlineImg) {
- // dump JBIG2 globals stream if available
- JBIG2Stream *jb2Str = static_cast<JBIG2Stream *>(str);
- Object *globals = jb2Str->getGlobalsStream();
- if (globals->isStream()) {
- FILE *f;
- int c;
- Stream *globalsStr = globals->getStream();
-
- setFilename("jb2g");
- if (!(f = fopen(fileName, "wb"))) {
- error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
- return;
- }
- globalsStr->reset();
- while ((c = globalsStr->getChar()) != EOF)
- fputc(c, f);
- globalsStr->close();
- fclose(f);
+void ImageOutputDev::writeImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool inlineImg)
+{
+ ImageFormat format;
+ EmbedStream *embedStr;
+
+ if (inlineImg) {
+ embedStr = (EmbedStream *)(str->getBaseStream());
+ // Record the stream. This determines the size.
+ getInlineImageLength(str, width, height, colorMap);
+ // Reading the stream again will return EOF at end of recording.
+ embedStr->rewind();
}
- // dump JBIG2 embedded file
- writeRawImage(str, "jb2e");
+ if (dumpJPEG && str->getKind() == strDCT) {
+ // dump JPEG file
+ writeRawImage(str, "jpg");
+
+ } else if (dumpJP2 && str->getKind() == strJPX && !inlineImg) {
+ // dump JPEG2000 file
+ writeRawImage(str, "jp2");
+
+ } else if (dumpJBIG2 && str->getKind() == strJBIG2 && !inlineImg) {
+ // dump JBIG2 globals stream if available
+ JBIG2Stream *jb2Str = static_cast<JBIG2Stream *>(str);
+ Object *globals = jb2Str->getGlobalsStream();
+ if (globals->isStream()) {
+ FILE *f;
+ int c;
+ Stream *globalsStr = globals->getStream();
+
+ setFilename("jb2g");
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+ globalsStr->reset();
+ while ((c = globalsStr->getChar()) != EOF)
+ fputc(c, f);
+ globalsStr->close();
+ fclose(f);
+ }
- } else if (dumpCCITT && str->getKind() == strCCITTFax) {
- // write CCITT parameters
- CCITTFaxStream *ccittStr = static_cast<CCITTFaxStream *>(str);
- FILE *f;
- setFilename("params");
- if (!(f = fopen(fileName, "wb"))) {
- error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
- return;
- }
- if (ccittStr->getEncoding() < 0)
- fprintf(f, "-4 ");
- else if (ccittStr->getEncoding() == 0)
- fprintf(f, "-1 ");
- else
- fprintf(f, "-2 ");
+ // dump JBIG2 embedded file
+ writeRawImage(str, "jb2e");
+
+ } else if (dumpCCITT && str->getKind() == strCCITTFax) {
+ // write CCITT parameters
+ CCITTFaxStream *ccittStr = static_cast<CCITTFaxStream *>(str);
+ FILE *f;
+ setFilename("params");
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+ if (ccittStr->getEncoding() < 0)
+ fprintf(f, "-4 ");
+ else if (ccittStr->getEncoding() == 0)
+ fprintf(f, "-1 ");
+ else
+ fprintf(f, "-2 ");
- if (ccittStr->getEndOfLine())
- fprintf(f, "-A ");
- else
- fprintf(f, "-P ");
+ if (ccittStr->getEndOfLine())
+ fprintf(f, "-A ");
+ else
+ fprintf(f, "-P ");
- fprintf(f, "-X %d ", ccittStr->getColumns());
+ fprintf(f, "-X %d ", ccittStr->getColumns());
- if (ccittStr->getBlackIs1())
- fprintf(f, "-W ");
- else
- fprintf(f, "-B ");
+ if (ccittStr->getBlackIs1())
+ fprintf(f, "-W ");
+ else
+ fprintf(f, "-B ");
- fprintf(f, "-M\n"); // PDF uses MSB first
+ fprintf(f, "-M\n"); // PDF uses MSB first
- fclose(f);
+ fclose(f);
- // dump CCITT file
- writeRawImage(str, "ccitt");
+ // dump CCITT file
+ writeRawImage(str, "ccitt");
- } else if (outputPNG && !(outputTiff && colorMap &&
- (colorMap->getColorSpace()->getMode() == csDeviceCMYK ||
- (colorMap->getColorSpace()->getMode() == csICCBased &&
- colorMap->getNumPixelComps() == 4)))) {
- // output in PNG format
+ } else if (outputPNG && !(outputTiff && colorMap && (colorMap->getColorSpace()->getMode() == csDeviceCMYK || (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 4)))) {
+ // output in PNG format
#ifdef ENABLE_LIBPNG
- ImgWriter *writer;
-
- if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
- writer = new PNGWriter(PNGWriter::MONOCHROME);
- format = imgMonochrome;
- } else if (colorMap->getColorSpace()->getMode() == csDeviceGray ||
- colorMap->getColorSpace()->getMode() == csCalGray) {
- writer = new PNGWriter(PNGWriter::GRAY);
- format = imgGray;
- } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB ||
- colorMap->getColorSpace()->getMode() == csCalRGB ||
- (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3)) &&
- colorMap->getBits() > 8) {
- writer = new PNGWriter(PNGWriter::RGB48);
- format = imgRGB48;
- } else {
- writer = new PNGWriter(PNGWriter::RGB);
- format = imgRGB;
- }
+ ImgWriter *writer;
+
+ if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
+ writer = new PNGWriter(PNGWriter::MONOCHROME);
+ format = imgMonochrome;
+ } else if (colorMap->getColorSpace()->getMode() == csDeviceGray || colorMap->getColorSpace()->getMode() == csCalGray) {
+ writer = new PNGWriter(PNGWriter::GRAY);
+ format = imgGray;
+ } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB || colorMap->getColorSpace()->getMode() == csCalRGB || (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3))
+ && colorMap->getBits() > 8) {
+ writer = new PNGWriter(PNGWriter::RGB48);
+ format = imgRGB48;
+ } else {
+ writer = new PNGWriter(PNGWriter::RGB);
+ format = imgRGB;
+ }
- writeImageFile(writer, format, "png", str, width, height, colorMap);
+ writeImageFile(writer, format, "png", str, width, height, colorMap);
- delete writer;
+ delete writer;
#endif
- } else if (outputTiff) {
- // output in TIFF format
+ } else if (outputTiff) {
+ // output in TIFF format
#ifdef ENABLE_LIBTIFF
- ImgWriter *writer;
-
- if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
- writer = new TiffWriter(TiffWriter::MONOCHROME);
- format = imgMonochrome;
- } else if (colorMap->getColorSpace()->getMode() == csDeviceGray ||
- colorMap->getColorSpace()->getMode() == csCalGray) {
- writer = new TiffWriter(TiffWriter::GRAY);
- format = imgGray;
- } else if (colorMap->getColorSpace()->getMode() == csDeviceCMYK ||
- (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 4)) {
- writer = new TiffWriter(TiffWriter::CMYK);
- format = imgCMYK;
- } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB ||
- colorMap->getColorSpace()->getMode() == csCalRGB ||
- (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3)) &&
- colorMap->getBits() > 8) {
- writer = new TiffWriter(TiffWriter::RGB48);
- format = imgRGB48;
- } else {
- writer = new TiffWriter(TiffWriter::RGB);
- format = imgRGB;
- }
+ ImgWriter *writer;
+
+ if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
+ writer = new TiffWriter(TiffWriter::MONOCHROME);
+ format = imgMonochrome;
+ } else if (colorMap->getColorSpace()->getMode() == csDeviceGray || colorMap->getColorSpace()->getMode() == csCalGray) {
+ writer = new TiffWriter(TiffWriter::GRAY);
+ format = imgGray;
+ } else if (colorMap->getColorSpace()->getMode() == csDeviceCMYK || (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 4)) {
+ writer = new TiffWriter(TiffWriter::CMYK);
+ format = imgCMYK;
+ } else if ((colorMap->getColorSpace()->getMode() == csDeviceRGB || colorMap->getColorSpace()->getMode() == csCalRGB || (colorMap->getColorSpace()->getMode() == csICCBased && colorMap->getNumPixelComps() == 3))
+ && colorMap->getBits() > 8) {
+ writer = new TiffWriter(TiffWriter::RGB48);
+ format = imgRGB48;
+ } else {
+ writer = new TiffWriter(TiffWriter::RGB);
+ format = imgRGB;
+ }
- writeImageFile(writer, format, "tif", str, width, height, colorMap);
+ writeImageFile(writer, format, "tif", str, width, height, colorMap);
- delete writer;
+ delete writer;
#endif
- } else {
- // output in PPM/PBM format
- ImgWriter *writer;
-
- if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
- writer = new NetPBMWriter(NetPBMWriter::MONOCHROME);
- format = imgMonochrome;
} else {
- writer = new NetPBMWriter(NetPBMWriter::RGB);
- format = imgRGB;
- }
+ // output in PPM/PBM format
+ ImgWriter *writer;
- writeImageFile(writer, format,
- format == imgRGB ? "ppm" : "pbm",
- str, width, height, colorMap);
+ if (!colorMap || (colorMap->getNumPixelComps() == 1 && colorMap->getBits() == 1)) {
+ writer = new NetPBMWriter(NetPBMWriter::MONOCHROME);
+ format = imgMonochrome;
+ } else {
+ writer = new NetPBMWriter(NetPBMWriter::RGB);
+ format = imgRGB;
+ }
- delete writer;
- }
+ writeImageFile(writer, format, format == imgRGB ? "ppm" : "pbm", str, width, height, colorMap);
- if (inlineImg)
- embedStr->restore();
+ delete writer;
+ }
+
+ if (inlineImg)
+ embedStr->restore();
}
-bool ImageOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str,
- const double *pmat, int paintType, int tilingType, Dict *resDict,
- const double *mat, const double *bbox,
- int x0, int y0, int x1, int y1,
- double xStep, double yStep) {
- return true;
- // do nothing -- this avoids the potentially slow loop in Gfx.cc
+bool ImageOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str, const double *pmat, int paintType, int tilingType, Dict *resDict, const double *mat, const double *bbox, int x0, int y0, int x1, int y1,
+ double xStep, double yStep)
+{
+ return true;
+ // do nothing -- this avoids the potentially slow loop in Gfx.cc
}
-void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, bool invert,
- bool interpolate, bool inlineImg) {
- if (listImages)
- listImage(state, ref, str, width, height, nullptr, interpolate, inlineImg, imgStencil);
- else
- writeImage(state, ref, str, width, height, nullptr, inlineImg);
+void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg)
+{
+ if (listImages)
+ listImage(state, ref, str, width, height, nullptr, interpolate, inlineImg, imgStencil);
+ else
+ writeImage(state, ref, str, width, height, nullptr, inlineImg);
}
-void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- bool interpolate, const int *maskColors, bool inlineImg) {
- if (listImages)
- listImage(state, ref, str, width, height, colorMap, interpolate, inlineImg, imgImage);
- else
- writeImage(state, ref, str, width, height, colorMap, inlineImg);
+void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg)
+{
+ if (listImages)
+ listImage(state, ref, str, width, height, colorMap, interpolate, inlineImg, imgImage);
+ else
+ writeImage(state, ref, str, width, height, colorMap, inlineImg);
}
-void ImageOutputDev::drawMaskedImage(
- GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap, bool interpolate,
- Stream *maskStr, int maskWidth, int maskHeight, bool maskInvert, bool maskInterpolate) {
- if (listImages) {
- listImage(state, ref, str, width, height, colorMap, interpolate, false, imgImage);
- listImage(state, ref, str, maskWidth, maskHeight, nullptr, maskInterpolate, false, imgMask);
- } else {
- writeImage(state, ref, str, width, height, colorMap, false);
- writeImage(state, ref, maskStr, maskWidth, maskHeight, nullptr, false);
- }
+void ImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, bool maskInvert, bool maskInterpolate)
+{
+ if (listImages) {
+ listImage(state, ref, str, width, height, colorMap, interpolate, false, imgImage);
+ listImage(state, ref, str, maskWidth, maskHeight, nullptr, maskInterpolate, false, imgMask);
+ } else {
+ writeImage(state, ref, str, width, height, colorMap, false);
+ writeImage(state, ref, maskStr, maskWidth, maskHeight, nullptr, false);
+ }
}
-void ImageOutputDev::drawSoftMaskedImage(
- GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap, bool interpolate,
- Stream *maskStr, int maskWidth, int maskHeight,
- GfxImageColorMap *maskColorMap, bool maskInterpolate) {
- if (listImages) {
- listImage(state, ref, str, width, height, colorMap, interpolate, false, imgImage);
- listImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate, false, imgSmask);
- } else {
- writeImage(state, ref, str, width, height, colorMap, false);
- writeImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap, false);
- }
+void ImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap,
+ bool maskInterpolate)
+{
+ if (listImages) {
+ listImage(state, ref, str, width, height, colorMap, interpolate, false, imgImage);
+ listImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate, false, imgSmask);
+ } else {
+ writeImage(state, ref, str, width, height, colorMap, false);
+ writeImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap, false);
+ }
}
diff --git a/utils/ImageOutputDev.h b/utils/ImageOutputDev.h
index 34c670fb..a665f3f8 100644
--- a/utils/ImageOutputDev.h
+++ b/utils/ImageOutputDev.h
@@ -41,136 +41,114 @@ class GfxState;
// ImageOutputDev
//------------------------------------------------------------------------
-class ImageOutputDev: public OutputDev {
+class ImageOutputDev : public OutputDev
+{
public:
- enum ImageType {
- imgImage,
- imgStencil,
- imgMask,
- imgSmask
- };
- enum ImageFormat {
- imgRGB,
- imgRGB48,
- imgGray,
- imgMonochrome,
- imgCMYK
- };
-
- // Create an OutputDev which will write images to files named
- // <fileRoot>-NNN.<type> or <fileRoot>-PPP-NNN.<type>, if
- // <pageNames> is set. Normally, all images are written as PBM
- // (.pbm) or PPM (.ppm) files unless PNG or Tiff output is enabled
- // (PNG is used if both are enabled). If Jpeg is enabled, JPEG images
- // are written as JPEG (.jpg) files.
- ImageOutputDev(char *fileRootA, bool pageNamesA, bool listImagesA);
-
- // Destructor.
- ~ImageOutputDev() override;
-
- // Use PNG format for output
- void enablePNG(bool png) { outputPNG = png; }
-
- // Use TIFF format for output
- void enableTiff(bool tiff) { outputTiff = tiff; }
-
- // Use Jpeg format for Jpeg files
- void enableJpeg(bool jpeg) { dumpJPEG = jpeg; }
-
- // Use Jpeg2000 format for Jpeg2000 files
- void enableJpeg2000(bool jp2) { dumpJP2 = jp2; }
-
- // Use JBIG2 format for JBIG2 files
- void enableJBig2(bool jbig2) { dumpJBIG2 = jbig2; }
-
- // Use CCITT format for CCITT files
- void enableCCITT(bool ccitt) { dumpCCITT = ccitt; }
-
- // Check if file was successfully created.
- virtual bool isOk() { return ok; }
-
- // Does this device use tilingPatternFill()? If this returns false,
- // tiling pattern fills will be reduced to a series of other drawing
- // operations.
- bool useTilingPatternFill() override { return true; }
-
- // Does this device use beginType3Char/endType3Char? Otherwise,
- // text in Type 3 fonts will be drawn with drawChar/drawString.
- bool interpretType3Chars() override { return false; }
-
- // Does this device need non-text content?
- bool needNonText() override { return true; }
-
- // Start a page
- void startPage(int pageNumA, GfxState *state, XRef *xref) override
- { pageNum = pageNumA; }
-
- //---- get info about output device
-
- // Does this device use upside-down coordinates?
- // (Upside-down means (0,0) is the top left corner of the page.)
- bool upsideDown() override { return true; }
-
- // Does this device use drawChar() or drawString()?
- bool useDrawChar() override { return false; }
-
- //----- path painting
- bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str,
- const double *pmat, int paintType, int tilingType, Dict *resDict,
- const double *mat, const double *bbox,
- int x0, int y0, int x1, int y1,
- double xStep, double yStep) override;
-
- //----- image drawing
- void drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, bool invert,
- bool interpolate, bool inlineImg) override;
- void drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
- bool interpolate, const int *maskColors, bool inlineImg) override;
- void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- bool interpolate,
- Stream *maskStr, int maskWidth, int maskHeight,
- bool maskInvert, bool maskInterpolate) override;
- void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- bool interpolate,
- Stream *maskStr,
- int maskWidth, int maskHeight,
- GfxImageColorMap *maskColorMap,
- bool maskInterpolate) override;
+ enum ImageType
+ {
+ imgImage,
+ imgStencil,
+ imgMask,
+ imgSmask
+ };
+ enum ImageFormat
+ {
+ imgRGB,
+ imgRGB48,
+ imgGray,
+ imgMonochrome,
+ imgCMYK
+ };
+
+ // Create an OutputDev which will write images to files named
+ // <fileRoot>-NNN.<type> or <fileRoot>-PPP-NNN.<type>, if
+ // <pageNames> is set. Normally, all images are written as PBM
+ // (.pbm) or PPM (.ppm) files unless PNG or Tiff output is enabled
+ // (PNG is used if both are enabled). If Jpeg is enabled, JPEG images
+ // are written as JPEG (.jpg) files.
+ ImageOutputDev(char *fileRootA, bool pageNamesA, bool listImagesA);
+
+ // Destructor.
+ ~ImageOutputDev() override;
+
+ // Use PNG format for output
+ void enablePNG(bool png) { outputPNG = png; }
+
+ // Use TIFF format for output
+ void enableTiff(bool tiff) { outputTiff = tiff; }
+
+ // Use Jpeg format for Jpeg files
+ void enableJpeg(bool jpeg) { dumpJPEG = jpeg; }
+
+ // Use Jpeg2000 format for Jpeg2000 files
+ void enableJpeg2000(bool jp2) { dumpJP2 = jp2; }
+
+ // Use JBIG2 format for JBIG2 files
+ void enableJBig2(bool jbig2) { dumpJBIG2 = jbig2; }
+
+ // Use CCITT format for CCITT files
+ void enableCCITT(bool ccitt) { dumpCCITT = ccitt; }
+
+ // Check if file was successfully created.
+ virtual bool isOk() { return ok; }
+
+ // Does this device use tilingPatternFill()? If this returns false,
+ // tiling pattern fills will be reduced to a series of other drawing
+ // operations.
+ bool useTilingPatternFill() override { return true; }
+
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ bool interpretType3Chars() override { return false; }
+
+ // Does this device need non-text content?
+ bool needNonText() override { return true; }
+
+ // Start a page
+ void startPage(int pageNumA, GfxState *state, XRef *xref) override { pageNum = pageNumA; }
+
+ //---- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ bool upsideDown() override { return true; }
+
+ // Does this device use drawChar() or drawString()?
+ bool useDrawChar() override { return false; }
+
+ //----- path painting
+ bool tilingPatternFill(GfxState *state, Gfx *gfx, Catalog *cat, Object *str, const double *pmat, int paintType, int tilingType, Dict *resDict, const double *mat, const double *bbox, int x0, int y0, int x1, int y1, double xStep,
+ double yStep) override;
+
+ //----- image drawing
+ void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override;
+ void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override;
+ void drawMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, bool maskInvert, bool maskInterpolate) override;
+ void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap,
+ bool maskInterpolate) override;
private:
- // Sets the output filename with a given file extension
- void setFilename(const char *fileExt);
- void listImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- bool interpolate, bool inlineImg,
- ImageType imageType);
- void writeImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap, bool inlineImg);
- void writeRawImage(Stream *str, const char *ext);
- void writeImageFile(ImgWriter *writer, ImageFormat format, const char *ext,
- Stream *str, int width, int height, GfxImageColorMap *colorMap);
- long getInlineImageLength(Stream *str, int width, int height, GfxImageColorMap *colorMap);
-
- char *fileRoot; // root of output file names
- char *fileName; // buffer for output file names
- bool listImages; // list images instead of dumping
- bool dumpJPEG; // set to dump native JPEG files
- bool dumpJP2; // set to dump native JPEG2000 files
- bool dumpJBIG2; // set to dump native JBIG2 files
- bool dumpCCITT; // set to dump native CCITT files
- bool outputPNG; // set to output in PNG format
- bool outputTiff; // set to output in TIFF format
- bool pageNames; // set to include page number in file names
- int pageNum; // current page number
- int imgNum; // current image number
- bool ok; // set up ok?
+ // Sets the output filename with a given file extension
+ void setFilename(const char *fileExt);
+ void listImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, bool inlineImg, ImageType imageType);
+ void writeImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool inlineImg);
+ void writeRawImage(Stream *str, const char *ext);
+ void writeImageFile(ImgWriter *writer, ImageFormat format, const char *ext, Stream *str, int width, int height, GfxImageColorMap *colorMap);
+ long getInlineImageLength(Stream *str, int width, int height, GfxImageColorMap *colorMap);
+
+ char *fileRoot; // root of output file names
+ char *fileName; // buffer for output file names
+ bool listImages; // list images instead of dumping
+ bool dumpJPEG; // set to dump native JPEG files
+ bool dumpJP2; // set to dump native JPEG2000 files
+ bool dumpJBIG2; // set to dump native JBIG2 files
+ bool dumpCCITT; // set to dump native CCITT files
+ bool outputPNG; // set to output in PNG format
+ bool outputTiff; // set to output in TIFF format
+ bool pageNames; // set to include page number in file names
+ int pageNum; // current page number
+ int imgNum; // current image number
+ bool ok; // set up ok?
};
#endif
diff --git a/utils/InMemoryFile.cc b/utils/InMemoryFile.cc
index 56225381..b4e09e60 100644
--- a/utils/InMemoryFile.cc
+++ b/utils/InMemoryFile.cc
@@ -20,14 +20,10 @@
#include <cstring>
#include <sstream>
-InMemoryFile::InMemoryFile()
- : iohead(0)
- , fptr(nullptr)
-{
-}
+InMemoryFile::InMemoryFile() : iohead(0), fptr(nullptr) { }
#ifdef HAVE_IN_MEMORY_FILE_FOPENCOOKIE
-ssize_t InMemoryFile::_read(char* buf, size_t sz)
+ssize_t InMemoryFile::_read(char *buf, size_t sz)
{
auto toRead = std::min<size_t>(data.size() - iohead, sz);
memcpy(&buf[0], &data[iohead], toRead);
@@ -35,21 +31,27 @@ ssize_t InMemoryFile::_read(char* buf, size_t sz)
return toRead;
}
-ssize_t InMemoryFile::_write(const char* buf, size_t sz)
+ssize_t InMemoryFile::_write(const char *buf, size_t sz)
{
if (iohead + sz > data.size())
data.resize(iohead + sz);
memcpy(&data[iohead], buf, sz);
iohead += sz;
- return sz;
+ return sz;
}
-int InMemoryFile::_seek(off64_t* offset, int whence)
+int InMemoryFile::_seek(off64_t *offset, int whence)
{
switch (whence) {
- case SEEK_SET: iohead = (*offset); break;
- case SEEK_CUR: iohead += (*offset); break;
- case SEEK_END: iohead -= (*offset); break;
+ case SEEK_SET:
+ iohead = (*offset);
+ break;
+ case SEEK_CUR:
+ iohead += (*offset);
+ break;
+ case SEEK_END:
+ iohead -= (*offset);
+ break;
}
(*offset) = std::min<off64_t>(std::max<off64_t>(iohead, 0l), data.size());
iohead = static_cast<size_t>(*offset);
@@ -57,7 +59,7 @@ int InMemoryFile::_seek(off64_t* offset, int whence)
}
#endif // def HAVE_IN_MEMORY_FILE_FOPENCOOKIE
-FILE* InMemoryFile::open(const char* mode)
+FILE *InMemoryFile::open(const char *mode)
{
#ifdef HAVE_IN_MEMORY_FILE_FOPENCOOKIE
if (fptr != nullptr) {
@@ -65,14 +67,18 @@ FILE* InMemoryFile::open(const char* mode)
return nullptr; // maybe there's some legit reason for it, whoever comes up with one can remove this line
}
static const cookie_io_functions_t methods = {
- /* .read = */ [](void* self, char* buf, size_t sz) { return ((InMemoryFile*)self)->_read(buf, sz); },
- /* .write = */ [](void* self, const char* buf, size_t sz) { return ((InMemoryFile*)self)->_write(buf, sz); },
- /* .seek = */ [](void* self, off64_t* offset, int whence) { return ((InMemoryFile*)self)->_seek(offset, whence); },
- /* .close = */ [](void* self) { ((InMemoryFile*)self)->fptr = nullptr; return 0; },
+ /* .read = */ [](void *self, char *buf, size_t sz) { return ((InMemoryFile *)self)->_read(buf, sz); },
+ /* .write = */ [](void *self, const char *buf, size_t sz) { return ((InMemoryFile *)self)->_write(buf, sz); },
+ /* .seek = */ [](void *self, off64_t *offset, int whence) { return ((InMemoryFile *)self)->_seek(offset, whence); },
+ /* .close = */
+ [](void *self) {
+ ((InMemoryFile *)self)->fptr = nullptr;
+ return 0;
+ },
};
return fptr = fopencookie(this, mode, methods);
#else
- fprintf (stderr, "If you can read this, your platform does not support the features necessary to achieve your goals.");
+ fprintf(stderr, "If you can read this, your platform does not support the features necessary to achieve your goals.");
return nullptr;
#endif
}
diff --git a/utils/InMemoryFile.h b/utils/InMemoryFile.h
index 5a6ab9e8..5e16ad09 100644
--- a/utils/InMemoryFile.h
+++ b/utils/InMemoryFile.h
@@ -22,20 +22,21 @@
#include <vector>
#if defined(__USE_GNU) && !defined(__ANDROID_API__)
-# define HAVE_IN_MEMORY_FILE (1)
-# define HAVE_IN_MEMORY_FILE_FOPENCOOKIE (1) // used internally
+# define HAVE_IN_MEMORY_FILE (1)
+# define HAVE_IN_MEMORY_FILE_FOPENCOOKIE (1) // used internally
#endif
-class InMemoryFile {
+class InMemoryFile
+{
private:
size_t iohead;
std::vector<char> data;
FILE *fptr;
#ifdef HAVE_IN_MEMORY_FILE_FOPENCOOKIE
- ssize_t _read(char* buf, size_t sz);
- ssize_t _write(const char* buf, size_t sz);
- int _seek(off64_t* offset, int whence);
+ ssize_t _read(char *buf, size_t sz);
+ ssize_t _write(const char *buf, size_t sz);
+ int _seek(off64_t *offset, int whence);
#endif
public:
@@ -44,10 +45,9 @@ public:
public:
/* Returns a file handle for this file. This is scoped to this object
* and must be fclosed() by the caller before destruction. */
- FILE* open(const char* mode);
+ FILE *open(const char *mode);
- const std::vector<char>& getBuffer() const
- { return data; }
+ const std::vector<char> &getBuffer() const { return data; }
};
#endif // IN_MEMORY_FILE_H
diff --git a/utils/Win32Console.cc b/utils/Win32Console.cc
index 60520ba5..ea46e17b 100644
--- a/utils/Win32Console.cc
+++ b/utils/Win32Console.cc
@@ -13,14 +13,14 @@
#ifdef _WIN32
-#include "goo/gmem.h"
-#include "UTF.h"
+# include "goo/gmem.h"
+# include "UTF.h"
-#define WIN32_CONSOLE_IMPL
-#include "Win32Console.h"
+# define WIN32_CONSOLE_IMPL
+# include "Win32Console.h"
-#include <windows.h>
-#include <shellapi.h>
+# include <windows.h>
+# include <shellapi.h>
static const int BUF_SIZE = 4096;
static int bufLen = 0;
@@ -36,132 +36,129 @@ static HANDLE consoleHandle = nullptr;
// writes.
static void flush(bool all = false)
{
- int nchars = 0;
-
- if (all || bufLen > BUF_SIZE/2) {
- nchars = bufLen;
- } else if (bufLen > 0) {
- // find num chars up to and including last '\n'
- for (nchars = bufLen; nchars > 0; --nchars) {
- if (buf[nchars-1] == '\n')
- break;
+ int nchars = 0;
+
+ if (all || bufLen > BUF_SIZE / 2) {
+ nchars = bufLen;
+ } else if (bufLen > 0) {
+ // find num chars up to and including last '\n'
+ for (nchars = bufLen; nchars > 0; --nchars) {
+ if (buf[nchars - 1] == '\n')
+ break;
+ }
}
- }
-
- if (nchars > 0) {
- DWORD wlen = utf8ToUtf16(buf, (uint16_t*)wbuf, BUF_SIZE, nchars);
- WriteConsoleW(consoleHandle, wbuf, wlen, &wlen, nullptr);
- if (nchars < bufLen) {
- memmove(buf, buf + nchars, bufLen - nchars);
- bufLen -= nchars;
- } else {
- bufLen = 0;
+
+ if (nchars > 0) {
+ DWORD wlen = utf8ToUtf16(buf, (uint16_t *)wbuf, BUF_SIZE, nchars);
+ WriteConsoleW(consoleHandle, wbuf, wlen, &wlen, nullptr);
+ if (nchars < bufLen) {
+ memmove(buf, buf + nchars, bufLen - nchars);
+ bufLen -= nchars;
+ } else {
+ bufLen = 0;
+ }
}
- }
}
static inline bool streamIsConsole(FILE *stream)
{
- return ((stream == stdout && stdoutIsConsole) || (stream == stderr && stderrIsConsole));
+ return ((stream == stdout && stdoutIsConsole) || (stream == stderr && stderrIsConsole));
}
int win32_fprintf(FILE *stream, ...)
{
- va_list args;
- int ret = 0;
-
- va_start(args, stream);
- const char *format = va_arg(args, const char *);
- if (streamIsConsole(stream)) {
- ret = vsnprintf(buf + bufLen, BUF_SIZE - bufLen, format, args);
- bufLen += ret;
- if (ret >= BUF_SIZE - bufLen) {
- // output was truncated
- buf[BUF_SIZE - 1] = 0;
- bufLen = BUF_SIZE - 1;
+ va_list args;
+ int ret = 0;
+
+ va_start(args, stream);
+ const char *format = va_arg(args, const char *);
+ if (streamIsConsole(stream)) {
+ ret = vsnprintf(buf + bufLen, BUF_SIZE - bufLen, format, args);
+ bufLen += ret;
+ if (ret >= BUF_SIZE - bufLen) {
+ // output was truncated
+ buf[BUF_SIZE - 1] = 0;
+ bufLen = BUF_SIZE - 1;
+ }
+ flush();
+ } else {
+ vfprintf(stream, format, args);
}
- flush();
- } else {
- vfprintf(stream, format, args);
- }
- va_end(args);
+ va_end(args);
- return ret;
+ return ret;
}
size_t win32_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
- size_t ret = 0;
-
- if (streamIsConsole(stream)) {
- int n = size * nmemb;
- if (n > BUF_SIZE - bufLen - 1)
- n = BUF_SIZE - bufLen - 1;
- memcpy(buf + bufLen, ptr, n);
- bufLen += n;
- buf[bufLen] = 0;
- flush();
- } else {
- ret = fwrite(ptr, size, nmemb, stream);
- }
-
- return ret;
-}
+ size_t ret = 0;
+
+ if (streamIsConsole(stream)) {
+ int n = size * nmemb;
+ if (n > BUF_SIZE - bufLen - 1)
+ n = BUF_SIZE - bufLen - 1;
+ memcpy(buf + bufLen, ptr, n);
+ bufLen += n;
+ buf[bufLen] = 0;
+ flush();
+ } else {
+ ret = fwrite(ptr, size, nmemb, stream);
+ }
+ return ret;
+}
Win32Console::Win32Console(int *argc, char **argv[])
{
- LPWSTR *wargv;
- fpos_t pos;
-
- argList = nullptr;
- privateArgList = nullptr;
- wargv = CommandLineToArgvW(GetCommandLineW(), &numArgs);
- if (wargv) {
- argList = new char*[numArgs];
- privateArgList = new char*[numArgs];
- for (int i = 0; i < numArgs; i++) {
- argList[i] = utf16ToUtf8((uint16_t*)(wargv[i]));
- // parseArgs will rearrange the argv list so we keep our own copy
- // to use for freeing all the strings
- privateArgList[i] = argList[i];
+ LPWSTR *wargv;
+ fpos_t pos;
+
+ argList = nullptr;
+ privateArgList = nullptr;
+ wargv = CommandLineToArgvW(GetCommandLineW(), &numArgs);
+ if (wargv) {
+ argList = new char *[numArgs];
+ privateArgList = new char *[numArgs];
+ for (int i = 0; i < numArgs; i++) {
+ argList[i] = utf16ToUtf8((uint16_t *)(wargv[i]));
+ // parseArgs will rearrange the argv list so we keep our own copy
+ // to use for freeing all the strings
+ privateArgList[i] = argList[i];
+ }
+ LocalFree(wargv);
+ *argc = numArgs;
+ *argv = argList;
}
- LocalFree(wargv);
- *argc = numArgs;
- *argv = argList;
- }
-
- bufLen = 0;
- buf[0] = 0;
- wbuf[0] = 0;
-
- // check if stdout or stderr redirected
- // GetFileType() returns CHAR for console and special devices COMx, PRN, CON, NUL etc
- // fgetpos() succeeds on all CHAR devices except console and CON.
-
- stdoutIsConsole = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_CHAR)
- && (fgetpos(stdout, &pos) != 0);
-
- stderrIsConsole = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_CHAR)
- && (fgetpos(stderr, &pos) != 0);
-
- // Need a handle to the console. Doesn't matter if we use stdout or stderr as
- // long as the handle output is to the console.
- if (stdoutIsConsole)
- consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
- else if (stderrIsConsole)
- consoleHandle = GetStdHandle(STD_ERROR_HANDLE);
+
+ bufLen = 0;
+ buf[0] = 0;
+ wbuf[0] = 0;
+
+ // check if stdout or stderr redirected
+ // GetFileType() returns CHAR for console and special devices COMx, PRN, CON, NUL etc
+ // fgetpos() succeeds on all CHAR devices except console and CON.
+
+ stdoutIsConsole = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_CHAR) && (fgetpos(stdout, &pos) != 0);
+
+ stderrIsConsole = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_CHAR) && (fgetpos(stderr, &pos) != 0);
+
+ // Need a handle to the console. Doesn't matter if we use stdout or stderr as
+ // long as the handle output is to the console.
+ if (stdoutIsConsole)
+ consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+ else if (stderrIsConsole)
+ consoleHandle = GetStdHandle(STD_ERROR_HANDLE);
}
Win32Console::~Win32Console()
{
- flush(true);
- if (argList) {
- for (int i = 0; i < numArgs; i++)
- gfree(privateArgList[i]);
- delete[] argList;
- delete[] privateArgList;
- }
+ flush(true);
+ if (argList) {
+ for (int i = 0; i < numArgs; i++)
+ gfree(privateArgList[i]);
+ delete[] argList;
+ delete[] privateArgList;
+ }
}
#endif // _WIN32
diff --git a/utils/Win32Console.h b/utils/Win32Console.h
index a1ef6efc..a2d13924 100644
--- a/utils/Win32Console.h
+++ b/utils/Win32Console.h
@@ -26,33 +26,34 @@
// Ensure stdio.h is included before redefining stdio functions. We need to provide
// our own declarations for the redefined functions because win32 stdio.h functions
// have DLL export decorations.
-#include <cstdio>
+# include <cstdio>
-#ifndef WIN32_CONSOLE_IMPL // don't redefine in Win32Console.cc so we can call original functions
-#define printf(...) win32_fprintf(stdout, __VA_ARGS__)
-#define fprintf(stream, ...) win32_fprintf(stream, __VA_ARGS__)
-#define puts(s) win32_fprintf(stdout, "%s\n", s)
-#define fputs(s, stream) win32_fprintf(stream, "%s", s)
-#define putc(c) win32_fprintf(stdout, "%c", c)
-#define putchar(c) win32_fprintf(stdout, "%c", c)
-#define fputc(c, stream) win32_fprintf(stream, "%c", c)
-#define fwrite(ptr, size, nmemb, stream) win32_fwrite(ptr, size, nmemb, stream)
-#endif
+# ifndef WIN32_CONSOLE_IMPL // don't redefine in Win32Console.cc so we can call original functions
+# define printf(...) win32_fprintf(stdout, __VA_ARGS__)
+# define fprintf(stream, ...) win32_fprintf(stream, __VA_ARGS__)
+# define puts(s) win32_fprintf(stdout, "%s\n", s)
+# define fputs(s, stream) win32_fprintf(stream, "%s", s)
+# define putc(c) win32_fprintf(stdout, "%c", c)
+# define putchar(c) win32_fprintf(stdout, "%c", c)
+# define fputc(c, stream) win32_fprintf(stream, "%c", c)
+# define fwrite(ptr, size, nmemb, stream) win32_fwrite(ptr, size, nmemb, stream)
+# endif
extern "C" {
- int win32_fprintf(FILE *stream, ...);
- size_t win32_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
+int win32_fprintf(FILE *stream, ...);
+size_t win32_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
}
class Win32Console
{
public:
- Win32Console(int *argc, char **argv[]);
- ~Win32Console();
+ Win32Console(int *argc, char **argv[]);
+ ~Win32Console();
+
private:
- int numArgs;
- char **argList;
- char **privateArgList;
+ int numArgs;
+ char **argList;
+ char **privateArgList;
};
#else
@@ -62,7 +63,7 @@ private:
class Win32Console
{
public:
- Win32Console(int *argc, char ***argv) {}
+ Win32Console(int *argc, char ***argv) { }
};
#endif // _WIN32
diff --git a/utils/numberofcharacters.h b/utils/numberofcharacters.h
index 1b01faba..3915b0d8 100644
--- a/utils/numberofcharacters.h
+++ b/utils/numberofcharacters.h
@@ -13,14 +13,13 @@
static int numberOfCharacters(unsigned int n)
{
- int charNum = 0;
- while (n >= 10)
- {
- n = n / 10;
+ int charNum = 0;
+ while (n >= 10) {
+ n = n / 10;
+ charNum++;
+ }
charNum++;
- }
- charNum++;
- return charNum;
+ return charNum;
}
#endif
diff --git a/utils/parseargs.cc b/utils/parseargs.cc
index 9baa4567..89e9453f 100644
--- a/utils/parseargs.cc
+++ b/utils/parseargs.cc
@@ -36,185 +36,191 @@
static const ArgDesc *findArg(const ArgDesc *args, char *arg);
static bool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[]);
-bool parseArgs(const ArgDesc *args, int *argc, char *argv[]) {
- const ArgDesc *arg;
- int i, j;
- bool ok;
-
- ok = true;
- i = 1;
- while (i < *argc) {
- if (!strcmp(argv[i], "--")) {
- --*argc;
- for (j = i; j < *argc; ++j)
- argv[j] = argv[j+1];
- break;
- } else if ((arg = findArg(args, argv[i]))) {
- if (!grabArg(arg, i, argc, argv))
- ok = false;
- } else {
- ++i;
+bool parseArgs(const ArgDesc *args, int *argc, char *argv[])
+{
+ const ArgDesc *arg;
+ int i, j;
+ bool ok;
+
+ ok = true;
+ i = 1;
+ while (i < *argc) {
+ if (!strcmp(argv[i], "--")) {
+ --*argc;
+ for (j = i; j < *argc; ++j)
+ argv[j] = argv[j + 1];
+ break;
+ } else if ((arg = findArg(args, argv[i]))) {
+ if (!grabArg(arg, i, argc, argv))
+ ok = false;
+ } else {
+ ++i;
+ }
}
- }
- return ok;
+ return ok;
}
-void printUsage(const char *program, const char *otherArgs, const ArgDesc *args) {
- const ArgDesc *arg;
- const char *typ;
- int w, w1;
-
- w = 0;
- for (arg = args; arg->arg; ++arg) {
- if ((w1 = strlen(arg->arg)) > w)
- w = w1;
- }
-
- fprintf(stderr, "Usage: %s [options]", program);
- if (otherArgs)
- fprintf(stderr, " %s", otherArgs);
- fprintf(stderr, "\n");
-
- for (arg = args; arg->arg; ++arg) {
- fprintf(stderr, " %s", arg->arg);
- w1 = 9 + w - strlen(arg->arg);
- switch (arg->kind) {
- case argInt:
- case argIntDummy:
- typ = " <int>";
- break;
- case argFP:
- case argFPDummy:
- typ = " <fp>";
- break;
- case argString:
- case argStringDummy:
- case argGooString:
- typ = " <string>";
- break;
- case argFlag:
- case argFlagDummy:
- default:
- typ = "";
- break;
+void printUsage(const char *program, const char *otherArgs, const ArgDesc *args)
+{
+ const ArgDesc *arg;
+ const char *typ;
+ int w, w1;
+
+ w = 0;
+ for (arg = args; arg->arg; ++arg) {
+ if ((w1 = strlen(arg->arg)) > w)
+ w = w1;
}
- fprintf(stderr, "%-*s", w1, typ);
- if (arg->usage)
- fprintf(stderr, ": %s", arg->usage);
+
+ fprintf(stderr, "Usage: %s [options]", program);
+ if (otherArgs)
+ fprintf(stderr, " %s", otherArgs);
fprintf(stderr, "\n");
- }
+
+ for (arg = args; arg->arg; ++arg) {
+ fprintf(stderr, " %s", arg->arg);
+ w1 = 9 + w - strlen(arg->arg);
+ switch (arg->kind) {
+ case argInt:
+ case argIntDummy:
+ typ = " <int>";
+ break;
+ case argFP:
+ case argFPDummy:
+ typ = " <fp>";
+ break;
+ case argString:
+ case argStringDummy:
+ case argGooString:
+ typ = " <string>";
+ break;
+ case argFlag:
+ case argFlagDummy:
+ default:
+ typ = "";
+ break;
+ }
+ fprintf(stderr, "%-*s", w1, typ);
+ if (arg->usage)
+ fprintf(stderr, ": %s", arg->usage);
+ fprintf(stderr, "\n");
+ }
}
-static const ArgDesc *findArg(const ArgDesc *args, char *arg) {
- const ArgDesc *p;
+static const ArgDesc *findArg(const ArgDesc *args, char *arg)
+{
+ const ArgDesc *p;
- for (p = args; p->arg; ++p) {
- if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
- return p;
- }
- return nullptr;
+ for (p = args; p->arg; ++p) {
+ if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
+ return p;
+ }
+ return nullptr;
}
-static bool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[]) {
- int n;
- int j;
- bool ok;
-
- ok = true;
- n = 0;
- switch (arg->kind) {
- case argFlag:
- *(bool *)arg->val = true;
- n = 1;
- break;
- case argInt:
- if (i + 1 < *argc && isInt(argv[i+1])) {
- *(int *)arg->val = atoi(argv[i+1]);
- n = 2;
- } else {
- ok = false;
- n = 1;
- }
- break;
- case argFP:
- if (i + 1 < *argc && isFP(argv[i+1])) {
- *(double *)arg->val = gatof(argv[i+1]);
- n = 2;
- } else {
- ok = false;
- n = 1;
- }
- break;
- case argString:
- if (i + 1 < *argc) {
- strncpy((char *)arg->val, argv[i+1], arg->size - 1);
- ((char *)arg->val)[arg->size - 1] = '\0';
- n = 2;
- } else {
- ok = false;
- n = 1;
+static bool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[])
+{
+ int n;
+ int j;
+ bool ok;
+
+ ok = true;
+ n = 0;
+ switch (arg->kind) {
+ case argFlag:
+ *(bool *)arg->val = true;
+ n = 1;
+ break;
+ case argInt:
+ if (i + 1 < *argc && isInt(argv[i + 1])) {
+ *(int *)arg->val = atoi(argv[i + 1]);
+ n = 2;
+ } else {
+ ok = false;
+ n = 1;
+ }
+ break;
+ case argFP:
+ if (i + 1 < *argc && isFP(argv[i + 1])) {
+ *(double *)arg->val = gatof(argv[i + 1]);
+ n = 2;
+ } else {
+ ok = false;
+ n = 1;
+ }
+ break;
+ case argString:
+ if (i + 1 < *argc) {
+ strncpy((char *)arg->val, argv[i + 1], arg->size - 1);
+ ((char *)arg->val)[arg->size - 1] = '\0';
+ n = 2;
+ } else {
+ ok = false;
+ n = 1;
+ }
+ break;
+ case argGooString:
+ if (i + 1 < *argc) {
+ ((GooString *)arg->val)->Set(argv[i + 1]);
+ n = 2;
+ } else {
+ ok = false;
+ n = 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Internal error in arg table\n");
+ n = 1;
+ break;
}
- break;
- case argGooString:
- if (i + 1 < *argc) {
- ((GooString*)arg->val)->Set(argv[i+1]);
- n = 2;
- } else {
- ok = false;
- n = 1;
+ if (n > 0) {
+ *argc -= n;
+ for (j = i; j < *argc; ++j)
+ argv[j] = argv[j + n];
}
- break;
- default:
- fprintf(stderr, "Internal error in arg table\n");
- n = 1;
- break;
- }
- if (n > 0) {
- *argc -= n;
- for (j = i; j < *argc; ++j)
- argv[j] = argv[j+n];
- }
- return ok;
+ return ok;
}
-bool isInt(const char *s) {
- if (*s == '-' || *s == '+')
- ++s;
- while (isdigit(*s))
- ++s;
- if (*s)
- return false;
- return true;
+bool isInt(const char *s)
+{
+ if (*s == '-' || *s == '+')
+ ++s;
+ while (isdigit(*s))
+ ++s;
+ if (*s)
+ return false;
+ return true;
}
-bool isFP(const char *s) {
- int n;
-
- if (*s == '-' || *s == '+')
- ++s;
- n = 0;
- while (isdigit(*s)) {
- ++s;
- ++n;
- }
- if (*s == '.')
- ++s;
- while (isdigit(*s)) {
- ++s;
- ++n;
- }
- if (n > 0 && (*s == 'e' || *s == 'E')) {
- ++s;
+bool isFP(const char *s)
+{
+ int n;
+
if (*s == '-' || *s == '+')
- ++s;
+ ++s;
n = 0;
- if (!isdigit(*s))
- return false;
- do {
- ++s;
- } while (isdigit(*s));
- }
- if (*s)
- return false;
- return true;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (*s == '.')
+ ++s;
+ while (isdigit(*s)) {
+ ++s;
+ ++n;
+ }
+ if (n > 0 && (*s == 'e' || *s == 'E')) {
+ ++s;
+ if (*s == '-' || *s == '+')
+ ++s;
+ n = 0;
+ if (!isdigit(*s))
+ return false;
+ do {
+ ++s;
+ } while (isdigit(*s));
+ }
+ if (*s)
+ return false;
+ return true;
}
diff --git a/utils/parseargs.h b/utils/parseargs.h
index c3ebb7cd..d927e56e 100644
--- a/utils/parseargs.h
+++ b/utils/parseargs.h
@@ -31,34 +31,36 @@ extern "C" {
/*
* Argument kinds.
*/
-typedef enum {
- argFlag, /* flag (present / not-present) */
- /* [val: bool *] */
- argInt, /* integer arg */
- /* [val: int *] */
- argFP, /* floating point arg */
- /* [val: double *] */
- argString, /* string arg */
- /* [val: char *] */
- argGooString, /* string arg */
- /* [val: GooString *] */
- /* dummy entries -- these show up in the usage listing only; */
- /* useful for X args, for example */
- argFlagDummy,
- argIntDummy,
- argFPDummy,
- argStringDummy
+typedef enum
+{
+ argFlag, /* flag (present / not-present) */
+ /* [val: bool *] */
+ argInt, /* integer arg */
+ /* [val: int *] */
+ argFP, /* floating point arg */
+ /* [val: double *] */
+ argString, /* string arg */
+ /* [val: char *] */
+ argGooString, /* string arg */
+ /* [val: GooString *] */
+ /* dummy entries -- these show up in the usage listing only; */
+ /* useful for X args, for example */
+ argFlagDummy,
+ argIntDummy,
+ argFPDummy,
+ argStringDummy
} ArgKind;
/*
* Argument descriptor.
*/
-typedef struct {
- const char *arg; /* the command line switch */
- ArgKind kind; /* kind of arg */
- void *val; /* place to store value */
- int size; /* for argString: size of string */
- const char *usage; /* usage string */
+typedef struct
+{
+ const char *arg; /* the command line switch */
+ ArgKind kind; /* kind of arg */
+ void *val; /* place to store value */
+ int size; /* for argString: size of string */
+ const char *usage; /* usage string */
} ArgDesc;
/*
diff --git a/utils/pdfattach.cc b/utils/pdfattach.cc
index f4f71cbb..192a0096 100644
--- a/utils/pdfattach.cc
+++ b/utils/pdfattach.cc
@@ -27,86 +27,79 @@ static bool doReplace = false;
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-replace", argFlag, &doReplace, 0,
- "replace embedded file with same name (if it exists)"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- { }
-};
+static const ArgDesc argDesc[] = { { "-replace", argFlag, &doReplace, 0, "replace embedded file with same name (if it exists)" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
static bool fileExists(const char *filePath)
{
- FILE *f = openFile(filePath, "r");
- if (f != nullptr) {
- fclose(f);
- return true;
- }
- return false;
+ FILE *f = openFile(filePath, "r");
+ if (f != nullptr) {
+ fclose(f);
+ return true;
+ }
+ return false;
}
-int main(int argc, char *argv[]) {
- Win32Console win32Console(&argc, &argv);
-
- // parse args
- const bool ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 4 || printVersion || printHelp) {
- fprintf(stderr, "pdfattach version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfattach", "<input-PDF-file> <file-to-attach> <output-PDF-file>", argDesc);
+int main(int argc, char *argv[])
+{
+ Win32Console win32Console(&argc, &argv);
+
+ // parse args
+ const bool ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc != 4 || printVersion || printHelp) {
+ fprintf(stderr, "pdfattach version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfattach", "<input-PDF-file> <file-to-attach> <output-PDF-file>", argDesc);
+ }
+ return 99;
}
- return 99;
- }
- const GooString pdfFileName(argv[1]);
- const GooString attachFilePath(argv[2]);
-
- // init GlobalParams
- globalParams = std::make_unique<GlobalParams>();
-
- // open PDF file
- std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(pdfFileName, nullptr, nullptr));
-
- if (!doc->isOk()) {
- fprintf(stderr, "Couldn't open %s\n", pdfFileName.c_str());
- return 1;
- }
-
- std::unique_ptr<GooFile> attachFile(GooFile::open(&attachFilePath));
- if (!attachFile) {
- fprintf(stderr, "Couldn't open %s\n", attachFilePath.c_str());
- return 2;
- }
-
- if (fileExists(argv[3])) {
- fprintf(stderr, "File %s already exists.\n", argv[3]);
- return 3;
- }
-
- const std::string attachFileName = gbasename(attachFilePath.c_str());
-
- if (!doReplace && doc->getCatalog()->hasEmbeddedFile(attachFileName)) {
- fprintf(stderr, "There is already an embedded file named %s.\n", attachFileName.c_str());
- return 4;
- }
-
- doc->getCatalog()->addEmbeddedFile(attachFile.get(), attachFileName);
-
- const GooString outputPdfFilePath(argv[3]);
- const int saveResult = doc->saveAs(&outputPdfFilePath);
- if (saveResult != errNone) {
- fprintf(stderr, "Couldn't save the file properly.\n");
- return 5;
- }
-
- return 0;
+ const GooString pdfFileName(argv[1]);
+ const GooString attachFilePath(argv[2]);
+
+ // init GlobalParams
+ globalParams = std::make_unique<GlobalParams>();
+
+ // open PDF file
+ std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(pdfFileName, nullptr, nullptr));
+
+ if (!doc->isOk()) {
+ fprintf(stderr, "Couldn't open %s\n", pdfFileName.c_str());
+ return 1;
+ }
+
+ std::unique_ptr<GooFile> attachFile(GooFile::open(&attachFilePath));
+ if (!attachFile) {
+ fprintf(stderr, "Couldn't open %s\n", attachFilePath.c_str());
+ return 2;
+ }
+
+ if (fileExists(argv[3])) {
+ fprintf(stderr, "File %s already exists.\n", argv[3]);
+ return 3;
+ }
+
+ const std::string attachFileName = gbasename(attachFilePath.c_str());
+
+ if (!doReplace && doc->getCatalog()->hasEmbeddedFile(attachFileName)) {
+ fprintf(stderr, "There is already an embedded file named %s.\n", attachFileName.c_str());
+ return 4;
+ }
+
+ doc->getCatalog()->addEmbeddedFile(attachFile.get(), attachFileName);
+
+ const GooString outputPdfFilePath(argv[3]);
+ const int saveResult = doc->saveAs(&outputPdfFilePath);
+ if (saveResult != errNone) {
+ fprintf(stderr, "Couldn't save the file properly.\n");
+ return 5;
+ }
+
+ return 0;
}
diff --git a/utils/pdfdetach.cc b/utils/pdfdetach.cc
index 9e3efca5..78846ea4 100644
--- a/utils/pdfdetach.cc
+++ b/utils/pdfdetach.cc
@@ -55,299 +55,282 @@ static char userPassword[33] = "\001";
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-list", argFlag, &doList, 0,
- "list all embedded files"},
- {"-save", argInt, &saveNum, 0,
- "save the specified embedded file (file number)"},
- {"-savefile",argString, &saveFile, sizeof(saveFile),
- "save the specified embedded file (file name)"},
- {"-saveall", argFlag, &saveAll, 0,
- "save all embedded files"},
- {"-o", argString, savePath, sizeof(savePath),
- "file name for the saved embedded file"},
- {"-enc", argString, textEncName, sizeof(textEncName),
- "output text encoding name"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- { }
-};
+static const ArgDesc argDesc[] = { { "-list", argFlag, &doList, 0, "list all embedded files" },
+ { "-save", argInt, &saveNum, 0, "save the specified embedded file (file number)" },
+ { "-savefile", argString, &saveFile, sizeof(saveFile), "save the specified embedded file (file name)" },
+ { "-saveall", argFlag, &saveAll, 0, "save all embedded files" },
+ { "-o", argString, savePath, sizeof(savePath), "file name for the saved embedded file" },
+ { "-enc", argString, textEncName, sizeof(textEncName), "output text encoding name" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
-int main(int argc, char *argv[]) {
- GooString *fileName;
- const UnicodeMap *uMap;
- GooString *ownerPW, *userPW;
- PDFDoc *doc;
- char uBuf[8];
- char path[1024];
- char *p;
- bool ok;
- bool hasSaveFile;
- int exitCode;
- std::vector<FileSpec*> embeddedFiles;
- int nFiles, nPages, n, i, j;
- FileSpec *fileSpec;
- Page *page;
- Annots *annots;
- Annot *annot;
- const GooString *s1;
- Unicode u;
- bool isUnicode;
+int main(int argc, char *argv[])
+{
+ GooString *fileName;
+ const UnicodeMap *uMap;
+ GooString *ownerPW, *userPW;
+ PDFDoc *doc;
+ char uBuf[8];
+ char path[1024];
+ char *p;
+ bool ok;
+ bool hasSaveFile;
+ int exitCode;
+ std::vector<FileSpec *> embeddedFiles;
+ int nFiles, nPages, n, i, j;
+ FileSpec *fileSpec;
+ Page *page;
+ Annots *annots;
+ Annot *annot;
+ const GooString *s1;
+ Unicode u;
+ bool isUnicode;
- Win32Console win32Console(&argc, &argv);
- exitCode = 99;
+ Win32Console win32Console(&argc, &argv);
+ exitCode = 99;
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- hasSaveFile = strlen(saveFile) > 0;
- if ((doList ? 1 : 0) +
- ((saveNum != 0) ? 1 : 0) +
- ((hasSaveFile != 0) ? 1 : 0) +
- (saveAll ? 1 : 0) != 1) {
- ok = false;
- }
- if (!ok || argc != 2 || printVersion || printHelp) {
- fprintf(stderr, "pdfdetach version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfdetach", "<PDF-file>", argDesc);
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ hasSaveFile = strlen(saveFile) > 0;
+ if ((doList ? 1 : 0) + ((saveNum != 0) ? 1 : 0) + ((hasSaveFile != 0) ? 1 : 0) + (saveAll ? 1 : 0) != 1) {
+ ok = false;
}
- goto err0;
- }
- fileName = new GooString(argv[1]);
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
- if (textEncName[0]) {
- globalParams->setTextEncoding(textEncName);
- }
-
- // get mapping to output encoding
- if (!(uMap = globalParams->getTextEncoding())) {
- error(errConfig, -1, "Couldn't get text encoding");
- delete fileName;
- goto err0;
- }
-
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0] != '\001') {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
+ if (!ok || argc != 2 || printVersion || printHelp) {
+ fprintf(stderr, "pdfdetach version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfdetach", "<PDF-file>", argDesc);
+ }
+ goto err0;
+ }
+ fileName = new GooString(argv[1]);
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+ if (textEncName[0]) {
+ globalParams->setTextEncoding(textEncName);
+ }
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err2;
- }
+ // get mapping to output encoding
+ if (!(uMap = globalParams->getTextEncoding())) {
+ error(errConfig, -1, "Couldn't get text encoding");
+ delete fileName;
+ goto err0;
+ }
- for (i = 0; i < doc->getCatalog()->numEmbeddedFiles(); ++i)
- embeddedFiles.push_back(doc->getCatalog()->embeddedFile(i));
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = new GooString(ownerPassword);
+ } else {
+ ownerPW = nullptr;
+ }
+ if (userPassword[0] != '\001') {
+ userPW = new GooString(userPassword);
+ } else {
+ userPW = nullptr;
+ }
- nPages = doc->getCatalog()->getNumPages();
- for (i = 0; i < nPages; ++i) {
- page = doc->getCatalog()->getPage(i + 1);
- if (!page)
- continue;
- annots = page->getAnnots();
- if (!annots)
- break;
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- for (j = 0; j < annots->getNumAnnots(); ++j) {
- annot = annots->getAnnot(j);
- if (annot->getType() != Annot::typeFileAttachment)
- continue;
- embeddedFiles.push_back(new FileSpec(static_cast<AnnotFileAttachment *>(annot)->getFile()));
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err2;
}
- }
- nFiles = embeddedFiles.size();
+ for (i = 0; i < doc->getCatalog()->numEmbeddedFiles(); ++i)
+ embeddedFiles.push_back(doc->getCatalog()->embeddedFile(i));
- // list embedded files
- if (doList) {
- printf("%d embedded files\n", nFiles);
- for (i = 0; i < nFiles; ++i) {
- fileSpec = embeddedFiles[i];
- printf("%d: ", i+1);
- s1 = fileSpec->getFileName();
- if (!s1) {
- exitCode = 3;
- goto err2;
- }
- if (s1->hasUnicodeMarker()) {
- isUnicode = true;
- j = 2;
- } else {
- isUnicode = false;
- j = 0;
- }
- while (j < s1->getLength()) {
- if (isUnicode) {
- u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
- j += 2;
- } else {
- u = pdfDocEncoding[s1->getChar(j) & 0xff];
- ++j;
+ nPages = doc->getCatalog()->getNumPages();
+ for (i = 0; i < nPages; ++i) {
+ page = doc->getCatalog()->getPage(i + 1);
+ if (!page)
+ continue;
+ annots = page->getAnnots();
+ if (!annots)
+ break;
+
+ for (j = 0; j < annots->getNumAnnots(); ++j) {
+ annot = annots->getAnnot(j);
+ if (annot->getType() != Annot::typeFileAttachment)
+ continue;
+ embeddedFiles.push_back(new FileSpec(static_cast<AnnotFileAttachment *>(annot)->getFile()));
}
- n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
- fwrite(uBuf, 1, n, stdout);
- }
- fputc('\n', stdout);
}
- // save all embedded files
- } else if (saveAll) {
- for (i = 0; i < nFiles; ++i) {
- fileSpec = embeddedFiles[i];
- if (savePath[0]) {
- n = strlen(savePath);
- if (n > (int)sizeof(path) - 2) {
- n = sizeof(path) - 2;
- }
- memcpy(path, savePath, n);
- path[n] = '/';
- p = path + n + 1;
- } else {
- p = path;
- }
- s1 = fileSpec->getFileName();
- if (!s1) {
- exitCode = 3;
- goto err2;
- }
- if (s1->hasUnicodeMarker()) {
- isUnicode = true;
- j = 2;
- } else {
- isUnicode = false;
- j = 0;
- }
- while (j < s1->getLength()) {
- if (isUnicode) {
- u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
- j += 2;
- } else {
- u = pdfDocEncoding[s1->getChar(j) & 0xff];
- ++j;
+ nFiles = embeddedFiles.size();
+
+ // list embedded files
+ if (doList) {
+ printf("%d embedded files\n", nFiles);
+ for (i = 0; i < nFiles; ++i) {
+ fileSpec = embeddedFiles[i];
+ printf("%d: ", i + 1);
+ s1 = fileSpec->getFileName();
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
+ isUnicode = true;
+ j = 2;
+ } else {
+ isUnicode = false;
+ j = 0;
+ }
+ while (j < s1->getLength()) {
+ if (isUnicode) {
+ u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j + 1) & 0xff);
+ j += 2;
+ } else {
+ u = pdfDocEncoding[s1->getChar(j) & 0xff];
+ ++j;
+ }
+ n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
+ fwrite(uBuf, 1, n, stdout);
+ }
+ fputc('\n', stdout);
}
- n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
- if (p + n >= path + sizeof(path))
- break;
- memcpy(p, uBuf, n);
- p += n;
- }
- *p = '\0';
- auto *embFile = fileSpec->getEmbeddedFile();
- if (!embFile || !embFile->isOk()) {
- exitCode = 3;
- goto err2;
- }
- if (!embFile->save(path)) {
- error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
- exitCode = 2;
- goto err2;
- }
- }
+ // save all embedded files
+ } else if (saveAll) {
+ for (i = 0; i < nFiles; ++i) {
+ fileSpec = embeddedFiles[i];
+ if (savePath[0]) {
+ n = strlen(savePath);
+ if (n > (int)sizeof(path) - 2) {
+ n = sizeof(path) - 2;
+ }
+ memcpy(path, savePath, n);
+ path[n] = '/';
+ p = path + n + 1;
+ } else {
+ p = path;
+ }
+ s1 = fileSpec->getFileName();
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
+ isUnicode = true;
+ j = 2;
+ } else {
+ isUnicode = false;
+ j = 0;
+ }
+ while (j < s1->getLength()) {
+ if (isUnicode) {
+ u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j + 1) & 0xff);
+ j += 2;
+ } else {
+ u = pdfDocEncoding[s1->getChar(j) & 0xff];
+ ++j;
+ }
+ n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
+ if (p + n >= path + sizeof(path))
+ break;
+ memcpy(p, uBuf, n);
+ p += n;
+ }
+ *p = '\0';
- // save an embedded file
- } else {
- if (hasSaveFile) {
- for (i = 0; i < nFiles; ++i) {
- fileSpec = embeddedFiles[i];
- s1 = fileSpec->getFileName();
- if (strcmp(s1->c_str(), saveFile) == 0) {
- saveNum = i + 1;
- break;
+ auto *embFile = fileSpec->getEmbeddedFile();
+ if (!embFile || !embFile->isOk()) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (!embFile->save(path)) {
+ error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
+ exitCode = 2;
+ goto err2;
+ }
}
- }
- }
- if (saveNum < 1 || saveNum > nFiles) {
- error(errCommandLine, -1, hasSaveFile ? "Invalid file name" : "Invalid file number");
- goto err2;
- }
- fileSpec = embeddedFiles[saveNum - 1];
- if (savePath[0]) {
- p = savePath;
+ // save an embedded file
} else {
- p = path;
- s1 = fileSpec->getFileName();
- if (!s1) {
- exitCode = 3;
- goto err2;
- }
- if (s1->hasUnicodeMarker()) {
- isUnicode = true;
- j = 2;
- } else {
- isUnicode = false;
- j = 0;
- }
- while (j < s1->getLength()) {
- if (isUnicode) {
- u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff);
- j += 2;
+ if (hasSaveFile) {
+ for (i = 0; i < nFiles; ++i) {
+ fileSpec = embeddedFiles[i];
+ s1 = fileSpec->getFileName();
+ if (strcmp(s1->c_str(), saveFile) == 0) {
+ saveNum = i + 1;
+ break;
+ }
+ }
+ }
+ if (saveNum < 1 || saveNum > nFiles) {
+ error(errCommandLine, -1, hasSaveFile ? "Invalid file name" : "Invalid file number");
+ goto err2;
+ }
+
+ fileSpec = embeddedFiles[saveNum - 1];
+ if (savePath[0]) {
+ p = savePath;
} else {
- u = pdfDocEncoding[s1->getChar(j) & 0xff];
- ++j;
+ p = path;
+ s1 = fileSpec->getFileName();
+ if (!s1) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (s1->hasUnicodeMarker()) {
+ isUnicode = true;
+ j = 2;
+ } else {
+ isUnicode = false;
+ j = 0;
+ }
+ while (j < s1->getLength()) {
+ if (isUnicode) {
+ u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j + 1) & 0xff);
+ j += 2;
+ } else {
+ u = pdfDocEncoding[s1->getChar(j) & 0xff];
+ ++j;
+ }
+ n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
+ if (p + n >= path + sizeof(path))
+ break;
+ memcpy(p, uBuf, n);
+ p += n;
+ }
+ *p = '\0';
+ p = path;
}
- n = uMap->mapUnicode(u, uBuf, sizeof(uBuf));
- if (p + n >= path + sizeof(path))
- break;
- memcpy(p, uBuf, n);
- p += n;
- }
- *p = '\0';
- p = path;
- }
- auto *embFile = fileSpec->getEmbeddedFile();
- if (!embFile || !embFile->isOk()) {
- exitCode = 3;
- goto err2;
- }
- if (!embFile->save(p)) {
- error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
- exitCode = 2;
- goto err2;
+ auto *embFile = fileSpec->getEmbeddedFile();
+ if (!embFile || !embFile->isOk()) {
+ exitCode = 3;
+ goto err2;
+ }
+ if (!embFile->save(p)) {
+ error(errIO, -1, "Error saving embedded file as '{0:s}'", p);
+ exitCode = 2;
+ goto err2;
+ }
}
- }
- exitCode = 0;
+ exitCode = 0;
- // clean up
- err2:
- for (auto& file : embeddedFiles)
- delete file;
- delete doc;
- err0:
+ // clean up
+err2:
+ for (auto &file : embeddedFiles)
+ delete file;
+ delete doc;
+err0:
- return exitCode;
+ return exitCode;
}
diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc
index 598a4913..09a09d5b 100644
--- a/utils/pdffonts.cc
+++ b/utils/pdffonts.cc
@@ -44,20 +44,7 @@
#include "FontInfo.h"
#include "Win32Console.h"
-static const char *fontTypeNames[] = {
- "unknown",
- "Type 1",
- "Type 1C",
- "Type 1C (OT)",
- "Type 3",
- "TrueType",
- "TrueType (OT)",
- "CID Type 0",
- "CID Type 0C",
- "CID Type 0C (OT)",
- "CID TrueType",
- "CID TrueType (OT)"
-};
+static const char *fontTypeNames[] = { "unknown", "Type 1", "Type 1C", "Type 1C (OT)", "Type 3", "TrueType", "TrueType (OT)", "CID Type 0", "CID Type 0C", "CID Type 0C (OT)", "CID TrueType", "CID TrueType (OT)" };
static int firstPage = 1;
static int lastPage = 0;
@@ -67,135 +54,112 @@ static char userPassword[33] = "\001";
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to examine"},
- {"-l", argInt, &lastPage, 0,
- "last page to examine"},
- {"-subst", argFlag, &showSubst, 0,
- "show font substitutions"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
-
-int main(int argc, char *argv[]) {
- std::unique_ptr<GooString> ownerPW, userPW;
- bool ok;
-
- Win32Console win32Console(&argc, &argv);
-
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 2 || printVersion || printHelp) {
- fprintf(stderr, "pdffonts version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdffonts", "<PDF-file>", argDesc);
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to examine" },
+ { "-l", argInt, &lastPage, 0, "last page to examine" },
+ { "-subst", argFlag, &showSubst, 0, "show font substitutions" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
+
+int main(int argc, char *argv[])
+{
+ std::unique_ptr<GooString> ownerPW, userPW;
+ bool ok;
+
+ Win32Console win32Console(&argc, &argv);
+
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc != 2 || printVersion || printHelp) {
+ fprintf(stderr, "pdffonts version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdffonts", "<PDF-file>", argDesc);
+ }
+ if (printVersion || printHelp)
+ return 0;
+ return 99;
+ }
+
+ std::string fileName(argv[1]);
+ if (fileName == "-") {
+ fileName = "fd://0";
+ }
+
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = std::make_unique<GooString>(ownerPassword);
+ }
+ if (userPassword[0] != '\001') {
+ userPW = std::make_unique<GooString>(userPassword);
+ }
+
+ auto doc = std::unique_ptr<PDFDoc>(PDFDocFactory().createPDFDoc(GooString(fileName), ownerPW.get(), userPW.get()));
+
+ if (!doc->isOk()) {
+ return 1;
}
- if (printVersion || printHelp)
- return 0;
- return 99;
- }
-
- std::string fileName(argv[1]);
- if (fileName == "-") {
- fileName = "fd://0";
- }
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
-
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = std::make_unique<GooString>(ownerPassword);
- }
- if (userPassword[0] != '\001') {
- userPW = std::make_unique<GooString>(userPassword);
- }
-
- auto doc = std::unique_ptr<PDFDoc>(PDFDocFactory().createPDFDoc(GooString(fileName), ownerPW.get(), userPW.get()));
-
- if (!doc->isOk()) {
- return 1;
- }
-
- // get page range
- if (firstPage < 1) {
- firstPage = 1;
- }
- if (lastPage < 1 || lastPage > doc->getNumPages()) {
- lastPage = doc->getNumPages();
- }
- if (lastPage < firstPage) {
- fprintf(stderr,
- "Wrong page range given: the first page (%d) can not be after the last page (%d).\n",
- firstPage, lastPage);
- return 99;
- }
-
- // get the fonts
- {
- FontInfoScanner scanner(doc.get(), firstPage - 1);
- const std::vector<FontInfo*> fonts = scanner.scan(lastPage - firstPage + 1);
-
- if (showSubst) {
- // print the font substitutions
- printf("name object ID substitute font substitute font file\n");
- printf("------------------------------------ --------- ------------------------------------ ------------------------------------\n");
- for (const FontInfo* font : fonts) {
- if (font->getFile()) {
- printf("%-36s",
- font->getName() ? font->getName()->c_str() : "[none]");
- const Ref fontRef = font->getRef();
- if (fontRef.gen >= 100000) {
- printf(" [none]");
- } else {
- printf(" %6d %2d", fontRef.num, fontRef.gen);
+
+ // get page range
+ if (firstPage < 1) {
+ firstPage = 1;
+ }
+ if (lastPage < 1 || lastPage > doc->getNumPages()) {
+ lastPage = doc->getNumPages();
+ }
+ if (lastPage < firstPage) {
+ fprintf(stderr, "Wrong page range given: the first page (%d) can not be after the last page (%d).\n", firstPage, lastPage);
+ return 99;
+ }
+
+ // get the fonts
+ {
+ FontInfoScanner scanner(doc.get(), firstPage - 1);
+ const std::vector<FontInfo *> fonts = scanner.scan(lastPage - firstPage + 1);
+
+ if (showSubst) {
+ // print the font substitutions
+ printf("name object ID substitute font substitute font file\n");
+ printf("------------------------------------ --------- ------------------------------------ ------------------------------------\n");
+ for (const FontInfo *font : fonts) {
+ if (font->getFile()) {
+ printf("%-36s", font->getName() ? font->getName()->c_str() : "[none]");
+ const Ref fontRef = font->getRef();
+ if (fontRef.gen >= 100000) {
+ printf(" [none]");
+ } else {
+ printf(" %6d %2d", fontRef.num, fontRef.gen);
+ }
+ printf(" %-36s %s\n", font->getSubstituteName() ? font->getSubstituteName()->c_str() : "[none]", font->getFile()->c_str());
+ }
+ delete font;
+ }
+ } else {
+ // print the font info
+ printf("name type encoding emb sub uni object ID\n");
+ printf("------------------------------------ ----------------- ---------------- --- --- --- ---------\n");
+ for (const FontInfo *font : fonts) {
+ printf("%-36s %-17s %-16s %-3s %-3s %-3s", font->getName() ? font->getName()->c_str() : "[none]", fontTypeNames[font->getType()], font->getEncoding()->c_str(), font->getEmbedded() ? "yes" : "no",
+ font->getSubset() ? "yes" : "no", font->getToUnicode() ? "yes" : "no");
+ const Ref fontRef = font->getRef();
+ if (fontRef.gen >= 100000) {
+ printf(" [none]\n");
+ } else {
+ printf(" %6d %2d\n", fontRef.num, fontRef.gen);
+ }
+ delete font;
}
- printf(" %-36s %s\n",
- font->getSubstituteName() ? font->getSubstituteName()->c_str() : "[none]",
- font->getFile()->c_str());
- }
- delete font;
- }
- } else {
- // print the font info
- printf("name type encoding emb sub uni object ID\n");
- printf("------------------------------------ ----------------- ---------------- --- --- --- ---------\n");
- for (const FontInfo* font : fonts) {
- printf("%-36s %-17s %-16s %-3s %-3s %-3s",
- font->getName() ? font->getName()->c_str() : "[none]",
- fontTypeNames[font->getType()],
- font->getEncoding()->c_str(),
- font->getEmbedded() ? "yes" : "no",
- font->getSubset() ? "yes" : "no",
- font->getToUnicode() ? "yes" : "no");
- const Ref fontRef = font->getRef();
- if (fontRef.gen >= 100000) {
- printf(" [none]\n");
- } else {
- printf(" %6d %2d\n", fontRef.num, fontRef.gen);
- }
- delete font;
}
}
- }
- return 0;
+ return 0;
}
-
-
diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc
index 6ae92b34..46cebf98 100644
--- a/utils/pdfimages.cc
+++ b/utils/pdfimages.cc
@@ -69,173 +69,148 @@ static bool quiet = false;
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to convert"},
- {"-l", argInt, &lastPage, 0,
- "last page to convert"},
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to convert" },
+ { "-l", argInt, &lastPage, 0, "last page to convert" },
#ifdef ENABLE_LIBPNG
- {"-png", argFlag, &enablePNG, 0,
- "change the default output format to PNG"},
+ { "-png", argFlag, &enablePNG, 0, "change the default output format to PNG" },
#endif
#ifdef ENABLE_LIBTIFF
- {"-tiff", argFlag, &enableTiff, 0,
- "change the default output format to TIFF"},
+ { "-tiff", argFlag, &enableTiff, 0, "change the default output format to TIFF" },
#endif
- {"-j", argFlag, &dumpJPEG, 0,
- "write JPEG images as JPEG files"},
- {"-jp2", argFlag, &dumpJP2, 0,
- "write JPEG2000 images as JP2 files"},
- {"-jbig2", argFlag, &dumpJBIG2, 0,
- "write JBIG2 images as JBIG2 files"},
- {"-ccitt", argFlag, &dumpCCITT, 0,
- "write CCITT images as CCITT files"},
- {"-all", argFlag, &allFormats, 0,
- "equivalent to -png -tiff -j -jp2 -jbig2 -ccitt"},
- {"-list", argFlag, &listImages, 0,
- "print list of images instead of saving"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-p", argFlag, &pageNames, 0,
- "include page numbers in output file names"},
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
-
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName;
- char *imgRoot = nullptr;
- GooString *ownerPW, *userPW;
- ImageOutputDev *imgOut;
- bool ok;
- int exitCode;
-
- Win32Console win32Console(&argc, &argv);
- exitCode = 99;
-
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || (listImages && argc != 2) || (!listImages && argc != 3) || printVersion || printHelp) {
- fprintf(stderr, "pdfimages version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfimages", "<PDF-file> <image-root>", argDesc);
+ { "-j", argFlag, &dumpJPEG, 0, "write JPEG images as JPEG files" },
+ { "-jp2", argFlag, &dumpJP2, 0, "write JPEG2000 images as JP2 files" },
+ { "-jbig2", argFlag, &dumpJBIG2, 0, "write JBIG2 images as JBIG2 files" },
+ { "-ccitt", argFlag, &dumpCCITT, 0, "write CCITT images as CCITT files" },
+ { "-all", argFlag, &allFormats, 0, "equivalent to -png -tiff -j -jp2 -jbig2 -ccitt" },
+ { "-list", argFlag, &listImages, 0, "print list of images instead of saving" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-p", argFlag, &pageNames, 0, "include page numbers in output file names" },
+ { "-q", argFlag, &quiet, 0, "don't print any messages or errors" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
+
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName;
+ char *imgRoot = nullptr;
+ GooString *ownerPW, *userPW;
+ ImageOutputDev *imgOut;
+ bool ok;
+ int exitCode;
+
+ Win32Console win32Console(&argc, &argv);
+ exitCode = 99;
+
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || (listImages && argc != 2) || (!listImages && argc != 3) || printVersion || printHelp) {
+ fprintf(stderr, "pdfimages version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfimages", "<PDF-file> <image-root>", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ goto err0;
}
- if (printVersion || printHelp)
- exitCode = 0;
- goto err0;
- }
- fileName = new GooString(argv[1]);
- if (!listImages)
- imgRoot = argv[2];
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
-
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0] != '\001') {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
-
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- delete fileName;
-
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err1;
- }
-
- // check for copy permission
+ fileName = new GooString(argv[1]);
+ if (!listImages)
+ imgRoot = argv[2];
+
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
+ }
+
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = new GooString(ownerPassword);
+ } else {
+ ownerPW = nullptr;
+ }
+ if (userPassword[0] != '\001') {
+ userPW = new GooString(userPassword);
+ } else {
+ userPW = nullptr;
+ }
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
+ }
+
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+ delete fileName;
+
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err1;
+ }
+
+ // check for copy permission
#ifdef ENFORCE_PERMISSIONS
- if (!doc->okToCopy()) {
- error(errNotAllowed, -1, "Copying of images from this document is not allowed.");
- exitCode = 3;
- goto err1;
- }
+ if (!doc->okToCopy()) {
+ error(errNotAllowed, -1, "Copying of images from this document is not allowed.");
+ exitCode = 3;
+ goto err1;
+ }
#endif
- // get page range
- if (firstPage < 1)
- firstPage = 1;
- if (firstPage > doc->getNumPages()) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be larger then the number of pages in the document ({1:d}).",
- firstPage, doc->getNumPages());
- goto err1;
- }
- if (lastPage < 1 || lastPage > doc->getNumPages())
- lastPage = doc->getNumPages();
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- goto err1;
- }
-
- // write image files
- imgOut = new ImageOutputDev(imgRoot, pageNames, listImages);
- if (imgOut->isOk()) {
- if (allFormats) {
- imgOut->enablePNG(true);
- imgOut->enableTiff(true);
- imgOut->enableJpeg(true);
- imgOut->enableJpeg2000(true);
- imgOut->enableJBig2(true);
- imgOut->enableCCITT(true);
- } else {
- imgOut->enablePNG(enablePNG);
- imgOut->enableTiff(enableTiff);
- imgOut->enableJpeg(dumpJPEG);
- imgOut->enableJpeg2000(dumpJP2);
- imgOut->enableJBig2(dumpJBIG2);
- imgOut->enableCCITT(dumpCCITT);
+ // get page range
+ if (firstPage < 1)
+ firstPage = 1;
+ if (firstPage > doc->getNumPages()) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be larger then the number of pages in the document ({1:d}).", firstPage, doc->getNumPages());
+ goto err1;
+ }
+ if (lastPage < 1 || lastPage > doc->getNumPages())
+ lastPage = doc->getNumPages();
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ goto err1;
+ }
+
+ // write image files
+ imgOut = new ImageOutputDev(imgRoot, pageNames, listImages);
+ if (imgOut->isOk()) {
+ if (allFormats) {
+ imgOut->enablePNG(true);
+ imgOut->enableTiff(true);
+ imgOut->enableJpeg(true);
+ imgOut->enableJpeg2000(true);
+ imgOut->enableJBig2(true);
+ imgOut->enableCCITT(true);
+ } else {
+ imgOut->enablePNG(enablePNG);
+ imgOut->enableTiff(enableTiff);
+ imgOut->enableJpeg(dumpJPEG);
+ imgOut->enableJpeg2000(dumpJP2);
+ imgOut->enableJBig2(dumpJBIG2);
+ imgOut->enableCCITT(dumpCCITT);
+ }
+ doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0, true, false, false);
}
- doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
- true, false, false);
- }
- delete imgOut;
+ delete imgOut;
- exitCode = 0;
+ exitCode = 0;
- // clean up
- err1:
- delete doc;
- err0:
+ // clean up
+err1:
+ delete doc;
+err0:
- return exitCode;
+ return exitCode;
}
diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc
index 2b5eb02e..6180dbea 100644
--- a/utils/pdfinfo.cc
+++ b/utils/pdfinfo.cc
@@ -69,7 +69,6 @@
#include "StructElement.h"
#include "Win32Console.h"
-
static int firstPage = 1;
static int lastPage = 0;
static bool printBoxes = false;
@@ -87,906 +86,871 @@ static bool printStructure = false;
static bool printStructureText = false;
static bool printDests = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to convert"},
- {"-l", argInt, &lastPage, 0,
- "last page to convert"},
- {"-box", argFlag, &printBoxes, 0,
- "print the page bounding boxes"},
- {"-meta", argFlag, &printMetadata, 0,
- "print the document metadata (XML)"},
- {"-js", argFlag, &printJS, 0,
- "print all JavaScript in the PDF"},
- {"-struct", argFlag, &printStructure, 0,
- "print the logical document structure (for tagged files)"},
- {"-struct-text", argFlag, &printStructureText, 0,
- "print text contents along with document structure (for tagged files)"},
- {"-isodates", argFlag, &isoDates, 0,
- "print the dates in ISO-8601 format"},
- {"-rawdates", argFlag, &rawDates, 0,
- "print the undecoded date strings directly from the PDF file"},
- {"-dests", argFlag, &printDests, 0,
- "print all named destinations in the PDF"},
- {"-enc", argString, textEncName, sizeof(textEncName),
- "output text encoding name"},
- {"-listenc",argFlag, &printEnc, 0,
- "list available encodings"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
-
-static void printInfoString(Dict *infoDict, const char *key, const char *text,
- const UnicodeMap *uMap) {
- const GooString *s1;
- Unicode *u;
- char buf[8];
- int i, n, len;
-
- Object obj = infoDict->lookup(key);
- if (obj.isString()) {
- fputs(text, stdout);
- s1 = obj.getString();
- len = TextStringToUCS4(s1, &u);
- for (i = 0; i < len; i++) {
- n = uMap->mapUnicode(u[i], buf, sizeof(buf));
- fwrite(buf, 1, n, stdout);
- }
- gfree(u);
- fputc('\n', stdout);
- }
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to convert" },
+ { "-l", argInt, &lastPage, 0, "last page to convert" },
+ { "-box", argFlag, &printBoxes, 0, "print the page bounding boxes" },
+ { "-meta", argFlag, &printMetadata, 0, "print the document metadata (XML)" },
+ { "-js", argFlag, &printJS, 0, "print all JavaScript in the PDF" },
+ { "-struct", argFlag, &printStructure, 0, "print the logical document structure (for tagged files)" },
+ { "-struct-text", argFlag, &printStructureText, 0, "print text contents along with document structure (for tagged files)" },
+ { "-isodates", argFlag, &isoDates, 0, "print the dates in ISO-8601 format" },
+ { "-rawdates", argFlag, &rawDates, 0, "print the undecoded date strings directly from the PDF file" },
+ { "-dests", argFlag, &printDests, 0, "print all named destinations in the PDF" },
+ { "-enc", argString, textEncName, sizeof(textEncName), "output text encoding name" },
+ { "-listenc", argFlag, &printEnc, 0, "list available encodings" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
+
+static void printInfoString(Dict *infoDict, const char *key, const char *text, const UnicodeMap *uMap)
+{
+ const GooString *s1;
+ Unicode *u;
+ char buf[8];
+ int i, n, len;
+
+ Object obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ fputs(text, stdout);
+ s1 = obj.getString();
+ len = TextStringToUCS4(s1, &u);
+ for (i = 0; i < len; i++) {
+ n = uMap->mapUnicode(u[i], buf, sizeof(buf));
+ fwrite(buf, 1, n, stdout);
+ }
+ gfree(u);
+ fputc('\n', stdout);
+ }
}
-static void printInfoDate(Dict *infoDict, const char *key, const char *text) {
- const char *s;
- int year, mon, day, hour, min, sec, tz_hour, tz_minute;
- char tz;
- struct tm tmStruct;
- time_t time;
- char buf[256];
-
- Object obj = infoDict->lookup(key);
- if (obj.isString()) {
- fputs(text, stdout);
- s = obj.getString()->c_str();
- // TODO do something with the timezone info
- if ( parseDateString( s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute ) ) {
- tmStruct.tm_year = year - 1900;
- tmStruct.tm_mon = mon - 1;
- tmStruct.tm_mday = day;
- tmStruct.tm_hour = hour;
- tmStruct.tm_min = min;
- tmStruct.tm_sec = sec;
- tmStruct.tm_wday = -1;
- tmStruct.tm_yday = -1;
- tmStruct.tm_isdst = -1;
- // compute the tm_wday and tm_yday fields
- time = timegm(&tmStruct);
- if (time != (time_t)-1) {
- int offset = (tz_hour*60 + tz_minute)*60;
- if (tz == '-')
- offset *= -1;
- time -= offset;
- localtime_r(&time, &tmStruct);
- strftime(buf, sizeof(buf), "%c %Z", &tmStruct);
- fputs(buf, stdout);
- } else {
- fputs(s, stdout);
- }
- } else {
- fputs(s, stdout);
+static void printInfoDate(Dict *infoDict, const char *key, const char *text)
+{
+ const char *s;
+ int year, mon, day, hour, min, sec, tz_hour, tz_minute;
+ char tz;
+ struct tm tmStruct;
+ time_t time;
+ char buf[256];
+
+ Object obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ fputs(text, stdout);
+ s = obj.getString()->c_str();
+ // TODO do something with the timezone info
+ if (parseDateString(s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute)) {
+ tmStruct.tm_year = year - 1900;
+ tmStruct.tm_mon = mon - 1;
+ tmStruct.tm_mday = day;
+ tmStruct.tm_hour = hour;
+ tmStruct.tm_min = min;
+ tmStruct.tm_sec = sec;
+ tmStruct.tm_wday = -1;
+ tmStruct.tm_yday = -1;
+ tmStruct.tm_isdst = -1;
+ // compute the tm_wday and tm_yday fields
+ time = timegm(&tmStruct);
+ if (time != (time_t)-1) {
+ int offset = (tz_hour * 60 + tz_minute) * 60;
+ if (tz == '-')
+ offset *= -1;
+ time -= offset;
+ localtime_r(&time, &tmStruct);
+ strftime(buf, sizeof(buf), "%c %Z", &tmStruct);
+ fputs(buf, stdout);
+ } else {
+ fputs(s, stdout);
+ }
+ } else {
+ fputs(s, stdout);
+ }
+ fputc('\n', stdout);
}
- fputc('\n', stdout);
- }
}
static void printISODate(Dict *infoDict, const char *key, const char *text)
{
- const char *s;
- int year, mon, day, hour, min, sec, tz_hour, tz_minute;
- char tz;
-
- Object obj = infoDict->lookup(key);
- if (obj.isString()) {
- fputs(text, stdout);
- s = obj.getString()->c_str();
- if ( parseDateString( s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute ) ) {
- fprintf(stdout, "%04d-%02d-%02dT%02d:%02d:%02d", year, mon, day, hour, min, sec);
- if (tz_hour == 0 && tz_minute == 0) {
- fprintf(stdout, "Z");
- } else {
- fprintf(stdout, "%c%02d", tz, tz_hour);
- if (tz_minute)
- fprintf(stdout, ":%02d", tz_minute);
- }
- } else {
- fputs(s, stdout);
+ const char *s;
+ int year, mon, day, hour, min, sec, tz_hour, tz_minute;
+ char tz;
+
+ Object obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ fputs(text, stdout);
+ s = obj.getString()->c_str();
+ if (parseDateString(s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute)) {
+ fprintf(stdout, "%04d-%02d-%02dT%02d:%02d:%02d", year, mon, day, hour, min, sec);
+ if (tz_hour == 0 && tz_minute == 0) {
+ fprintf(stdout, "Z");
+ } else {
+ fprintf(stdout, "%c%02d", tz, tz_hour);
+ if (tz_minute)
+ fprintf(stdout, ":%02d", tz_minute);
+ }
+ } else {
+ fputs(s, stdout);
+ }
+ fputc('\n', stdout);
}
- fputc('\n', stdout);
- }
}
-static void printBox(const char *text, const PDFRectangle *box) {
- printf("%s%8.2f %8.2f %8.2f %8.2f\n",
- text, box->x1, box->y1, box->x2, box->y2);
+static void printBox(const char *text, const PDFRectangle *box)
+{
+ printf("%s%8.2f %8.2f %8.2f %8.2f\n", text, box->x1, box->y1, box->x2, box->y2);
}
-static void printIndent(unsigned indent) {
- while (indent--) {
- putchar(' ');
- putchar(' ');
- }
+static void printIndent(unsigned indent)
+{
+ while (indent--) {
+ putchar(' ');
+ putchar(' ');
+ }
}
static void printAttribute(const Attribute *attribute, unsigned indent)
{
- printIndent(indent);
- printf(" /%s ", attribute->getTypeName());
- if (attribute->getType() == Attribute::UserProperty) {
- GooString *name = attribute->getName();
- printf("(%s) ", name->c_str());
- delete name;
- }
- attribute->getValue()->print(stdout);
- if (attribute->getFormattedValue()) {
- printf(" \"%s\"", attribute->getFormattedValue());
- }
- if (attribute->isHidden()) {
- printf(" [hidden]");
- }
+ printIndent(indent);
+ printf(" /%s ", attribute->getTypeName());
+ if (attribute->getType() == Attribute::UserProperty) {
+ GooString *name = attribute->getName();
+ printf("(%s) ", name->c_str());
+ delete name;
+ }
+ attribute->getValue()->print(stdout);
+ if (attribute->getFormattedValue()) {
+ printf(" \"%s\"", attribute->getFormattedValue());
+ }
+ if (attribute->isHidden()) {
+ printf(" [hidden]");
+ }
}
-static void printStruct(const StructElement *element, unsigned indent) {
- if (element->isObjectRef()) {
- printIndent(indent);
- printf("Object %i %i\n", element->getObjectRef().num, element->getObjectRef().gen);
- return;
- }
+static void printStruct(const StructElement *element, unsigned indent)
+{
+ if (element->isObjectRef()) {
+ printIndent(indent);
+ printf("Object %i %i\n", element->getObjectRef().num, element->getObjectRef().gen);
+ return;
+ }
- if (printStructureText && element->isContent()) {
- GooString *text = element->getText(false);
- printIndent(indent);
- if (text) {
- printf("\"%s\"\n", text->c_str());
- } else {
- printf("(No content?)\n");
- }
- delete text;
- }
-
- if (!element->isContent()) {
- printIndent(indent);
- printf("%s", element->getTypeName());
- if (element->getID()) {
- printf(" <%s>", element->getID()->c_str());
- }
- if (element->getTitle()) {
- printf(" \"%s\"", element->getTitle()->c_str());
- }
- if (element->getRevision() > 0) {
- printf(" r%u", element->getRevision());
- }
- if (element->isInline() || element->isBlock()) {
- printf(" (%s)", element->isInline() ? "inline" : "block");
- }
- if (element->getNumAttributes()) {
- putchar(':');
- for (unsigned i = 0; i < element->getNumAttributes(); i++) {
- putchar('\n');
- printAttribute(element->getAttribute(i), indent + 1);
- }
- }
-
- putchar('\n');
- for (unsigned i = 0; i < element->getNumChildren(); i++) {
- printStruct(element->getChild(i), indent + 1);
- }
- }
+ if (printStructureText && element->isContent()) {
+ GooString *text = element->getText(false);
+ printIndent(indent);
+ if (text) {
+ printf("\"%s\"\n", text->c_str());
+ } else {
+ printf("(No content?)\n");
+ }
+ delete text;
+ }
+
+ if (!element->isContent()) {
+ printIndent(indent);
+ printf("%s", element->getTypeName());
+ if (element->getID()) {
+ printf(" <%s>", element->getID()->c_str());
+ }
+ if (element->getTitle()) {
+ printf(" \"%s\"", element->getTitle()->c_str());
+ }
+ if (element->getRevision() > 0) {
+ printf(" r%u", element->getRevision());
+ }
+ if (element->isInline() || element->isBlock()) {
+ printf(" (%s)", element->isInline() ? "inline" : "block");
+ }
+ if (element->getNumAttributes()) {
+ putchar(':');
+ for (unsigned i = 0; i < element->getNumAttributes(); i++) {
+ putchar('\n');
+ printAttribute(element->getAttribute(i), indent + 1);
+ }
+ }
+
+ putchar('\n');
+ for (unsigned i = 0; i < element->getNumChildren(); i++) {
+ printStruct(element->getChild(i), indent + 1);
+ }
+ }
}
-struct GooStringCompare {
- bool operator() (GooString* lhs, GooString* rhs) const {
- return lhs->cmp(const_cast<GooString*>(rhs)) < 0;
- }
+struct GooStringCompare
+{
+ bool operator()(GooString *lhs, GooString *rhs) const { return lhs->cmp(const_cast<GooString *>(rhs)) < 0; }
};
-static void printLinkDest(const std::unique_ptr<LinkDest>& dest) {
- GooString s;
+static void printLinkDest(const std::unique_ptr<LinkDest> &dest)
+{
+ GooString s;
- switch (dest->getKind()) {
+ switch (dest->getKind()) {
case destXYZ:
- s.append("[ XYZ ");
- if (dest->getChangeLeft()) {
- s.appendf("{0:4.0g} ", dest->getLeft());
- } else {
- s.append("null ");
- }
- if (dest->getChangeTop()) {
- s.appendf("{0:4.0g} ", dest->getTop());
- } else {
- s.append("null ");
- }
- if (dest->getChangeZoom()) {
- s.appendf("{0:4.2f} ", dest->getZoom());
- } else {
- s.append("null ");
- }
- break;
+ s.append("[ XYZ ");
+ if (dest->getChangeLeft()) {
+ s.appendf("{0:4.0g} ", dest->getLeft());
+ } else {
+ s.append("null ");
+ }
+ if (dest->getChangeTop()) {
+ s.appendf("{0:4.0g} ", dest->getTop());
+ } else {
+ s.append("null ");
+ }
+ if (dest->getChangeZoom()) {
+ s.appendf("{0:4.2f} ", dest->getZoom());
+ } else {
+ s.append("null ");
+ }
+ break;
case destFit:
- s.append("[ Fit ");
- break;
+ s.append("[ Fit ");
+ break;
case destFitH:
- if (dest->getChangeTop()) {
- s.appendf("[ FitH {0:4.0g} ", dest->getTop());
- } else {
- s.append("[ FitH null ");
- }
- break;
+ if (dest->getChangeTop()) {
+ s.appendf("[ FitH {0:4.0g} ", dest->getTop());
+ } else {
+ s.append("[ FitH null ");
+ }
+ break;
case destFitV:
- if (dest->getChangeLeft()) {
- s.appendf("[ FitV {0:4.0g} ", dest->getLeft());
- } else {
- s.append("[ FitV null ");
- }
- break;
+ if (dest->getChangeLeft()) {
+ s.appendf("[ FitV {0:4.0g} ", dest->getLeft());
+ } else {
+ s.append("[ FitV null ");
+ }
+ break;
case destFitR:
- s.appendf("[ FitR {0:4.0g} {1:4.0g} {2:4.0g} {3:4.0g} ",
- dest->getLeft(),
- dest->getBottom(),
- dest->getRight(),
- dest->getTop());
- break;
+ s.appendf("[ FitR {0:4.0g} {1:4.0g} {2:4.0g} {3:4.0g} ", dest->getLeft(), dest->getBottom(), dest->getRight(), dest->getTop());
+ break;
case destFitB:
- s.append("[ FitB ");
- break;
+ s.append("[ FitB ");
+ break;
case destFitBH:
- if (dest->getChangeTop()) {
- s.appendf("[ FitBH {0:4.0g} ", dest->getTop());
- } else {
- s.append("[ FitBH null ");
- }
- break;
+ if (dest->getChangeTop()) {
+ s.appendf("[ FitBH {0:4.0g} ", dest->getTop());
+ } else {
+ s.append("[ FitBH null ");
+ }
+ break;
case destFitBV:
- if (dest->getChangeLeft()) {
- s.appendf("[ FitBV {0:4.0g} ", dest->getLeft());
- } else {
- s.append("[ FitBV null ");
- }
- break;
- }
-
- s.append(" ");
- s.setChar(26, ']');
- s.setChar(27, '\0');
- printf("%s", s.c_str());
-}
-
-static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap) {
- std::map<Ref,std::map<GooString*,std::unique_ptr<LinkDest>,GooStringCompare> > map;
-
- int numDests = doc->getCatalog()->numDestNameTree();
- for (int i = 0; i < numDests; i++) {
- GooString *name = new GooString(doc->getCatalog()->getDestNameTreeName(i));
- std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestNameTreeDest(i);
- if (dest && dest->isPageRef()) {
- Ref pageRef = dest->getPageRef();
- map[pageRef].insert(std::make_pair(name, std::move(dest)));
- } else {
- delete name;
+ if (dest->getChangeLeft()) {
+ s.appendf("[ FitBV {0:4.0g} ", dest->getLeft());
+ } else {
+ s.append("[ FitBV null ");
+ }
+ break;
}
- }
- numDests = doc->getCatalog()->numDests();
- for (int i = 0; i < numDests; i++) {
- GooString *name = new GooString(doc->getCatalog()->getDestsName(i));
- std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestsDest(i);
- if (dest && dest->isPageRef()) {
- Ref pageRef = dest->getPageRef();
- map[pageRef].insert(std::make_pair(name, std::move(dest)));
- } else {
- delete name;
- }
- }
-
- printf("Page Destination Name\n");
- for (int i = firstPage; i <= lastPage; i++) {
- Ref *ref = doc->getCatalog()->getPageRef(i);
- if (ref) {
- auto pageDests = map.find(*ref);
- if (pageDests != map.end()) {
- for (auto& it: pageDests->second) {
- printf("%4d ", i);
- printLinkDest(it.second);
- printf(" \"");
- Unicode *u;
- char buf[8];
- const int len = TextStringToUCS4(it.first, &u);
- for (int j = 0; j < len; j++) {
- const int n = uMap->mapUnicode(u[j], buf, sizeof(buf));
- fwrite(buf, 1, n, stdout);
- }
- gfree(u);
- printf("\"\n");
- delete it.first;
- }
- }
- }
- }
+ s.append(" ");
+ s.setChar(26, ']');
+ s.setChar(27, '\0');
+ printf("%s", s.c_str());
}
-static void printPdfSubtype(PDFDoc *doc, const UnicodeMap *uMap) {
- const Object info = doc->getDocInfo();
- if (info.isDict()) {
- const PDFSubtype pdftype = doc->getPDFSubtype();
-
- if ((pdftype == subtypeNull) | (pdftype == subtypeNone)) {
- return;
+static void printDestinations(PDFDoc *doc, const UnicodeMap *uMap)
+{
+ std::map<Ref, std::map<GooString *, std::unique_ptr<LinkDest>, GooStringCompare>> map;
+
+ int numDests = doc->getCatalog()->numDestNameTree();
+ for (int i = 0; i < numDests; i++) {
+ GooString *name = new GooString(doc->getCatalog()->getDestNameTreeName(i));
+ std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestNameTreeDest(i);
+ if (dest && dest->isPageRef()) {
+ Ref pageRef = dest->getPageRef();
+ map[pageRef].insert(std::make_pair(name, std::move(dest)));
+ } else {
+ delete name;
+ }
}
- std::unique_ptr<GooString> part;
- std::unique_ptr<GooString> abbr;
- std::unique_ptr<GooString> standard;
- std::unique_ptr<GooString> typeExp;
- std::unique_ptr<GooString> confExp;
+ numDests = doc->getCatalog()->numDests();
+ for (int i = 0; i < numDests; i++) {
+ GooString *name = new GooString(doc->getCatalog()->getDestsName(i));
+ std::unique_ptr<LinkDest> dest = doc->getCatalog()->getDestsDest(i);
+ if (dest && dest->isPageRef()) {
+ Ref pageRef = dest->getPageRef();
+ map[pageRef].insert(std::make_pair(name, std::move(dest)));
+ } else {
+ delete name;
+ }
+ }
- // Form title from PDFSubtype
- switch (pdftype)
- {
- case subtypePDFA:
- printInfoString(info.getDict(), "GTS_PDFA1Version", "PDF subtype: ", uMap);
- typeExp = std::make_unique<GooString>("ISO 19005 - Electronic document file format for long-term preservation (PDF/A)");
- standard = std::make_unique<GooString>("ISO 19005");
- abbr = std::make_unique<GooString>("PDF/A");
- break;
- case subtypePDFE:
- printInfoString(info.getDict(), "GTS_PDFEVersion", "PDF subtype: ", uMap);
- typeExp = std::make_unique<GooString>("ISO 24517 - Engineering document format using PDF (PDF/E)");
- standard = std::make_unique<GooString>("ISO 24517");
- abbr = std::make_unique<GooString>("PDF/E");
- break;
- case subtypePDFUA:
- printInfoString(info.getDict(), "GTS_PDFUAVersion", "PDF subtype: ", uMap);
- typeExp = std::make_unique<GooString>("ISO 14289 - Electronic document file format enhancement for accessibility (PDF/UA)");
- standard = std::make_unique<GooString>("ISO 14289");
- abbr = std::make_unique<GooString>("PDF/UA");
- break;
- case subtypePDFVT:
- printInfoString(info.getDict(), "GTS_PDFVTVersion", "PDF subtype: ", uMap);
- typeExp = std::make_unique<GooString>("ISO 16612 - Electronic document file format for variable data exchange (PDF/VT)");
- standard = std::make_unique<GooString>("ISO 16612");
- abbr = std::make_unique<GooString>("PDF/VT");
- break;
- case subtypePDFX:
- printInfoString(info.getDict(), "GTS_PDFXVersion", "PDF subtype: ", uMap);
- typeExp = std::make_unique<GooString>("ISO 15930 - Electronic document file format for prepress digital data exchange (PDF/X)");
- standard = std::make_unique<GooString>("ISO 15930");
- abbr = std::make_unique<GooString>("PDF/X");
- break;
- case subtypeNone:
- case subtypeNull:
- default:
- return;
+ printf("Page Destination Name\n");
+ for (int i = firstPage; i <= lastPage; i++) {
+ Ref *ref = doc->getCatalog()->getPageRef(i);
+ if (ref) {
+ auto pageDests = map.find(*ref);
+ if (pageDests != map.end()) {
+ for (auto &it : pageDests->second) {
+ printf("%4d ", i);
+ printLinkDest(it.second);
+ printf(" \"");
+ Unicode *u;
+ char buf[8];
+ const int len = TextStringToUCS4(it.first, &u);
+ for (int j = 0; j < len; j++) {
+ const int n = uMap->mapUnicode(u[j], buf, sizeof(buf));
+ fwrite(buf, 1, n, stdout);
+ }
+ gfree(u);
+ printf("\"\n");
+ delete it.first;
+ }
+ }
+ }
}
+}
- // Form the abbreviation from PDFSubtypePart and PDFSubtype
- const PDFSubtypePart subpart = doc->getPDFSubtypePart();
- switch (pdftype) {
- case subtypePDFX:
- switch (subpart) {
- case subtypePart1:
- abbr->append("-1:2001");
- break;
- case subtypePart2:
- abbr->append("-2");
- break;
- case subtypePart3:
- abbr->append("-3:2002");
- break;
- case subtypePart4:
- abbr->append("-1:2003");
- break;
- case subtypePart5:
- abbr->append("-2");
+static void printPdfSubtype(PDFDoc *doc, const UnicodeMap *uMap)
+{
+ const Object info = doc->getDocInfo();
+ if (info.isDict()) {
+ const PDFSubtype pdftype = doc->getPDFSubtype();
+
+ if ((pdftype == subtypeNull) | (pdftype == subtypeNone)) {
+ return;
+ }
+
+ std::unique_ptr<GooString> part;
+ std::unique_ptr<GooString> abbr;
+ std::unique_ptr<GooString> standard;
+ std::unique_ptr<GooString> typeExp;
+ std::unique_ptr<GooString> confExp;
+
+ // Form title from PDFSubtype
+ switch (pdftype) {
+ case subtypePDFA:
+ printInfoString(info.getDict(), "GTS_PDFA1Version", "PDF subtype: ", uMap);
+ typeExp = std::make_unique<GooString>("ISO 19005 - Electronic document file format for long-term preservation (PDF/A)");
+ standard = std::make_unique<GooString>("ISO 19005");
+ abbr = std::make_unique<GooString>("PDF/A");
break;
- case subtypePart6:
- abbr->append("-3:2003");
+ case subtypePDFE:
+ printInfoString(info.getDict(), "GTS_PDFEVersion", "PDF subtype: ", uMap);
+ typeExp = std::make_unique<GooString>("ISO 24517 - Engineering document format using PDF (PDF/E)");
+ standard = std::make_unique<GooString>("ISO 24517");
+ abbr = std::make_unique<GooString>("PDF/E");
break;
- case subtypePart7:
- abbr->append("-4");
+ case subtypePDFUA:
+ printInfoString(info.getDict(), "GTS_PDFUAVersion", "PDF subtype: ", uMap);
+ typeExp = std::make_unique<GooString>("ISO 14289 - Electronic document file format enhancement for accessibility (PDF/UA)");
+ standard = std::make_unique<GooString>("ISO 14289");
+ abbr = std::make_unique<GooString>("PDF/UA");
break;
- case subtypePart8:
- abbr->append("-5");
+ case subtypePDFVT:
+ printInfoString(info.getDict(), "GTS_PDFVTVersion", "PDF subtype: ", uMap);
+ typeExp = std::make_unique<GooString>("ISO 16612 - Electronic document file format for variable data exchange (PDF/VT)");
+ standard = std::make_unique<GooString>("ISO 16612");
+ abbr = std::make_unique<GooString>("PDF/VT");
break;
- default:
+ case subtypePDFX:
+ printInfoString(info.getDict(), "GTS_PDFXVersion", "PDF subtype: ", uMap);
+ typeExp = std::make_unique<GooString>("ISO 15930 - Electronic document file format for prepress digital data exchange (PDF/X)");
+ standard = std::make_unique<GooString>("ISO 15930");
+ abbr = std::make_unique<GooString>("PDF/X");
break;
+ case subtypeNone:
+ case subtypeNull:
+ default:
+ return;
}
- break;
- case subtypeNone:
- case subtypeNull:
- break;
- default:
- abbr->appendf("-{0:d}", subpart);
- break;
- }
- // Form standard from PDFSubtypePart
- switch (subpart) {
- case subtypePartNone:
- case subtypePartNull:
- break;
- default:
- standard->appendf("-{0:d}", subpart);
- break;
- }
-
- // Form the subtitle from PDFSubtypePart and PDFSubtype
- switch (pdftype) {
- case subtypePDFA:
- switch (subpart) {
- case subtypePart1:
- part = std::make_unique<GooString>("Use of PDF 1.4");
- break;
- case subtypePart2:
- part = std::make_unique<GooString>("Use of ISO 32000-1");
+ // Form the abbreviation from PDFSubtypePart and PDFSubtype
+ const PDFSubtypePart subpart = doc->getPDFSubtypePart();
+ switch (pdftype) {
+ case subtypePDFX:
+ switch (subpart) {
+ case subtypePart1:
+ abbr->append("-1:2001");
+ break;
+ case subtypePart2:
+ abbr->append("-2");
+ break;
+ case subtypePart3:
+ abbr->append("-3:2002");
+ break;
+ case subtypePart4:
+ abbr->append("-1:2003");
+ break;
+ case subtypePart5:
+ abbr->append("-2");
+ break;
+ case subtypePart6:
+ abbr->append("-3:2003");
+ break;
+ case subtypePart7:
+ abbr->append("-4");
+ break;
+ case subtypePart8:
+ abbr->append("-5");
+ break;
+ default:
+ break;
+ }
break;
- case subtypePart3:
- part = std::make_unique<GooString>("Use of ISO 32000-1 with support for embedded files");
+ case subtypeNone:
+ case subtypeNull:
break;
- default:
+ default:
+ abbr->appendf("-{0:d}", subpart);
break;
- }
- break;
- case subtypePDFE:
- switch (subpart) {
- case subtypePart1:
- part = std::make_unique<GooString>("Use of PDF 1.6");
- break;
- default:
- break;
- }
- break;
- case subtypePDFUA:
+ }
+
+ // Form standard from PDFSubtypePart
switch (subpart) {
- case subtypePart1:
- part = std::make_unique<GooString>("Use of ISO 32000-1");
+ case subtypePartNone:
+ case subtypePartNull:
break;
- case subtypePart2:
- part = std::make_unique<GooString>("Use of ISO 32000-2");
+ default:
+ standard->appendf("-{0:d}", subpart);
break;
- case subtypePart3:
- part = std::make_unique<GooString>("Use of ISO 32000-1 with support for embedded files");
+ }
+
+ // Form the subtitle from PDFSubtypePart and PDFSubtype
+ switch (pdftype) {
+ case subtypePDFA:
+ switch (subpart) {
+ case subtypePart1:
+ part = std::make_unique<GooString>("Use of PDF 1.4");
+ break;
+ case subtypePart2:
+ part = std::make_unique<GooString>("Use of ISO 32000-1");
+ break;
+ case subtypePart3:
+ part = std::make_unique<GooString>("Use of ISO 32000-1 with support for embedded files");
+ break;
+ default:
+ break;
+ }
break;
- default:
+ case subtypePDFE:
+ switch (subpart) {
+ case subtypePart1:
+ part = std::make_unique<GooString>("Use of PDF 1.6");
+ break;
+ default:
+ break;
+ }
break;
- }
- break;
- case subtypePDFVT:
- switch (subpart) {
- case subtypePart1:
- part = std::make_unique<GooString>("Using PPML 2.1 and PDF 1.4");
+ case subtypePDFUA:
+ switch (subpart) {
+ case subtypePart1:
+ part = std::make_unique<GooString>("Use of ISO 32000-1");
+ break;
+ case subtypePart2:
+ part = std::make_unique<GooString>("Use of ISO 32000-2");
+ break;
+ case subtypePart3:
+ part = std::make_unique<GooString>("Use of ISO 32000-1 with support for embedded files");
+ break;
+ default:
+ break;
+ }
break;
- case subtypePart2:
- part = std::make_unique<GooString>("Using PDF/X-4 and PDF/X-5 (PDF/VT-1 and PDF/VT-2)");
+ case subtypePDFVT:
+ switch (subpart) {
+ case subtypePart1:
+ part = std::make_unique<GooString>("Using PPML 2.1 and PDF 1.4");
+ break;
+ case subtypePart2:
+ part = std::make_unique<GooString>("Using PDF/X-4 and PDF/X-5 (PDF/VT-1 and PDF/VT-2)");
+ break;
+ case subtypePart3:
+ part = std::make_unique<GooString>("Using PDF/X-6 (PDF/VT-3)");
+ break;
+ default:
+ break;
+ }
break;
- case subtypePart3:
- part = std::make_unique<GooString>("Using PDF/X-6 (PDF/VT-3)");
+ case subtypePDFX:
+ switch (subpart) {
+ case subtypePart1:
+ part = std::make_unique<GooString>("Complete exchange using CMYK data (PDF/X-1 and PDF/X-1a)");
+ break;
+ case subtypePart3:
+ part = std::make_unique<GooString>("Complete exchange suitable for colour-managed workflows (PDF/X-3)");
+ break;
+ case subtypePart4:
+ part = std::make_unique<GooString>("Complete exchange of CMYK and spot colour printing data using PDF 1.4 (PDF/X-1a)");
+ break;
+ case subtypePart5:
+ part = std::make_unique<GooString>("Partial exchange of printing data using PDF 1.4 (PDF/X-2) [Withdrawn]");
+ break;
+ case subtypePart6:
+ part = std::make_unique<GooString>("Complete exchange of printing data suitable for colour-managed workflows using PDF 1.4 (PDF/X-3)");
+ break;
+ case subtypePart7:
+ part = std::make_unique<GooString>("Complete exchange of printing data (PDF/X-4) and partial exchange of printing data with external profile reference (PDF/X-4p) using PDF 1.6");
+ break;
+ case subtypePart8:
+ part = std::make_unique<GooString>("Partial exchange of printing data using PDF 1.6 (PDF/X-5)");
+ break;
+ default:
+ break;
+ }
break;
- default:
+ default:
break;
- }
- break;
- case subtypePDFX:
- switch (subpart) {
- case subtypePart1:
- part = std::make_unique<GooString>("Complete exchange using CMYK data (PDF/X-1 and PDF/X-1a)");
+ }
+
+ // Form Conformance explanation from PDFSubtypeConformance
+ switch (doc->getPDFSubtypeConformance()) {
+ case subtypeConfA:
+ confExp = std::make_unique<GooString>("Level A, Accessible");
break;
- case subtypePart3:
- part = std::make_unique<GooString>("Complete exchange suitable for colour-managed workflows (PDF/X-3)");
+ case subtypeConfB:
+ confExp = std::make_unique<GooString>("Level B, Basic");
break;
- case subtypePart4:
- part = std::make_unique<GooString>("Complete exchange of CMYK and spot colour printing data using PDF 1.4 (PDF/X-1a)");
+ case subtypeConfG:
+ confExp = std::make_unique<GooString>("Level G, External graphical content");
break;
- case subtypePart5:
- part = std::make_unique<GooString>("Partial exchange of printing data using PDF 1.4 (PDF/X-2) [Withdrawn]");
+ case subtypeConfN:
+ confExp = std::make_unique<GooString>("Level N, External ICC profile");
break;
- case subtypePart6:
- part = std::make_unique<GooString>("Complete exchange of printing data suitable for colour-managed workflows using PDF 1.4 (PDF/X-3)");
+ case subtypeConfP:
+ confExp = std::make_unique<GooString>("Level P, Embedded ICC profile");
break;
- case subtypePart7:
- part = std::make_unique<GooString>("Complete exchange of printing data (PDF/X-4) and partial exchange of printing data with external profile reference (PDF/X-4p) using PDF 1.6");
+ case subtypeConfPG:
+ confExp = std::make_unique<GooString>("Level PG, Embedded ICC profile and external graphical content");
break;
- case subtypePart8:
- part = std::make_unique<GooString>("Partial exchange of printing data using PDF 1.6 (PDF/X-5)");
+ case subtypeConfU:
+ confExp = std::make_unique<GooString>("Level U, Unicode support");
break;
- default:
+ case subtypeConfNone:
+ case subtypeConfNull:
+ default:
+ confExp.reset();
break;
- }
- break;
- default:
- break;
+ }
+
+ printf(" Title: %s\n", typeExp->c_str());
+ printf(" Abbreviation: %s\n", abbr->c_str());
+ if (part.get())
+ printf(" Subtitle: Part %d: %s\n", subpart, part->c_str());
+ else
+ printf(" Subtitle: Part %d\n", subpart);
+ printf(" Standard: %s-%d\n", typeExp->toStr().substr(0, 9).c_str(), subpart);
+ if (confExp.get())
+ printf(" Conformance: %s\n", confExp->c_str());
}
+}
- // Form Conformance explanation from PDFSubtypeConformance
- switch (doc->getPDFSubtypeConformance())
- {
- case subtypeConfA:
- confExp = std::make_unique<GooString>("Level A, Accessible");
- break;
- case subtypeConfB:
- confExp = std::make_unique<GooString>("Level B, Basic");
- break;
- case subtypeConfG:
- confExp = std::make_unique<GooString>("Level G, External graphical content");
- break;
- case subtypeConfN:
- confExp = std::make_unique<GooString>("Level N, External ICC profile");
- break;
- case subtypeConfP:
- confExp = std::make_unique<GooString>("Level P, Embedded ICC profile");
- break;
- case subtypeConfPG:
- confExp = std::make_unique<GooString>("Level PG, Embedded ICC profile and external graphical content");
- break;
- case subtypeConfU:
- confExp = std::make_unique<GooString>("Level U, Unicode support");
- break;
- case subtypeConfNone:
- case subtypeConfNull:
- default:
- confExp.reset();
- break;
+static void printInfo(PDFDoc *doc, const UnicodeMap *uMap, long long filesize, bool multiPage)
+{
+ Page *page;
+ char buf[256];
+ double w, h, wISO, hISO, isoThreshold;
+ int pg, i;
+ int r;
+
+ // print doc info
+ Object info = doc->getDocInfo();
+ if (info.isDict()) {
+ printInfoString(info.getDict(), "Title", "Title: ", uMap);
+ printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
+ printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
+ printInfoString(info.getDict(), "Author", "Author: ", uMap);
+ printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
+ printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
+ if (isoDates) {
+ printISODate(info.getDict(), "CreationDate", "CreationDate: ");
+ printISODate(info.getDict(), "ModDate", "ModDate: ");
+ } else if (rawDates) {
+ printInfoString(info.getDict(), "CreationDate", "CreationDate: ", uMap);
+ printInfoString(info.getDict(), "ModDate", "ModDate: ", uMap);
+ } else {
+ printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
+ printInfoDate(info.getDict(), "ModDate", "ModDate: ");
+ }
}
- printf(" Title: %s\n",typeExp->c_str());
- printf(" Abbreviation: %s\n", abbr->c_str());
- if (part.get())
- printf(" Subtitle: Part %d: %s\n", subpart, part->c_str());
- else
- printf(" Subtitle: Part %d\n", subpart);
- printf(" Standard: %s-%d\n", typeExp->toStr().substr(0,9).c_str(), subpart);
- if (confExp.get())
- printf(" Conformance: %s\n", confExp->c_str());
- }
-}
+ // print tagging info
+ printf("Tagged: %s\n", (doc->getCatalog()->getMarkInfo() & Catalog::markInfoMarked) ? "yes" : "no");
+ printf("UserProperties: %s\n", (doc->getCatalog()->getMarkInfo() & Catalog::markInfoUserProperties) ? "yes" : "no");
+ printf("Suspects: %s\n", (doc->getCatalog()->getMarkInfo() & Catalog::markInfoSuspects) ? "yes" : "no");
-static void printInfo(PDFDoc *doc, const UnicodeMap *uMap, long long filesize, bool multiPage) {
- Page *page;
- char buf[256];
- double w, h, wISO, hISO, isoThreshold;
- int pg, i;
- int r;
-
- // print doc info
- Object info = doc->getDocInfo();
- if (info.isDict()) {
- printInfoString(info.getDict(), "Title", "Title: ", uMap);
- printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
- printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
- printInfoString(info.getDict(), "Author", "Author: ", uMap);
- printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
- printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
- if (isoDates) {
- printISODate(info.getDict(), "CreationDate", "CreationDate: ");
- printISODate(info.getDict(), "ModDate", "ModDate: ");
- } else if (rawDates) {
- printInfoString(info.getDict(), "CreationDate", "CreationDate: ",
- uMap);
- printInfoString(info.getDict(), "ModDate", "ModDate: ",
- uMap);
- } else {
- printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
- printInfoDate(info.getDict(), "ModDate", "ModDate: ");
- }
- }
-
- // print tagging info
- printf("Tagged: %s\n",
- (doc->getCatalog()->getMarkInfo() & Catalog::markInfoMarked) ? "yes" : "no");
- printf("UserProperties: %s\n",
- (doc->getCatalog()->getMarkInfo() & Catalog::markInfoUserProperties) ? "yes" : "no");
- printf("Suspects: %s\n",
- (doc->getCatalog()->getMarkInfo() & Catalog::markInfoSuspects) ? "yes" : "no");
-
- // print form info
- switch (doc->getCatalog()->getFormType())
- {
+ // print form info
+ switch (doc->getCatalog()->getFormType()) {
case Catalog::NoForm:
- printf("Form: none\n");
- break;
+ printf("Form: none\n");
+ break;
case Catalog::AcroForm:
- printf("Form: AcroForm\n");
- break;
+ printf("Form: AcroForm\n");
+ break;
case Catalog::XfaForm:
- printf("Form: XFA\n");
- break;
- }
-
- // print javascript info
- {
- JSInfo jsInfo(doc, firstPage - 1);
- jsInfo.scanJS(lastPage - firstPage + 1);
- printf("JavaScript: %s\n", jsInfo.containsJS() ? "yes" : "no");
- }
-
- // print page count
- printf("Pages: %d\n", doc->getNumPages());
-
- // print encryption info
- printf("Encrypted: ");
- if (doc->isEncrypted()) {
- unsigned char *fileKey;
- CryptAlgorithm encAlgorithm;
- int keyLength;
- doc->getXRef()->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
-
- const char *encAlgorithmName = "unknown";
- switch (encAlgorithm)
+ printf("Form: XFA\n");
+ break;
+ }
+
+ // print javascript info
{
- case cryptRC4:
- encAlgorithmName = "RC4";
- break;
- case cryptAES:
- encAlgorithmName = "AES";
- break;
- case cryptAES256:
- encAlgorithmName = "AES-256";
- break;
- case cryptNone:
- break;
- }
-
- printf("yes (print:%s copy:%s change:%s addNotes:%s algorithm:%s)\n",
- doc->okToPrint(true) ? "yes" : "no",
- doc->okToCopy(true) ? "yes" : "no",
- doc->okToChange(true) ? "yes" : "no",
- doc->okToAddNotes(true) ? "yes" : "no",
- encAlgorithmName);
- } else {
- printf("no\n");
- }
-
- // print page size
- for (pg = firstPage; pg <= lastPage; ++pg) {
- w = doc->getPageCropWidth(pg);
- h = doc->getPageCropHeight(pg);
- if (multiPage) {
- printf("Page %4d size: %g x %g pts", pg, w, h);
- } else {
- printf("Page size: %g x %g pts", w, h);
+ JSInfo jsInfo(doc, firstPage - 1);
+ jsInfo.scanJS(lastPage - firstPage + 1);
+ printf("JavaScript: %s\n", jsInfo.containsJS() ? "yes" : "no");
}
- if ((fabs(w - 612) < 1 && fabs(h - 792) < 1) ||
- (fabs(w - 792) < 1 && fabs(h - 612) < 1)) {
- printf(" (letter)");
+
+ // print page count
+ printf("Pages: %d\n", doc->getNumPages());
+
+ // print encryption info
+ printf("Encrypted: ");
+ if (doc->isEncrypted()) {
+ unsigned char *fileKey;
+ CryptAlgorithm encAlgorithm;
+ int keyLength;
+ doc->getXRef()->getEncryptionParameters(&fileKey, &encAlgorithm, &keyLength);
+
+ const char *encAlgorithmName = "unknown";
+ switch (encAlgorithm) {
+ case cryptRC4:
+ encAlgorithmName = "RC4";
+ break;
+ case cryptAES:
+ encAlgorithmName = "AES";
+ break;
+ case cryptAES256:
+ encAlgorithmName = "AES-256";
+ break;
+ case cryptNone:
+ break;
+ }
+
+ printf("yes (print:%s copy:%s change:%s addNotes:%s algorithm:%s)\n", doc->okToPrint(true) ? "yes" : "no", doc->okToCopy(true) ? "yes" : "no", doc->okToChange(true) ? "yes" : "no", doc->okToAddNotes(true) ? "yes" : "no",
+ encAlgorithmName);
} else {
- hISO = sqrt(sqrt(2.0)) * 7200 / 2.54;
- wISO = hISO / sqrt(2.0);
- isoThreshold = hISO * 0.003; ///< allow for 0.3% error when guessing conformance to ISO 216, A series
- for (i = 0; i <= 6; ++i) {
- if ((fabs(w - wISO) < isoThreshold && fabs(h - hISO) < isoThreshold) ||
- (fabs(w - hISO) < isoThreshold && fabs(h - wISO) < isoThreshold)) {
- printf(" (A%d)", i);
- break;
- }
- hISO = wISO;
- wISO /= sqrt(2.0);
- isoThreshold /= sqrt(2.0);
- }
- }
- printf("\n");
- r = doc->getPageRotate(pg);
- if (multiPage) {
- printf("Page %4d rot: %d\n", pg, r);
+ printf("no\n");
+ }
+
+ // print page size
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ w = doc->getPageCropWidth(pg);
+ h = doc->getPageCropHeight(pg);
+ if (multiPage) {
+ printf("Page %4d size: %g x %g pts", pg, w, h);
+ } else {
+ printf("Page size: %g x %g pts", w, h);
+ }
+ if ((fabs(w - 612) < 1 && fabs(h - 792) < 1) || (fabs(w - 792) < 1 && fabs(h - 612) < 1)) {
+ printf(" (letter)");
+ } else {
+ hISO = sqrt(sqrt(2.0)) * 7200 / 2.54;
+ wISO = hISO / sqrt(2.0);
+ isoThreshold = hISO * 0.003; ///< allow for 0.3% error when guessing conformance to ISO 216, A series
+ for (i = 0; i <= 6; ++i) {
+ if ((fabs(w - wISO) < isoThreshold && fabs(h - hISO) < isoThreshold) || (fabs(w - hISO) < isoThreshold && fabs(h - wISO) < isoThreshold)) {
+ printf(" (A%d)", i);
+ break;
+ }
+ hISO = wISO;
+ wISO /= sqrt(2.0);
+ isoThreshold /= sqrt(2.0);
+ }
+ }
+ printf("\n");
+ r = doc->getPageRotate(pg);
+ if (multiPage) {
+ printf("Page %4d rot: %d\n", pg, r);
+ } else {
+ printf("Page rot: %d\n", r);
+ }
+ }
+
+ // print the boxes
+ if (printBoxes) {
+ if (multiPage) {
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ page = doc->getPage(pg);
+ if (!page) {
+ error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", pg);
+ continue;
+ }
+ sprintf(buf, "Page %4d MediaBox: ", pg);
+ printBox(buf, page->getMediaBox());
+ sprintf(buf, "Page %4d CropBox: ", pg);
+ printBox(buf, page->getCropBox());
+ sprintf(buf, "Page %4d BleedBox: ", pg);
+ printBox(buf, page->getBleedBox());
+ sprintf(buf, "Page %4d TrimBox: ", pg);
+ printBox(buf, page->getTrimBox());
+ sprintf(buf, "Page %4d ArtBox: ", pg);
+ printBox(buf, page->getArtBox());
+ }
+ } else {
+ page = doc->getPage(firstPage);
+ if (!page) {
+ error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", firstPage);
+ } else {
+ printBox("MediaBox: ", page->getMediaBox());
+ printBox("CropBox: ", page->getCropBox());
+ printBox("BleedBox: ", page->getBleedBox());
+ printBox("TrimBox: ", page->getTrimBox());
+ printBox("ArtBox: ", page->getArtBox());
+ }
+ }
+ }
+
+ // print file size
+ printf("File size: %lld bytes\n", filesize);
+
+ // print linearization info
+ printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
+
+ // print PDF version
+ printf("PDF version: %d.%d\n", doc->getPDFMajorVersion(), doc->getPDFMinorVersion());
+
+ printPdfSubtype(doc, uMap);
+}
+
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName;
+ GooString *ownerPW, *userPW;
+ const UnicodeMap *uMap;
+ FILE *f;
+ bool ok;
+ int exitCode;
+ bool multiPage;
+
+ exitCode = 99;
+
+ // parse args
+ Win32Console win32console(&argc, &argv);
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || (argc != 2 && !printEnc) || printVersion || printHelp) {
+ fprintf(stderr, "pdfinfo version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfinfo", "<PDF-file>", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ goto err0;
+ }
+
+ if (printStructureText)
+ printStructure = true;
+
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+
+ if (printEnc) {
+ printEncodings();
+ exitCode = 0;
+ goto err0;
+ }
+
+ fileName = new GooString(argv[1]);
+
+ if (textEncName[0]) {
+ globalParams->setTextEncoding(textEncName);
+ }
+
+ // get mapping to output encoding
+ if (!(uMap = globalParams->getTextEncoding())) {
+ error(errCommandLine, -1, "Couldn't get text encoding");
+ delete fileName;
+ goto err1;
+ }
+
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = new GooString(ownerPassword);
} else {
- printf("Page rot: %d\n", r);
- }
- }
-
- // print the boxes
- if (printBoxes) {
- if (multiPage) {
- for (pg = firstPage; pg <= lastPage; ++pg) {
- page = doc->getPage(pg);
- if (!page) {
- error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", pg);
- continue;
- }
- sprintf(buf, "Page %4d MediaBox: ", pg);
- printBox(buf, page->getMediaBox());
- sprintf(buf, "Page %4d CropBox: ", pg);
- printBox(buf, page->getCropBox());
- sprintf(buf, "Page %4d BleedBox: ", pg);
- printBox(buf, page->getBleedBox());
- sprintf(buf, "Page %4d TrimBox: ", pg);
- printBox(buf, page->getTrimBox());
- sprintf(buf, "Page %4d ArtBox: ", pg);
- printBox(buf, page->getArtBox());
- }
+ ownerPW = nullptr;
+ }
+ if (userPassword[0] != '\001') {
+ userPW = new GooString(userPassword);
} else {
- page = doc->getPage(firstPage);
- if (!page) {
- error(errSyntaxError, -1, "Failed to print boxes for page {0:d}", firstPage);
- } else {
- printBox("MediaBox: ", page->getMediaBox());
- printBox("CropBox: ", page->getCropBox());
- printBox("BleedBox: ", page->getBleedBox());
- printBox("TrimBox: ", page->getTrimBox());
- printBox("ArtBox: ", page->getArtBox());
- }
+ userPW = nullptr;
}
- }
- // print file size
- printf("File size: %lld bytes\n", filesize);
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
+ }
- // print linearization info
- printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- // print PDF version
- printf("PDF version: %d.%d\n", doc->getPDFMajorVersion(), doc->getPDFMinorVersion());
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err2;
+ }
- printPdfSubtype(doc, uMap);
-}
+ // get page range
+ if (firstPage < 1) {
+ firstPage = 1;
+ }
+ if (lastPage == 0) {
+ multiPage = false;
+ } else {
+ multiPage = true;
+ }
+ if (lastPage < 1 || lastPage > doc->getNumPages()) {
+ lastPage = doc->getNumPages();
+ }
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ goto err2;
+ }
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName;
- GooString *ownerPW, *userPW;
- const UnicodeMap *uMap;
- FILE *f;
- bool ok;
- int exitCode;
- bool multiPage;
-
- exitCode = 99;
-
- // parse args
- Win32Console win32console(&argc, &argv);
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || (argc != 2 && !printEnc) || printVersion || printHelp) {
- fprintf(stderr, "pdfinfo version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfinfo", "<PDF-file>", argDesc);
- }
- if (printVersion || printHelp)
- exitCode = 0;
- goto err0;
- }
-
- if (printStructureText)
- printStructure = true;
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
-
- if (printEnc) {
- printEncodings();
- exitCode = 0;
- goto err0;
- }
+ if (printMetadata) {
+ // print the metadata
+ const GooString *metadata = doc->readMetadata();
+ if (metadata) {
+ fputs(metadata->c_str(), stdout);
+ fputc('\n', stdout);
+ delete metadata;
+ }
+ } else if (printJS) {
+ // print javascript
+ JSInfo jsInfo(doc, firstPage - 1);
+ jsInfo.scanJS(lastPage - firstPage + 1, stdout, uMap);
+ } else if (printStructure || printStructureText) {
+ // print structure
+ const StructTreeRoot *structTree = doc->getCatalog()->getStructTreeRoot();
+ if (structTree) {
+ for (unsigned i = 0; i < structTree->getNumChildren(); i++) {
+ printStruct(structTree->getChild(i), 0);
+ }
+ }
+ } else if (printDests) {
+ printDestinations(doc, uMap);
+ } else {
+ // print info
+ long long filesize = 0;
+
+ f = fopen(fileName->c_str(), "rb");
+ if (f) {
+ Gfseek(f, 0, SEEK_END);
+ filesize = Gftell(f);
+ fclose(f);
+ }
- fileName = new GooString(argv[1]);
+ if (multiPage == false)
+ lastPage = 1;
- if (textEncName[0]) {
- globalParams->setTextEncoding(textEncName);
- }
+ printInfo(doc, uMap, filesize, multiPage);
+ }
+ exitCode = 0;
- // get mapping to output encoding
- if (!(uMap = globalParams->getTextEncoding())) {
- error(errCommandLine, -1, "Couldn't get text encoding");
+ // clean up
+err2:
+ delete doc;
delete fileName;
- goto err1;
- }
-
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0] != '\001') {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
-
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
-
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
-
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err2;
- }
-
- // get page range
- if (firstPage < 1) {
- firstPage = 1;
- }
- if (lastPage == 0) {
- multiPage = false;
- } else {
- multiPage = true;
- }
- if (lastPage < 1 || lastPage > doc->getNumPages()) {
- lastPage = doc->getNumPages();
- }
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- goto err2;
- }
-
- if (printMetadata) {
- // print the metadata
- const GooString *metadata = doc->readMetadata();
- if (metadata) {
- fputs(metadata->c_str(), stdout);
- fputc('\n', stdout);
- delete metadata;
- }
- } else if (printJS) {
- // print javascript
- JSInfo jsInfo(doc, firstPage - 1);
- jsInfo.scanJS(lastPage - firstPage + 1, stdout, uMap);
- } else if (printStructure || printStructureText) {
- // print structure
- const StructTreeRoot *structTree = doc->getCatalog()->getStructTreeRoot();
- if (structTree) {
- for (unsigned i = 0; i < structTree->getNumChildren(); i++) {
- printStruct(structTree->getChild(i), 0);
- }
- }
- } else if (printDests) {
- printDestinations(doc, uMap);
- } else {
- // print info
- long long filesize = 0;
-
- f = fopen(fileName->c_str(), "rb");
- if (f) {
- Gfseek(f, 0, SEEK_END);
- filesize = Gftell(f);
- fclose(f);
- }
-
- if (multiPage == false)
- lastPage = 1;
-
- printInfo(doc, uMap, filesize, multiPage);
- }
- exitCode = 0;
-
- // clean up
- err2:
- delete doc;
- delete fileName;
- err1:
- err0:
-
- return exitCode;
+err1:
+err0:
+
+ return exitCode;
}
diff --git a/utils/pdfseparate.cc b/utils/pdfseparate.cc
index 240022a6..7fc5d029 100644
--- a/utils/pdfseparate.cc
+++ b/utils/pdfseparate.cc
@@ -34,148 +34,134 @@ static int lastPage = 0;
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to extract"},
- {"-l", argInt, &lastPage, 0,
- "last page to extract"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to extract" },
+ { "-l", argInt, &lastPage, 0, "last page to extract" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
-static bool extractPages (const char *srcFileName, const char *destFileName) {
- char pathName[4096];
- GooString *gfileName = new GooString (srcFileName);
- PDFDoc *doc = new PDFDoc (gfileName, nullptr, nullptr, nullptr);
+static bool extractPages(const char *srcFileName, const char *destFileName)
+{
+ char pathName[4096];
+ GooString *gfileName = new GooString(srcFileName);
+ PDFDoc *doc = new PDFDoc(gfileName, nullptr, nullptr, nullptr);
- if (!doc->isOk()) {
- error(errSyntaxError, -1, "Could not extract page(s) from damaged file ('{0:s}')", srcFileName);
- delete doc;
- return false;
- }
+ if (!doc->isOk()) {
+ error(errSyntaxError, -1, "Could not extract page(s) from damaged file ('{0:s}')", srcFileName);
+ delete doc;
+ return false;
+ }
- // destFileName can have multiple %% and one %d
- // We use auxDestFileName to replace all the valid % appearances
- // by 'A' (random char that is not %), if at the end of replacing
- // any of the valid appearances there is still any % around, the
- // pattern is wrong
- if (firstPage == 0 && lastPage == 0) {
- firstPage = 1;
- lastPage = doc->getNumPages();
- }
- if (lastPage == 0)
- lastPage = doc->getNumPages();
- if (firstPage == 0)
- firstPage = 1;
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- delete doc;
- return false;
- }
- bool foundmatch = false;
- char *auxDestFileName = strdup(destFileName);
- char *p = strstr(auxDestFileName, "%d");
- if (p != nullptr) {
- foundmatch = true;
- *p = 'A';
- } else {
- char pattern[6];
- for (int i = 2; i < 10; i++) {
- sprintf(pattern, "%%0%dd", i);
- p = strstr(auxDestFileName, pattern);
- if (p != nullptr) {
- foundmatch = true;
- *p = 'A';
- break;
- }
+ // destFileName can have multiple %% and one %d
+ // We use auxDestFileName to replace all the valid % appearances
+ // by 'A' (random char that is not %), if at the end of replacing
+ // any of the valid appearances there is still any % around, the
+ // pattern is wrong
+ if (firstPage == 0 && lastPage == 0) {
+ firstPage = 1;
+ lastPage = doc->getNumPages();
+ }
+ if (lastPage == 0)
+ lastPage = doc->getNumPages();
+ if (firstPage == 0)
+ firstPage = 1;
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ delete doc;
+ return false;
+ }
+ bool foundmatch = false;
+ char *auxDestFileName = strdup(destFileName);
+ char *p = strstr(auxDestFileName, "%d");
+ if (p != nullptr) {
+ foundmatch = true;
+ *p = 'A';
+ } else {
+ char pattern[6];
+ for (int i = 2; i < 10; i++) {
+ sprintf(pattern, "%%0%dd", i);
+ p = strstr(auxDestFileName, pattern);
+ if (p != nullptr) {
+ foundmatch = true;
+ *p = 'A';
+ break;
+ }
+ }
+ }
+ if (!foundmatch && firstPage != lastPage) {
+ error(errSyntaxError, -1, "'{0:s}' must contain '%d' (or any variant respecting printf format) if more than one page should be extracted, in order to print the page number", destFileName);
+ free(auxDestFileName);
+ delete doc;
+ return false;
}
- }
- if (!foundmatch && firstPage != lastPage) {
- error(errSyntaxError, -1, "'{0:s}' must contain '%d' (or any variant respecting printf format) if more than one page should be extracted, in order to print the page number", destFileName);
- free(auxDestFileName);
- delete doc;
- return false;
- }
- // at this point auxDestFileName can only contain %%
- p = strstr(auxDestFileName, "%%");
- while (p != nullptr) {
- *p = 'A';
- *(p + 1) = 'A';
- p = strstr(p, "%%");
- }
+ // at this point auxDestFileName can only contain %%
+ p = strstr(auxDestFileName, "%%");
+ while (p != nullptr) {
+ *p = 'A';
+ *(p + 1) = 'A';
+ p = strstr(p, "%%");
+ }
- // at this point any other % is wrong
- p = strstr(auxDestFileName, "%");
- if (p != nullptr) {
- error(errSyntaxError, -1, "'{0:s}' can only contain one '%d' pattern", destFileName);
+ // at this point any other % is wrong
+ p = strstr(auxDestFileName, "%");
+ if (p != nullptr) {
+ error(errSyntaxError, -1, "'{0:s}' can only contain one '%d' pattern", destFileName);
+ free(auxDestFileName);
+ delete doc;
+ return false;
+ }
free(auxDestFileName);
- delete doc;
- return false;
- }
- free(auxDestFileName);
-
- for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) {
- snprintf (pathName, sizeof (pathName) - 1, destFileName, pageNo);
- GooString *gpageName = new GooString (pathName);
- PDFDoc *pagedoc = new PDFDoc (new GooString (srcFileName), nullptr, nullptr, nullptr);
- int errCode = pagedoc->savePageAs(gpageName, pageNo);
- if ( errCode != errNone) {
- delete gpageName;
- delete doc;
- delete pagedoc;
- return false;
+
+ for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) {
+ snprintf(pathName, sizeof(pathName) - 1, destFileName, pageNo);
+ GooString *gpageName = new GooString(pathName);
+ PDFDoc *pagedoc = new PDFDoc(new GooString(srcFileName), nullptr, nullptr, nullptr);
+ int errCode = pagedoc->savePageAs(gpageName, pageNo);
+ if (errCode != errNone) {
+ delete gpageName;
+ delete doc;
+ delete pagedoc;
+ return false;
+ }
+ delete pagedoc;
+ delete gpageName;
}
- delete pagedoc;
- delete gpageName;
- }
- delete doc;
- return true;
+ delete doc;
+ return true;
}
-int
-main (int argc, char *argv[])
+int main(int argc, char *argv[])
{
- bool ok;
- int exitCode;
+ bool ok;
+ int exitCode;
- exitCode = 99;
+ exitCode = 99;
- // parse args
- Win32Console win32console(&argc, &argv);
- ok = parseArgs (argDesc, &argc, argv);
- if (!ok || argc != 3 || printVersion || printHelp)
- {
- fprintf (stderr, "pdfseparate version %s\n", PACKAGE_VERSION);
- fprintf (stderr, "%s\n", popplerCopyright);
- fprintf (stderr, "%s\n", xpdfCopyright);
- if (!printVersion)
- {
- printUsage ("pdfseparate", "<PDF-sourcefile> <PDF-pattern-destfile>",
- argDesc);
- }
- if (printVersion || printHelp)
- exitCode = 0;
- goto err0;
+ // parse args
+ Win32Console win32console(&argc, &argv);
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc != 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdfseparate version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfseparate", "<PDF-sourcefile> <PDF-pattern-destfile>", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ goto err0;
+ }
+ globalParams = std::make_unique<GlobalParams>();
+ ok = extractPages(argv[1], argv[2]);
+ if (ok) {
+ exitCode = 0;
}
- globalParams = std::make_unique<GlobalParams>();
- ok = extractPages (argv[1], argv[2]);
- if (ok) {
- exitCode = 0;
- }
err0:
- return exitCode;
+ return exitCode;
}
diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc
index e24cc9ba..7b2bed99 100644
--- a/utils/pdfsig.cc
+++ b/utils/pdfsig.cc
@@ -41,60 +41,60 @@
#include "numberofcharacters.h"
#include <libgen.h>
-static const char * getReadableSigState(SignatureValidationStatus sig_vs)
+static const char *getReadableSigState(SignatureValidationStatus sig_vs)
{
- switch(sig_vs) {
+ switch (sig_vs) {
case SIGNATURE_VALID:
- return "Signature is Valid.";
+ return "Signature is Valid.";
case SIGNATURE_INVALID:
- return "Signature is Invalid.";
+ return "Signature is Invalid.";
case SIGNATURE_DIGEST_MISMATCH:
- return "Digest Mismatch.";
+ return "Digest Mismatch.";
case SIGNATURE_DECODING_ERROR:
- return "Document isn't signed or corrupted data.";
+ return "Document isn't signed or corrupted data.";
case SIGNATURE_NOT_VERIFIED:
- return "Signature has not yet been verified.";
+ return "Signature has not yet been verified.";
default:
- return "Unknown Validation Failure.";
- }
+ return "Unknown Validation Failure.";
+ }
}
-static const char * getReadableCertState(CertificateValidationStatus cert_vs)
+static const char *getReadableCertState(CertificateValidationStatus cert_vs)
{
- switch(cert_vs) {
+ switch (cert_vs) {
case CERTIFICATE_TRUSTED:
- return "Certificate is Trusted.";
+ return "Certificate is Trusted.";
case CERTIFICATE_UNTRUSTED_ISSUER:
- return "Certificate issuer isn't Trusted.";
+ return "Certificate issuer isn't Trusted.";
case CERTIFICATE_UNKNOWN_ISSUER:
- return "Certificate issuer is unknown.";
+ return "Certificate issuer is unknown.";
case CERTIFICATE_REVOKED:
- return "Certificate has been Revoked.";
+ return "Certificate has been Revoked.";
case CERTIFICATE_EXPIRED:
- return "Certificate has Expired";
+ return "Certificate has Expired";
case CERTIFICATE_NOT_VERIFIED:
- return "Certificate has not yet been verified.";
+ return "Certificate has not yet been verified.";
default:
- return "Unknown issue with Certificate or corrupted data.";
- }
+ return "Unknown issue with Certificate or corrupted data.";
+ }
}
static char *getReadableTime(time_t unix_time)
{
- char * time_str = (char *) gmalloc(64);
- strftime(time_str, 64, "%b %d %Y %H:%M:%S", localtime(&unix_time));
- return time_str;
+ char *time_str = (char *)gmalloc(64);
+ strftime(time_str, 64, "%b %d %Y %H:%M:%S", localtime(&unix_time));
+ return time_str;
}
static bool dumpSignature(int sig_num, int sigCount, FormFieldSignature *s, const char *filename)
@@ -127,148 +127,134 @@ static bool printHelp = false;
static bool dontVerifyCert = false;
static bool dumpSignatures = false;
-static const ArgDesc argDesc[] = {
- {"-nssdir", argGooString, &nssDir, 0,
- "path to directory of libnss3 database"},
- {"-nocert", argFlag, &dontVerifyCert, 0,
- "don't perform certificate validation"},
- {"-dump", argFlag, &dumpSignatures, 0,
- "dump all signatures into current directory"},
-
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
+static const ArgDesc argDesc[] = { { "-nssdir", argGooString, &nssDir, 0, "path to directory of libnss3 database" },
+ { "-nocert", argFlag, &dontVerifyCert, 0, "don't perform certificate validation" },
+ { "-dump", argFlag, &dumpSignatures, 0, "dump all signatures into current directory" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
int main(int argc, char *argv[])
{
- char *time_str = nullptr;
- globalParams = std::make_unique<GlobalParams>();
+ char *time_str = nullptr;
+ globalParams = std::make_unique<GlobalParams>();
- Win32Console win32Console(&argc, &argv);
+ Win32Console win32Console(&argc, &argv);
- const bool ok = parseArgs(argDesc, &argc, argv);
+ const bool ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 2 || printVersion || printHelp) {
- fprintf(stderr, "pdfsig version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfsig", "<PDF-file>", argDesc);
+ if (!ok || argc != 2 || printVersion || printHelp) {
+ fprintf(stderr, "pdfsig version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfsig", "<PDF-file>", argDesc);
+ }
+ if (printVersion || printHelp)
+ return 0;
+ return 99;
}
- if (printVersion || printHelp)
- return 0;
- return 99;
- }
-
- std::unique_ptr<GooString> fileName = std::make_unique<GooString>(argv[argc - 1]);
- SignatureHandler::setNSSDir(nssDir);
+ std::unique_ptr<GooString> fileName = std::make_unique<GooString>(argv[argc - 1]);
- // open PDF file
- std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr));
+ SignatureHandler::setNSSDir(nssDir);
- if (!doc->isOk()) {
- return 1;
- }
+ // open PDF file
+ std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr));
- const std::vector<FormFieldSignature*> signatures = doc->getSignatureFields();
- const unsigned int sigCount = signatures.size();
+ if (!doc->isOk()) {
+ return 1;
+ }
- if (sigCount >= 1) {
- if (dumpSignatures) {
- printf("Dumping Signatures: %u\n", sigCount);
- for (unsigned int i = 0; i < sigCount; i++) {
- const bool dumpingOk = dumpSignature(i, sigCount, signatures.at(i), fileName->c_str());
- if (!dumpingOk) {
- return 3;
+ const std::vector<FormFieldSignature *> signatures = doc->getSignatureFields();
+ const unsigned int sigCount = signatures.size();
+
+ if (sigCount >= 1) {
+ if (dumpSignatures) {
+ printf("Dumping Signatures: %u\n", sigCount);
+ for (unsigned int i = 0; i < sigCount; i++) {
+ const bool dumpingOk = dumpSignature(i, sigCount, signatures.at(i), fileName->c_str());
+ if (!dumpingOk) {
+ return 3;
+ }
+ }
+ return 0;
+ } else {
+ printf("Digital Signature Info of: %s\n", fileName->c_str());
}
- }
- return 0;
} else {
- printf("Digital Signature Info of: %s\n", fileName->c_str());
- }
- } else {
- printf("File '%s' does not contain any signatures\n", fileName->c_str());
- return 2;
- }
-
- for (unsigned int i = 0; i < sigCount; i++) {
- const SignatureInfo *sig_info = signatures.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
- printf("Signature #%u:\n", i+1);
- printf(" - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
- printf(" - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
- printf(" - Signing Time: %s\n", time_str = getReadableTime(sig_info->getSigningTime()));
- printf(" - Signing Hash Algorithm: ");
- switch (sig_info->getHashAlgorithm())
- {
- case HASH_AlgMD2:
- printf("MD2\n");
- break;
- case HASH_AlgMD5:
- printf("MD5\n");
- break;
- case HASH_AlgSHA1:
- printf("SHA1\n");
- break;
- case HASH_AlgSHA256:
- printf("SHA-256\n");
- break;
- case HASH_AlgSHA384:
- printf("SHA-384\n");
- break;
- case HASH_AlgSHA512:
- printf("SHA-512\n");
- break;
- case HASH_AlgSHA224:
- printf("SHA-224\n");
- break;
- default:
- printf("unknown\n");
- }
- printf(" - Signature Type: ");
- switch (signatures.at(i)->getSignatureType())
- {
- case adbe_pkcs7_sha1:
- printf("adbe.pkcs7.sha1\n");
- break;
- case adbe_pkcs7_detached:
- printf("adbe.pkcs7.detached\n");
- break;
- case ETSI_CAdES_detached:
- printf("ETSI.CAdES.detached\n");
- break;
- default:
- printf("unknown\n");
+ printf("File '%s' does not contain any signatures\n", fileName->c_str());
+ return 2;
}
- std::vector<Goffset> ranges = signatures.at(i)->getSignedRangeBounds();
- if (ranges.size() == 4)
- {
- printf(" - Signed Ranges: [%lld - %lld], [%lld - %lld]\n",
- ranges[0], ranges[1], ranges[2], ranges[3]);
- Goffset checked_file_size;
- GooString* signature = signatures.at(i)->getCheckedSignature(&checked_file_size);
- if (signature && checked_file_size == ranges[3]) {
- printf(" - Total document signed\n");
- } else {
- printf(" - Not total document signed\n");
- }
- delete signature;
- }
- printf(" - Signature Validation: %s\n", getReadableSigState(sig_info->getSignatureValStatus()));
- gfree(time_str);
- if (sig_info->getSignatureValStatus() != SIGNATURE_VALID || dontVerifyCert) {
- continue;
+
+ for (unsigned int i = 0; i < sigCount; i++) {
+ const SignatureInfo *sig_info = signatures.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
+ printf("Signature #%u:\n", i + 1);
+ printf(" - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
+ printf(" - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
+ printf(" - Signing Time: %s\n", time_str = getReadableTime(sig_info->getSigningTime()));
+ printf(" - Signing Hash Algorithm: ");
+ switch (sig_info->getHashAlgorithm()) {
+ case HASH_AlgMD2:
+ printf("MD2\n");
+ break;
+ case HASH_AlgMD5:
+ printf("MD5\n");
+ break;
+ case HASH_AlgSHA1:
+ printf("SHA1\n");
+ break;
+ case HASH_AlgSHA256:
+ printf("SHA-256\n");
+ break;
+ case HASH_AlgSHA384:
+ printf("SHA-384\n");
+ break;
+ case HASH_AlgSHA512:
+ printf("SHA-512\n");
+ break;
+ case HASH_AlgSHA224:
+ printf("SHA-224\n");
+ break;
+ default:
+ printf("unknown\n");
+ }
+ printf(" - Signature Type: ");
+ switch (signatures.at(i)->getSignatureType()) {
+ case adbe_pkcs7_sha1:
+ printf("adbe.pkcs7.sha1\n");
+ break;
+ case adbe_pkcs7_detached:
+ printf("adbe.pkcs7.detached\n");
+ break;
+ case ETSI_CAdES_detached:
+ printf("ETSI.CAdES.detached\n");
+ break;
+ default:
+ printf("unknown\n");
+ }
+ std::vector<Goffset> ranges = signatures.at(i)->getSignedRangeBounds();
+ if (ranges.size() == 4) {
+ printf(" - Signed Ranges: [%lld - %lld], [%lld - %lld]\n", ranges[0], ranges[1], ranges[2], ranges[3]);
+ Goffset checked_file_size;
+ GooString *signature = signatures.at(i)->getCheckedSignature(&checked_file_size);
+ if (signature && checked_file_size == ranges[3]) {
+ printf(" - Total document signed\n");
+ } else {
+ printf(" - Not total document signed\n");
+ }
+ delete signature;
+ }
+ printf(" - Signature Validation: %s\n", getReadableSigState(sig_info->getSignatureValStatus()));
+ gfree(time_str);
+ if (sig_info->getSignatureValStatus() != SIGNATURE_VALID || dontVerifyCert) {
+ continue;
+ }
+ printf(" - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
}
- printf(" - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
- }
- return 0;
+ return 0;
}
diff --git a/utils/pdftocairo-win32.cc b/utils/pdftocairo-win32.cc
index 8918daff..9dc6ad95 100644
--- a/utils/pdftocairo-win32.cc
+++ b/utils/pdftocairo-win32.cc
@@ -14,17 +14,17 @@
#include <cairo.h>
#ifdef CAIRO_HAS_WIN32_SURFACE
-#include <cairo-win32.h>
+# include <cairo-win32.h>
-#include "parseargs.h"
-#include "pdftocairo-win32.h"
-#include "Win32Console.h"
+# include "parseargs.h"
+# include "pdftocairo-win32.h"
+# include "Win32Console.h"
-#include <dlgs.h>
-#include <commctrl.h>
-#include <commdlg.h>
-#include <windowsx.h>
-#include <winspool.h>
+# include <dlgs.h>
+# include <commctrl.h>
+# include <commdlg.h>
+# include <windowsx.h>
+# include <winspool.h>
static HDC hdc;
static HGLOBAL hDevmode = nullptr;
@@ -34,204 +34,162 @@ static char *printerName;
struct Win32Option
{
- const char *name;
- int value;
+ const char *name;
+ int value;
};
-static const Win32Option win32PaperSource[] =
-{
- {"upper", DMBIN_UPPER},
- {"onlyone", DMBIN_ONLYONE},
- {"lower", DMBIN_LOWER},
- {"middle", DMBIN_MIDDLE},
- {"manual", DMBIN_MANUAL},
- {"envelope", DMBIN_ENVELOPE},
- {"envmanual", DMBIN_ENVMANUAL},
- {"auto", DMBIN_AUTO},
- {"tractor", DMBIN_TRACTOR},
- {"smallfmt", DMBIN_SMALLFMT},
- {"largefmt", DMBIN_LARGEFMT},
- {"largecapacity", DMBIN_LARGECAPACITY},
- {"formsource", DMBIN_FORMSOURCE},
- {nullptr, 0}
-};
+static const Win32Option win32PaperSource[] = { { "upper", DMBIN_UPPER }, { "onlyone", DMBIN_ONLYONE },
+ { "lower", DMBIN_LOWER }, { "middle", DMBIN_MIDDLE },
+ { "manual", DMBIN_MANUAL }, { "envelope", DMBIN_ENVELOPE },
+ { "envmanual", DMBIN_ENVMANUAL }, { "auto", DMBIN_AUTO },
+ { "tractor", DMBIN_TRACTOR }, { "smallfmt", DMBIN_SMALLFMT },
+ { "largefmt", DMBIN_LARGEFMT }, { "largecapacity", DMBIN_LARGECAPACITY },
+ { "formsource", DMBIN_FORMSOURCE }, { nullptr, 0 } };
static void parseSource(GooString *source)
{
- const Win32Option *option = win32PaperSource;
- while (option->name) {
- if (source->cmp(option->name) == 0) {
- devmode->dmDefaultSource = option->value;
- devmode->dmFields |= DM_DEFAULTSOURCE;
- return;
+ const Win32Option *option = win32PaperSource;
+ while (option->name) {
+ if (source->cmp(option->name) == 0) {
+ devmode->dmDefaultSource = option->value;
+ devmode->dmFields |= DM_DEFAULTSOURCE;
+ return;
+ }
+ option++;
}
- option++;
- }
- fprintf(stderr, "Warning: Unknown paper source \"%s\"\n", source->c_str());
+ fprintf(stderr, "Warning: Unknown paper source \"%s\"\n", source->c_str());
}
-static const Win32Option win32DuplexMode[] =
-{
- {"off", DMDUP_SIMPLEX},
- {"short", DMDUP_HORIZONTAL},
- {"long", DMDUP_VERTICAL},
- {nullptr, 0}
-};
+static const Win32Option win32DuplexMode[] = { { "off", DMDUP_SIMPLEX }, { "short", DMDUP_HORIZONTAL }, { "long", DMDUP_VERTICAL }, { nullptr, 0 } };
static void parseDuplex(GooString *mode)
{
- const Win32Option *option = win32DuplexMode;
- while (option->name) {
- if (mode->cmp(option->name) == 0) {
- devmode->dmDuplex = option->value;
- devmode->dmFields |= DM_DUPLEX;
- return;
+ const Win32Option *option = win32DuplexMode;
+ while (option->name) {
+ if (mode->cmp(option->name) == 0) {
+ devmode->dmDuplex = option->value;
+ devmode->dmFields |= DM_DUPLEX;
+ return;
+ }
+ option++;
}
- option++;
- }
- fprintf(stderr, "Warning: Unknown duplex mode \"%s\"\n", mode->c_str());
+ fprintf(stderr, "Warning: Unknown duplex mode \"%s\"\n", mode->c_str());
}
static void fillCommonPrinterOptions(bool duplex)
{
- if (duplex) {
- devmode->dmDuplex = DMDUP_HORIZONTAL;
- devmode->dmFields |= DM_DUPLEX;
- }
+ if (duplex) {
+ devmode->dmDuplex = DMDUP_HORIZONTAL;
+ devmode->dmFields |= DM_DUPLEX;
+ }
}
static void fillPagePrinterOptions(double w, double h)
{
- w *= 254.0 / 72.0; // units are 0.1mm
- h *= 254.0 / 72.0;
- if (w > h) {
- devmode->dmOrientation = DMORIENT_LANDSCAPE;
- devmode->dmPaperWidth = h;
- devmode->dmPaperLength = w;
- } else {
- devmode->dmOrientation = DMORIENT_PORTRAIT;
- devmode->dmPaperWidth = w;
- devmode->dmPaperLength = h;
- }
- devmode->dmPaperSize = 0;
- devmode->dmFields |= DM_ORIENTATION | DM_PAPERWIDTH | DM_PAPERLENGTH;
+ w *= 254.0 / 72.0; // units are 0.1mm
+ h *= 254.0 / 72.0;
+ if (w > h) {
+ devmode->dmOrientation = DMORIENT_LANDSCAPE;
+ devmode->dmPaperWidth = h;
+ devmode->dmPaperLength = w;
+ } else {
+ devmode->dmOrientation = DMORIENT_PORTRAIT;
+ devmode->dmPaperWidth = w;
+ devmode->dmPaperLength = h;
+ }
+ devmode->dmPaperSize = 0;
+ devmode->dmFields |= DM_ORIENTATION | DM_PAPERWIDTH | DM_PAPERLENGTH;
}
-
static void fillPrinterOptions(bool duplex, GooString *printOpt)
{
- //printOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
- const char *nextOpt = printOpt->c_str();
- while (nextOpt && *nextOpt)
- {
- const char *comma = strchr(nextOpt, ',');
- GooString opt;
- if (comma) {
- opt.Set(nextOpt, comma - nextOpt);
- nextOpt = comma + 1;
- } else {
- opt.Set(nextOpt);
- nextOpt = NULL;
+ // printOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
+ const char *nextOpt = printOpt->c_str();
+ while (nextOpt && *nextOpt) {
+ const char *comma = strchr(nextOpt, ',');
+ GooString opt;
+ if (comma) {
+ opt.Set(nextOpt, comma - nextOpt);
+ nextOpt = comma + 1;
+ } else {
+ opt.Set(nextOpt);
+ nextOpt = NULL;
+ }
+ // here opt is "<optN>=<valN> "
+ const char *equal = strchr(opt.c_str(), '=');
+ if (!equal) {
+ fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.c_str());
+ continue;
+ }
+ int iequal = equal - opt.c_str();
+ GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
+ opt.del(iequal, opt.getLength() - iequal);
+ // here opt is "<optN>" and value is "<valN>"
+
+ if (opt.cmp("source") == 0) {
+ parseSource(&value);
+ } else if (opt.cmp("duplex") == 0) {
+ if (duplex)
+ fprintf(stderr, "Warning: duplex mode is specified both as standalone and printer options\n");
+ else
+ parseDuplex(&value);
+ } else {
+ fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.c_str());
+ }
}
- //here opt is "<optN>=<valN> "
- const char *equal = strchr(opt.c_str(), '=');
- if (!equal) {
- fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.c_str());
- continue;
- }
- int iequal = equal - opt.c_str();
- GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
- opt.del(iequal, opt.getLength() - iequal);
- //here opt is "<optN>" and value is "<valN>"
-
- if (opt.cmp("source") == 0) {
- parseSource(&value);
- } else if (opt.cmp("duplex") == 0) {
- if (duplex)
- fprintf(stderr, "Warning: duplex mode is specified both as standalone and printer options\n");
- else
- parseDuplex( &value);
- } else {
- fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.c_str());
- }
- }
}
static void getLocalPos(HWND wind, HWND dlg, RECT *rect)
{
- GetClientRect(wind, rect);
- MapWindowPoints(wind, dlg, (LPPOINT)rect, 2);
+ GetClientRect(wind, rect);
+ MapWindowPoints(wind, dlg, (LPPOINT)rect, 2);
}
static HWND createGroupBox(HWND parent, HINSTANCE hInstance, HMENU id, const char *label, RECT *rect)
{
- HWND hwnd = CreateWindowA(WC_BUTTONA,
- label,
- WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
- rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top,
- parent, id,
- hInstance, NULL);
- HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
- if (hFont)
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
- return hwnd;
+ HWND hwnd = CreateWindowA(WC_BUTTONA, label, WS_CHILD | WS_VISIBLE | BS_GROUPBOX, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, parent, id, hInstance, NULL);
+ HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
+ if (hFont)
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)0);
+ return hwnd;
}
static HWND createCheckBox(HWND parent, HINSTANCE hInstance, HMENU id, const char *label, RECT *rect)
{
- HWND hwnd = CreateWindowA(WC_BUTTONA,
- label,
- WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP,
- rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top,
- parent, id,
- hInstance, NULL);
- HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
- if (hFont)
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
- return hwnd;
+ HWND hwnd = CreateWindowA(WC_BUTTONA, label, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, parent, id, hInstance, NULL);
+ HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
+ if (hFont)
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)0);
+ return hwnd;
}
static HWND createStaticText(HWND parent, HINSTANCE hinstance, HMENU id, const char *text, RECT *rect)
{
- HWND hwnd = CreateWindowA(WC_STATICA,
- text,
- WS_CHILD | WS_VISIBLE | SS_LEFT,
- rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top,
- parent, id,
- hinstance, NULL);
- HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
- if (hFont)
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
- return hwnd;
+ HWND hwnd = CreateWindowA(WC_STATICA, text, WS_CHILD | WS_VISIBLE | SS_LEFT, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, parent, id, hinstance, NULL);
+ HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
+ if (hFont)
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)0);
+ return hwnd;
}
static HWND createPageScaleComboBox(HWND parent, HINSTANCE hinstance, HMENU id, RECT *rect)
{
- HWND hwnd = CreateWindowA(WC_COMBOBOX,
- "",
- WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP |
- CBS_DROPDOWNLIST,
- rect->left, rect->top,
- rect->right - rect->left,
- rect->bottom - rect->top,
- parent, id,
- hinstance, NULL);
- HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
- if (hFont)
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
- ComboBox_AddString(hwnd, "None");
- ComboBox_AddString(hwnd, "Shrink to Printable Area");
- ComboBox_AddString(hwnd, "Fit to Printable Area");
- return hwnd;
+ HWND hwnd = CreateWindowA(WC_COMBOBOX, "", WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | CBS_DROPDOWNLIST, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, parent, id, hinstance, NULL);
+ HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
+ if (hFont)
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)0);
+ ComboBox_AddString(hwnd, "None");
+ ComboBox_AddString(hwnd, "Shrink to Printable Area");
+ ComboBox_AddString(hwnd, "Fit to Printable Area");
+ return hwnd;
}
-enum PageScale { NONE = 0, SHRINK = 1, FIT = 2 };
+enum PageScale
+{
+ NONE = 0,
+ SHRINK = 1,
+ FIT = 2
+};
// used to set/get option values in printDialogHookProc
static PageScale pageScale;
@@ -241,325 +199,308 @@ static bool useOrigPageSize;
// PrintDlg callback to customize the print dialog with additional controls.
static UINT_PTR CALLBACK printDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
- if (uiMsg == WM_INITDIALOG) {
- // Get the extant controls. See dlgs.h and prnsetup.dlg for the PrintDlg control ids.
- HWND printerGroupWind = GetDlgItem(hdlg, grp4);
- HWND printerComboWind = GetDlgItem(hdlg, cmb4);
- HWND nameLabelWind = GetDlgItem(hdlg, stc6);
- HWND statusLabelWind = GetDlgItem(hdlg, stc8);
- HWND printRangeGroupWind = GetDlgItem(hdlg, grp1);
- HWND radio1Wind = GetDlgItem(hdlg, rad1);
- HWND radio2Wind = GetDlgItem(hdlg, rad3);
- HWND copiesGroupWind = GetDlgItem(hdlg, grp2);
- HWND okWind = GetDlgItem(hdlg, IDOK);
- HWND cancelWind = GetDlgItem(hdlg, IDCANCEL);
- if (!printerGroupWind || !printerComboWind || !nameLabelWind || !statusLabelWind ||
- !printRangeGroupWind || !radio1Wind || !radio2Wind || !copiesGroupWind ||
- !okWind || !cancelWind)
- return 0;
-
- // Get the size and position of the above controls relative to the
- // print dialog window
- RECT printerGroupRect;
- RECT printerComboRect;
- RECT nameLabelRect;
- RECT statusLabelRect;
- RECT printRangeGroupRect;
- RECT radio1Rect, radio2Rect;
- RECT copiesGroupRect;
- RECT okRect, cancelRect;
- getLocalPos(printerGroupWind, hdlg, &printerGroupRect);
- getLocalPos(printerComboWind, hdlg, &printerComboRect);
- getLocalPos(nameLabelWind, hdlg, &nameLabelRect);
- getLocalPos(statusLabelWind, hdlg, &statusLabelRect);
- getLocalPos(printRangeGroupWind, hdlg, &printRangeGroupRect);
- getLocalPos(radio1Wind, hdlg, &radio1Rect);
- getLocalPos(radio2Wind, hdlg, &radio2Rect);
- getLocalPos(copiesGroupWind, hdlg, &copiesGroupRect);
- getLocalPos(okWind, hdlg, &okRect);
- getLocalPos(cancelWind, hdlg, &cancelRect);
-
- // Calc space required for new group
- int interGroupSpace = printRangeGroupRect.top - printerGroupRect.bottom;
- int groupHeight = statusLabelRect.top - printerGroupRect.top +
- printRangeGroupRect.bottom - radio1Rect.bottom;
-
- // Increase dialog size
- RECT dlgRect;
- GetWindowRect(hdlg, &dlgRect);
- SetWindowPos(hdlg, nullptr,
- dlgRect.left, dlgRect.top,
- dlgRect.right - dlgRect.left,
- dlgRect.bottom - dlgRect.top + interGroupSpace + groupHeight,
- SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER);
-
- // Add new group and controls
- HINSTANCE hinstance = (HINSTANCE)GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
- RECT pdfGroupBoxRect;
- pdfGroupBoxRect.left = printRangeGroupRect.left;
- pdfGroupBoxRect.right = copiesGroupRect.right;
- pdfGroupBoxRect.top = printRangeGroupRect.bottom + interGroupSpace;
- pdfGroupBoxRect.bottom = pdfGroupBoxRect.top + groupHeight;
- createGroupBox(hdlg, hinstance, (HMENU)grp3, "PDF Print Options", &pdfGroupBoxRect);
-
- RECT textRect;
- textRect.left = nameLabelRect.left;
- textRect.right = nameLabelRect.left + 1.8*(printerComboRect.left - nameLabelRect.left);
- textRect.top = pdfGroupBoxRect.top + nameLabelRect.top - printerGroupRect.top;
- textRect.bottom = textRect.top + nameLabelRect.bottom - nameLabelRect.top;
- createStaticText(hdlg, hinstance, (HMENU)stc1, "Page Scaling:", &textRect);
-
- RECT comboBoxRect;
- comboBoxRect.left = textRect.right;
- comboBoxRect.right = comboBoxRect.left + printerComboRect.right - printerComboRect.left;;
- comboBoxRect.top = pdfGroupBoxRect.top + printerComboRect.top - printerGroupRect.top;
- comboBoxRect.bottom = textRect.top + 4*(printerComboRect.bottom - printerComboRect.top);
- HWND comboBoxWind = createPageScaleComboBox(hdlg, hinstance, (HMENU)cmb1, &comboBoxRect);
-
- RECT checkBox1Rect;
- checkBox1Rect.left = radio1Rect.left;
- checkBox1Rect.right = pdfGroupBoxRect.right - 10;
- checkBox1Rect.top = pdfGroupBoxRect.top + statusLabelRect.top - printerGroupRect.top;
- checkBox1Rect.bottom = checkBox1Rect.top + radio1Rect.bottom - radio1Rect.top;
- HWND checkBox1Wind = createCheckBox(hdlg, hinstance, (HMENU)chx3, "Center", &checkBox1Rect);
-
- RECT checkBox2Rect;
- checkBox2Rect.left = radio1Rect.left;
- checkBox2Rect.right = pdfGroupBoxRect.right - 10;
- checkBox2Rect.top = checkBox1Rect.top + radio2Rect.top - radio1Rect.top;
- checkBox2Rect.bottom = checkBox2Rect.top + radio1Rect.bottom - radio1Rect.top;
- HWND checkBox2Wind = createCheckBox(hdlg, hinstance, (HMENU)chx4, "Select page size using document page size", &checkBox2Rect);
-
- // Move OK and Cancel buttons down ensuring they are last in the Z order
- // so that the tab order is correct.
- SetWindowPos(okWind,
- HWND_BOTTOM,
- okRect.left,
- okRect.top + interGroupSpace + groupHeight,
- 0, 0,
- SWP_NOSIZE); // keep current size
- SetWindowPos(cancelWind,
- HWND_BOTTOM,
- cancelRect.left,
- cancelRect.top + interGroupSpace + groupHeight,
- 0, 0,
- SWP_NOSIZE); // keep current size
-
- // Initialize control values
- ComboBox_SetCurSel(comboBoxWind, pageScale);
- Button_SetCheck(checkBox1Wind, centerPage ? BST_CHECKED : BST_UNCHECKED);
- Button_SetCheck(checkBox2Wind, useOrigPageSize ? BST_CHECKED : BST_UNCHECKED);
-
- } else if (uiMsg == WM_COMMAND) {
- // Save settings
- UINT id = LOWORD(wParam);
- if (id == cmb1)
- pageScale = (PageScale)ComboBox_GetCurSel(GetDlgItem(hdlg, cmb1));
- if (id == chx3)
- centerPage = IsDlgButtonChecked(hdlg, chx3);
- if (id == chx4)
- useOrigPageSize = IsDlgButtonChecked(hdlg, chx4);
- }
- return 0;
+ if (uiMsg == WM_INITDIALOG) {
+ // Get the extant controls. See dlgs.h and prnsetup.dlg for the PrintDlg control ids.
+ HWND printerGroupWind = GetDlgItem(hdlg, grp4);
+ HWND printerComboWind = GetDlgItem(hdlg, cmb4);
+ HWND nameLabelWind = GetDlgItem(hdlg, stc6);
+ HWND statusLabelWind = GetDlgItem(hdlg, stc8);
+ HWND printRangeGroupWind = GetDlgItem(hdlg, grp1);
+ HWND radio1Wind = GetDlgItem(hdlg, rad1);
+ HWND radio2Wind = GetDlgItem(hdlg, rad3);
+ HWND copiesGroupWind = GetDlgItem(hdlg, grp2);
+ HWND okWind = GetDlgItem(hdlg, IDOK);
+ HWND cancelWind = GetDlgItem(hdlg, IDCANCEL);
+ if (!printerGroupWind || !printerComboWind || !nameLabelWind || !statusLabelWind || !printRangeGroupWind || !radio1Wind || !radio2Wind || !copiesGroupWind || !okWind || !cancelWind)
+ return 0;
+
+ // Get the size and position of the above controls relative to the
+ // print dialog window
+ RECT printerGroupRect;
+ RECT printerComboRect;
+ RECT nameLabelRect;
+ RECT statusLabelRect;
+ RECT printRangeGroupRect;
+ RECT radio1Rect, radio2Rect;
+ RECT copiesGroupRect;
+ RECT okRect, cancelRect;
+ getLocalPos(printerGroupWind, hdlg, &printerGroupRect);
+ getLocalPos(printerComboWind, hdlg, &printerComboRect);
+ getLocalPos(nameLabelWind, hdlg, &nameLabelRect);
+ getLocalPos(statusLabelWind, hdlg, &statusLabelRect);
+ getLocalPos(printRangeGroupWind, hdlg, &printRangeGroupRect);
+ getLocalPos(radio1Wind, hdlg, &radio1Rect);
+ getLocalPos(radio2Wind, hdlg, &radio2Rect);
+ getLocalPos(copiesGroupWind, hdlg, &copiesGroupRect);
+ getLocalPos(okWind, hdlg, &okRect);
+ getLocalPos(cancelWind, hdlg, &cancelRect);
+
+ // Calc space required for new group
+ int interGroupSpace = printRangeGroupRect.top - printerGroupRect.bottom;
+ int groupHeight = statusLabelRect.top - printerGroupRect.top + printRangeGroupRect.bottom - radio1Rect.bottom;
+
+ // Increase dialog size
+ RECT dlgRect;
+ GetWindowRect(hdlg, &dlgRect);
+ SetWindowPos(hdlg, nullptr, dlgRect.left, dlgRect.top, dlgRect.right - dlgRect.left, dlgRect.bottom - dlgRect.top + interGroupSpace + groupHeight, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);
+
+ // Add new group and controls
+ HINSTANCE hinstance = (HINSTANCE)GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
+ RECT pdfGroupBoxRect;
+ pdfGroupBoxRect.left = printRangeGroupRect.left;
+ pdfGroupBoxRect.right = copiesGroupRect.right;
+ pdfGroupBoxRect.top = printRangeGroupRect.bottom + interGroupSpace;
+ pdfGroupBoxRect.bottom = pdfGroupBoxRect.top + groupHeight;
+ createGroupBox(hdlg, hinstance, (HMENU)grp3, "PDF Print Options", &pdfGroupBoxRect);
+
+ RECT textRect;
+ textRect.left = nameLabelRect.left;
+ textRect.right = nameLabelRect.left + 1.8 * (printerComboRect.left - nameLabelRect.left);
+ textRect.top = pdfGroupBoxRect.top + nameLabelRect.top - printerGroupRect.top;
+ textRect.bottom = textRect.top + nameLabelRect.bottom - nameLabelRect.top;
+ createStaticText(hdlg, hinstance, (HMENU)stc1, "Page Scaling:", &textRect);
+
+ RECT comboBoxRect;
+ comboBoxRect.left = textRect.right;
+ comboBoxRect.right = comboBoxRect.left + printerComboRect.right - printerComboRect.left;
+ ;
+ comboBoxRect.top = pdfGroupBoxRect.top + printerComboRect.top - printerGroupRect.top;
+ comboBoxRect.bottom = textRect.top + 4 * (printerComboRect.bottom - printerComboRect.top);
+ HWND comboBoxWind = createPageScaleComboBox(hdlg, hinstance, (HMENU)cmb1, &comboBoxRect);
+
+ RECT checkBox1Rect;
+ checkBox1Rect.left = radio1Rect.left;
+ checkBox1Rect.right = pdfGroupBoxRect.right - 10;
+ checkBox1Rect.top = pdfGroupBoxRect.top + statusLabelRect.top - printerGroupRect.top;
+ checkBox1Rect.bottom = checkBox1Rect.top + radio1Rect.bottom - radio1Rect.top;
+ HWND checkBox1Wind = createCheckBox(hdlg, hinstance, (HMENU)chx3, "Center", &checkBox1Rect);
+
+ RECT checkBox2Rect;
+ checkBox2Rect.left = radio1Rect.left;
+ checkBox2Rect.right = pdfGroupBoxRect.right - 10;
+ checkBox2Rect.top = checkBox1Rect.top + radio2Rect.top - radio1Rect.top;
+ checkBox2Rect.bottom = checkBox2Rect.top + radio1Rect.bottom - radio1Rect.top;
+ HWND checkBox2Wind = createCheckBox(hdlg, hinstance, (HMENU)chx4, "Select page size using document page size", &checkBox2Rect);
+
+ // Move OK and Cancel buttons down ensuring they are last in the Z order
+ // so that the tab order is correct.
+ SetWindowPos(okWind, HWND_BOTTOM, okRect.left, okRect.top + interGroupSpace + groupHeight, 0, 0,
+ SWP_NOSIZE); // keep current size
+ SetWindowPos(cancelWind, HWND_BOTTOM, cancelRect.left, cancelRect.top + interGroupSpace + groupHeight, 0, 0,
+ SWP_NOSIZE); // keep current size
+
+ // Initialize control values
+ ComboBox_SetCurSel(comboBoxWind, pageScale);
+ Button_SetCheck(checkBox1Wind, centerPage ? BST_CHECKED : BST_UNCHECKED);
+ Button_SetCheck(checkBox2Wind, useOrigPageSize ? BST_CHECKED : BST_UNCHECKED);
+
+ } else if (uiMsg == WM_COMMAND) {
+ // Save settings
+ UINT id = LOWORD(wParam);
+ if (id == cmb1)
+ pageScale = (PageScale)ComboBox_GetCurSel(GetDlgItem(hdlg, cmb1));
+ if (id == chx3)
+ centerPage = IsDlgButtonChecked(hdlg, chx3);
+ if (id == chx4)
+ useOrigPageSize = IsDlgButtonChecked(hdlg, chx4);
+ }
+ return 0;
}
-void win32SetupPrinter(GooString *printer, GooString *printOpt,
- bool duplex, bool setupdlg)
+void win32SetupPrinter(GooString *printer, GooString *printOpt, bool duplex, bool setupdlg)
{
- if (printer->c_str()[0] == 0) {
- DWORD size = 0;
- GetDefaultPrinterA(nullptr, &size);
- printerName = (char*)gmalloc(size);
- GetDefaultPrinterA(printerName, &size);
- } else {
- printerName = copyString(printer->c_str(), printer->getLength());
- }
-
- //Query the size of the DEVMODE struct
- LONG szProp = DocumentPropertiesA(nullptr, nullptr, printerName, nullptr, nullptr, 0);
- if (szProp < 0) {
- fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
- exit(99);
- }
- devmode = (DEVMODEA*)gmalloc(szProp);
- memset(devmode, 0, szProp);
- devmode->dmSize = sizeof(DEVMODEA);
- devmode->dmSpecVersion = DM_SPECVERSION;
- //Load the current default configuration for the printer into devmode
- if (DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, DM_OUT_BUFFER) < 0) {
- fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
- exit(99);
- }
-
- // Update devmode with selected print options
- fillCommonPrinterOptions(duplex);
- fillPrinterOptions(duplex, printOpt);
-
- // Call DocumentProperties again so the driver can update its private data
- // with the modified print options. This will also display the printer
- // properties dialog if setupdlg is true.
- int ret;
- DWORD mode = DM_IN_BUFFER | DM_OUT_BUFFER;
- if (setupdlg)
- mode |= DM_IN_PROMPT;
- ret = DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, mode);
- if (ret < 0) {
- fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
- exit(99);
- }
- if (setupdlg && ret == IDCANCEL)
- exit(0);
-
- hdc = CreateDCA(nullptr, printerName, nullptr, devmode);
- if (!hdc) {
- fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
- exit(99);
- }
+ if (printer->c_str()[0] == 0) {
+ DWORD size = 0;
+ GetDefaultPrinterA(nullptr, &size);
+ printerName = (char *)gmalloc(size);
+ GetDefaultPrinterA(printerName, &size);
+ } else {
+ printerName = copyString(printer->c_str(), printer->getLength());
+ }
+
+ // Query the size of the DEVMODE struct
+ LONG szProp = DocumentPropertiesA(nullptr, nullptr, printerName, nullptr, nullptr, 0);
+ if (szProp < 0) {
+ fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
+ exit(99);
+ }
+ devmode = (DEVMODEA *)gmalloc(szProp);
+ memset(devmode, 0, szProp);
+ devmode->dmSize = sizeof(DEVMODEA);
+ devmode->dmSpecVersion = DM_SPECVERSION;
+ // Load the current default configuration for the printer into devmode
+ if (DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, DM_OUT_BUFFER) < 0) {
+ fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
+ exit(99);
+ }
+
+ // Update devmode with selected print options
+ fillCommonPrinterOptions(duplex);
+ fillPrinterOptions(duplex, printOpt);
+
+ // Call DocumentProperties again so the driver can update its private data
+ // with the modified print options. This will also display the printer
+ // properties dialog if setupdlg is true.
+ int ret;
+ DWORD mode = DM_IN_BUFFER | DM_OUT_BUFFER;
+ if (setupdlg)
+ mode |= DM_IN_PROMPT;
+ ret = DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, mode);
+ if (ret < 0) {
+ fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
+ exit(99);
+ }
+ if (setupdlg && ret == IDCANCEL)
+ exit(0);
+
+ hdc = CreateDCA(nullptr, printerName, nullptr, devmode);
+ if (!hdc) {
+ fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
+ exit(99);
+ }
}
-void win32ShowPrintDialog(bool *expand, bool *noShrink, bool *noCenter,
- bool *usePDFPageSize, bool *allPages,
- int *firstPage, int *lastPage, int maxPages)
+void win32ShowPrintDialog(bool *expand, bool *noShrink, bool *noCenter, bool *usePDFPageSize, bool *allPages, int *firstPage, int *lastPage, int maxPages)
{
- PRINTDLG pd;
- memset(&pd, 0, sizeof(PRINTDLG));
- pd.lStructSize = sizeof(PRINTDLG);
- pd.Flags = PD_NOSELECTION | PD_ENABLEPRINTHOOK | PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
- if (*allPages) {
- pd.nFromPage = 1;
- pd.nToPage = maxPages;
- } else {
- pd.Flags |= PD_PAGENUMS;
- pd.nFromPage = *firstPage;
- pd.nToPage = *lastPage;
- }
- pd.nCopies = 1;
- pd.nMinPage = 1;
- pd.nMaxPage = maxPages;
- pd.lpfnPrintHook = printDialogHookProc;
- if (!*expand && *noShrink)
- pageScale = NONE;
- else if (!*expand && !*noShrink)
- pageScale = SHRINK;
- else
- pageScale = FIT;
- centerPage = !*noCenter;
- useOrigPageSize = *usePDFPageSize;
-
- if (PrintDlgA(&pd)) {
- // Ok
- hDevnames = pd.hDevNames;
- DEVNAMES *devnames = (DEVNAMES*)GlobalLock(hDevnames);
- printerName = (char*)devnames + devnames->wDeviceOffset;
- hDevmode = pd.hDevMode;
- devmode = (DEVMODEA*)GlobalLock(hDevmode);
- hdc = pd.hDC;
- if (pd.Flags & PD_PAGENUMS) {
- *allPages = false;
- *firstPage = pd.nFromPage;
- *lastPage = pd.nToPage;
+ PRINTDLG pd;
+ memset(&pd, 0, sizeof(PRINTDLG));
+ pd.lStructSize = sizeof(PRINTDLG);
+ pd.Flags = PD_NOSELECTION | PD_ENABLEPRINTHOOK | PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
+ if (*allPages) {
+ pd.nFromPage = 1;
+ pd.nToPage = maxPages;
} else {
- *allPages = true;
+ pd.Flags |= PD_PAGENUMS;
+ pd.nFromPage = *firstPage;
+ pd.nToPage = *lastPage;
}
- if (pageScale == NONE) {
- *expand = false;
- *noShrink = true;
- } else if (pageScale == SHRINK) {
- *expand = false;
- *noShrink = false;
+ pd.nCopies = 1;
+ pd.nMinPage = 1;
+ pd.nMaxPage = maxPages;
+ pd.lpfnPrintHook = printDialogHookProc;
+ if (!*expand && *noShrink)
+ pageScale = NONE;
+ else if (!*expand && !*noShrink)
+ pageScale = SHRINK;
+ else
+ pageScale = FIT;
+ centerPage = !*noCenter;
+ useOrigPageSize = *usePDFPageSize;
+
+ if (PrintDlgA(&pd)) {
+ // Ok
+ hDevnames = pd.hDevNames;
+ DEVNAMES *devnames = (DEVNAMES *)GlobalLock(hDevnames);
+ printerName = (char *)devnames + devnames->wDeviceOffset;
+ hDevmode = pd.hDevMode;
+ devmode = (DEVMODEA *)GlobalLock(hDevmode);
+ hdc = pd.hDC;
+ if (pd.Flags & PD_PAGENUMS) {
+ *allPages = false;
+ *firstPage = pd.nFromPage;
+ *lastPage = pd.nToPage;
+ } else {
+ *allPages = true;
+ }
+ if (pageScale == NONE) {
+ *expand = false;
+ *noShrink = true;
+ } else if (pageScale == SHRINK) {
+ *expand = false;
+ *noShrink = false;
+ } else {
+ *expand = true;
+ *noShrink = false;
+ }
+ *noCenter = !centerPage;
+ *usePDFPageSize = useOrigPageSize;
} else {
- *expand = true;
- *noShrink = false;
+ // Cancel
+ exit(0);
}
- *noCenter = !centerPage;
- *usePDFPageSize = useOrigPageSize;
- } else {
- // Cancel
- exit(0);
- }
}
cairo_surface_t *win32BeginDocument(GooString *inputFileName, GooString *outputFileName)
{
- DOCINFOA docinfo;
- memset(&docinfo, 0, sizeof(docinfo));
- docinfo.cbSize = sizeof(docinfo);
- if (inputFileName->cmp("fd://0") == 0)
- docinfo.lpszDocName = "pdftocairo <stdin>";
- else
- docinfo.lpszDocName = inputFileName->c_str();
- if (outputFileName)
- docinfo.lpszOutput = outputFileName->c_str();
- if (StartDocA(hdc, &docinfo) <=0) {
- fprintf(stderr, "Error: StartDoc failed\n");
- exit(99);
- }
-
- return cairo_win32_printing_surface_create(hdc);
+ DOCINFOA docinfo;
+ memset(&docinfo, 0, sizeof(docinfo));
+ docinfo.cbSize = sizeof(docinfo);
+ if (inputFileName->cmp("fd://0") == 0)
+ docinfo.lpszDocName = "pdftocairo <stdin>";
+ else
+ docinfo.lpszDocName = inputFileName->c_str();
+ if (outputFileName)
+ docinfo.lpszOutput = outputFileName->c_str();
+ if (StartDocA(hdc, &docinfo) <= 0) {
+ fprintf(stderr, "Error: StartDoc failed\n");
+ exit(99);
+ }
+
+ return cairo_win32_printing_surface_create(hdc);
}
void win32BeginPage(double *w, double *h, bool changePageSize, bool useFullPage)
{
- if (changePageSize)
- fillPagePrinterOptions(*w, *h);
- if (DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER) < 0) {
- fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
- exit(99);
- }
- ResetDCA(hdc, devmode);
-
- // Get actual paper size or if useFullPage is false the printable area.
- // Transform the hdc scale to points to be consistent with other cairo backends
- int x_dpi = GetDeviceCaps (hdc, LOGPIXELSX);
- int y_dpi = GetDeviceCaps (hdc, LOGPIXELSY);
- int x_off = GetDeviceCaps (hdc, PHYSICALOFFSETX);
- int y_off = GetDeviceCaps (hdc, PHYSICALOFFSETY);
- if (useFullPage) {
- *w = GetDeviceCaps (hdc, PHYSICALWIDTH)*72.0/x_dpi;
- *h = GetDeviceCaps (hdc, PHYSICALHEIGHT)*72.0/y_dpi;
- } else {
- *w = GetDeviceCaps (hdc, HORZRES)*72.0/x_dpi;
- *h = GetDeviceCaps (hdc, VERTRES)*72.0/y_dpi;
- }
- XFORM xform;
- xform.eM11 = x_dpi/72.0;
- xform.eM12 = 0;
- xform.eM21 = 0;
- xform.eM22 = y_dpi/72.0;
- if (useFullPage) {
- xform.eDx = -x_off;
- xform.eDy = -y_off;
- } else {
- xform.eDx = 0;
- xform.eDy = 0;
- }
- SetGraphicsMode (hdc, GM_ADVANCED);
- SetWorldTransform (hdc, &xform);
-
- StartPage(hdc);
+ if (changePageSize)
+ fillPagePrinterOptions(*w, *h);
+ if (DocumentPropertiesA(nullptr, nullptr, printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER) < 0) {
+ fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
+ exit(99);
+ }
+ ResetDCA(hdc, devmode);
+
+ // Get actual paper size or if useFullPage is false the printable area.
+ // Transform the hdc scale to points to be consistent with other cairo backends
+ int x_dpi = GetDeviceCaps(hdc, LOGPIXELSX);
+ int y_dpi = GetDeviceCaps(hdc, LOGPIXELSY);
+ int x_off = GetDeviceCaps(hdc, PHYSICALOFFSETX);
+ int y_off = GetDeviceCaps(hdc, PHYSICALOFFSETY);
+ if (useFullPage) {
+ *w = GetDeviceCaps(hdc, PHYSICALWIDTH) * 72.0 / x_dpi;
+ *h = GetDeviceCaps(hdc, PHYSICALHEIGHT) * 72.0 / y_dpi;
+ } else {
+ *w = GetDeviceCaps(hdc, HORZRES) * 72.0 / x_dpi;
+ *h = GetDeviceCaps(hdc, VERTRES) * 72.0 / y_dpi;
+ }
+ XFORM xform;
+ xform.eM11 = x_dpi / 72.0;
+ xform.eM12 = 0;
+ xform.eM21 = 0;
+ xform.eM22 = y_dpi / 72.0;
+ if (useFullPage) {
+ xform.eDx = -x_off;
+ xform.eDy = -y_off;
+ } else {
+ xform.eDx = 0;
+ xform.eDy = 0;
+ }
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+
+ StartPage(hdc);
}
void win32EndPage(GooString *imageFileName)
{
- EndPage(hdc);
+ EndPage(hdc);
}
void win32EndDocument()
{
- EndDoc(hdc);
- DeleteDC(hdc);
- if (hDevmode) {
- GlobalUnlock(hDevmode);
- GlobalFree(hDevmode);
- } else {
- gfree(devmode);
- }
- if (hDevnames) {
- GlobalUnlock(hDevnames);
- GlobalFree(hDevnames);
- } else {
- gfree(printerName);
- }
+ EndDoc(hdc);
+ DeleteDC(hdc);
+ if (hDevmode) {
+ GlobalUnlock(hDevmode);
+ GlobalFree(hDevmode);
+ } else {
+ gfree(devmode);
+ }
+ if (hDevnames) {
+ GlobalUnlock(hDevnames);
+ GlobalFree(hDevnames);
+ } else {
+ gfree(printerName);
+ }
}
#endif // CAIRO_HAS_WIN32_SURFACE
diff --git a/utils/pdftocairo-win32.h b/utils/pdftocairo-win32.h
index 1c859bcf..b99bd406 100644
--- a/utils/pdftocairo-win32.h
+++ b/utils/pdftocairo-win32.h
@@ -17,13 +17,10 @@
#ifdef CAIRO_HAS_WIN32_SURFACE
-#include <cairo-win32.h>
+# include <cairo-win32.h>
-void win32SetupPrinter(GooString *printer, GooString *printOpt,
- bool duplex, bool setupdlg);
-void win32ShowPrintDialog(bool *expand, bool *noShrink, bool *noCenter,
- bool *usePDFPageSize, bool *allPages,
- int *firstPage, int *lastPage, int maxPages);
+void win32SetupPrinter(GooString *printer, GooString *printOpt, bool duplex, bool setupdlg);
+void win32ShowPrintDialog(bool *expand, bool *noShrink, bool *noCenter, bool *usePDFPageSize, bool *allPages, int *firstPage, int *lastPage, int maxPages);
cairo_surface_t *win32BeginDocument(GooString *inputFileName, GooString *outputFileName);
void win32BeginPage(double *w, double *h, bool changePageSize, bool useFullPage);
void win32EndPage(GooString *imageFileName);
diff --git a/utils/pdftocairo.cc b/utils/pdftocairo.cc
index a6d9384f..d3302c7b 100644
--- a/utils/pdftocairo.cc
+++ b/utils/pdftocairo.cc
@@ -63,22 +63,21 @@
#include "Win32Console.h"
#include "numberofcharacters.h"
#ifdef USE_CMS
-#include <lcms2.h>
+# include <lcms2.h>
#endif
#include <cairo.h>
#ifdef CAIRO_HAS_PS_SURFACE
-#include <cairo-ps.h>
+# include <cairo-ps.h>
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
-#include <cairo-pdf.h>
+# include <cairo-pdf.h>
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
-#include <cairo-svg.h>
+# include <cairo-svg.h>
#endif
#include "pdftocairo-win32.h"
-
static bool png = false;
static bool jpeg = false;
static bool ps = false;
@@ -144,145 +143,89 @@ static bool setupdlg = false;
static const ArgDesc argDesc[] = {
#ifdef ENABLE_LIBPNG
- {"-png", argFlag, &png, 0,
- "generate a PNG file"},
+ { "-png", argFlag, &png, 0, "generate a PNG file" },
#endif
#ifdef ENABLE_LIBJPEG
- {"-jpeg", argFlag, &jpeg, 0,
- "generate a JPEG file"},
- {"-jpegopt", argGooString, &jpegOpt, 0,
- "jpeg options, with format <opt1>=<val1>[,<optN>=<valN>]*"},
+ { "-jpeg", argFlag, &jpeg, 0, "generate a JPEG file" },
+ { "-jpegopt", argGooString, &jpegOpt, 0, "jpeg options, with format <opt1>=<val1>[,<optN>=<valN>]*" },
#endif
#ifdef ENABLE_LIBTIFF
- {"-tiff", argFlag, &tiff, 0,
- "generate a TIFF file"},
- {"-tiffcompression", argString, tiffCompressionStr, sizeof(tiffCompressionStr),
- "set TIFF compression: none, packbits, jpeg, lzw, deflate"},
+ { "-tiff", argFlag, &tiff, 0, "generate a TIFF file" },
+ { "-tiffcompression", argString, tiffCompressionStr, sizeof(tiffCompressionStr), "set TIFF compression: none, packbits, jpeg, lzw, deflate" },
#endif
#ifdef CAIRO_HAS_PS_SURFACE
- {"-ps", argFlag, &ps, 0,
- "generate PostScript file"},
- {"-eps", argFlag, &eps, 0,
- "generate Encapsulated PostScript (EPS)"},
+ { "-ps", argFlag, &ps, 0, "generate PostScript file" },
+ { "-eps", argFlag, &eps, 0, "generate Encapsulated PostScript (EPS)" },
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
- {"-pdf", argFlag, &pdf, 0,
- "generate a PDF file"},
+ { "-pdf", argFlag, &pdf, 0, "generate a PDF file" },
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
- {"-svg", argFlag, &svg, 0,
- "generate a Scalable Vector Graphics (SVG) file"},
+ { "-svg", argFlag, &svg, 0, "generate a Scalable Vector Graphics (SVG) file" },
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
- {"-print", argFlag, &printToWin32, 0,
- "print to a Windows printer"},
- {"-printdlg", argFlag, &printdlg, 0,
- "show Windows print dialog and print"},
- {"-printer", argGooString, &printer, 0,
- "printer name or use default if this option is not specified"},
- {"-printopt", argGooString, &printOpt, 0,
- "printer options, with format <opt1>=<val1>[,<optN>=<valN>]*"},
- {"-setupdlg", argFlag, &setupdlg, 0,
- "show printer setup dialog before printing"},
+ { "-print", argFlag, &printToWin32, 0, "print to a Windows printer" },
+ { "-printdlg", argFlag, &printdlg, 0, "show Windows print dialog and print" },
+ { "-printer", argGooString, &printer, 0, "printer name or use default if this option is not specified" },
+ { "-printopt", argGooString, &printOpt, 0, "printer options, with format <opt1>=<val1>[,<optN>=<valN>]*" },
+ { "-setupdlg", argFlag, &setupdlg, 0, "show printer setup dialog before printing" },
#endif
- {"-f", argInt, &firstPage, 0,
- "first page to print"},
- {"-l", argInt, &lastPage, 0,
- "last page to print"},
- {"-o", argFlag, &printOnlyOdd, 0,
- "print only odd pages"},
- {"-e", argFlag, &printOnlyEven, 0,
- "print only even pages"},
- {"-singlefile", argFlag, &singleFile, 0,
- "write only the first page and do not add digits"},
-
- {"-r", argFP, &resolution, 0,
- "resolution, in PPI (default is 150)"},
- {"-rx", argFP, &x_resolution, 0,
- "X resolution, in PPI (default is 150)"},
- {"-ry", argFP, &y_resolution, 0,
- "Y resolution, in PPI (default is 150)"},
- {"-scale-to", argInt, &scaleTo, 0,
- "scales each page to fit within scale-to*scale-to pixel box"},
- {"-scale-to-x", argInt, &x_scaleTo, 0,
- "scales each page horizontally to fit in scale-to-x pixels"},
- {"-scale-to-y", argInt, &y_scaleTo, 0,
- "scales each page vertically to fit in scale-to-y pixels"},
-
- {"-x", argInt, &crop_x, 0,
- "x-coordinate of the crop area top left corner"},
- {"-y", argInt, &crop_y, 0,
- "y-coordinate of the crop area top left corner"},
- {"-W", argInt, &crop_w, 0,
- "width of crop area in pixels (default is 0)"},
- {"-H", argInt, &crop_h, 0,
- "height of crop area in pixels (default is 0)"},
- {"-sz", argInt, &sz, 0,
- "size of crop square in pixels (sets W and H)"},
- {"-cropbox",argFlag, &useCropBox, 0,
- "use the crop box rather than media box"},
-
- {"-mono", argFlag, &mono, 0,
- "generate a monochrome image file (PNG, JPEG)"},
- {"-gray", argFlag, &gray, 0,
- "generate a grayscale image file (PNG, JPEG)"},
- {"-transp", argFlag, &transp, 0,
- "use a transparent background instead of white (PNG)"},
- {"-antialias", argGooString, &antialias, 0,
- "set cairo antialias option"},
+ { "-f", argInt, &firstPage, 0, "first page to print" },
+ { "-l", argInt, &lastPage, 0, "last page to print" },
+ { "-o", argFlag, &printOnlyOdd, 0, "print only odd pages" },
+ { "-e", argFlag, &printOnlyEven, 0, "print only even pages" },
+ { "-singlefile", argFlag, &singleFile, 0, "write only the first page and do not add digits" },
+
+ { "-r", argFP, &resolution, 0, "resolution, in PPI (default is 150)" },
+ { "-rx", argFP, &x_resolution, 0, "X resolution, in PPI (default is 150)" },
+ { "-ry", argFP, &y_resolution, 0, "Y resolution, in PPI (default is 150)" },
+ { "-scale-to", argInt, &scaleTo, 0, "scales each page to fit within scale-to*scale-to pixel box" },
+ { "-scale-to-x", argInt, &x_scaleTo, 0, "scales each page horizontally to fit in scale-to-x pixels" },
+ { "-scale-to-y", argInt, &y_scaleTo, 0, "scales each page vertically to fit in scale-to-y pixels" },
+
+ { "-x", argInt, &crop_x, 0, "x-coordinate of the crop area top left corner" },
+ { "-y", argInt, &crop_y, 0, "y-coordinate of the crop area top left corner" },
+ { "-W", argInt, &crop_w, 0, "width of crop area in pixels (default is 0)" },
+ { "-H", argInt, &crop_h, 0, "height of crop area in pixels (default is 0)" },
+ { "-sz", argInt, &sz, 0, "size of crop square in pixels (sets W and H)" },
+ { "-cropbox", argFlag, &useCropBox, 0, "use the crop box rather than media box" },
+
+ { "-mono", argFlag, &mono, 0, "generate a monochrome image file (PNG, JPEG)" },
+ { "-gray", argFlag, &gray, 0, "generate a grayscale image file (PNG, JPEG)" },
+ { "-transp", argFlag, &transp, 0, "use a transparent background instead of white (PNG)" },
+ { "-antialias", argGooString, &antialias, 0, "set cairo antialias option" },
#ifdef USE_CMS
- {"-icc", argGooString, &icc, 0,
- "ICC color profile to use"},
+ { "-icc", argGooString, &icc, 0, "ICC color profile to use" },
#endif
- {"-level2", argFlag, &level2, 0,
- "generate Level 2 PostScript (PS, EPS)"},
- {"-level3", argFlag, &level3, 0,
- "generate Level 3 PostScript (PS, EPS)"},
- {"-origpagesizes",argFlag, &origPageSizes,0,
- "conserve original page sizes (PS, PDF, SVG)"},
- {"-paper", argString, paperSize, sizeof(paperSize),
- "paper size (letter, legal, A4, A3, match)"},
- {"-paperw", argInt, &paperWidth, 0,
- "paper width, in points"},
- {"-paperh", argInt, &paperHeight, 0,
- "paper height, in points"},
- {"-nocrop", argFlag, &noCrop, 0,
- "don't crop pages to CropBox"},
- {"-expand", argFlag, &expand, 0,
- "expand pages smaller than the paper size"},
- {"-noshrink", argFlag, &noShrink, 0,
- "don't shrink pages larger than the paper size"},
- {"-nocenter", argFlag, &noCenter, 0,
- "don't center pages smaller than the paper size"},
- {"-duplex", argFlag, &duplex, 0,
- "enable duplex printing"},
-
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
-
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
+ { "-level2", argFlag, &level2, 0, "generate Level 2 PostScript (PS, EPS)" },
+ { "-level3", argFlag, &level3, 0, "generate Level 3 PostScript (PS, EPS)" },
+ { "-origpagesizes", argFlag, &origPageSizes, 0, "conserve original page sizes (PS, PDF, SVG)" },
+ { "-paper", argString, paperSize, sizeof(paperSize), "paper size (letter, legal, A4, A3, match)" },
+ { "-paperw", argInt, &paperWidth, 0, "paper width, in points" },
+ { "-paperh", argInt, &paperHeight, 0, "paper height, in points" },
+ { "-nocrop", argFlag, &noCrop, 0, "don't crop pages to CropBox" },
+ { "-expand", argFlag, &expand, 0, "expand pages smaller than the paper size" },
+ { "-noshrink", argFlag, &noShrink, 0, "don't shrink pages larger than the paper size" },
+ { "-nocenter", argFlag, &noCenter, 0, "don't center pages smaller than the paper size" },
+ { "-duplex", argFlag, &duplex, 0, "enable duplex printing" },
+
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+
+ { "-q", argFlag, &quiet, 0, "don't print any messages or errors" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {}
};
-
-static cairo_surface_t *surface;
-static bool printing;
-static FILE *output_file;
+static cairo_surface_t *surface;
+static bool printing;
+static FILE *output_file;
static bool usePDFPageSize;
static cairo_antialias_t antialiasEnum = CAIRO_ANTIALIAS_DEFAULT;
@@ -294,1004 +237,970 @@ static GfxLCMSProfilePtr profile;
struct AntialiasOption
{
- const char *name;
- cairo_antialias_t value;
+ const char *name;
+ cairo_antialias_t value;
};
-static const AntialiasOption antialiasOptions[] =
-{
- { "default", CAIRO_ANTIALIAS_DEFAULT },
- { "none", CAIRO_ANTIALIAS_NONE },
- { "gray", CAIRO_ANTIALIAS_GRAY },
- { "subpixel", CAIRO_ANTIALIAS_SUBPIXEL },
- { "fast", CAIRO_ANTIALIAS_FAST },
- { "good", CAIRO_ANTIALIAS_GOOD },
- { "best", CAIRO_ANTIALIAS_BEST },
- { nullptr, CAIRO_ANTIALIAS_DEFAULT },
+static const AntialiasOption antialiasOptions[] = {
+ { "default", CAIRO_ANTIALIAS_DEFAULT }, { "none", CAIRO_ANTIALIAS_NONE }, { "gray", CAIRO_ANTIALIAS_GRAY }, { "subpixel", CAIRO_ANTIALIAS_SUBPIXEL },
+ { "fast", CAIRO_ANTIALIAS_FAST }, { "good", CAIRO_ANTIALIAS_GOOD }, { "best", CAIRO_ANTIALIAS_BEST }, { nullptr, CAIRO_ANTIALIAS_DEFAULT },
};
static bool parseAntialiasOption()
{
- const AntialiasOption *option = antialiasOptions;
- while (option->name) {
- if (antialias.cmp(option->name) == 0) {
- antialiasEnum = option->value;
- return true;
+ const AntialiasOption *option = antialiasOptions;
+ while (option->name) {
+ if (antialias.cmp(option->name) == 0) {
+ antialiasEnum = option->value;
+ return true;
+ }
+ option++;
+ }
+
+ fprintf(stderr, "Error: Invalid antialias option \"%s\"\n", antialias.c_str());
+ fprintf(stderr, "Valid options are:\n");
+ option = antialiasOptions;
+ while (option->name) {
+ fprintf(stderr, " %s\n", option->name);
+ option++;
}
- option++;
- }
-
- fprintf(stderr, "Error: Invalid antialias option \"%s\"\n", antialias.c_str());
- fprintf(stderr, "Valid options are:\n");
- option = antialiasOptions;
- while (option->name) {
- fprintf(stderr, " %s\n", option->name);
- option++;
- }
- return false;
+ return false;
}
static bool parseJpegOptions()
{
- //jpegOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
- const char *nextOpt = jpegOpt.c_str();
- while (nextOpt && *nextOpt)
- {
- const char *comma = strchr(nextOpt, ',');
- GooString opt;
- if (comma) {
- opt.Set(nextOpt, comma - nextOpt);
- nextOpt = comma + 1;
- } else {
- opt.Set(nextOpt);
- nextOpt = nullptr;
- }
- //here opt is "<optN>=<valN> "
- const char *equal = strchr(opt.c_str(), '=');
- if (!equal) {
- fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
- return false;
- }
- int iequal = equal - opt.c_str();
- GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
- opt.del(iequal, opt.getLength() - iequal);
- //here opt is "<optN>" and value is "<valN>"
-
- if (opt.cmp("quality") == 0) {
- if (!isInt(value.c_str())) {
- fprintf(stderr, "Invalid jpeg quality\n");
- return false;
- }
- jpegQuality = atoi(value.c_str());
- if (jpegQuality < 0 || jpegQuality > 100) {
- fprintf(stderr, "jpeg quality must be between 0 and 100\n");
- return false;
- }
- } else if (opt.cmp("progressive") == 0) {
- jpegProgressive = false;
- if (value.cmp("y") == 0) {
- jpegProgressive = true;
- } else if (value.cmp("n") != 0) {
- fprintf(stderr, "jpeg progressive option must be \"y\" or \"n\"\n");
- return false;
- }
- } else if (opt.cmp("optimize") == 0 || opt.cmp("optimise") == 0) {
- jpegOptimize = false;
- if (value.cmp("y") == 0) {
- jpegOptimize = true;
- } else if (value.cmp("n") != 0) {
- fprintf(stderr, "jpeg optimize option must be \"y\" or \"n\"\n");
- return false;
- }
- } else {
- fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
- return false;
+ // jpegOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
+ const char *nextOpt = jpegOpt.c_str();
+ while (nextOpt && *nextOpt) {
+ const char *comma = strchr(nextOpt, ',');
+ GooString opt;
+ if (comma) {
+ opt.Set(nextOpt, comma - nextOpt);
+ nextOpt = comma + 1;
+ } else {
+ opt.Set(nextOpt);
+ nextOpt = nullptr;
+ }
+ // here opt is "<optN>=<valN> "
+ const char *equal = strchr(opt.c_str(), '=');
+ if (!equal) {
+ fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
+ return false;
+ }
+ int iequal = equal - opt.c_str();
+ GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
+ opt.del(iequal, opt.getLength() - iequal);
+ // here opt is "<optN>" and value is "<valN>"
+
+ if (opt.cmp("quality") == 0) {
+ if (!isInt(value.c_str())) {
+ fprintf(stderr, "Invalid jpeg quality\n");
+ return false;
+ }
+ jpegQuality = atoi(value.c_str());
+ if (jpegQuality < 0 || jpegQuality > 100) {
+ fprintf(stderr, "jpeg quality must be between 0 and 100\n");
+ return false;
+ }
+ } else if (opt.cmp("progressive") == 0) {
+ jpegProgressive = false;
+ if (value.cmp("y") == 0) {
+ jpegProgressive = true;
+ } else if (value.cmp("n") != 0) {
+ fprintf(stderr, "jpeg progressive option must be \"y\" or \"n\"\n");
+ return false;
+ }
+ } else if (opt.cmp("optimize") == 0 || opt.cmp("optimise") == 0) {
+ jpegOptimize = false;
+ if (value.cmp("y") == 0) {
+ jpegOptimize = true;
+ } else if (value.cmp("n") != 0) {
+ fprintf(stderr, "jpeg optimize option must be \"y\" or \"n\"\n");
+ return false;
+ }
+ } else {
+ fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
+ return false;
+ }
}
- }
- return true;
+ return true;
}
static void writePageImage(GooString *filename)
{
- ImgWriter *writer = nullptr;
- FILE *file;
- int height, width, stride;
- unsigned char *data;
+ ImgWriter *writer = nullptr;
+ FILE *file;
+ int height, width, stride;
+ unsigned char *data;
- if (png) {
+ if (png) {
#ifdef ENABLE_LIBPNG
- if (transp)
- writer = new PNGWriter(PNGWriter::RGBA);
- else if (gray)
- writer = new PNGWriter(PNGWriter::GRAY);
- else if (mono)
- writer = new PNGWriter(PNGWriter::MONOCHROME);
- else
- writer = new PNGWriter(PNGWriter::RGB);
-
-#ifdef USE_CMS
- if (icc_data) {
- cmsUInt8Number profileID[17];
- profileID[16] = '\0';
-
- cmsGetHeaderProfileID(profile.get(),profileID);
- static_cast<PNGWriter*>(writer)->setICCProfile(reinterpret_cast<char *>(profileID), icc_data, icc_data_size);
- } else {
- static_cast<PNGWriter*>(writer)->setSRGBProfile();
- }
-#endif
+ if (transp)
+ writer = new PNGWriter(PNGWriter::RGBA);
+ else if (gray)
+ writer = new PNGWriter(PNGWriter::GRAY);
+ else if (mono)
+ writer = new PNGWriter(PNGWriter::MONOCHROME);
+ else
+ writer = new PNGWriter(PNGWriter::RGB);
+
+# ifdef USE_CMS
+ if (icc_data) {
+ cmsUInt8Number profileID[17];
+ profileID[16] = '\0';
+
+ cmsGetHeaderProfileID(profile.get(), profileID);
+ static_cast<PNGWriter *>(writer)->setICCProfile(reinterpret_cast<char *>(profileID), icc_data, icc_data_size);
+ } else {
+ static_cast<PNGWriter *>(writer)->setSRGBProfile();
+ }
+# endif
#endif
- } else if (jpeg) {
+ } else if (jpeg) {
#ifdef ENABLE_LIBJPEG
- if (gray)
- writer = new JpegWriter(JpegWriter::GRAY);
- else
- writer = new JpegWriter(JpegWriter::RGB);
-
- static_cast<JpegWriter*>(writer)->setOptimize(jpegOptimize);
- static_cast<JpegWriter*>(writer)->setProgressive(jpegProgressive);
- if (jpegQuality >= 0)
- static_cast<JpegWriter*>(writer)->setQuality(jpegQuality);
+ if (gray)
+ writer = new JpegWriter(JpegWriter::GRAY);
+ else
+ writer = new JpegWriter(JpegWriter::RGB);
+
+ static_cast<JpegWriter *>(writer)->setOptimize(jpegOptimize);
+ static_cast<JpegWriter *>(writer)->setProgressive(jpegProgressive);
+ if (jpegQuality >= 0)
+ static_cast<JpegWriter *>(writer)->setQuality(jpegQuality);
#endif
- } else if (tiff) {
+ } else if (tiff) {
#ifdef ENABLE_LIBTIFF
- if (transp)
- writer = new TiffWriter(TiffWriter::RGBA_PREMULTIPLIED);
- else if (gray)
- writer = new TiffWriter(TiffWriter::GRAY);
- else if (mono)
- writer = new TiffWriter(TiffWriter::MONOCHROME);
- else
- writer = new TiffWriter(TiffWriter::RGB);
- static_cast<TiffWriter*>(writer)->setCompressionString(tiffCompressionStr);
+ if (transp)
+ writer = new TiffWriter(TiffWriter::RGBA_PREMULTIPLIED);
+ else if (gray)
+ writer = new TiffWriter(TiffWriter::GRAY);
+ else if (mono)
+ writer = new TiffWriter(TiffWriter::MONOCHROME);
+ else
+ writer = new TiffWriter(TiffWriter::RGB);
+ static_cast<TiffWriter *>(writer)->setCompressionString(tiffCompressionStr);
#endif
- }
- if (!writer)
- return;
-
- if (filename->cmp("fd://0") == 0)
- file = stdout;
- else
- file = fopen(filename->c_str(), "wb");
-
- if (!file) {
- fprintf(stderr, "Error opening output file %s\n", filename->c_str());
- exit(2);
- }
-
- height = cairo_image_surface_get_height(surface);
- width = cairo_image_surface_get_width(surface);
- stride = cairo_image_surface_get_stride(surface);
- cairo_surface_flush(surface);
- data = cairo_image_surface_get_data(surface);
-
- if (!writer->init(file, width, height, x_resolution, y_resolution)) {
- fprintf(stderr, "Error writing %s\n", filename->c_str());
- exit(2);
- }
- unsigned char *row = (unsigned char *) gmallocn(width, 4);
-
- for (int y = 0; y < height; y++ ) {
- uint32_t *pixel = reinterpret_cast<uint32_t *>((data + y*stride));
- unsigned char *rowp = row;
- int bit = 7;
- for (int x = 0; x < width; x++, pixel++) {
- if (transp) {
- if (tiff) {
- // RGBA premultipled format
- *rowp++ = (*pixel & 0xff0000) >> 16;
- *rowp++ = (*pixel & 0x00ff00) >> 8;
- *rowp++ = (*pixel & 0x0000ff) >> 0;
- *rowp++ = (*pixel & 0xff000000) >> 24;
- } else {
- // unpremultiply into RGBA format
- uint8_t a;
- a = (*pixel & 0xff000000) >> 24;
- if (a == 0) {
- *rowp++ = 0;
- *rowp++ = 0;
- *rowp++ = 0;
- } else {
- *rowp++ = (((*pixel & 0xff0000) >> 16) * 255 + a / 2) / a;
- *rowp++ = (((*pixel & 0x00ff00) >> 8) * 255 + a / 2) / a;
- *rowp++ = (((*pixel & 0x0000ff) >> 0) * 255 + a / 2) / a;
- }
- *rowp++ = a;
- }
- } else if (gray || mono) {
- // convert to gray
- // The PDF Reference specifies the DeviceRGB to DeviceGray conversion as
- // gray = 0.3*red + 0.59*green + 0.11*blue
- const int r = (*pixel & 0x00ff0000) >> 16;
- const int g = (*pixel & 0x0000ff00) >> 8;
- const int b = (*pixel & 0x000000ff) >> 0;
- // an arbitrary integer approximation of .3*r + .59*g + .11*b
- const int grayValue = (r*19661+g*38666+b*7209 + 32829)>>16;
- if (mono) {
- if (bit == 7)
- *rowp = 0;
- if (grayValue > 127)
- *rowp |= (1 << bit);
- bit--;
- if (bit < 0) {
- bit = 7;
- rowp++;
- }
- } else {
- *rowp++ = grayValue;
+ }
+ if (!writer)
+ return;
+
+ if (filename->cmp("fd://0") == 0)
+ file = stdout;
+ else
+ file = fopen(filename->c_str(), "wb");
+
+ if (!file) {
+ fprintf(stderr, "Error opening output file %s\n", filename->c_str());
+ exit(2);
+ }
+
+ height = cairo_image_surface_get_height(surface);
+ width = cairo_image_surface_get_width(surface);
+ stride = cairo_image_surface_get_stride(surface);
+ cairo_surface_flush(surface);
+ data = cairo_image_surface_get_data(surface);
+
+ if (!writer->init(file, width, height, x_resolution, y_resolution)) {
+ fprintf(stderr, "Error writing %s\n", filename->c_str());
+ exit(2);
+ }
+ unsigned char *row = (unsigned char *)gmallocn(width, 4);
+
+ for (int y = 0; y < height; y++) {
+ uint32_t *pixel = reinterpret_cast<uint32_t *>((data + y * stride));
+ unsigned char *rowp = row;
+ int bit = 7;
+ for (int x = 0; x < width; x++, pixel++) {
+ if (transp) {
+ if (tiff) {
+ // RGBA premultipled format
+ *rowp++ = (*pixel & 0xff0000) >> 16;
+ *rowp++ = (*pixel & 0x00ff00) >> 8;
+ *rowp++ = (*pixel & 0x0000ff) >> 0;
+ *rowp++ = (*pixel & 0xff000000) >> 24;
+ } else {
+ // unpremultiply into RGBA format
+ uint8_t a;
+ a = (*pixel & 0xff000000) >> 24;
+ if (a == 0) {
+ *rowp++ = 0;
+ *rowp++ = 0;
+ *rowp++ = 0;
+ } else {
+ *rowp++ = (((*pixel & 0xff0000) >> 16) * 255 + a / 2) / a;
+ *rowp++ = (((*pixel & 0x00ff00) >> 8) * 255 + a / 2) / a;
+ *rowp++ = (((*pixel & 0x0000ff) >> 0) * 255 + a / 2) / a;
+ }
+ *rowp++ = a;
+ }
+ } else if (gray || mono) {
+ // convert to gray
+ // The PDF Reference specifies the DeviceRGB to DeviceGray conversion as
+ // gray = 0.3*red + 0.59*green + 0.11*blue
+ const int r = (*pixel & 0x00ff0000) >> 16;
+ const int g = (*pixel & 0x0000ff00) >> 8;
+ const int b = (*pixel & 0x000000ff) >> 0;
+ // an arbitrary integer approximation of .3*r + .59*g + .11*b
+ const int grayValue = (r * 19661 + g * 38666 + b * 7209 + 32829) >> 16;
+ if (mono) {
+ if (bit == 7)
+ *rowp = 0;
+ if (grayValue > 127)
+ *rowp |= (1 << bit);
+ bit--;
+ if (bit < 0) {
+ bit = 7;
+ rowp++;
+ }
+ } else {
+ *rowp++ = grayValue;
+ }
+ } else {
+ // copy into RGB format
+ *rowp++ = (*pixel & 0x00ff0000) >> 16;
+ *rowp++ = (*pixel & 0x0000ff00) >> 8;
+ *rowp++ = (*pixel & 0x000000ff) >> 0;
+ }
}
- } else {
- // copy into RGB format
- *rowp++ = (*pixel & 0x00ff0000) >> 16;
- *rowp++ = (*pixel & 0x0000ff00) >> 8;
- *rowp++ = (*pixel & 0x000000ff) >> 0;
- }
+ writer->writeRow(&row);
}
- writer->writeRow(&row);
- }
- gfree(row);
- writer->close();
- delete writer;
- if (file == stdout) fflush(file);
- else fclose(file);
+ gfree(row);
+ writer->close();
+ delete writer;
+ if (file == stdout)
+ fflush(file);
+ else
+ fclose(file);
}
static void getCropSize(double page_w, double page_h, double *width, double *height)
{
- int w = crop_w;
- int h = crop_h;
+ int w = crop_w;
+ int h = crop_h;
- if (w == 0)
- w = (int)ceil(page_w);
+ if (w == 0)
+ w = (int)ceil(page_w);
- if (h == 0)
- h = (int)ceil(page_h);
+ if (h == 0)
+ h = (int)ceil(page_h);
- *width = (crop_x + w > page_w ? (int)ceil(page_w - crop_x) : w);
- *height = (crop_y + h > page_h ? (int)ceil(page_h - crop_y) : h);
+ *width = (crop_x + w > page_w ? (int)ceil(page_w - crop_x) : w);
+ *height = (crop_y + h > page_h ? (int)ceil(page_h - crop_y) : h);
}
static void getOutputSize(double page_w, double page_h, double *width, double *height)
{
- if (printing) {
- if (usePDFPageSize) {
- *width = page_w;
- *height = page_h;
+ if (printing) {
+ if (usePDFPageSize) {
+ *width = page_w;
+ *height = page_h;
+ } else {
+ if (page_w > page_h) {
+ *width = paperHeight;
+ *height = paperWidth;
+ } else {
+ *width = paperWidth;
+ *height = paperHeight;
+ }
+ }
} else {
- if (page_w > page_h) {
- *width = paperHeight;
- *height = paperWidth;
- } else {
- *width = paperWidth;
- *height = paperHeight;
- }
+ getCropSize(page_w * (x_resolution / 72.0), page_h * (y_resolution / 72.0), width, height);
}
- } else {
- getCropSize(page_w * (x_resolution / 72.0),
- page_h * (y_resolution / 72.0),
- width, height);
- }
}
-static void getFitToPageTransform(double page_w, double page_h,
- double paper_w, double paper_h,
- cairo_matrix_t *m)
+static void getFitToPageTransform(double page_w, double page_h, double paper_w, double paper_h, cairo_matrix_t *m)
{
- double x_scale, y_scale, scale;
-
- x_scale = paper_w / page_w;
- y_scale = paper_h / page_h;
- if (x_scale < y_scale)
- scale = x_scale;
- else
- scale = y_scale;
-
- if (scale > 1.0 && !expand)
- scale = 1.0;
- if (scale < 1.0 && noShrink)
- scale = 1.0;
-
- cairo_matrix_init_identity (m);
- if (!noCenter) {
- // centre page
- cairo_matrix_translate (m, (paper_w - page_w*scale)/2, (paper_h - page_h*scale)/2);
- } else if (!svg) {
- // move to PostScript origin
- cairo_matrix_translate (m, 0, (paper_h - page_h*scale));
- }
- cairo_matrix_scale (m, scale, scale);
+ double x_scale, y_scale, scale;
+
+ x_scale = paper_w / page_w;
+ y_scale = paper_h / page_h;
+ if (x_scale < y_scale)
+ scale = x_scale;
+ else
+ scale = y_scale;
+
+ if (scale > 1.0 && !expand)
+ scale = 1.0;
+ if (scale < 1.0 && noShrink)
+ scale = 1.0;
+
+ cairo_matrix_init_identity(m);
+ if (!noCenter) {
+ // centre page
+ cairo_matrix_translate(m, (paper_w - page_w * scale) / 2, (paper_h - page_h * scale) / 2);
+ } else if (!svg) {
+ // move to PostScript origin
+ cairo_matrix_translate(m, 0, (paper_h - page_h * scale));
+ }
+ cairo_matrix_scale(m, scale, scale);
}
static cairo_status_t writeStream(void *closure, const unsigned char *data, unsigned int length)
{
- FILE *file = (FILE *)closure;
+ FILE *file = (FILE *)closure;
- if (fwrite(data, length, 1, file) == 1)
- return CAIRO_STATUS_SUCCESS;
- else
- return CAIRO_STATUS_WRITE_ERROR;
+ if (fwrite(data, length, 1, file) == 1)
+ return CAIRO_STATUS_SUCCESS;
+ else
+ return CAIRO_STATUS_WRITE_ERROR;
}
static void beginDocument(GooString *inputFileName, GooString *outputFileName, double w, double h)
{
- if (printing) {
- if (printToWin32) {
- output_file = nullptr;
- } else {
- if (outputFileName->cmp("fd://0") == 0)
- output_file = stdout;
- else
- {
- output_file = fopen(outputFileName->c_str(), "wb");
- if (!output_file) {
- fprintf(stderr, "Error opening output file %s\n", outputFileName->c_str());
- exit(2);
+ if (printing) {
+ if (printToWin32) {
+ output_file = nullptr;
+ } else {
+ if (outputFileName->cmp("fd://0") == 0)
+ output_file = stdout;
+ else {
+ output_file = fopen(outputFileName->c_str(), "wb");
+ if (!output_file) {
+ fprintf(stderr, "Error opening output file %s\n", outputFileName->c_str());
+ exit(2);
+ }
+ }
}
- }
- }
- if (ps || eps) {
+ if (ps || eps) {
#ifdef CAIRO_HAS_PS_SURFACE
- surface = cairo_ps_surface_create_for_stream(writeStream, output_file, w, h);
- if (level2)
- cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_2);
- if (eps)
- cairo_ps_surface_set_eps (surface, 1);
- if (duplex) {
- cairo_ps_surface_dsc_comment(surface, "%%Requirements: duplex");
- cairo_ps_surface_dsc_begin_setup(surface);
- cairo_ps_surface_dsc_comment(surface, "%%IncludeFeature: *Duplex DuplexNoTumble");
- }
- cairo_ps_surface_dsc_begin_page_setup (surface);
+ surface = cairo_ps_surface_create_for_stream(writeStream, output_file, w, h);
+ if (level2)
+ cairo_ps_surface_restrict_to_level(surface, CAIRO_PS_LEVEL_2);
+ if (eps)
+ cairo_ps_surface_set_eps(surface, 1);
+ if (duplex) {
+ cairo_ps_surface_dsc_comment(surface, "%%Requirements: duplex");
+ cairo_ps_surface_dsc_begin_setup(surface);
+ cairo_ps_surface_dsc_comment(surface, "%%IncludeFeature: *Duplex DuplexNoTumble");
+ }
+ cairo_ps_surface_dsc_begin_page_setup(surface);
#endif
- } else if (pdf) {
+ } else if (pdf) {
#ifdef CAIRO_HAS_PDF_SURFACE
- surface = cairo_pdf_surface_create_for_stream(writeStream, output_file, w, h);
+ surface = cairo_pdf_surface_create_for_stream(writeStream, output_file, w, h);
#endif
- } else if (svg) {
+ } else if (svg) {
#ifdef CAIRO_HAS_SVG_SURFACE
- surface = cairo_svg_surface_create_for_stream(writeStream, output_file, w, h);
- cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
+ surface = cairo_svg_surface_create_for_stream(writeStream, output_file, w, h);
+ cairo_svg_surface_restrict_to_version(surface, CAIRO_SVG_VERSION_1_2);
#endif
- }
+ }
#ifdef CAIRO_HAS_WIN32_SURFACE
- if (printToWin32)
- surface = win32BeginDocument(inputFileName, outputFileName);
+ if (printToWin32)
+ surface = win32BeginDocument(inputFileName, outputFileName);
#endif
- }
+ }
}
static void beginPage(double *w, double *h)
{
- if (printing) {
- if (ps || eps) {
+ if (printing) {
+ if (ps || eps) {
#ifdef CAIRO_HAS_PS_SURFACE
- if (*w > *h) {
- cairo_ps_surface_dsc_comment (surface, "%%PageOrientation: Landscape");
- cairo_ps_surface_set_size (surface, *h, *w);
- } else {
- cairo_ps_surface_dsc_comment (surface, "%%PageOrientation: Portrait");
- cairo_ps_surface_set_size (surface, *w, *h);
- }
+ if (*w > *h) {
+ cairo_ps_surface_dsc_comment(surface, "%%PageOrientation: Landscape");
+ cairo_ps_surface_set_size(surface, *h, *w);
+ } else {
+ cairo_ps_surface_dsc_comment(surface, "%%PageOrientation: Portrait");
+ cairo_ps_surface_set_size(surface, *w, *h);
+ }
#endif
- }
+ }
#ifdef CAIRO_HAS_PDF_SURFACE
- if (pdf)
- cairo_pdf_surface_set_size (surface, *w, *h);
+ if (pdf)
+ cairo_pdf_surface_set_size(surface, *w, *h);
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
- if (printToWin32) {
- bool changePageSize = true;
- if (setupdlg && !origPageSizes)
- changePageSize = false;
- win32BeginPage(w, h, changePageSize, noShrink); // w,h will be changed to actual size used
- }
+ if (printToWin32) {
+ bool changePageSize = true;
+ if (setupdlg && !origPageSizes)
+ changePageSize = false;
+ win32BeginPage(w, h, changePageSize, noShrink); // w,h will be changed to actual size used
+ }
#endif
- cairo_surface_set_fallback_resolution (surface, x_resolution, y_resolution);
+ cairo_surface_set_fallback_resolution(surface, x_resolution, y_resolution);
- } else {
- surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ceil(*w), ceil(*h));
- }
+ } else {
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ceil(*w), ceil(*h));
+ }
}
-static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg,
- double page_w, double page_h,
- double output_w, double output_h)
+static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg, double page_w, double page_h, double output_w, double output_h)
{
- cairo_t *cr;
- cairo_status_t status;
- cairo_matrix_t m;
-
- cr = cairo_create(surface);
-
- cairoOut->setCairo(cr);
- cairoOut->setPrinting(printing);
- cairoOut->setAntialias(antialiasEnum);
-
- cairo_save(cr);
- if (ps && output_w > output_h) {
- // rotate 90 deg for landscape
- cairo_translate (cr, 0, output_w);
- cairo_matrix_init (&m, 0, -1, 1, 0, 0, 0);
- cairo_transform (cr, &m);
- }
- cairo_translate (cr, -crop_x, -crop_y);
- if (printing) {
- double cropped_w, cropped_h;
- getCropSize(page_w, page_h, &cropped_w, &cropped_h);
- getFitToPageTransform(cropped_w, cropped_h, output_w, output_h, &m);
- cairo_transform (cr, &m);
- cairo_rectangle(cr, crop_x, crop_y, cropped_w, cropped_h);
- cairo_clip(cr);
- } else {
- cairo_scale (cr, x_resolution/72.0, y_resolution/72.0);
- }
- doc->displayPageSlice(cairoOut,
- pg,
- 72.0, 72.0,
- 0, /* rotate */
- !useCropBox, /* useMediaBox */
- false, /* Crop */
- printing,
- -1, -1, -1, -1);
- cairo_restore(cr);
- cairoOut->setCairo(nullptr);
-
- // Blend onto white page
- if (!printing && !transp) {
+ cairo_t *cr;
+ cairo_status_t status;
+ cairo_matrix_t m;
+
+ cr = cairo_create(surface);
+
+ cairoOut->setCairo(cr);
+ cairoOut->setPrinting(printing);
+ cairoOut->setAntialias(antialiasEnum);
+
cairo_save(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_paint(cr);
+ if (ps && output_w > output_h) {
+ // rotate 90 deg for landscape
+ cairo_translate(cr, 0, output_w);
+ cairo_matrix_init(&m, 0, -1, 1, 0, 0, 0);
+ cairo_transform(cr, &m);
+ }
+ cairo_translate(cr, -crop_x, -crop_y);
+ if (printing) {
+ double cropped_w, cropped_h;
+ getCropSize(page_w, page_h, &cropped_w, &cropped_h);
+ getFitToPageTransform(cropped_w, cropped_h, output_w, output_h, &m);
+ cairo_transform(cr, &m);
+ cairo_rectangle(cr, crop_x, crop_y, cropped_w, cropped_h);
+ cairo_clip(cr);
+ } else {
+ cairo_scale(cr, x_resolution / 72.0, y_resolution / 72.0);
+ }
+ doc->displayPageSlice(cairoOut, pg, 72.0, 72.0, 0, /* rotate */
+ !useCropBox, /* useMediaBox */
+ false, /* Crop */
+ printing, -1, -1, -1, -1);
cairo_restore(cr);
- }
+ cairoOut->setCairo(nullptr);
+
+ // Blend onto white page
+ if (!printing && !transp) {
+ cairo_save(cr);
+ cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_paint(cr);
+ cairo_restore(cr);
+ }
- status = cairo_status(cr);
- if (status)
- fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
- cairo_destroy (cr);
+ status = cairo_status(cr);
+ if (status)
+ fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
+ cairo_destroy(cr);
}
static void endPage(GooString *imageFileName)
{
- cairo_status_t status;
+ cairo_status_t status;
- if (printing) {
- cairo_surface_show_page(surface);
+ if (printing) {
+ cairo_surface_show_page(surface);
#ifdef CAIRO_HAS_WIN32_SURFACE
- if (printToWin32)
- win32EndPage(imageFileName);
+ if (printToWin32)
+ win32EndPage(imageFileName);
#endif
- } else {
- writePageImage(imageFileName);
- cairo_surface_finish(surface);
- status = cairo_surface_status(surface);
- if (status)
- fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
- cairo_surface_destroy(surface);
- }
-
+ } else {
+ writePageImage(imageFileName);
+ cairo_surface_finish(surface);
+ status = cairo_surface_status(surface);
+ if (status)
+ fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
+ cairo_surface_destroy(surface);
+ }
}
static void endDocument()
{
- cairo_status_t status;
-
- if (printing) {
- cairo_surface_finish(surface);
- status = cairo_surface_status(surface);
- if (status)
- fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
- cairo_surface_destroy(surface);
+ cairo_status_t status;
+
+ if (printing) {
+ cairo_surface_finish(surface);
+ status = cairo_surface_status(surface);
+ if (status)
+ fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status));
+ cairo_surface_destroy(surface);
#ifdef CAIRO_HAS_WIN32_SURFACE
- if (printToWin32)
- win32EndDocument();
+ if (printToWin32)
+ win32EndDocument();
#endif
- if (output_file)
- fclose(output_file);
- }
+ if (output_file)
+ fclose(output_file);
+ }
}
-static bool setPSPaperSize(char *size, int &psPaperWidth, int &psPaperHeight) {
- if (!strcmp(size, "match")) {
- psPaperWidth = psPaperHeight = -1;
- } else if (!strcmp(size, "letter")) {
- psPaperWidth = 612;
- psPaperHeight = 792;
- } else if (!strcmp(size, "legal")) {
- psPaperWidth = 612;
- psPaperHeight = 1008;
- } else if (!strcmp(size, "A4")) {
- psPaperWidth = 595;
- psPaperHeight = 842;
- } else if (!strcmp(size, "A3")) {
- psPaperWidth = 842;
- psPaperHeight = 1190;
- } else {
- return false;
- }
- return true;
+static bool setPSPaperSize(char *size, int &psPaperWidth, int &psPaperHeight)
+{
+ if (!strcmp(size, "match")) {
+ psPaperWidth = psPaperHeight = -1;
+ } else if (!strcmp(size, "letter")) {
+ psPaperWidth = 612;
+ psPaperHeight = 792;
+ } else if (!strcmp(size, "legal")) {
+ psPaperWidth = 612;
+ psPaperHeight = 1008;
+ } else if (!strcmp(size, "A4")) {
+ psPaperWidth = 595;
+ psPaperHeight = 842;
+ } else if (!strcmp(size, "A3")) {
+ psPaperWidth = 842;
+ psPaperHeight = 1190;
+ } else {
+ return false;
+ }
+ return true;
}
static GooString *getImageFileName(GooString *outputFileName, int numDigits, int page)
{
- char buf[10];
- GooString *imageName = new GooString(outputFileName);
- if (!singleFile) {
- snprintf(buf, sizeof(buf), "-%0*d", numDigits, page);
- imageName->append(buf);
- }
- if (outputFileName->cmp("fd://0") != 0) {
- if (png)
- imageName->append(".png");
- else if (jpeg)
- imageName->append(".jpg");
- else if (tiff)
- imageName->append(".tif");
- }
-
- return imageName;
+ char buf[10];
+ GooString *imageName = new GooString(outputFileName);
+ if (!singleFile) {
+ snprintf(buf, sizeof(buf), "-%0*d", numDigits, page);
+ imageName->append(buf);
+ }
+ if (outputFileName->cmp("fd://0") != 0) {
+ if (png)
+ imageName->append(".png");
+ else if (jpeg)
+ imageName->append(".jpg");
+ else if (tiff)
+ imageName->append(".tif");
+ }
+
+ return imageName;
}
// If (printing || singleFile) the output file name includes the
// extension. Otherwise it is the file name base.
static GooString *getOutputFileName(GooString *fileName, GooString *outputName)
{
- GooString *name;
-
- if (outputName) {
- if (outputName->cmp("-") == 0) {
- if (printToWin32 || (!printing && !singleFile)) {
- fprintf(stderr, "Error: stdout may only be used with the ps, eps, pdf, svg output options or if -singlefile is used.\n");
- exit(99);
- }
- return new GooString("fd://0");
+ GooString *name;
+
+ if (outputName) {
+ if (outputName->cmp("-") == 0) {
+ if (printToWin32 || (!printing && !singleFile)) {
+ fprintf(stderr, "Error: stdout may only be used with the ps, eps, pdf, svg output options or if -singlefile is used.\n");
+ exit(99);
+ }
+ return new GooString("fd://0");
+ }
+ return new GooString(outputName);
}
- return new GooString(outputName);
- }
-
- if (printToWin32)
- return nullptr; // No output file means print to printer
-
- if (fileName->cmp("fd://0") == 0) {
- fprintf(stderr, "Error: an output filename or '-' must be supplied when the PDF file is stdin.\n");
- exit(99);
- }
-
- // be careful not to overwrite the input file when the output format is PDF
- if (pdf && fileName->cmpN("http://", 7) != 0 && fileName->cmpN("https://", 8) != 0) {
- fprintf(stderr, "Error: an output filename or '-' must be supplied when the output format is PDF and input PDF file is a local file.\n");
- exit(99);
- }
-
- // strip everything up to last '/'
- const char *s = fileName->c_str();
- const char *p = strrchr(s, '/');
- if (p) {
- p++;
- if (*p == 0) {
- fprintf(stderr, "Error: invalid output filename.\n");
- exit(99);
+
+ if (printToWin32)
+ return nullptr; // No output file means print to printer
+
+ if (fileName->cmp("fd://0") == 0) {
+ fprintf(stderr, "Error: an output filename or '-' must be supplied when the PDF file is stdin.\n");
+ exit(99);
+ }
+
+ // be careful not to overwrite the input file when the output format is PDF
+ if (pdf && fileName->cmpN("http://", 7) != 0 && fileName->cmpN("https://", 8) != 0) {
+ fprintf(stderr, "Error: an output filename or '-' must be supplied when the output format is PDF and input PDF file is a local file.\n");
+ exit(99);
}
- name = new GooString(p);
- } else {
- name = new GooString(s);
- }
-
- // remove .pdf extension
- p = strrchr(name->c_str(), '.');
- if (p && strcasecmp(p, ".pdf") == 0) {
- GooString *name2 = new GooString(name->c_str(), name->getLength() - 4);
- delete name;
- name = name2;
- }
-
- // append new extension
- if (ps)
- name->append(".ps");
- else if (eps)
- name->append(".eps");
- else if (pdf)
- name->append(".pdf");
- else if (svg)
- name->append(".svg");
-
- return name;
+
+ // strip everything up to last '/'
+ const char *s = fileName->c_str();
+ const char *p = strrchr(s, '/');
+ if (p) {
+ p++;
+ if (*p == 0) {
+ fprintf(stderr, "Error: invalid output filename.\n");
+ exit(99);
+ }
+ name = new GooString(p);
+ } else {
+ name = new GooString(s);
+ }
+
+ // remove .pdf extension
+ p = strrchr(name->c_str(), '.');
+ if (p && strcasecmp(p, ".pdf") == 0) {
+ GooString *name2 = new GooString(name->c_str(), name->getLength() - 4);
+ delete name;
+ name = name2;
+ }
+
+ // append new extension
+ if (ps)
+ name->append(".ps");
+ else if (eps)
+ name->append(".eps");
+ else if (pdf)
+ name->append(".pdf");
+ else if (svg)
+ name->append(".svg");
+
+ return name;
}
static void checkInvalidPrintOption(bool option, const char *option_name)
{
- if (option) {
- fprintf(stderr, "Error: %s may only be used with the -png, -jpeg, or -tiff output options.\n", option_name);
- exit(99);
- }
+ if (option) {
+ fprintf(stderr, "Error: %s may only be used with the -png, -jpeg, or -tiff output options.\n", option_name);
+ exit(99);
+ }
}
static void checkInvalidImageOption(bool option, const char *option_name)
{
- if (option) {
- fprintf(stderr, "Error: %s may only be used with the -ps, -eps, -pdf, or -svg output options.\n", option_name);
- exit(99);
- }
+ if (option) {
+ fprintf(stderr, "Error: %s may only be used with the -ps, -eps, -pdf, or -svg output options.\n", option_name);
+ exit(99);
+ }
}
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName = nullptr;
- GooString *outputName = nullptr;
- GooString *outputFileName = nullptr;
- GooString *imageFileName = nullptr;
- GooString *ownerPW, *userPW;
- CairoOutputDev *cairoOut;
- int pg, pg_num_len;
- double pg_w, pg_h, tmp, output_w, output_h;
- int num_outputs;
-
- // parse args
- Win32Console win32Console(&argc, &argv);
- if (!parseArgs(argDesc, &argc, argv)) {
- printUsage("pdftocairo", nullptr, argDesc);
- exit(99);
- }
-
- if ( resolution != 0.0 &&
- (x_resolution == 150.0 ||
- y_resolution == 150.0)) {
- x_resolution = resolution;
- y_resolution = resolution;
- }
- if (argc < 2 || argc > 3 || printVersion || printHelp) {
- fprintf(stderr, "pdftocairo version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdftocairo", "<PDF-file> [<output-file>]", argDesc);
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName = nullptr;
+ GooString *outputName = nullptr;
+ GooString *outputFileName = nullptr;
+ GooString *imageFileName = nullptr;
+ GooString *ownerPW, *userPW;
+ CairoOutputDev *cairoOut;
+ int pg, pg_num_len;
+ double pg_w, pg_h, tmp, output_w, output_h;
+ int num_outputs;
+
+ // parse args
+ Win32Console win32Console(&argc, &argv);
+ if (!parseArgs(argDesc, &argc, argv)) {
+ printUsage("pdftocairo", nullptr, argDesc);
+ exit(99);
+ }
+
+ if (resolution != 0.0 && (x_resolution == 150.0 || y_resolution == 150.0)) {
+ x_resolution = resolution;
+ y_resolution = resolution;
+ }
+ if (argc < 2 || argc > 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdftocairo version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdftocairo", "<PDF-file> [<output-file>]", argDesc);
+ }
+ if (printVersion || printHelp)
+ exit(0);
+ else
+ exit(99);
}
- if (printVersion || printHelp)
- exit(0);
+
+ num_outputs = (png ? 1 : 0) + (jpeg ? 1 : 0) + (tiff ? 1 : 0) + (ps ? 1 : 0) + (eps ? 1 : 0) + (pdf ? 1 : 0) + (printToWin32 ? 1 : 0) + (printdlg ? 1 : 0) + (svg ? 1 : 0);
+ if (num_outputs == 0) {
+ fprintf(stderr, "Error: one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -print, -printdlg, -svg) must be used.\n");
+ exit(99);
+ }
+ if (num_outputs > 1) {
+ fprintf(stderr, "Error: use only one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -printdlg, -print, -svg).\n");
+ exit(99);
+ }
+ if (png || jpeg || tiff)
+ printing = false;
else
- exit(99);
- }
-
- num_outputs = (png ? 1 : 0) +
- (jpeg ? 1 : 0) +
- (tiff ? 1 : 0) +
- (ps ? 1 : 0) +
- (eps ? 1 : 0) +
- (pdf ? 1 : 0) +
- (printToWin32 ? 1 : 0) +
- (printdlg ? 1 : 0) +
- (svg ? 1 : 0);
- if (num_outputs == 0) {
- fprintf(stderr, "Error: one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -print, -printdlg, -svg) must be used.\n");
- exit(99);
- }
- if (num_outputs > 1) {
- fprintf(stderr, "Error: use only one of the output format options (-png, -jpeg, -ps, -eps, -pdf, -printdlg, -print, -svg).\n");
- exit(99);
- }
- if (png || jpeg || tiff)
- printing = false;
- else
- printing = true;
-
- if (printing) {
- checkInvalidPrintOption(mono, "-mono");
- checkInvalidPrintOption(gray, "-gray");
- checkInvalidPrintOption(transp, "-transp");
- checkInvalidPrintOption(icc.c_str()[0], "-icc");
- checkInvalidPrintOption(singleFile, "-singlefile");
- checkInvalidPrintOption(useCropBox, "-cropbox");
- checkInvalidPrintOption(scaleTo != 0, "-scale-to");
- checkInvalidPrintOption(x_scaleTo != 0, "-scale-to-x");
- checkInvalidPrintOption(y_scaleTo != 0, "-scale-to-y");
- } else {
- checkInvalidImageOption(level2, "-level2");
- checkInvalidImageOption(level3, "-level3");
- checkInvalidImageOption(origPageSizes, "-origpagesizes");
- checkInvalidImageOption(paperSize[0], "-paper");
- checkInvalidImageOption(paperWidth > 0, "-paperw");
- checkInvalidImageOption(paperHeight > 0, "-paperh");
- checkInvalidImageOption(noCrop, "-nocrop");
- checkInvalidImageOption(expand, "-expand");
- checkInvalidImageOption(noShrink, "-noshrink");
- checkInvalidImageOption(noCenter, "-nocenter");
- checkInvalidImageOption(duplex, "-duplex");
- }
-
- if (printing)
- useCropBox = !noCrop;
-
- if (icc.c_str()[0] && !png) {
- fprintf(stderr, "Error: -icc may only be used with png output.\n");
- exit(99);
- }
-
- if (antialias.getLength() > 0) {
- if (!parseAntialiasOption())
- exit(99);
- }
-
- if (transp && !(png || tiff)) {
- fprintf(stderr, "Error: -transp may only be used with png or tiff output.\n");
- exit(99);
- }
-
- if (mono && gray) {
- fprintf(stderr, "Error: -mono and -gray may not be used together.\n");
- exit(99);
- }
-
- if (mono && !(png || tiff)) {
- fprintf(stderr, "Error: -mono may only be used with png or tiff output.\n");
- exit(99);
- }
-
- if (jpegOpt.getLength() > 0) {
- if (!jpeg) {
- fprintf(stderr, "Error: -jpegopt may only be used with jpeg output.\n");
- exit(99);
+ printing = true;
+
+ if (printing) {
+ checkInvalidPrintOption(mono, "-mono");
+ checkInvalidPrintOption(gray, "-gray");
+ checkInvalidPrintOption(transp, "-transp");
+ checkInvalidPrintOption(icc.c_str()[0], "-icc");
+ checkInvalidPrintOption(singleFile, "-singlefile");
+ checkInvalidPrintOption(useCropBox, "-cropbox");
+ checkInvalidPrintOption(scaleTo != 0, "-scale-to");
+ checkInvalidPrintOption(x_scaleTo != 0, "-scale-to-x");
+ checkInvalidPrintOption(y_scaleTo != 0, "-scale-to-y");
+ } else {
+ checkInvalidImageOption(level2, "-level2");
+ checkInvalidImageOption(level3, "-level3");
+ checkInvalidImageOption(origPageSizes, "-origpagesizes");
+ checkInvalidImageOption(paperSize[0], "-paper");
+ checkInvalidImageOption(paperWidth > 0, "-paperw");
+ checkInvalidImageOption(paperHeight > 0, "-paperh");
+ checkInvalidImageOption(noCrop, "-nocrop");
+ checkInvalidImageOption(expand, "-expand");
+ checkInvalidImageOption(noShrink, "-noshrink");
+ checkInvalidImageOption(noCenter, "-nocenter");
+ checkInvalidImageOption(duplex, "-duplex");
}
- if (!parseJpegOptions())
- exit(99);
- }
-
- if (strlen(tiffCompressionStr) > 0 && !tiff) {
- fprintf(stderr, "Error: -tiffcompression may only be used with tiff output.\n");
- exit(99);
- }
-
- if (level2 && level3) {
- fprintf(stderr, "Error: use only one of the 'level' options.\n");
- exit(99);
- }
- if (!level2 && !level3)
- level3 = true;
-
- if (eps && (origPageSizes || paperSize[0] || paperWidth > 0 || paperHeight > 0)) {
- fprintf(stderr, "Error: page size options may not be used with eps output.\n");
- exit(99);
- }
-
- if ((paperWidth > 0 && paperHeight <= 0) || (paperWidth <= 0 && paperHeight > 0)) {
- fprintf(stderr, "Error: both -paperw and -paperh must be specified.\n");
- exit(99);
- }
-
- if (paperSize[0]) {
- if (origPageSizes) {
- fprintf(stderr, "Error: -origpagesizes and -paper may not be used together.\n");
- exit(99);
+
+ if (printing)
+ useCropBox = !noCrop;
+
+ if (icc.c_str()[0] && !png) {
+ fprintf(stderr, "Error: -icc may only be used with png output.\n");
+ exit(99);
}
- if (!setPSPaperSize(paperSize, paperWidth, paperHeight)) {
- fprintf(stderr, "Invalid paper size\n");
- exit(99);
+
+ if (antialias.getLength() > 0) {
+ if (!parseAntialiasOption())
+ exit(99);
}
- }
- if (origPageSizes || paperWidth < 0 || paperHeight < 0)
- usePDFPageSize = true;
- else
- usePDFPageSize = false;
-
- if (printdlg)
- printToWin32 = true;
-
- globalParams = std::make_unique<GlobalParams>();
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
-
- // open PDF file
- if (ownerPassword[0]) {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0]) {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
-
- fileName = new GooString(argv[1]);
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
- if (argc == 3)
- outputName = new GooString(argv[2]);
- else
- outputName = nullptr;
-
- outputFileName = getOutputFileName(fileName, outputName);
-#ifdef USE_CMS
- icc_data = nullptr;
- if (icc.c_str()[0]) {
- FILE *file = fopen(icc.c_str(), "rb");
- if (!file) {
- fprintf(stderr, "Error: unable to open icc profile %s\n", icc.c_str());
- exit(4);
+ if (transp && !(png || tiff)) {
+ fprintf(stderr, "Error: -transp may only be used with png or tiff output.\n");
+ exit(99);
+ }
+
+ if (mono && gray) {
+ fprintf(stderr, "Error: -mono and -gray may not be used together.\n");
+ exit(99);
+ }
+
+ if (mono && !(png || tiff)) {
+ fprintf(stderr, "Error: -mono may only be used with png or tiff output.\n");
+ exit(99);
+ }
+
+ if (jpegOpt.getLength() > 0) {
+ if (!jpeg) {
+ fprintf(stderr, "Error: -jpegopt may only be used with jpeg output.\n");
+ exit(99);
+ }
+ if (!parseJpegOptions())
+ exit(99);
+ }
+
+ if (strlen(tiffCompressionStr) > 0 && !tiff) {
+ fprintf(stderr, "Error: -tiffcompression may only be used with tiff output.\n");
+ exit(99);
+ }
+
+ if (level2 && level3) {
+ fprintf(stderr, "Error: use only one of the 'level' options.\n");
+ exit(99);
+ }
+ if (!level2 && !level3)
+ level3 = true;
+
+ if (eps && (origPageSizes || paperSize[0] || paperWidth > 0 || paperHeight > 0)) {
+ fprintf(stderr, "Error: page size options may not be used with eps output.\n");
+ exit(99);
+ }
+
+ if ((paperWidth > 0 && paperHeight <= 0) || (paperWidth <= 0 && paperHeight > 0)) {
+ fprintf(stderr, "Error: both -paperw and -paperh must be specified.\n");
+ exit(99);
+ }
+
+ if (paperSize[0]) {
+ if (origPageSizes) {
+ fprintf(stderr, "Error: -origpagesizes and -paper may not be used together.\n");
+ exit(99);
+ }
+ if (!setPSPaperSize(paperSize, paperWidth, paperHeight)) {
+ fprintf(stderr, "Invalid paper size\n");
+ exit(99);
+ }
+ }
+ if (origPageSizes || paperWidth < 0 || paperHeight < 0)
+ usePDFPageSize = true;
+ else
+ usePDFPageSize = false;
+
+ if (printdlg)
+ printToWin32 = true;
+
+ globalParams = std::make_unique<GlobalParams>();
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
+ }
+
+ // open PDF file
+ if (ownerPassword[0]) {
+ ownerPW = new GooString(ownerPassword);
+ } else {
+ ownerPW = nullptr;
+ }
+ if (userPassword[0]) {
+ userPW = new GooString(userPassword);
+ } else {
+ userPW = nullptr;
}
- fseek (file, 0, SEEK_END);
- icc_data_size = ftell(file);
- fseek (file, 0, SEEK_SET);
- icc_data = (unsigned char*)gmalloc(icc_data_size);
- if (fread(icc_data, icc_data_size, 1, file) != 1) {
- fprintf(stderr, "Error: unable to read icc profile %s\n", icc.c_str());
- exit(4);
+
+ fileName = new GooString(argv[1]);
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
}
- fclose(file);
- profile = make_GfxLCMSProfilePtr(cmsOpenProfileFromMem(icc_data, icc_data_size));
- if (!profile) {
- fprintf(stderr, "Error: lcms error opening profile\n");
- exit(4);
+ if (argc == 3)
+ outputName = new GooString(argv[2]);
+ else
+ outputName = nullptr;
+
+ outputFileName = getOutputFileName(fileName, outputName);
+
+#ifdef USE_CMS
+ icc_data = nullptr;
+ if (icc.c_str()[0]) {
+ FILE *file = fopen(icc.c_str(), "rb");
+ if (!file) {
+ fprintf(stderr, "Error: unable to open icc profile %s\n", icc.c_str());
+ exit(4);
+ }
+ fseek(file, 0, SEEK_END);
+ icc_data_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ icc_data = (unsigned char *)gmalloc(icc_data_size);
+ if (fread(icc_data, icc_data_size, 1, file) != 1) {
+ fprintf(stderr, "Error: unable to read icc profile %s\n", icc.c_str());
+ exit(4);
+ }
+ fclose(file);
+ profile = make_GfxLCMSProfilePtr(cmsOpenProfileFromMem(icc_data, icc_data_size));
+ if (!profile) {
+ fprintf(stderr, "Error: lcms error opening profile\n");
+ exit(4);
+ }
+ } else {
+ profile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
}
- } else {
- profile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
- }
#endif
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- if (!doc->isOk()) {
- fprintf(stderr, "Error opening PDF file.\n");
- exit(1);
- }
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+ if (!doc->isOk()) {
+ fprintf(stderr, "Error opening PDF file.\n");
+ exit(1);
+ }
#ifdef ENFORCE_PERMISSIONS
- // check for print permission
- if (printing && !doc->okToPrint()) {
- fprintf(stderr, "Printing this document is not allowed.\n");
- exit(3);
- }
+ // check for print permission
+ if (printing && !doc->okToPrint()) {
+ fprintf(stderr, "Printing this document is not allowed.\n");
+ exit(3);
+ }
#endif
- // get page range
- if (firstPage < 1)
- firstPage = 1;
- if (singleFile && lastPage < 1)
- lastPage = firstPage;
- if (lastPage < 1 || lastPage > doc->getNumPages())
- lastPage = doc->getNumPages();
-
- if (lastPage < firstPage) {
- fprintf(stderr,
- "Wrong page range given: the first page (%d) can not be after the last page (%d).\n",
- firstPage, lastPage);
- exit(99);
- }
- if (eps && firstPage != lastPage) {
- fprintf(stderr, "EPS files can only contain one page.\n");
- exit(99);
- }
-
- // If our page range selection and document size indicate we're only
- // outputting a single page, ensure that even/odd page selection doesn't
- // filter out that single page.
- if (firstPage == lastPage &&
- ((printOnlyEven && firstPage % 2 == 1) ||
- (printOnlyOdd && firstPage % 2 == 0))) {
- fprintf(stderr, "Invalid even/odd page selection, no pages match criteria.\n");
- exit(99);
- }
-
- if (singleFile && firstPage < lastPage) {
- if (!quiet) {
- fprintf(stderr,
- "Warning: Single file will write only the first of the %d pages.\n",
- lastPage + 1 - firstPage);
+ // get page range
+ if (firstPage < 1)
+ firstPage = 1;
+ if (singleFile && lastPage < 1)
+ lastPage = firstPage;
+ if (lastPage < 1 || lastPage > doc->getNumPages())
+ lastPage = doc->getNumPages();
+
+ if (lastPage < firstPage) {
+ fprintf(stderr, "Wrong page range given: the first page (%d) can not be after the last page (%d).\n", firstPage, lastPage);
+ exit(99);
+ }
+ if (eps && firstPage != lastPage) {
+ fprintf(stderr, "EPS files can only contain one page.\n");
+ exit(99);
+ }
+
+ // If our page range selection and document size indicate we're only
+ // outputting a single page, ensure that even/odd page selection doesn't
+ // filter out that single page.
+ if (firstPage == lastPage && ((printOnlyEven && firstPage % 2 == 1) || (printOnlyOdd && firstPage % 2 == 0))) {
+ fprintf(stderr, "Invalid even/odd page selection, no pages match criteria.\n");
+ exit(99);
+ }
+
+ if (singleFile && firstPage < lastPage) {
+ if (!quiet) {
+ fprintf(stderr, "Warning: Single file will write only the first of the %d pages.\n", lastPage + 1 - firstPage);
+ }
+ lastPage = firstPage;
}
- lastPage = firstPage;
- }
#ifdef CAIRO_HAS_WIN32_SURFACE
if (printdlg) {
- bool allPages = false;
- if (firstPage == 1 && lastPage == doc->getNumPages())
- allPages = true;
- win32ShowPrintDialog(&expand, &noShrink, &noCenter,
- &usePDFPageSize, &allPages,
- &firstPage, &lastPage, doc->getNumPages());
- if (allPages) {
- firstPage = 1;
- lastPage = doc->getNumPages();
- }
+ bool allPages = false;
+ if (firstPage == 1 && lastPage == doc->getNumPages())
+ allPages = true;
+ win32ShowPrintDialog(&expand, &noShrink, &noCenter, &usePDFPageSize, &allPages, &firstPage, &lastPage, doc->getNumPages());
+ if (allPages) {
+ firstPage = 1;
+ lastPage = doc->getNumPages();
+ }
} else if (printToWin32) {
- win32SetupPrinter(&printer, &printOpt,
- duplex, setupdlg);
+ win32SetupPrinter(&printer, &printOpt, duplex, setupdlg);
}
#endif
-
- cairoOut = new CairoOutputDev();
+ cairoOut = new CairoOutputDev();
#ifdef USE_CMS
- cairoOut->setDisplayProfile(profile);
+ cairoOut->setDisplayProfile(profile);
#endif
- cairoOut->startDoc(doc);
- if (sz != 0)
- crop_w = crop_h = sz;
- pg_num_len = numberOfCharacters(doc->getNumPages());
- for (pg = firstPage; pg <= lastPage; ++pg) {
- if (printOnlyEven && pg % 2 == 1) continue;
- if (printOnlyOdd && pg % 2 == 0) continue;
- if (useCropBox) {
- pg_w = doc->getPageCropWidth(pg);
- pg_h = doc->getPageCropHeight(pg);
- } else {
- pg_w = doc->getPageMediaWidth(pg);
- pg_h = doc->getPageMediaHeight(pg);
- }
+ cairoOut->startDoc(doc);
+ if (sz != 0)
+ crop_w = crop_h = sz;
+ pg_num_len = numberOfCharacters(doc->getNumPages());
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (printOnlyEven && pg % 2 == 1)
+ continue;
+ if (printOnlyOdd && pg % 2 == 0)
+ continue;
+ if (useCropBox) {
+ pg_w = doc->getPageCropWidth(pg);
+ pg_h = doc->getPageCropHeight(pg);
+ } else {
+ pg_w = doc->getPageMediaWidth(pg);
+ pg_h = doc->getPageMediaHeight(pg);
+ }
- if (printing && pg == firstPage) {
- if (paperWidth < 0 || paperHeight < 0) {
- paperWidth = (int)ceil(pg_w);
- paperHeight = (int)ceil(pg_h);
- }
- }
+ if (printing && pg == firstPage) {
+ if (paperWidth < 0 || paperHeight < 0) {
+ paperWidth = (int)ceil(pg_w);
+ paperHeight = (int)ceil(pg_h);
+ }
+ }
- if ((doc->getPageRotate(pg) == 90) || (doc->getPageRotate(pg) == 270)) {
- tmp = pg_w;
- pg_w = pg_h;
- pg_h = tmp;
- }
- if (scaleTo != 0) {
- resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h);
- x_resolution = y_resolution = resolution;
- } else {
- if (x_scaleTo > 0) {
- x_resolution = (72.0 * x_scaleTo) / pg_w;
- if (y_scaleTo == -1)
- y_resolution = x_resolution;
- }
- if (y_scaleTo > 0) {
- y_resolution = (72.0 * y_scaleTo) / pg_h;
- if (x_scaleTo == -1)
- x_resolution = y_resolution;
- }
- }
- if (imageFileName) {
- delete imageFileName;
- imageFileName = nullptr;
+ if ((doc->getPageRotate(pg) == 90) || (doc->getPageRotate(pg) == 270)) {
+ tmp = pg_w;
+ pg_w = pg_h;
+ pg_h = tmp;
+ }
+ if (scaleTo != 0) {
+ resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h);
+ x_resolution = y_resolution = resolution;
+ } else {
+ if (x_scaleTo > 0) {
+ x_resolution = (72.0 * x_scaleTo) / pg_w;
+ if (y_scaleTo == -1)
+ y_resolution = x_resolution;
+ }
+ if (y_scaleTo > 0) {
+ y_resolution = (72.0 * y_scaleTo) / pg_h;
+ if (x_scaleTo == -1)
+ x_resolution = y_resolution;
+ }
+ }
+ if (imageFileName) {
+ delete imageFileName;
+ imageFileName = nullptr;
+ }
+ if (!printing)
+ imageFileName = getImageFileName(outputFileName, pg_num_len, pg);
+ getOutputSize(pg_w, pg_h, &output_w, &output_h);
+
+ if (pg == firstPage)
+ beginDocument(fileName, outputFileName, output_w, output_h);
+ beginPage(&output_w, &output_h);
+ renderPage(doc, cairoOut, pg, pg_w, pg_h, output_w, output_h);
+ endPage(imageFileName);
}
- if (!printing)
- imageFileName = getImageFileName(outputFileName, pg_num_len, pg);
- getOutputSize(pg_w, pg_h, &output_w, &output_h);
-
- if (pg == firstPage)
- beginDocument(fileName, outputFileName, output_w, output_h);
- beginPage(&output_w, &output_h);
- renderPage(doc, cairoOut, pg, pg_w, pg_h, output_w, output_h);
- endPage(imageFileName);
- }
- endDocument();
-
- // clean up
- delete cairoOut;
- delete doc;
- if (fileName)
- delete fileName;
- if (outputName)
- delete outputName;
- if (outputFileName)
- delete outputFileName;
- if (imageFileName)
- delete imageFileName;
- if (ownerPW)
- delete ownerPW;
- if (userPW)
- delete userPW;
+ endDocument();
+
+ // clean up
+ delete cairoOut;
+ delete doc;
+ if (fileName)
+ delete fileName;
+ if (outputName)
+ delete outputName;
+ if (outputFileName)
+ delete outputFileName;
+ if (imageFileName)
+ delete imageFileName;
+ if (ownerPW)
+ delete ownerPW;
+ if (userPW)
+ delete userPW;
#ifdef USE_CMS
- if (icc_data)
- gfree(icc_data);
+ if (icc_data)
+ gfree(icc_data);
#endif
- return 0;
+ return 0;
}
diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc
index cdb7964e..bbf4bf4f 100644
--- a/utils/pdftohtml.cc
+++ b/utils/pdftohtml.cc
@@ -42,7 +42,7 @@
#include <cstddef>
#include <cstring>
#ifdef HAVE_DIRENT_H
-#include <dirent.h>
+# include <dirent.h>
#endif
#include <ctime>
#include "parseargs.h"
@@ -62,8 +62,8 @@
#include "PDFDocFactory.h"
#include "HtmlOutputDev.h"
#ifdef HAVE_SPLASH
-#include "SplashOutputDev.h"
-#include "splash/SplashBitmap.h"
+# include "SplashOutputDev.h"
+# include "splash/SplashBitmap.h"
#endif
#include "GlobalParams.h"
#include "PDFDocEncoding.h"
@@ -79,19 +79,19 @@ static bool rawOrder = true;
bool printCommands = true;
static bool printHelp = false;
bool printHtml = false;
-bool complexMode=false;
-bool singleHtml=false; // singleHtml
+bool complexMode = false;
+bool singleHtml = false; // singleHtml
bool dataUrls = false;
-bool ignore=false;
-static char extension[5]="png";
-static double scale=1.5;
-bool noframes=false;
-bool stout=false;
-bool xml=false;
+bool ignore = false;
+static char extension[5] = "png";
+static double scale = 1.5;
+bool noframes = false;
+bool stout = false;
+bool xml = false;
bool noRoundedCoordinates = false;
-static bool errQuiet=false;
-static bool noDrm=false;
-double wordBreakThreshold=10; // 10%, below converted into a coefficient - 0.1
+static bool errQuiet = false;
+static bool noDrm = false;
+double wordBreakThreshold = 10; // 10%, below converted into a coefficient - 0.1
bool showHidden = false;
bool noMerge = false;
@@ -100,450 +100,397 @@ static char ownerPassword[33] = "";
static char userPassword[33] = "";
static bool printVersion = false;
-static GooString* getInfoString(Dict *infoDict, const char *key);
-static GooString* getInfoDate(Dict *infoDict, const char *key);
+static GooString *getInfoString(Dict *infoDict, const char *key);
+static GooString *getInfoDate(Dict *infoDict, const char *key);
static char textEncName[128] = "";
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to convert"},
- {"-l", argInt, &lastPage, 0,
- "last page to convert"},
- /*{"-raw", argFlag, &rawOrder, 0,
- "keep strings in content stream order"},*/
- {"-q", argFlag, &errQuiet, 0,
- "don't print any messages or errors"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-p", argFlag, &printHtml, 0,
- "exchange .pdf links by .html"},
- {"-c", argFlag, &complexMode, 0,
- "generate complex document"},
- {"-s", argFlag, &singleHtml, 0,
- "generate single document that includes all pages"},
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to convert" },
+ { "-l", argInt, &lastPage, 0, "last page to convert" },
+ /*{"-raw", argFlag, &rawOrder, 0,
+ "keep strings in content stream order"},*/
+ { "-q", argFlag, &errQuiet, 0, "don't print any messages or errors" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-p", argFlag, &printHtml, 0, "exchange .pdf links by .html" },
+ { "-c", argFlag, &complexMode, 0, "generate complex document" },
+ { "-s", argFlag, &singleHtml, 0, "generate single document that includes all pages" },
#ifdef HAVE_IN_MEMORY_FILE
- {"-dataurls", argFlag, &dataUrls, 0,
- "use data URLs instead of external images in HTML"},
+ { "-dataurls", argFlag, &dataUrls, 0, "use data URLs instead of external images in HTML" },
#endif
- {"-i", argFlag, &ignore, 0,
- "ignore images"},
- {"-noframes", argFlag, &noframes, 0,
- "generate no frames"},
- {"-stdout" ,argFlag, &stout, 0,
- "use standard output"},
- {"-zoom", argFP, &scale, 0,
- "zoom the pdf document (default 1.5)"},
- {"-xml", argFlag, &xml, 0,
- "output for XML post-processing"},
- {"-noroundcoord", argFlag, &noRoundedCoordinates, 0,
- "do not round coordinates (with XML output only)"},
- {"-hidden", argFlag, &showHidden, 0,
- "output hidden text"},
- {"-nomerge", argFlag, &noMerge, 0,
- "do not merge paragraphs"},
- {"-enc", argString, textEncName, sizeof(textEncName),
- "output text encoding name"},
- {"-fmt", argString, extension, sizeof(extension),
- "image file format for Splash output (png or jpg)"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-nodrm", argFlag, &noDrm, 0,
- "override document DRM settings"},
- {"-wbt", argFP, &wordBreakThreshold, 0,
- "word break threshold (default 10 percent)"},
- {"-fontfullname", argFlag, &fontFullName, 0,
- "outputs font full name"},
- {}
-};
+ { "-i", argFlag, &ignore, 0, "ignore images" },
+ { "-noframes", argFlag, &noframes, 0, "generate no frames" },
+ { "-stdout", argFlag, &stout, 0, "use standard output" },
+ { "-zoom", argFP, &scale, 0, "zoom the pdf document (default 1.5)" },
+ { "-xml", argFlag, &xml, 0, "output for XML post-processing" },
+ { "-noroundcoord", argFlag, &noRoundedCoordinates, 0, "do not round coordinates (with XML output only)" },
+ { "-hidden", argFlag, &showHidden, 0, "output hidden text" },
+ { "-nomerge", argFlag, &noMerge, 0, "do not merge paragraphs" },
+ { "-enc", argString, textEncName, sizeof(textEncName), "output text encoding name" },
+ { "-fmt", argString, extension, sizeof(extension), "image file format for Splash output (png or jpg)" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-nodrm", argFlag, &noDrm, 0, "override document DRM settings" },
+ { "-wbt", argFP, &wordBreakThreshold, 0, "word break threshold (default 10 percent)" },
+ { "-fontfullname", argFlag, &fontFullName, 0, "outputs font full name" },
+ {} };
#ifdef HAVE_SPLASH
-class SplashOutputDevNoText : public SplashOutputDev {
+class SplashOutputDevNoText : public SplashOutputDev
+{
public:
- SplashOutputDevNoText(SplashColorMode colorModeA, int bitmapRowPadA,
- bool reverseVideoA, SplashColorPtr paperColorA,
- bool bitmapTopDownA = true) : SplashOutputDev(colorModeA,
- bitmapRowPadA, reverseVideoA, paperColorA, bitmapTopDownA) { }
- ~SplashOutputDevNoText() override { }
-
- void drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, int nBytes, const Unicode *u, int uLen) override { }
- bool beginType3Char(GfxState *state, double x, double y,
- double dx, double dy,
- CharCode code, const Unicode *u, int uLen) override { return false; }
- void endType3Char(GfxState *state) override { }
- void beginTextObject(GfxState *state) override { }
- void endTextObject(GfxState *state) override { }
- bool interpretType3Chars() override { return false; }
+ SplashOutputDevNoText(SplashColorMode colorModeA, int bitmapRowPadA, bool reverseVideoA, SplashColorPtr paperColorA, bool bitmapTopDownA = true)
+ : SplashOutputDev(colorModeA, bitmapRowPadA, reverseVideoA, paperColorA, bitmapTopDownA) { }
+ ~SplashOutputDevNoText() override { }
+
+ void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen) override { }
+ bool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, const Unicode *u, int uLen) override { return false; }
+ void endType3Char(GfxState *state) override { }
+ void beginTextObject(GfxState *state) override { }
+ void endTextObject(GfxState *state) override { }
+ bool interpretType3Chars() override { return false; }
};
#endif
-int main(int argc, char *argv[]) {
- PDFDoc *doc = nullptr;
- GooString *fileName = nullptr;
- GooString *docTitle = nullptr;
- GooString *author = nullptr, *keywords = nullptr, *subject = nullptr, *date = nullptr;
- GooString *htmlFileName = nullptr;
- HtmlOutputDev *htmlOut = nullptr;
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc = nullptr;
+ GooString *fileName = nullptr;
+ GooString *docTitle = nullptr;
+ GooString *author = nullptr, *keywords = nullptr, *subject = nullptr, *date = nullptr;
+ GooString *htmlFileName = nullptr;
+ HtmlOutputDev *htmlOut = nullptr;
#ifdef HAVE_SPLASH
- SplashOutputDev *splashOut = nullptr;
+ SplashOutputDev *splashOut = nullptr;
#endif
- bool doOutline;
- bool ok;
- GooString *ownerPW, *userPW;
- Object info;
- int exit_status = EXIT_FAILURE;
-
- Win32Console win32Console(&argc, &argv);
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc < 2 || argc > 3 || printHelp || printVersion) {
- fprintf(stderr, "pdftohtml version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", "Copyright 1999-2003 Gueorgui Ovtcharov and Rainer Dorsch");
- fprintf(stderr, "%s\n\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdftohtml", "<PDF-file> [<html-file> <xml-file>]", argDesc);
- }
- exit(printHelp || printVersion ? 0 : 1);
- }
-
- // init error file
- //errorInit();
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
-
- if (errQuiet) {
- globalParams->setErrQuiet(errQuiet);
- printCommands = false; // I'm not 100% what is the difference between them
- }
-
- if (textEncName[0]) {
- globalParams->setTextEncoding(textEncName);
- if( !globalParams->getTextEncoding() ) {
- goto error;
+ bool doOutline;
+ bool ok;
+ GooString *ownerPW, *userPW;
+ Object info;
+ int exit_status = EXIT_FAILURE;
+
+ Win32Console win32Console(&argc, &argv);
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc < 2 || argc > 3 || printHelp || printVersion) {
+ fprintf(stderr, "pdftohtml version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", "Copyright 1999-2003 Gueorgui Ovtcharov and Rainer Dorsch");
+ fprintf(stderr, "%s\n\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdftohtml", "<PDF-file> [<html-file> <xml-file>]", argDesc);
+ }
+ exit(printHelp || printVersion ? 0 : 1);
}
- }
-
- // convert from user-friendly percents into a coefficient
- wordBreakThreshold /= 100.0;
-
- // open PDF file
- if (ownerPassword[0]) {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0]) {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
-
- fileName = new GooString(argv[1]);
-
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
-
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
-
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- goto error;
- }
-
- // check for copy permission
- if (!doc->okToCopy()) {
- if (!noDrm) {
- error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
- goto error;
+
+ // init error file
+ // errorInit();
+
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+
+ if (errQuiet) {
+ globalParams->setErrQuiet(errQuiet);
+ printCommands = false; // I'm not 100% what is the difference between them
}
- fprintf(stderr, "Document has copy-protection bit set.\n");
- }
-
- // construct text file name
- if (argc == 3) {
- GooString* tmp = new GooString(argv[2]);
- if (!xml) {
- if (tmp->getLength() >= 5) {
- const char *p = tmp->c_str() + tmp->getLength() - 5;
- if (!strcmp(p, ".html") || !strcmp(p, ".HTML")) {
- htmlFileName = new GooString(tmp->c_str(), tmp->getLength() - 5);
+
+ if (textEncName[0]) {
+ globalParams->setTextEncoding(textEncName);
+ if (!globalParams->getTextEncoding()) {
+ goto error;
}
- }
+ }
+
+ // convert from user-friendly percents into a coefficient
+ wordBreakThreshold /= 100.0;
+
+ // open PDF file
+ if (ownerPassword[0]) {
+ ownerPW = new GooString(ownerPassword);
+ } else {
+ ownerPW = nullptr;
+ }
+ if (userPassword[0]) {
+ userPW = new GooString(userPassword);
} else {
- if (tmp->getLength() >= 4) {
- const char *p = tmp->c_str() + tmp->getLength() - 4;
- if (!strcmp(p, ".xml") || !strcmp(p, ".XML")) {
- htmlFileName = new GooString(tmp->c_str(), tmp->getLength() - 4);
+ userPW = nullptr;
+ }
+
+ fileName = new GooString(argv[1]);
+
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
+ }
+
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ goto error;
+ }
+
+ // check for copy permission
+ if (!doc->okToCopy()) {
+ if (!noDrm) {
+ error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
+ goto error;
}
- }
+ fprintf(stderr, "Document has copy-protection bit set.\n");
+ }
+
+ // construct text file name
+ if (argc == 3) {
+ GooString *tmp = new GooString(argv[2]);
+ if (!xml) {
+ if (tmp->getLength() >= 5) {
+ const char *p = tmp->c_str() + tmp->getLength() - 5;
+ if (!strcmp(p, ".html") || !strcmp(p, ".HTML")) {
+ htmlFileName = new GooString(tmp->c_str(), tmp->getLength() - 5);
+ }
+ }
+ } else {
+ if (tmp->getLength() >= 4) {
+ const char *p = tmp->c_str() + tmp->getLength() - 4;
+ if (!strcmp(p, ".xml") || !strcmp(p, ".XML")) {
+ htmlFileName = new GooString(tmp->c_str(), tmp->getLength() - 4);
+ }
+ }
+ }
+ if (!htmlFileName) {
+ htmlFileName = new GooString(tmp);
+ }
+ delete tmp;
+ } else if (fileName->cmp("fd://0") == 0) {
+ error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
+ goto error;
+ } else {
+ const char *p = fileName->c_str() + fileName->getLength() - 4;
+ if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF"))
+ htmlFileName = new GooString(fileName->c_str(), fileName->getLength() - 4);
+ else
+ htmlFileName = fileName->copy();
+ // htmlFileName->append(".html");
+ }
+
+ if (scale > 3.0)
+ scale = 3.0;
+ if (scale < 0.5)
+ scale = 0.5;
+
+ if (complexMode) {
+ // noframes=false;
+ stout = false;
}
- if (!htmlFileName) {
- htmlFileName =new GooString(tmp);
+
+ if (stout) {
+ noframes = true;
+ complexMode = false;
+ }
+
+ if (xml) {
+ complexMode = true;
+ singleHtml = false;
+ noframes = true;
+ noMerge = true;
+ }
+
+ // get page range
+ if (firstPage < 1)
+ firstPage = 1;
+ if (lastPage < 1 || lastPage > doc->getNumPages())
+ lastPage = doc->getNumPages();
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ goto error;
+ }
+
+ info = doc->getDocInfo();
+ if (info.isDict()) {
+ docTitle = getInfoString(info.getDict(), "Title");
+ author = getInfoString(info.getDict(), "Author");
+ keywords = getInfoString(info.getDict(), "Keywords");
+ subject = getInfoString(info.getDict(), "Subject");
+ date = getInfoDate(info.getDict(), "ModDate");
+ if (!date)
+ date = getInfoDate(info.getDict(), "CreationDate");
}
- delete tmp;
- } else if (fileName->cmp("fd://0") == 0) {
- error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
- goto error;
- } else {
- const char *p = fileName->c_str() + fileName->getLength() - 4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF"))
- htmlFileName = new GooString(fileName->c_str(),
- fileName->getLength() - 4);
+ if (!docTitle)
+ docTitle = new GooString(htmlFileName);
+
+ if (!singleHtml)
+ rawOrder = complexMode; // todo: figure out what exactly rawOrder do :)
else
- htmlFileName = fileName->copy();
- // htmlFileName->append(".html");
- }
-
- if (scale>3.0) scale=3.0;
- if (scale<0.5) scale=0.5;
-
- if (complexMode) {
- //noframes=false;
- stout=false;
- }
-
- if (stout) {
- noframes=true;
- complexMode=false;
- }
-
- if (xml)
- {
- complexMode = true;
- singleHtml = false;
- noframes = true;
- noMerge = true;
- }
-
- // get page range
- if (firstPage < 1)
- firstPage = 1;
- if (lastPage < 1 || lastPage > doc->getNumPages())
- lastPage = doc->getNumPages();
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- goto error;
- }
-
- info = doc->getDocInfo();
- if (info.isDict()) {
- docTitle = getInfoString(info.getDict(), "Title");
- author = getInfoString(info.getDict(), "Author");
- keywords = getInfoString(info.getDict(), "Keywords");
- subject = getInfoString(info.getDict(), "Subject");
- date = getInfoDate(info.getDict(), "ModDate");
- if( !date )
- date = getInfoDate(info.getDict(), "CreationDate");
- }
- if( !docTitle ) docTitle = new GooString(htmlFileName);
-
- if (!singleHtml)
- rawOrder = complexMode; // todo: figure out what exactly rawOrder do :)
- else
- rawOrder = singleHtml;
-
- doOutline = doc->getOutline()->getItems() != nullptr;
- // write text file
- htmlOut = new HtmlOutputDev(doc->getCatalog(), htmlFileName->c_str(),
- docTitle->c_str(),
- author ? author->c_str() : nullptr,
- keywords ? keywords->c_str() : nullptr,
- subject ? subject->c_str() : nullptr,
- date ? date->c_str() : nullptr,
- rawOrder,
- firstPage,
- doOutline);
- delete docTitle;
- if( author )
- {
- delete author;
- }
- if( keywords )
- {
- delete keywords;
- }
- if( subject )
- {
- delete subject;
- }
- if( date )
- {
- delete date;
- }
-
- if ((complexMode || singleHtml) && !xml && !ignore) {
-#ifdef HAVE_SPLASH
- GooString *imgFileName = nullptr;
- // White paper color
- SplashColor color;
- color[0] = color[1] = color[2] = 255;
- // If the user specified "jpg" use JPEG, otherwise PNG
- SplashImageFileFormat format = strcmp(extension, "jpg") ?
- splashFormatPng : splashFormatJpeg;
-
- splashOut = new SplashOutputDevNoText(splashModeRGB8, 4, false, color);
- splashOut->startDoc(doc);
-
- for (int pg = firstPage; pg <= lastPage; ++pg) {
- InMemoryFile imf;
- doc->displayPage(splashOut, pg,
- 72 * scale, 72 * scale,
- 0, true, false, false);
- SplashBitmap *bitmap = splashOut->getBitmap();
-
- imgFileName = GooString::format("{0:s}{1:03d}.{2:s}",
- htmlFileName->c_str(), pg, extension);
- auto f1 = dataUrls ? imf.open("wb") : fopen(imgFileName->c_str(), "wb");
- if (!f1) {
- fprintf(stderr, "Could not open %s\n", imgFileName->c_str());
- delete imgFileName;
- continue;
- }
- bitmap->writeImgFile(format, f1, 72 * scale, 72 * scale);
- fclose(f1);
- if (dataUrls) {
- htmlOut->addBackgroundImage(
- std::string((format == splashFormatJpeg) ? "data:image/jpeg;base64," : "data:image/png;base64,") +
- gbase64Encode(imf.getBuffer())
- );
- } else {
- htmlOut->addBackgroundImage(gbasename(imgFileName->c_str()));
- }
- delete imgFileName;
+ rawOrder = singleHtml;
+
+ doOutline = doc->getOutline()->getItems() != nullptr;
+ // write text file
+ htmlOut = new HtmlOutputDev(doc->getCatalog(), htmlFileName->c_str(), docTitle->c_str(), author ? author->c_str() : nullptr, keywords ? keywords->c_str() : nullptr, subject ? subject->c_str() : nullptr, date ? date->c_str() : nullptr,
+ rawOrder, firstPage, doOutline);
+ delete docTitle;
+ if (author) {
+ delete author;
+ }
+ if (keywords) {
+ delete keywords;
+ }
+ if (subject) {
+ delete subject;
+ }
+ if (date) {
+ delete date;
}
- delete splashOut;
+ if ((complexMode || singleHtml) && !xml && !ignore) {
+#ifdef HAVE_SPLASH
+ GooString *imgFileName = nullptr;
+ // White paper color
+ SplashColor color;
+ color[0] = color[1] = color[2] = 255;
+ // If the user specified "jpg" use JPEG, otherwise PNG
+ SplashImageFileFormat format = strcmp(extension, "jpg") ? splashFormatPng : splashFormatJpeg;
+
+ splashOut = new SplashOutputDevNoText(splashModeRGB8, 4, false, color);
+ splashOut->startDoc(doc);
+
+ for (int pg = firstPage; pg <= lastPage; ++pg) {
+ InMemoryFile imf;
+ doc->displayPage(splashOut, pg, 72 * scale, 72 * scale, 0, true, false, false);
+ SplashBitmap *bitmap = splashOut->getBitmap();
+
+ imgFileName = GooString::format("{0:s}{1:03d}.{2:s}", htmlFileName->c_str(), pg, extension);
+ auto f1 = dataUrls ? imf.open("wb") : fopen(imgFileName->c_str(), "wb");
+ if (!f1) {
+ fprintf(stderr, "Could not open %s\n", imgFileName->c_str());
+ delete imgFileName;
+ continue;
+ }
+ bitmap->writeImgFile(format, f1, 72 * scale, 72 * scale);
+ fclose(f1);
+ if (dataUrls) {
+ htmlOut->addBackgroundImage(std::string((format == splashFormatJpeg) ? "data:image/jpeg;base64," : "data:image/png;base64,") + gbase64Encode(imf.getBuffer()));
+ } else {
+ htmlOut->addBackgroundImage(gbasename(imgFileName->c_str()));
+ }
+ delete imgFileName;
+ }
+
+ delete splashOut;
#else
- fprintf(stderr, "Your pdftohtml was built without splash backend support. It is needed for the option you want to use.\n");
- delete htmlOut;
- delete htmlFileName;
- delete fileName;
- delete doc;
- return -1;
+ fprintf(stderr, "Your pdftohtml was built without splash backend support. It is needed for the option you want to use.\n");
+ delete htmlOut;
+ delete htmlFileName;
+ delete fileName;
+ delete doc;
+ return -1;
#endif
- }
+ }
- if (htmlOut->isOk())
- {
- doc->displayPages(htmlOut, firstPage, lastPage, 72 * scale, 72 * scale, 0,
- true, false, false);
- htmlOut->dumpDocOutline(doc);
- }
+ if (htmlOut->isOk()) {
+ doc->displayPages(htmlOut, firstPage, lastPage, 72 * scale, 72 * scale, 0, true, false, false);
+ htmlOut->dumpDocOutline(doc);
+ }
- delete htmlOut;
+ delete htmlOut;
- exit_status = EXIT_SUCCESS;
+ exit_status = EXIT_SUCCESS;
- // clean up
- error:
- if(doc) delete doc;
- delete fileName;
+ // clean up
+error:
+ if (doc)
+ delete doc;
+ delete fileName;
- if(htmlFileName) delete htmlFileName;
+ if (htmlFileName)
+ delete htmlFileName;
- return exit_status;
+ return exit_status;
}
-static GooString* getInfoString(Dict *infoDict, const char *key) {
- Object obj;
- // Raw value as read from PDF (may be in pdfDocEncoding or UCS2)
- const GooString *rawString;
- // Value converted to unicode
- Unicode *unicodeString;
- int unicodeLength;
- // Value HTML escaped and converted to desired encoding
- GooString *encodedString = nullptr;
- // Is rawString UCS2 (as opposed to pdfDocEncoding)
- bool isUnicode;
-
- obj = infoDict->lookup(key);
- if (obj.isString()) {
- rawString = obj.getString();
-
- // Convert rawString to unicode
- if (rawString->hasUnicodeMarker()) {
- isUnicode = true;
- unicodeLength = (obj.getString()->getLength() - 2) / 2;
- } else {
- isUnicode = false;
- unicodeLength = obj.getString()->getLength();
- }
- unicodeString = new Unicode[unicodeLength];
-
- for (int i=0; i<unicodeLength; i++) {
- if (isUnicode) {
- unicodeString[i] = ((rawString->getChar((i+1)*2) & 0xff) << 8) |
- (rawString->getChar(((i+1)*2)+1) & 0xff);
- } else {
- unicodeString[i] = pdfDocEncoding[rawString->getChar(i) & 0xff];
- }
- }
+static GooString *getInfoString(Dict *infoDict, const char *key)
+{
+ Object obj;
+ // Raw value as read from PDF (may be in pdfDocEncoding or UCS2)
+ const GooString *rawString;
+ // Value converted to unicode
+ Unicode *unicodeString;
+ int unicodeLength;
+ // Value HTML escaped and converted to desired encoding
+ GooString *encodedString = nullptr;
+ // Is rawString UCS2 (as opposed to pdfDocEncoding)
+ bool isUnicode;
+
+ obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ rawString = obj.getString();
+
+ // Convert rawString to unicode
+ if (rawString->hasUnicodeMarker()) {
+ isUnicode = true;
+ unicodeLength = (obj.getString()->getLength() - 2) / 2;
+ } else {
+ isUnicode = false;
+ unicodeLength = obj.getString()->getLength();
+ }
+ unicodeString = new Unicode[unicodeLength];
+
+ for (int i = 0; i < unicodeLength; i++) {
+ if (isUnicode) {
+ unicodeString[i] = ((rawString->getChar((i + 1) * 2) & 0xff) << 8) | (rawString->getChar(((i + 1) * 2) + 1) & 0xff);
+ } else {
+ unicodeString[i] = pdfDocEncoding[rawString->getChar(i) & 0xff];
+ }
+ }
- // HTML escape and encode unicode
- encodedString = HtmlFont::HtmlFilter(unicodeString, unicodeLength);
- delete[] unicodeString;
- }
+ // HTML escape and encode unicode
+ encodedString = HtmlFont::HtmlFilter(unicodeString, unicodeLength);
+ delete[] unicodeString;
+ }
- return encodedString;
+ return encodedString;
}
-static GooString* getInfoDate(Dict *infoDict, const char *key) {
- Object obj;
- const char *s;
- int year, mon, day, hour, min, sec, tz_hour, tz_minute;
- char tz;
- struct tm tmStruct;
- GooString *result = nullptr;
- char buf[256];
-
- obj = infoDict->lookup(key);
- if (obj.isString()) {
- s = obj.getString()->c_str();
- // TODO do something with the timezone info
- if ( parseDateString( s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute ) ) {
- tmStruct.tm_year = year - 1900;
- tmStruct.tm_mon = mon - 1;
- tmStruct.tm_mday = day;
- tmStruct.tm_hour = hour;
- tmStruct.tm_min = min;
- tmStruct.tm_sec = sec;
- tmStruct.tm_wday = -1;
- tmStruct.tm_yday = -1;
- tmStruct.tm_isdst = -1;
- mktime(&tmStruct); // compute the tm_wday and tm_yday fields
- if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S+00:00", &tmStruct)) {
- result = new GooString(buf);
- } else {
- result = new GooString(s);
- }
- } else {
- result = new GooString(s);
+static GooString *getInfoDate(Dict *infoDict, const char *key)
+{
+ Object obj;
+ const char *s;
+ int year, mon, day, hour, min, sec, tz_hour, tz_minute;
+ char tz;
+ struct tm tmStruct;
+ GooString *result = nullptr;
+ char buf[256];
+
+ obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ s = obj.getString()->c_str();
+ // TODO do something with the timezone info
+ if (parseDateString(s, &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute)) {
+ tmStruct.tm_year = year - 1900;
+ tmStruct.tm_mon = mon - 1;
+ tmStruct.tm_mday = day;
+ tmStruct.tm_hour = hour;
+ tmStruct.tm_min = min;
+ tmStruct.tm_sec = sec;
+ tmStruct.tm_wday = -1;
+ tmStruct.tm_yday = -1;
+ tmStruct.tm_isdst = -1;
+ mktime(&tmStruct); // compute the tm_wday and tm_yday fields
+ if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S+00:00", &tmStruct)) {
+ result = new GooString(buf);
+ } else {
+ result = new GooString(s);
+ }
+ } else {
+ result = new GooString(s);
+ }
}
- }
- return result;
+ return result;
}
-
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index 2652f799..ebb1c6d4 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -42,8 +42,8 @@
#include "config.h"
#include <poppler-config.h>
#ifdef _WIN32
-#include <fcntl.h> // for O_BINARY
-#include <io.h> // for setmode
+# include <fcntl.h> // for O_BINARY
+# include <io.h> // for setmode
#endif
#include <cstdio>
#include <cmath>
@@ -67,13 +67,13 @@
// #define UTILS_USE_PTHREADS 1
#ifdef UTILS_USE_PTHREADS
-#include <cerrno>
-#include <pthread.h>
-#include <deque>
+# include <cerrno>
+# include <pthread.h>
+# include <deque>
#endif // UTILS_USE_PTHREADS
#ifdef USE_CMS
-#include <lcms2.h>
+# include <lcms2.h>
#endif
static int firstPage = 1;
@@ -130,114 +130,68 @@ static bool quiet = false;
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to print"},
- {"-l", argInt, &lastPage, 0,
- "last page to print"},
- {"-o", argFlag, &printOnlyOdd, 0,
- "print only odd pages"},
- {"-e", argFlag, &printOnlyEven, 0,
- "print only even pages"},
- {"-singlefile", argFlag, &singleFile, 0,
- "write only the first page and do not add digits"},
- {"-scale-dimension-before-rotation", argFlag, &scaleDimensionBeforeRotation, 0,
- "for rotated pdf, resize dimensions before the rotation"},
-
- {"-r", argFP, &resolution, 0,
- "resolution, in DPI (default is 150)"},
- {"-rx", argFP, &x_resolution, 0,
- "X resolution, in DPI (default is 150)"},
- {"-ry", argFP, &y_resolution, 0,
- "Y resolution, in DPI (default is 150)"},
- {"-scale-to", argInt, &scaleTo, 0,
- "scales each page to fit within scale-to*scale-to pixel box"},
- {"-scale-to-x", argInt, &x_scaleTo, 0,
- "scales each page horizontally to fit in scale-to-x pixels"},
- {"-scale-to-y", argInt, &y_scaleTo, 0,
- "scales each page vertically to fit in scale-to-y pixels"},
-
- {"-x", argInt, &param_x, 0,
- "x-coordinate of the crop area top left corner"},
- {"-y", argInt, &param_y, 0,
- "y-coordinate of the crop area top left corner"},
- {"-W", argInt, &param_w, 0,
- "width of crop area in pixels (default is 0)"},
- {"-H", argInt, &param_h, 0,
- "height of crop area in pixels (default is 0)"},
- {"-sz", argInt, &sz, 0,
- "size of crop square in pixels (sets W and H)"},
- {"-cropbox",argFlag, &useCropBox, 0,
- "use the crop box rather than media box"},
- {"-hide-annotations", argFlag, &hideAnnotations, 0,
- "do not show annotations"},
-
- {"-mono", argFlag, &mono, 0,
- "generate a monochrome PBM file"},
- {"-gray", argFlag, &gray, 0,
- "generate a grayscale PGM file"},
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to print" },
+ { "-l", argInt, &lastPage, 0, "last page to print" },
+ { "-o", argFlag, &printOnlyOdd, 0, "print only odd pages" },
+ { "-e", argFlag, &printOnlyEven, 0, "print only even pages" },
+ { "-singlefile", argFlag, &singleFile, 0, "write only the first page and do not add digits" },
+ { "-scale-dimension-before-rotation", argFlag, &scaleDimensionBeforeRotation, 0, "for rotated pdf, resize dimensions before the rotation" },
+
+ { "-r", argFP, &resolution, 0, "resolution, in DPI (default is 150)" },
+ { "-rx", argFP, &x_resolution, 0, "X resolution, in DPI (default is 150)" },
+ { "-ry", argFP, &y_resolution, 0, "Y resolution, in DPI (default is 150)" },
+ { "-scale-to", argInt, &scaleTo, 0, "scales each page to fit within scale-to*scale-to pixel box" },
+ { "-scale-to-x", argInt, &x_scaleTo, 0, "scales each page horizontally to fit in scale-to-x pixels" },
+ { "-scale-to-y", argInt, &y_scaleTo, 0, "scales each page vertically to fit in scale-to-y pixels" },
+
+ { "-x", argInt, &param_x, 0, "x-coordinate of the crop area top left corner" },
+ { "-y", argInt, &param_y, 0, "y-coordinate of the crop area top left corner" },
+ { "-W", argInt, &param_w, 0, "width of crop area in pixels (default is 0)" },
+ { "-H", argInt, &param_h, 0, "height of crop area in pixels (default is 0)" },
+ { "-sz", argInt, &sz, 0, "size of crop square in pixels (sets W and H)" },
+ { "-cropbox", argFlag, &useCropBox, 0, "use the crop box rather than media box" },
+ { "-hide-annotations", argFlag, &hideAnnotations, 0, "do not show annotations" },
+
+ { "-mono", argFlag, &mono, 0, "generate a monochrome PBM file" },
+ { "-gray", argFlag, &gray, 0, "generate a grayscale PGM file" },
#ifdef USE_CMS
- {"-displayprofile", argGooString, &displayprofilename, 0,
- "ICC color profile to use as the display profile"},
+ { "-displayprofile", argGooString, &displayprofilename, 0, "ICC color profile to use as the display profile" },
#endif
- {"-sep", argString, sep, sizeof(sep),
- "single character separator between name and page number, default - "},
- {"-forcenum", argFlag, &forceNum, 0,
- "force page number even if there is only one page "},
+ { "-sep", argString, sep, sizeof(sep), "single character separator between name and page number, default - " },
+ { "-forcenum", argFlag, &forceNum, 0, "force page number even if there is only one page " },
#ifdef ENABLE_LIBPNG
- {"-png", argFlag, &png, 0,
- "generate a PNG file"},
+ { "-png", argFlag, &png, 0, "generate a PNG file" },
#endif
#ifdef ENABLE_LIBJPEG
- {"-jpeg", argFlag, &jpeg, 0,
- "generate a JPEG file"},
- {"-jpegcmyk",argFlag, &jpegcmyk, 0,
- "generate a CMYK JPEG file"},
- {"-jpegopt", argGooString, &jpegOpt, 0,
- "jpeg options, with format <opt1>=<val1>[,<optN>=<valN>]*"},
+ { "-jpeg", argFlag, &jpeg, 0, "generate a JPEG file" },
+ { "-jpegcmyk", argFlag, &jpegcmyk, 0, "generate a CMYK JPEG file" },
+ { "-jpegopt", argGooString, &jpegOpt, 0, "jpeg options, with format <opt1>=<val1>[,<optN>=<valN>]*" },
#endif
- {"-overprint",argFlag, &overprint, 0,
- "enable overprint"},
+ { "-overprint", argFlag, &overprint, 0, "enable overprint" },
#ifdef ENABLE_LIBTIFF
- {"-tiff", argFlag, &tiff, 0,
- "generate a TIFF file"},
- {"-tiffcompression", argString, TiffCompressionStr, sizeof(TiffCompressionStr),
- "set TIFF compression: none, packbits, jpeg, lzw, deflate"},
+ { "-tiff", argFlag, &tiff, 0, "generate a TIFF file" },
+ { "-tiffcompression", argString, TiffCompressionStr, sizeof(TiffCompressionStr), "set TIFF compression: none, packbits, jpeg, lzw, deflate" },
#endif
- {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
- "enable FreeType font rasterizer: yes, no"},
- {"-thinlinemode", argString, thinLineModeStr, sizeof(thinLineModeStr),
- "set thin line mode: none, solid, shape. Default: none"},
-
- {"-aa", argString, antialiasStr, sizeof(antialiasStr),
- "enable font anti-aliasing: yes, no"},
- {"-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr),
- "enable vector anti-aliasing: yes, no"},
-
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
-
+ { "-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr), "enable FreeType font rasterizer: yes, no" },
+ { "-thinlinemode", argString, thinLineModeStr, sizeof(thinLineModeStr), "set thin line mode: none, solid, shape. Default: none" },
+
+ { "-aa", argString, antialiasStr, sizeof(antialiasStr), "enable font anti-aliasing: yes, no" },
+ { "-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr), "enable vector anti-aliasing: yes, no" },
+
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+
#ifdef UTILS_USE_PTHREADS
- {"-j", argInt, &numberOfJobs, 0,
- "number of jobs to run concurrently"},
+ { "-j", argInt, &numberOfJobs, 0, "number of jobs to run concurrently" },
#endif // UTILS_USE_PTHREADS
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
+ { "-q", argFlag, &quiet, 0, "don't print any messages or errors" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
static bool needToRotate(int angle)
{
@@ -246,493 +200,467 @@ static bool needToRotate(int angle)
static bool parseJpegOptions()
{
- //jpegOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
- const char *nextOpt = jpegOpt.c_str();
- while (nextOpt && *nextOpt)
- {
- const char *comma = strchr(nextOpt, ',');
- GooString opt;
- if (comma) {
- opt.Set(nextOpt, comma - nextOpt);
- nextOpt = comma + 1;
- } else {
- opt.Set(nextOpt);
- nextOpt = nullptr;
+ // jpegOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
+ const char *nextOpt = jpegOpt.c_str();
+ while (nextOpt && *nextOpt) {
+ const char *comma = strchr(nextOpt, ',');
+ GooString opt;
+ if (comma) {
+ opt.Set(nextOpt, comma - nextOpt);
+ nextOpt = comma + 1;
+ } else {
+ opt.Set(nextOpt);
+ nextOpt = nullptr;
+ }
+ // here opt is "<optN>=<valN> "
+ const char *equal = strchr(opt.c_str(), '=');
+ if (!equal) {
+ fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
+ return false;
+ }
+ int iequal = equal - opt.c_str();
+ GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
+ opt.del(iequal, opt.getLength() - iequal);
+ // here opt is "<optN>" and value is "<valN>"
+
+ if (opt.cmp("quality") == 0) {
+ if (!isInt(value.c_str())) {
+ fprintf(stderr, "Invalid jpeg quality\n");
+ return false;
+ }
+ jpegQuality = atoi(value.c_str());
+ if (jpegQuality < 0 || jpegQuality > 100) {
+ fprintf(stderr, "jpeg quality must be between 0 and 100\n");
+ return false;
+ }
+ } else if (opt.cmp("progressive") == 0) {
+ jpegProgressive = false;
+ if (value.cmp("y") == 0) {
+ jpegProgressive = true;
+ } else if (value.cmp("n") != 0) {
+ fprintf(stderr, "jpeg progressive option must be \"y\" or \"n\"\n");
+ return false;
+ }
+ } else if (opt.cmp("optimize") == 0 || opt.cmp("optimise") == 0) {
+ jpegOptimize = false;
+ if (value.cmp("y") == 0) {
+ jpegOptimize = true;
+ } else if (value.cmp("n") != 0) {
+ fprintf(stderr, "jpeg optimize option must be \"y\" or \"n\"\n");
+ return false;
+ }
+ } else {
+ fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
+ return false;
+ }
}
- //here opt is "<optN>=<valN> "
- const char *equal = strchr(opt.c_str(), '=');
- if (!equal) {
- fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
- return false;
- }
- int iequal = equal - opt.c_str();
- GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
- opt.del(iequal, opt.getLength() - iequal);
- //here opt is "<optN>" and value is "<valN>"
-
- if (opt.cmp("quality") == 0) {
- if (!isInt(value.c_str())) {
- fprintf(stderr, "Invalid jpeg quality\n");
- return false;
- }
- jpegQuality = atoi(value.c_str());
- if (jpegQuality < 0 || jpegQuality > 100) {
- fprintf(stderr, "jpeg quality must be between 0 and 100\n");
- return false;
- }
- } else if (opt.cmp("progressive") == 0) {
- jpegProgressive = false;
- if (value.cmp("y") == 0) {
- jpegProgressive = true;
- } else if (value.cmp("n") != 0) {
- fprintf(stderr, "jpeg progressive option must be \"y\" or \"n\"\n");
- return false;
- }
- } else if (opt.cmp("optimize") == 0 || opt.cmp("optimise") == 0) {
- jpegOptimize = false;
- if (value.cmp("y") == 0) {
- jpegOptimize = true;
- } else if (value.cmp("n") != 0) {
- fprintf(stderr, "jpeg optimize option must be \"y\" or \"n\"\n");
- return false;
- }
- } else {
- fprintf(stderr, "Unknown jpeg option \"%s\"\n", opt.c_str());
- return false;
- }
- }
- return true;
+ return true;
}
-static auto annotDisplayDecideCbk = [](Annot *annot, void *user_data) {
- return !hideAnnotations;
-};
+static auto annotDisplayDecideCbk = [](Annot *annot, void *user_data) { return !hideAnnotations; };
-static void savePageSlice(PDFDoc *doc,
- SplashOutputDev *splashOut,
- int pg, int x, int y, int w, int h,
- double pg_w, double pg_h,
- char *ppmFile) {
- if (w == 0) w = (int)ceil(pg_w);
- if (h == 0) h = (int)ceil(pg_h);
- w = (x+w > pg_w ? (int)ceil(pg_w-x) : w);
- h = (y+h > pg_h ? (int)ceil(pg_h-y) : h);
- doc->displayPageSlice(splashOut,
- pg, x_resolution, y_resolution,
- 0,
- !useCropBox, false, false,
- x, y, w, h,
- nullptr, nullptr, annotDisplayDecideCbk, nullptr
- );
-
- SplashBitmap *bitmap = splashOut->getBitmap();
-
- SplashBitmap::WriteImgParams params;
- params.jpegQuality = jpegQuality;
- params.jpegProgressive = jpegProgressive;
- params.jpegOptimize = jpegOptimize;
- params.tiffCompression.Set(TiffCompressionStr);
-
- if (ppmFile != nullptr) {
- if (png) {
- bitmap->writeImgFile(splashFormatPng, ppmFile, x_resolution, y_resolution);
- } else if (jpeg) {
- bitmap->writeImgFile(splashFormatJpeg, ppmFile, x_resolution, y_resolution, &params);
- } else if (jpegcmyk) {
- bitmap->writeImgFile(splashFormatJpegCMYK, ppmFile, x_resolution, y_resolution, &params);
- } else if (tiff) {
- bitmap->writeImgFile(splashFormatTiff, ppmFile, x_resolution, y_resolution, &params);
+static void savePageSlice(PDFDoc *doc, SplashOutputDev *splashOut, int pg, int x, int y, int w, int h, double pg_w, double pg_h, char *ppmFile)
+{
+ if (w == 0)
+ w = (int)ceil(pg_w);
+ if (h == 0)
+ h = (int)ceil(pg_h);
+ w = (x + w > pg_w ? (int)ceil(pg_w - x) : w);
+ h = (y + h > pg_h ? (int)ceil(pg_h - y) : h);
+ doc->displayPageSlice(splashOut, pg, x_resolution, y_resolution, 0, !useCropBox, false, false, x, y, w, h, nullptr, nullptr, annotDisplayDecideCbk, nullptr);
+
+ SplashBitmap *bitmap = splashOut->getBitmap();
+
+ SplashBitmap::WriteImgParams params;
+ params.jpegQuality = jpegQuality;
+ params.jpegProgressive = jpegProgressive;
+ params.jpegOptimize = jpegOptimize;
+ params.tiffCompression.Set(TiffCompressionStr);
+
+ if (ppmFile != nullptr) {
+ if (png) {
+ bitmap->writeImgFile(splashFormatPng, ppmFile, x_resolution, y_resolution);
+ } else if (jpeg) {
+ bitmap->writeImgFile(splashFormatJpeg, ppmFile, x_resolution, y_resolution, &params);
+ } else if (jpegcmyk) {
+ bitmap->writeImgFile(splashFormatJpegCMYK, ppmFile, x_resolution, y_resolution, &params);
+ } else if (tiff) {
+ bitmap->writeImgFile(splashFormatTiff, ppmFile, x_resolution, y_resolution, &params);
+ } else {
+ bitmap->writePNMFile(ppmFile);
+ }
} else {
- bitmap->writePNMFile(ppmFile);
- }
- } else {
#ifdef _WIN32
- setmode(fileno(stdout), O_BINARY);
+ setmode(fileno(stdout), O_BINARY);
#endif
- if (png) {
- bitmap->writeImgFile(splashFormatPng, stdout, x_resolution, y_resolution);
- } else if (jpeg) {
- bitmap->writeImgFile(splashFormatJpeg, stdout, x_resolution, y_resolution, &params);
- } else if (tiff) {
- bitmap->writeImgFile(splashFormatTiff, stdout, x_resolution, y_resolution, &params);
- } else {
- bitmap->writePNMFile(stdout);
+ if (png) {
+ bitmap->writeImgFile(splashFormatPng, stdout, x_resolution, y_resolution);
+ } else if (jpeg) {
+ bitmap->writeImgFile(splashFormatJpeg, stdout, x_resolution, y_resolution, &params);
+ } else if (tiff) {
+ bitmap->writeImgFile(splashFormatTiff, stdout, x_resolution, y_resolution, &params);
+ } else {
+ bitmap->writePNMFile(stdout);
+ }
}
- }
}
#ifdef UTILS_USE_PTHREADS
-struct PageJob {
- PDFDoc *doc;
- int pg;
-
- double pg_w, pg_h;
- SplashColor* paperColor;
-
- char *ppmFile;
+struct PageJob
+{
+ PDFDoc *doc;
+ int pg;
+
+ double pg_w, pg_h;
+ SplashColor *paperColor;
+
+ char *ppmFile;
};
static std::deque<PageJob> pageJobQueue;
static pthread_mutex_t pageJobMutex = PTHREAD_MUTEX_INITIALIZER;
-static void processPageJobs() {
- while(true) {
- // pop the next job or exit if queue is empty
- pthread_mutex_lock(&pageJobMutex);
-
- if(pageJobQueue.empty()) {
- pthread_mutex_unlock(&pageJobMutex);
- return;
+static void processPageJobs()
+{
+ while (true) {
+ // pop the next job or exit if queue is empty
+ pthread_mutex_lock(&pageJobMutex);
+
+ if (pageJobQueue.empty()) {
+ pthread_mutex_unlock(&pageJobMutex);
+ return;
+ }
+
+ PageJob pageJob = pageJobQueue.front();
+ pageJobQueue.pop_front();
+
+ pthread_mutex_unlock(&pageJobMutex);
+
+ // process the job
+ SplashOutputDev *splashOut = new SplashOutputDev(mono ? splashModeMono1 : gray ? splashModeMono8 : (jpegcmyk || overprint) ? splashModeDeviceN8 : splashModeRGB8, 4, false, *pageJob.paperColor, true, thinLineMode);
+ splashOut->setFontAntialias(fontAntialias);
+ splashOut->setVectorAntialias(vectorAntialias);
+ splashOut->setEnableFreeType(enableFreeType);
+# ifdef USE_CMS
+ splashOut->setDisplayProfile(displayprofile);
+# endif
+ splashOut->startDoc(pageJob.doc);
+
+ savePageSlice(pageJob.doc, splashOut, pageJob.pg, x, y, w, h, pageJob.pg_w, pageJob.pg_h, pageJob.ppmFile);
+
+ delete splashOut;
+ delete[] pageJob.ppmFile;
}
-
- PageJob pageJob = pageJobQueue.front();
- pageJobQueue.pop_front();
-
- pthread_mutex_unlock(&pageJobMutex);
-
- // process the job
- SplashOutputDev *splashOut = new SplashOutputDev(mono ? splashModeMono1 :
- gray ? splashModeMono8 :
- (jpegcmyk || overprint) ? splashModeDeviceN8 :
- splashModeRGB8, 4, false, *pageJob.paperColor, true, thinLineMode);
- splashOut->setFontAntialias(fontAntialias);
- splashOut->setVectorAntialias(vectorAntialias);
- splashOut->setEnableFreeType(enableFreeType);
-#ifdef USE_CMS
- splashOut->setDisplayProfile(displayprofile);
-#endif
- splashOut->startDoc(pageJob.doc);
-
- savePageSlice(pageJob.doc, splashOut, pageJob.pg, x, y, w, h, pageJob.pg_w, pageJob.pg_h, pageJob.ppmFile);
-
- delete splashOut;
- delete[] pageJob.ppmFile;
- }
}
#endif // UTILS_USE_PTHREADS
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName = nullptr;
- char *ppmRoot = nullptr;
- char *ppmFile;
- GooString *ownerPW, *userPW;
- SplashColor paperColor;
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName = nullptr;
+ char *ppmRoot = nullptr;
+ char *ppmFile;
+ GooString *ownerPW, *userPW;
+ SplashColor paperColor;
#ifndef UTILS_USE_PTHREADS
- SplashOutputDev *splashOut;
+ SplashOutputDev *splashOut;
#else
- pthread_t* jobs;
+ pthread_t *jobs;
#endif // UTILS_USE_PTHREADS
- bool ok;
- int exitCode;
- int pg, pg_num_len;
- double pg_w, pg_h;
+ bool ok;
+ int exitCode;
+ int pg, pg_num_len;
+ double pg_w, pg_h;
#ifdef USE_CMS
- cmsColorSpaceSignature displayprofilecolorspace;
+ cmsColorSpaceSignature displayprofilecolorspace;
#endif
- Win32Console win32Console(&argc, &argv);
- exitCode = 99;
-
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (mono && gray) {
- ok = false;
- }
- if ( resolution != 0.0 &&
- (x_resolution == 150.0 ||
- y_resolution == 150.0)) {
- x_resolution = resolution;
- y_resolution = resolution;
- }
- if (!ok || argc > 3 || printVersion || printHelp) {
- fprintf(stderr, "pdftoppm version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdftoppm", "[PDF-file [PPM-file-prefix]]", argDesc);
+ Win32Console win32Console(&argc, &argv);
+ exitCode = 99;
+
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (mono && gray) {
+ ok = false;
}
- if (printVersion || printHelp)
- exitCode = 0;
- goto err0;
- }
- if (argc > 1) fileName = new GooString(argv[1]);
- if (argc == 3) ppmRoot = argv[2];
-
- if (antialiasStr[0]) {
- if (!GlobalParams::parseYesNo2(antialiasStr, &fontAntialias)) {
- fprintf(stderr, "Bad '-aa' value on command line\n");
+ if (resolution != 0.0 && (x_resolution == 150.0 || y_resolution == 150.0)) {
+ x_resolution = resolution;
+ y_resolution = resolution;
}
- }
- if (vectorAntialiasStr[0]) {
- if (!GlobalParams::parseYesNo2(vectorAntialiasStr, &vectorAntialias)) {
- fprintf(stderr, "Bad '-aaVector' value on command line\n");
+ if (!ok || argc > 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdftoppm version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdftoppm", "[PDF-file [PPM-file-prefix]]", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ goto err0;
}
- }
-
- if (jpegOpt.getLength() > 0) {
- if (!jpeg)
- fprintf(stderr, "Warning: -jpegopt only valid with jpeg output.\n");
- parseJpegOptions();
- }
-
- // read config file
- globalParams = std::make_unique<GlobalParams>();
- if (enableFreeTypeStr[0]) {
- if (!GlobalParams::parseYesNo2(enableFreeTypeStr, &enableFreeType)) {
- fprintf(stderr, "Bad '-freetype' value on command line\n");
+ if (argc > 1)
+ fileName = new GooString(argv[1]);
+ if (argc == 3)
+ ppmRoot = argv[2];
+
+ if (antialiasStr[0]) {
+ if (!GlobalParams::parseYesNo2(antialiasStr, &fontAntialias)) {
+ fprintf(stderr, "Bad '-aa' value on command line\n");
+ }
}
- }
- if (thinLineModeStr[0]) {
- if (strcmp(thinLineModeStr, "solid") == 0) {
- thinLineMode = splashThinLineSolid;
- } else if (strcmp(thinLineModeStr, "shape") == 0) {
- thinLineMode = splashThinLineShape;
- } else if (strcmp(thinLineModeStr, "none") != 0) {
- fprintf(stderr, "Bad '-thinlinemode' value on command line\n");
+ if (vectorAntialiasStr[0]) {
+ if (!GlobalParams::parseYesNo2(vectorAntialiasStr, &vectorAntialias)) {
+ fprintf(stderr, "Bad '-aaVector' value on command line\n");
+ }
}
- }
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
-
- // open PDF file
- if (ownerPassword[0]) {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0]) {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
-
- if (fileName == nullptr) {
- fileName = new GooString("fd://0");
- }
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- delete fileName;
-
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err1;
- }
-
- // get page range
- if (firstPage < 1)
- firstPage = 1;
- if (singleFile && lastPage < 1)
- lastPage = firstPage;
- if (lastPage < 1 || lastPage > doc->getNumPages())
- lastPage = doc->getNumPages();
- if (lastPage < firstPage) {
- fprintf(stderr,
- "Wrong page range given: the first page (%d) can not be after the last page (%d).\n",
- firstPage, lastPage);
- goto err1;
- }
-
- // If our page range selection and document size indicate we're only
- // outputting a single page, ensure that even/odd page selection doesn't
- // filter out that single page.
- if (firstPage == lastPage &&
- ((printOnlyEven && firstPage % 2 == 1) ||
- (printOnlyOdd && firstPage % 2 == 0))) {
- fprintf(stderr, "Invalid even/odd page selection, no pages match criteria.\n");
- goto err1;
- }
-
-
- if (singleFile && firstPage < lastPage) {
- if (!quiet) {
- fprintf(stderr,
- "Warning: Single file will write only the first of the %d pages.\n",
- lastPage + 1 - firstPage);
+
+ if (jpegOpt.getLength() > 0) {
+ if (!jpeg)
+ fprintf(stderr, "Warning: -jpegopt only valid with jpeg output.\n");
+ parseJpegOptions();
}
- lastPage = firstPage;
- }
-
- // write PPM files
- if (jpegcmyk || overprint) {
- globalParams->setOverprintPreview(true);
- splashClearColor(paperColor);
- } else {
- paperColor[0] = 255;
- paperColor[1] = 255;
- paperColor[2] = 255;
- }
-#ifdef USE_CMS
- if (!displayprofilename.toStr().empty()) {
- displayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(displayprofilename.c_str(),"r"));
- if (!displayprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", displayprofilename.c_str());
- goto err1;
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
+ if (enableFreeTypeStr[0]) {
+ if (!GlobalParams::parseYesNo2(enableFreeTypeStr, &enableFreeType)) {
+ fprintf(stderr, "Bad '-freetype' value on command line\n");
+ }
}
- if(!cmsIsIntentSupported(displayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT) &&
- !cmsIsIntentSupported(displayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_OUTPUT) &&
- !cmsIsIntentSupported(displayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_OUTPUT) &&
- !cmsIsIntentSupported(displayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an output profile.\n", displayprofilename.c_str());
- goto err1;
+ if (thinLineModeStr[0]) {
+ if (strcmp(thinLineModeStr, "solid") == 0) {
+ thinLineMode = splashThinLineSolid;
+ } else if (strcmp(thinLineModeStr, "shape") == 0) {
+ thinLineMode = splashThinLineShape;
+ } else if (strcmp(thinLineModeStr, "none") != 0) {
+ fprintf(stderr, "Bad '-thinlinemode' value on command line\n");
+ }
}
- displayprofilecolorspace = cmsGetColorSpace(displayprofile.get());
- if (jpegcmyk || overprint) {
- if (displayprofilecolorspace != cmsSigCmykData) {
- fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a CMYK profile.\n",
- displayprofilename.c_str());
- }
- } else if (mono || gray) {
- if (displayprofilecolorspace != cmsSigGrayData) {
- fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a monochrome profile.\n",
- displayprofilename.c_str());
- }
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
+ }
+
+ // open PDF file
+ if (ownerPassword[0]) {
+ ownerPW = new GooString(ownerPassword);
} else {
- if (displayprofilecolorspace != cmsSigRgbData) {
- fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a RGB profile.\n",
- displayprofilename.c_str());
- }
+ ownerPW = nullptr;
+ }
+ if (userPassword[0]) {
+ userPW = new GooString(userPassword);
+ } else {
+ userPW = nullptr;
}
- }
-#endif
-
-#ifndef UTILS_USE_PTHREADS
- splashOut = new SplashOutputDev(mono ? splashModeMono1 :
- gray ? splashModeMono8 :
- (jpegcmyk || overprint) ? splashModeDeviceN8 :
- splashModeRGB8, 4,
- false, paperColor, true, thinLineMode);
+ if (fileName == nullptr) {
+ fileName = new GooString("fd://0");
+ }
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
+ }
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+ delete fileName;
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err1;
+ }
+ // get page range
+ if (firstPage < 1)
+ firstPage = 1;
+ if (singleFile && lastPage < 1)
+ lastPage = firstPage;
+ if (lastPage < 1 || lastPage > doc->getNumPages())
+ lastPage = doc->getNumPages();
+ if (lastPage < firstPage) {
+ fprintf(stderr, "Wrong page range given: the first page (%d) can not be after the last page (%d).\n", firstPage, lastPage);
+ goto err1;
+ }
- splashOut->setFontAntialias(fontAntialias);
- splashOut->setVectorAntialias(vectorAntialias);
- splashOut->setEnableFreeType(enableFreeType);
-#ifdef USE_CMS
- splashOut->setDisplayProfile(displayprofile);
-#endif
- splashOut->startDoc(doc);
-
-#endif // UTILS_USE_PTHREADS
-
- if (sz != 0) param_w = param_h = sz;
- pg_num_len = numberOfCharacters(doc->getNumPages());
- for (pg = firstPage; pg <= lastPage; ++pg) {
- if (printOnlyEven && pg % 2 == 1) continue;
- if (printOnlyOdd && pg % 2 == 0) continue;
- if (useCropBox) {
- pg_w = doc->getPageCropWidth(pg);
- pg_h = doc->getPageCropHeight(pg);
- } else {
- pg_w = doc->getPageMediaWidth(pg);
- pg_h = doc->getPageMediaHeight(pg);
+ // If our page range selection and document size indicate we're only
+ // outputting a single page, ensure that even/odd page selection doesn't
+ // filter out that single page.
+ if (firstPage == lastPage && ((printOnlyEven && firstPage % 2 == 1) || (printOnlyOdd && firstPage % 2 == 0))) {
+ fprintf(stderr, "Invalid even/odd page selection, no pages match criteria.\n");
+ goto err1;
}
- if (scaleDimensionBeforeRotation && needToRotate(doc->getPageRotate(pg)))
- std::swap(pg_w, pg_h);
+ if (singleFile && firstPage < lastPage) {
+ if (!quiet) {
+ fprintf(stderr, "Warning: Single file will write only the first of the %d pages.\n", lastPage + 1 - firstPage);
+ }
+ lastPage = firstPage;
+ }
- if (scaleTo != 0) {
- resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h);
- x_resolution = y_resolution = resolution;
+ // write PPM files
+ if (jpegcmyk || overprint) {
+ globalParams->setOverprintPreview(true);
+ splashClearColor(paperColor);
} else {
- if (x_scaleTo > 0) {
- x_resolution = (72.0 * x_scaleTo) / pg_w;
- if (y_scaleTo == -1)
- y_resolution = x_resolution;
- }
- if (y_scaleTo > 0) {
- y_resolution = (72.0 * y_scaleTo) / pg_h;
- if (x_scaleTo == -1)
- x_resolution = y_resolution;
- }
+ paperColor[0] = 255;
+ paperColor[1] = 255;
+ paperColor[2] = 255;
}
- pg_w = pg_w * (x_resolution / 72.0);
- pg_h = pg_h * (y_resolution / 72.0);
-
- if (!scaleDimensionBeforeRotation && needToRotate(doc->getPageRotate(pg)))
- std::swap(pg_w, pg_h);
-
- if (ppmRoot != nullptr) {
- const char *ext = png ? "png" : (jpeg || jpegcmyk) ? "jpg" : tiff ? "tif" : mono ? "pbm" : gray ? "pgm" : "ppm";
- if (singleFile && !forceNum ) {
- ppmFile = new char[strlen(ppmRoot) + 1 + strlen(ext) + 1];
- sprintf(ppmFile, "%s.%s", ppmRoot, ext);
- } else {
- ppmFile = new char[strlen(ppmRoot) + 1 + pg_num_len + 1 + strlen(ext) + 1];
- sprintf(ppmFile, "%s%s%0*d.%s", ppmRoot, sep, pg_num_len, pg, ext);
- }
- } else {
- ppmFile = nullptr;
+
+#ifdef USE_CMS
+ if (!displayprofilename.toStr().empty()) {
+ displayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(displayprofilename.c_str(), "r"));
+ if (!displayprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", displayprofilename.c_str());
+ goto err1;
+ }
+ if (!cmsIsIntentSupported(displayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_OUTPUT) && !cmsIsIntentSupported(displayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_OUTPUT)
+ && !cmsIsIntentSupported(displayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_OUTPUT) && !cmsIsIntentSupported(displayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an output profile.\n", displayprofilename.c_str());
+ goto err1;
+ }
+ displayprofilecolorspace = cmsGetColorSpace(displayprofile.get());
+ if (jpegcmyk || overprint) {
+ if (displayprofilecolorspace != cmsSigCmykData) {
+ fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a CMYK profile.\n", displayprofilename.c_str());
+ }
+ } else if (mono || gray) {
+ if (displayprofilecolorspace != cmsSigGrayData) {
+ fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a monochrome profile.\n", displayprofilename.c_str());
+ }
+ } else {
+ if (displayprofilecolorspace != cmsSigRgbData) {
+ fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a RGB profile.\n", displayprofilename.c_str());
+ }
+ }
}
+#endif
+
+#ifndef UTILS_USE_PTHREADS
+
+ splashOut = new SplashOutputDev(mono ? splashModeMono1 : gray ? splashModeMono8 : (jpegcmyk || overprint) ? splashModeDeviceN8 : splashModeRGB8, 4, false, paperColor, true, thinLineMode);
+
+ splashOut->setFontAntialias(fontAntialias);
+ splashOut->setVectorAntialias(vectorAntialias);
+ splashOut->setEnableFreeType(enableFreeType);
+# ifdef USE_CMS
+ splashOut->setDisplayProfile(displayprofile);
+# endif
+ splashOut->startDoc(doc);
+
+#endif // UTILS_USE_PTHREADS
+
+ if (sz != 0)
+ param_w = param_h = sz;
+ pg_num_len = numberOfCharacters(doc->getNumPages());
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (printOnlyEven && pg % 2 == 1)
+ continue;
+ if (printOnlyOdd && pg % 2 == 0)
+ continue;
+ if (useCropBox) {
+ pg_w = doc->getPageCropWidth(pg);
+ pg_h = doc->getPageCropHeight(pg);
+ } else {
+ pg_w = doc->getPageMediaWidth(pg);
+ pg_h = doc->getPageMediaHeight(pg);
+ }
+
+ if (scaleDimensionBeforeRotation && needToRotate(doc->getPageRotate(pg)))
+ std::swap(pg_w, pg_h);
+
+ if (scaleTo != 0) {
+ resolution = (72.0 * scaleTo) / (pg_w > pg_h ? pg_w : pg_h);
+ x_resolution = y_resolution = resolution;
+ } else {
+ if (x_scaleTo > 0) {
+ x_resolution = (72.0 * x_scaleTo) / pg_w;
+ if (y_scaleTo == -1)
+ y_resolution = x_resolution;
+ }
+ if (y_scaleTo > 0) {
+ y_resolution = (72.0 * y_scaleTo) / pg_h;
+ if (x_scaleTo == -1)
+ x_resolution = y_resolution;
+ }
+ }
+ pg_w = pg_w * (x_resolution / 72.0);
+ pg_h = pg_h * (y_resolution / 72.0);
+
+ if (!scaleDimensionBeforeRotation && needToRotate(doc->getPageRotate(pg)))
+ std::swap(pg_w, pg_h);
+
+ if (ppmRoot != nullptr) {
+ const char *ext = png ? "png" : (jpeg || jpegcmyk) ? "jpg" : tiff ? "tif" : mono ? "pbm" : gray ? "pgm" : "ppm";
+ if (singleFile && !forceNum) {
+ ppmFile = new char[strlen(ppmRoot) + 1 + strlen(ext) + 1];
+ sprintf(ppmFile, "%s.%s", ppmRoot, ext);
+ } else {
+ ppmFile = new char[strlen(ppmRoot) + 1 + pg_num_len + 1 + strlen(ext) + 1];
+ sprintf(ppmFile, "%s%s%0*d.%s", ppmRoot, sep, pg_num_len, pg, ext);
+ }
+ } else {
+ ppmFile = nullptr;
+ }
#ifndef UTILS_USE_PTHREADS
- // process job in main thread
- savePageSlice(doc, splashOut, pg, param_x, param_y, param_w, param_h, pg_w, pg_h, ppmFile);
-
- delete[] ppmFile;
+ // process job in main thread
+ savePageSlice(doc, splashOut, pg, param_x, param_y, param_w, param_h, pg_w, pg_h, ppmFile);
+
+ delete[] ppmFile;
#else
-
- // queue job for worker threads
- PageJob pageJob = {
- .doc = doc,
- .pg = pg,
-
- .pg_w = pg_w, .pg_h = pg_h,
-
- .paperColor = &paperColor,
-
- .ppmFile = ppmFile
- };
-
- pageJobQueue.push_back(pageJob);
-
+
+ // queue job for worker threads
+ PageJob pageJob = { .doc = doc,
+ .pg = pg,
+
+ .pg_w = pg_w,
+ .pg_h = pg_h,
+
+ .paperColor = &paperColor,
+
+ .ppmFile = ppmFile };
+
+ pageJobQueue.push_back(pageJob);
+
#endif // UTILS_USE_PTHREADS
- }
+ }
#ifndef UTILS_USE_PTHREADS
- delete splashOut;
+ delete splashOut;
#else
-
- // spawn worker threads and wait on them
- jobs = (pthread_t*)malloc(numberOfJobs * sizeof(pthread_t));
-
- for(int i=0; i < numberOfJobs; ++i) {
- if(pthread_create(&jobs[i], NULL, (void* (*)(void*))processPageJobs, NULL) != 0) {
- fprintf(stderr, "pthread_create() failed with errno: %d\n", errno);
- exit(EXIT_FAILURE);
+
+ // spawn worker threads and wait on them
+ jobs = (pthread_t *)malloc(numberOfJobs * sizeof(pthread_t));
+
+ for (int i = 0; i < numberOfJobs; ++i) {
+ if (pthread_create(&jobs[i], NULL, (void *(*)(void *))processPageJobs, NULL) != 0) {
+ fprintf(stderr, "pthread_create() failed with errno: %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
}
- }
-
- for(int i=0; i < numberOfJobs; ++i) {
- if(pthread_join(jobs[i], NULL) != 0) {
- fprintf(stderr, "pthread_join() failed with errno: %d\n", errno);
- exit(EXIT_FAILURE);
+
+ for (int i = 0; i < numberOfJobs; ++i) {
+ if (pthread_join(jobs[i], NULL) != 0) {
+ fprintf(stderr, "pthread_join() failed with errno: %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
}
- }
- free(jobs);
-
+ free(jobs);
+
#endif // UTILS_USE_PTHREADS
- exitCode = 0;
+ exitCode = 0;
- // clean up
- err1:
- delete doc;
- err0:
+ // clean up
+err1:
+ delete doc;
+err0:
- return exitCode;
+ return exitCode;
}
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index 097b670e..7aa794e1 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -55,28 +55,28 @@
#include "Error.h"
#include "Win32Console.h"
-static bool setPSPaperSize(char *size, int &psPaperWidth, int &psPaperHeight) {
- if (!strcmp(size, "match")) {
- psPaperWidth = psPaperHeight = -1;
- } else if (!strcmp(size, "letter")) {
- psPaperWidth = 612;
- psPaperHeight = 792;
- } else if (!strcmp(size, "legal")) {
- psPaperWidth = 612;
- psPaperHeight = 1008;
- } else if (!strcmp(size, "A4")) {
- psPaperWidth = 595;
- psPaperHeight = 842;
- } else if (!strcmp(size, "A3")) {
- psPaperWidth = 842;
- psPaperHeight = 1190;
- } else {
- return false;
- }
- return true;
+static bool setPSPaperSize(char *size, int &psPaperWidth, int &psPaperHeight)
+{
+ if (!strcmp(size, "match")) {
+ psPaperWidth = psPaperHeight = -1;
+ } else if (!strcmp(size, "letter")) {
+ psPaperWidth = 612;
+ psPaperHeight = 792;
+ } else if (!strcmp(size, "legal")) {
+ psPaperWidth = 612;
+ psPaperHeight = 1008;
+ } else if (!strcmp(size, "A4")) {
+ psPaperWidth = 595;
+ psPaperHeight = 842;
+ } else if (!strcmp(size, "A3")) {
+ psPaperWidth = 842;
+ psPaperHeight = 1190;
+ } else {
+ return false;
+ }
+ return true;
}
-
static int firstPage = 1;
static int lastPage = 0;
static bool level1 = false;
@@ -118,340 +118,281 @@ static bool printVersion = false;
static bool printHelp = false;
static bool overprint = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to print"},
- {"-l", argInt, &lastPage, 0,
- "last page to print"},
- {"-level1", argFlag, &level1, 0,
- "generate Level 1 PostScript"},
- {"-level1sep", argFlag, &level1Sep, 0,
- "generate Level 1 separable PostScript"},
- {"-level2", argFlag, &level2, 0,
- "generate Level 2 PostScript"},
- {"-level2sep", argFlag, &level2Sep, 0,
- "generate Level 2 separable PostScript"},
- {"-level3", argFlag, &level3, 0,
- "generate Level 3 PostScript"},
- {"-level3sep", argFlag, &level3Sep, 0,
- "generate Level 3 separable PostScript"},
- {"-origpagesizes",argFlag, &origPageSizes,0,
- "conserve original page sizes"},
- {"-eps", argFlag, &doEPS, 0,
- "generate Encapsulated PostScript (EPS)"},
- {"-form", argFlag, &doForm, 0,
- "generate a PostScript form"},
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to print" },
+ { "-l", argInt, &lastPage, 0, "last page to print" },
+ { "-level1", argFlag, &level1, 0, "generate Level 1 PostScript" },
+ { "-level1sep", argFlag, &level1Sep, 0, "generate Level 1 separable PostScript" },
+ { "-level2", argFlag, &level2, 0, "generate Level 2 PostScript" },
+ { "-level2sep", argFlag, &level2Sep, 0, "generate Level 2 separable PostScript" },
+ { "-level3", argFlag, &level3, 0, "generate Level 3 PostScript" },
+ { "-level3sep", argFlag, &level3Sep, 0, "generate Level 3 separable PostScript" },
+ { "-origpagesizes", argFlag, &origPageSizes, 0, "conserve original page sizes" },
+ { "-eps", argFlag, &doEPS, 0, "generate Encapsulated PostScript (EPS)" },
+ { "-form", argFlag, &doForm, 0, "generate a PostScript form" },
#ifdef OPI_SUPPORT
- {"-opi", argFlag, &doOPI, 0,
- "generate OPI comments"},
+ { "-opi", argFlag, &doOPI, 0, "generate OPI comments" },
#endif
- {"-r", argInt, &splashResolution, 0,
- "resolution for rasterization, in DPI (default is 300)"},
- {"-binary", argFlag, &psBinary, 0,
- "write binary data in Level 1 PostScript"},
- {"-noembt1", argFlag, &noEmbedT1Fonts, 0,
- "don't embed Type 1 fonts"},
- {"-noembtt", argFlag, &noEmbedTTFonts, 0,
- "don't embed TrueType fonts"},
- {"-noembcidps", argFlag, &noEmbedCIDPSFonts, 0,
- "don't embed CID PostScript fonts"},
- {"-noembcidtt", argFlag, &noEmbedCIDTTFonts, 0,
- "don't embed CID TrueType fonts"},
- {"-passfonts", argFlag, &fontPassthrough,0,
- "don't substitute missing fonts"},
- {"-aaRaster", argString, rasterAntialiasStr, sizeof(rasterAntialiasStr),
- "enable anti-aliasing on rasterization: yes, no"},
- {"-rasterize", argString, forceRasterizeStr, sizeof(forceRasterizeStr),
- "control rasterization: always, never, whenneeded"},
- {"-optimizecolorspace", argFlag, &optimizeColorSpace,0,
- "convert gray RGB images to gray color space"},
- {"-passlevel1customcolor", argFlag, &passLevel1CustomColor, 0,
- "pass custom color in level1sep"},
- {"-preload", argFlag, &preload, 0,
- "preload images and forms"},
- {"-paper", argString, paperSize, sizeof(paperSize),
- "paper size (letter, legal, A4, A3, match)"},
- {"-paperw", argInt, &paperWidth, 0,
- "paper width, in points"},
- {"-paperh", argInt, &paperHeight, 0,
- "paper height, in points"},
- {"-nocrop", argFlag, &noCrop, 0,
- "don't crop pages to CropBox"},
- {"-expand", argFlag, &expand, 0,
- "expand pages smaller than the paper size"},
- {"-noshrink", argFlag, &noShrink, 0,
- "don't shrink pages larger than the paper size"},
- {"-nocenter", argFlag, &noCenter, 0,
- "don't center pages smaller than the paper size"},
- {"-duplex", argFlag, &duplex, 0,
- "enable duplex printing"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-overprint",argFlag, &overprint, 0,
- "enable overprint"},
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
+ { "-r", argInt, &splashResolution, 0, "resolution for rasterization, in DPI (default is 300)" },
+ { "-binary", argFlag, &psBinary, 0, "write binary data in Level 1 PostScript" },
+ { "-noembt1", argFlag, &noEmbedT1Fonts, 0, "don't embed Type 1 fonts" },
+ { "-noembtt", argFlag, &noEmbedTTFonts, 0, "don't embed TrueType fonts" },
+ { "-noembcidps", argFlag, &noEmbedCIDPSFonts, 0, "don't embed CID PostScript fonts" },
+ { "-noembcidtt", argFlag, &noEmbedCIDTTFonts, 0, "don't embed CID TrueType fonts" },
+ { "-passfonts", argFlag, &fontPassthrough, 0, "don't substitute missing fonts" },
+ { "-aaRaster", argString, rasterAntialiasStr, sizeof(rasterAntialiasStr), "enable anti-aliasing on rasterization: yes, no" },
+ { "-rasterize", argString, forceRasterizeStr, sizeof(forceRasterizeStr), "control rasterization: always, never, whenneeded" },
+ { "-optimizecolorspace", argFlag, &optimizeColorSpace, 0, "convert gray RGB images to gray color space" },
+ { "-passlevel1customcolor", argFlag, &passLevel1CustomColor, 0, "pass custom color in level1sep" },
+ { "-preload", argFlag, &preload, 0, "preload images and forms" },
+ { "-paper", argString, paperSize, sizeof(paperSize), "paper size (letter, legal, A4, A3, match)" },
+ { "-paperw", argInt, &paperWidth, 0, "paper width, in points" },
+ { "-paperh", argInt, &paperHeight, 0, "paper height, in points" },
+ { "-nocrop", argFlag, &noCrop, 0, "don't crop pages to CropBox" },
+ { "-expand", argFlag, &expand, 0, "expand pages smaller than the paper size" },
+ { "-noshrink", argFlag, &noShrink, 0, "don't shrink pages larger than the paper size" },
+ { "-nocenter", argFlag, &noCenter, 0, "don't center pages smaller than the paper size" },
+ { "-duplex", argFlag, &duplex, 0, "enable duplex printing" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-overprint", argFlag, &overprint, 0, "enable overprint" },
+ { "-q", argFlag, &quiet, 0, "don't print any messages or errors" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName;
- GooString *psFileName;
- PSLevel level;
- PSOutMode mode;
- GooString *ownerPW, *userPW;
- PSOutputDev *psOut;
- bool ok;
- int exitCode;
- bool rasterAntialias = false;
- std::vector<int> pages;
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName;
+ GooString *psFileName;
+ PSLevel level;
+ PSOutMode mode;
+ GooString *ownerPW, *userPW;
+ PSOutputDev *psOut;
+ bool ok;
+ int exitCode;
+ bool rasterAntialias = false;
+ std::vector<int> pages;
- Win32Console win32Console(&argc, &argv);
- exitCode = 99;
+ Win32Console win32Console(&argc, &argv);
+ exitCode = 99;
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
- fprintf(stderr, "pdftops version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdftops", "<PDF-file> [<PS-file>]", argDesc);
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdftops version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdftops", "<PDF-file> [<PS-file>]", argDesc);
+ }
+ if (printVersion || printHelp)
+ exit(0);
+ else
+ exit(1);
+ }
+ if ((level1 ? 1 : 0) + (level1Sep ? 1 : 0) + (level2 ? 1 : 0) + (level2Sep ? 1 : 0) + (level3 ? 1 : 0) + (level3Sep ? 1 : 0) > 1) {
+ fprintf(stderr, "Error: use only one of the 'level' options.\n");
+ exit(1);
+ }
+ if ((doEPS ? 1 : 0) + (doForm ? 1 : 0) > 1) {
+ fprintf(stderr, "Error: use only one of -eps, and -form\n");
+ exit(1);
}
- if (printVersion || printHelp)
- exit(0);
- else
- exit(1);
- }
- if ((level1 ? 1 : 0) +
- (level1Sep ? 1 : 0) +
- (level2 ? 1 : 0) +
- (level2Sep ? 1 : 0) +
- (level3 ? 1 : 0) +
- (level3Sep ? 1 : 0) > 1) {
- fprintf(stderr, "Error: use only one of the 'level' options.\n");
- exit(1);
- }
- if ((doEPS ? 1 : 0) +
- (doForm ? 1 : 0) > 1) {
- fprintf(stderr, "Error: use only one of -eps, and -form\n");
- exit(1);
- }
- if (level1) {
- level = psLevel1;
- } else if (level1Sep) {
- level = psLevel1Sep;
- } else if (level2Sep) {
- level = psLevel2Sep;
- } else if (level3) {
- level = psLevel3;
- } else if (level3Sep) {
- level = psLevel3Sep;
- } else {
- level = psLevel2;
- }
- if (doForm && level < psLevel2) {
- fprintf(stderr, "Error: forms are only available with Level 2 output.\n");
- exit(1);
- }
- mode = doEPS ? psModeEPS
- : doForm ? psModeForm
- : psModePS;
- fileName = new GooString(argv[1]);
+ if (level1) {
+ level = psLevel1;
+ } else if (level1Sep) {
+ level = psLevel1Sep;
+ } else if (level2Sep) {
+ level = psLevel2Sep;
+ } else if (level3) {
+ level = psLevel3;
+ } else if (level3Sep) {
+ level = psLevel3Sep;
+ } else {
+ level = psLevel2;
+ }
+ if (doForm && level < psLevel2) {
+ fprintf(stderr, "Error: forms are only available with Level 2 output.\n");
+ exit(1);
+ }
+ mode = doEPS ? psModeEPS : doForm ? psModeForm : psModePS;
+ fileName = new GooString(argv[1]);
- // read config file
- globalParams = std::make_unique<GlobalParams>();
- if (origPageSizes) {
- paperWidth = paperHeight = -1;
- }
- if (paperSize[0]) {
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
if (origPageSizes) {
- fprintf(stderr, "Error: -origpagesizes and -paper may not be used together.\n");
- exit(1);
+ paperWidth = paperHeight = -1;
+ }
+ if (paperSize[0]) {
+ if (origPageSizes) {
+ fprintf(stderr, "Error: -origpagesizes and -paper may not be used together.\n");
+ exit(1);
+ }
+ if (!setPSPaperSize(paperSize, paperWidth, paperHeight)) {
+ fprintf(stderr, "Invalid paper size\n");
+ delete fileName;
+ goto err0;
+ }
}
- if (!setPSPaperSize(paperSize, paperWidth, paperHeight)) {
- fprintf(stderr, "Invalid paper size\n");
- delete fileName;
- goto err0;
+ if (overprint) {
+ globalParams->setOverprintPreview(true);
+ }
+ if (expand) {
+ globalParams->setPSExpandSmaller(true);
+ }
+ if (noShrink) {
+ globalParams->setPSShrinkLarger(false);
+ }
+ if (level1 || level1Sep || level2 || level2Sep || level3 || level3Sep) {
+ globalParams->setPSLevel(level);
+ }
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
}
- }
- if (overprint) {
- globalParams->setOverprintPreview(true);
- }
- if (expand) {
- globalParams->setPSExpandSmaller(true);
- }
- if (noShrink) {
- globalParams->setPSShrinkLarger(false);
- }
- if (level1 || level1Sep || level2 || level2Sep || level3 || level3Sep) {
- globalParams->setPSLevel(level);
- }
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0] != '\001') {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = new GooString(ownerPassword);
+ } else {
+ ownerPW = nullptr;
+ }
+ if (userPassword[0] != '\001') {
+ userPW = new GooString(userPassword);
+ } else {
+ userPW = nullptr;
+ }
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
+ }
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err1;
- }
+ if (userPW) {
+ delete userPW;
+ }
+ if (ownerPW) {
+ delete ownerPW;
+ }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err1;
+ }
#ifdef ENFORCE_PERMISSIONS
- // check for print permission
- if (!doc->okToPrint()) {
- error(errNotAllowed, -1, "Printing this document is not allowed.");
- exitCode = 3;
- goto err1;
- }
+ // check for print permission
+ if (!doc->okToPrint()) {
+ error(errNotAllowed, -1, "Printing this document is not allowed.");
+ exitCode = 3;
+ goto err1;
+ }
#endif
- // construct PostScript file name
- if (argc == 3) {
- psFileName = new GooString(argv[2]);
- } else if (fileName->cmp("fd://0") == 0) {
- error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
- goto err1;
- } else {
- const char *p = fileName->c_str() + fileName->getLength() - 4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
- psFileName = new GooString(fileName->c_str(),
- fileName->getLength() - 4);
+ // construct PostScript file name
+ if (argc == 3) {
+ psFileName = new GooString(argv[2]);
+ } else if (fileName->cmp("fd://0") == 0) {
+ error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
+ goto err1;
} else {
- psFileName = fileName->copy();
+ const char *p = fileName->c_str() + fileName->getLength() - 4;
+ if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
+ psFileName = new GooString(fileName->c_str(), fileName->getLength() - 4);
+ } else {
+ psFileName = fileName->copy();
+ }
+ psFileName->append(doEPS ? ".eps" : ".ps");
}
- psFileName->append(doEPS ? ".eps" : ".ps");
- }
- // get page range
- if (firstPage < 1) {
- firstPage = 1;
- }
- if (lastPage < 1 || lastPage > doc->getNumPages()) {
- lastPage = doc->getNumPages();
- }
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- goto err2;
- }
+ // get page range
+ if (firstPage < 1) {
+ firstPage = 1;
+ }
+ if (lastPage < 1 || lastPage > doc->getNumPages()) {
+ lastPage = doc->getNumPages();
+ }
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ goto err2;
+ }
- // check for multi-page EPS or form
- if ((doEPS || doForm) && firstPage != lastPage) {
- error(errCommandLine, -1, "EPS and form files can only contain one page.");
- goto err2;
- }
+ // check for multi-page EPS or form
+ if ((doEPS || doForm) && firstPage != lastPage) {
+ error(errCommandLine, -1, "EPS and form files can only contain one page.");
+ goto err2;
+ }
- for (int i = firstPage; i <= lastPage; ++i) {
- pages.push_back(i);
- }
+ for (int i = firstPage; i <= lastPage; ++i) {
+ pages.push_back(i);
+ }
- // write PostScript file
- psOut = new PSOutputDev(psFileName->c_str(), doc,
- nullptr, pages, mode,
- paperWidth,
- paperHeight,
- noCrop,
- duplex);
- if (noCenter) {
- psOut->setPSCenter(false);
- }
+ // write PostScript file
+ psOut = new PSOutputDev(psFileName->c_str(), doc, nullptr, pages, mode, paperWidth, paperHeight, noCrop, duplex);
+ if (noCenter) {
+ psOut->setPSCenter(false);
+ }
- if (rasterAntialiasStr[0]) {
- if (!GlobalParams::parseYesNo2(rasterAntialiasStr, &rasterAntialias)) {
- fprintf(stderr, "Bad '-aaRaster' value on command line\n");
+ if (rasterAntialiasStr[0]) {
+ if (!GlobalParams::parseYesNo2(rasterAntialiasStr, &rasterAntialias)) {
+ fprintf(stderr, "Bad '-aaRaster' value on command line\n");
+ }
}
- }
- if (forceRasterizeStr[0]) {
- PSForceRasterize forceRasterize = psRasterizeWhenNeeded;
- if (strcmp(forceRasterizeStr, "whenneeded") == 0) {
- forceRasterize = psRasterizeWhenNeeded;
- } else if (strcmp(forceRasterizeStr, "always") == 0) {
- forceRasterize = psAlwaysRasterize;
- } else if (strcmp(forceRasterizeStr, "never") == 0) {
- forceRasterize = psNeverRasterize;
- } else {
- fprintf(stderr, "Bad '-rasterize' value on command line\n");
+ if (forceRasterizeStr[0]) {
+ PSForceRasterize forceRasterize = psRasterizeWhenNeeded;
+ if (strcmp(forceRasterizeStr, "whenneeded") == 0) {
+ forceRasterize = psRasterizeWhenNeeded;
+ } else if (strcmp(forceRasterizeStr, "always") == 0) {
+ forceRasterize = psAlwaysRasterize;
+ } else if (strcmp(forceRasterizeStr, "never") == 0) {
+ forceRasterize = psNeverRasterize;
+ } else {
+ fprintf(stderr, "Bad '-rasterize' value on command line\n");
+ }
+ psOut->setForceRasterize(forceRasterize);
}
- psOut->setForceRasterize(forceRasterize);
- }
- if (splashResolution > 0) {
- psOut->setRasterResolution(splashResolution);
- }
- psOut->setEmbedType1(!noEmbedT1Fonts);
- psOut->setEmbedTrueType(!noEmbedTTFonts);
- psOut->setEmbedCIDPostScript(!noEmbedCIDPSFonts);
- psOut->setEmbedCIDTrueType(!noEmbedCIDTTFonts);
- psOut->setFontPassthrough(fontPassthrough);
- psOut->setPreloadImagesForms(preload);
- psOut->setOptimizeColorSpace(optimizeColorSpace);
- psOut->setPassLevel1CustomColor(passLevel1CustomColor);
+ if (splashResolution > 0) {
+ psOut->setRasterResolution(splashResolution);
+ }
+ psOut->setEmbedType1(!noEmbedT1Fonts);
+ psOut->setEmbedTrueType(!noEmbedTTFonts);
+ psOut->setEmbedCIDPostScript(!noEmbedCIDPSFonts);
+ psOut->setEmbedCIDTrueType(!noEmbedCIDTTFonts);
+ psOut->setFontPassthrough(fontPassthrough);
+ psOut->setPreloadImagesForms(preload);
+ psOut->setOptimizeColorSpace(optimizeColorSpace);
+ psOut->setPassLevel1CustomColor(passLevel1CustomColor);
#ifdef OPI_SUPPORT
- psOut->setGenerateOPI(doOPI);
+ psOut->setGenerateOPI(doOPI);
#endif
- psOut->setUseBinary(psBinary);
+ psOut->setUseBinary(psBinary);
- psOut->setRasterAntialias(rasterAntialias);
- if (psOut->isOk()) {
- for (int i = firstPage; i <= lastPage; ++i) {
- doc->displayPage(psOut, i, 72, 72,
- 0, noCrop, !noCrop, true);
+ psOut->setRasterAntialias(rasterAntialias);
+ if (psOut->isOk()) {
+ for (int i = firstPage; i <= lastPage; ++i) {
+ doc->displayPage(psOut, i, 72, 72, 0, noCrop, !noCrop, true);
+ }
+ } else {
+ delete psOut;
+ exitCode = 2;
+ goto err2;
}
- } else {
delete psOut;
- exitCode = 2;
- goto err2;
- }
- delete psOut;
- exitCode = 0;
+ exitCode = 0;
- // clean up
- err2:
- delete psFileName;
- err1:
- delete doc;
- delete fileName;
- err0:
+ // clean up
+err2:
+ delete psFileName;
+err1:
+ delete doc;
+ delete fileName;
+err0:
- return exitCode;
+ return exitCode;
}
diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc
index e90588a5..f17cfd53 100644
--- a/utils/pdftotext.cc
+++ b/utils/pdftotext.cc
@@ -67,8 +67,7 @@
#include <iomanip>
#include "Win32Console.h"
-static void printInfoString(FILE *f, Dict *infoDict, const char *key,
- const char *text1, const char *text2, const UnicodeMap *uMap);
+static void printInfoString(FILE *f, Dict *infoDict, const char *key, const char *text1, const char *text2, const UnicodeMap *uMap);
static void printInfoDate(FILE *f, Dict *infoDict, const char *key, const char *fmt);
void printDocBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last);
void printWordBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last);
@@ -97,481 +96,446 @@ static bool printVersion = false;
static bool printHelp = false;
static bool printEnc = false;
-static const ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
- "first page to convert"},
- {"-l", argInt, &lastPage, 0,
- "last page to convert"},
- {"-r", argFP, &resolution, 0,
- "resolution, in DPI (default is 72)"},
- {"-x", argInt, &x, 0,
- "x-coordinate of the crop area top left corner"},
- {"-y", argInt, &y, 0,
- "y-coordinate of the crop area top left corner"},
- {"-W", argInt, &w, 0,
- "width of crop area in pixels (default is 0)"},
- {"-H", argInt, &h, 0,
- "height of crop area in pixels (default is 0)"},
- {"-layout", argFlag, &physLayout, 0,
- "maintain original physical layout"},
- {"-fixed", argFP, &fixedPitch, 0,
- "assume fixed-pitch (or tabular) text"},
- {"-raw", argFlag, &rawOrder, 0,
- "keep strings in content stream order"},
- {"-nodiag", argFlag, &discardDiag, 0,
- "discard diagonal text"},
- {"-htmlmeta", argFlag, &htmlMeta, 0,
- "generate a simple HTML file, including the meta information"},
- {"-enc", argString, textEncName, sizeof(textEncName),
- "output text encoding name"},
- {"-listenc",argFlag, &printEnc, 0,
- "list available encodings"},
- {"-eol", argString, textEOLStr, sizeof(textEOLStr),
- "output end-of-line convention (unix, dos, or mac)"},
- {"-nopgbrk", argFlag, &noPageBreaks, 0,
- "don't insert page breaks between pages"},
- {"-bbox", argFlag, &bbox, 0,
- "output bounding box for each word and page size to html. Sets -htmlmeta"},
- {"-bbox-layout", argFlag, &bboxLayout, 0,
- "like -bbox but with extra layout bounding box data. Sets -htmlmeta"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {}
-};
-
-static std::string myStringReplace(const std::string &inString, const std::string &oldToken, const std::string &newToken) {
- std::string result = inString;
- size_t foundLoc;
- int advance = 0;
- do {
- foundLoc = result.find(oldToken, advance);
- if (foundLoc != std::string::npos){
- result.replace(foundLoc, oldToken.length(), newToken);
- advance = foundLoc + newToken.length();
- }
- } while (foundLoc != std::string::npos );
- return result;
+static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to convert" },
+ { "-l", argInt, &lastPage, 0, "last page to convert" },
+ { "-r", argFP, &resolution, 0, "resolution, in DPI (default is 72)" },
+ { "-x", argInt, &x, 0, "x-coordinate of the crop area top left corner" },
+ { "-y", argInt, &y, 0, "y-coordinate of the crop area top left corner" },
+ { "-W", argInt, &w, 0, "width of crop area in pixels (default is 0)" },
+ { "-H", argInt, &h, 0, "height of crop area in pixels (default is 0)" },
+ { "-layout", argFlag, &physLayout, 0, "maintain original physical layout" },
+ { "-fixed", argFP, &fixedPitch, 0, "assume fixed-pitch (or tabular) text" },
+ { "-raw", argFlag, &rawOrder, 0, "keep strings in content stream order" },
+ { "-nodiag", argFlag, &discardDiag, 0, "discard diagonal text" },
+ { "-htmlmeta", argFlag, &htmlMeta, 0, "generate a simple HTML file, including the meta information" },
+ { "-enc", argString, textEncName, sizeof(textEncName), "output text encoding name" },
+ { "-listenc", argFlag, &printEnc, 0, "list available encodings" },
+ { "-eol", argString, textEOLStr, sizeof(textEOLStr), "output end-of-line convention (unix, dos, or mac)" },
+ { "-nopgbrk", argFlag, &noPageBreaks, 0, "don't insert page breaks between pages" },
+ { "-bbox", argFlag, &bbox, 0, "output bounding box for each word and page size to html. Sets -htmlmeta" },
+ { "-bbox-layout", argFlag, &bboxLayout, 0, "like -bbox but with extra layout bounding box data. Sets -htmlmeta" },
+ { "-opw", argString, ownerPassword, sizeof(ownerPassword), "owner password (for encrypted files)" },
+ { "-upw", argString, userPassword, sizeof(userPassword), "user password (for encrypted files)" },
+ { "-q", argFlag, &quiet, 0, "don't print any messages or errors" },
+ { "-v", argFlag, &printVersion, 0, "print copyright and version info" },
+ { "-h", argFlag, &printHelp, 0, "print usage information" },
+ { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" },
+ { "-?", argFlag, &printHelp, 0, "print usage information" },
+ {} };
+
+static std::string myStringReplace(const std::string &inString, const std::string &oldToken, const std::string &newToken)
+{
+ std::string result = inString;
+ size_t foundLoc;
+ int advance = 0;
+ do {
+ foundLoc = result.find(oldToken, advance);
+ if (foundLoc != std::string::npos) {
+ result.replace(foundLoc, oldToken.length(), newToken);
+ advance = foundLoc + newToken.length();
+ }
+ } while (foundLoc != std::string::npos);
+ return result;
}
-static std::string myXmlTokenReplace(const char *inString){
- std::string myString(inString);
- myString = myStringReplace(myString, "&", "&amp;" );
- myString = myStringReplace(myString, "'", "&apos;" );
- myString = myStringReplace(myString, "\"", "&quot;" );
- myString = myStringReplace(myString, "<", "&lt;" );
- myString = myStringReplace(myString, ">", "&gt;" );
- return myString;
+static std::string myXmlTokenReplace(const char *inString)
+{
+ std::string myString(inString);
+ myString = myStringReplace(myString, "&", "&amp;");
+ myString = myStringReplace(myString, "'", "&apos;");
+ myString = myStringReplace(myString, "\"", "&quot;");
+ myString = myStringReplace(myString, "<", "&lt;");
+ myString = myStringReplace(myString, ">", "&gt;");
+ return myString;
}
-int main(int argc, char *argv[]) {
- PDFDoc *doc;
- GooString *fileName;
- GooString *textFileName;
- GooString *ownerPW, *userPW;
- TextOutputDev *textOut;
- FILE *f;
- const UnicodeMap *uMap;
- Object info;
- bool ok;
- int exitCode;
- EndOfLineKind textEOL = TextOutputDev::defaultEndOfLine();
-
- Win32Console win32Console(&argc, &argv);
- exitCode = 99;
-
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (bboxLayout) {
- bbox = true;
- }
- if (bbox) {
- htmlMeta = true;
- }
- if (!ok || (argc < 2 && !printEnc) || argc > 3 || printVersion || printHelp) {
- fprintf(stderr, "pdftotext version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdftotext", "<PDF-file> [<text-file>]", argDesc);
+int main(int argc, char *argv[])
+{
+ PDFDoc *doc;
+ GooString *fileName;
+ GooString *textFileName;
+ GooString *ownerPW, *userPW;
+ TextOutputDev *textOut;
+ FILE *f;
+ const UnicodeMap *uMap;
+ Object info;
+ bool ok;
+ int exitCode;
+ EndOfLineKind textEOL = TextOutputDev::defaultEndOfLine();
+
+ Win32Console win32Console(&argc, &argv);
+ exitCode = 99;
+
+ // parse args
+ ok = parseArgs(argDesc, &argc, argv);
+ if (bboxLayout) {
+ bbox = true;
+ }
+ if (bbox) {
+ htmlMeta = true;
+ }
+ if (!ok || (argc < 2 && !printEnc) || argc > 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdftotext version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdftotext", "<PDF-file> [<text-file>]", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ goto err0;
}
- if (printVersion || printHelp)
- exitCode = 0;
- goto err0;
- }
- // read config file
- globalParams = std::make_unique<GlobalParams>();
+ // read config file
+ globalParams = std::make_unique<GlobalParams>();
- if (printEnc) {
- printEncodings();
- exitCode = 0;
- goto err0;
- }
-
- fileName = new GooString(argv[1]);
- if (fixedPitch) {
- physLayout = true;
- }
-
- if (textEncName[0]) {
- globalParams->setTextEncoding(textEncName);
- }
- if (textEOLStr[0]) {
- if (!strcmp(textEOLStr, "unix")) {
- textEOL = eolUnix;
- } else if (!strcmp(textEOLStr, "dos")) {
- textEOL = eolDOS;
- } else if (!strcmp(textEOLStr, "mac")) {
- textEOL = eolMac;
- } else {
- fprintf(stderr, "Bad '-eol' value on command line\n");
+ if (printEnc) {
+ printEncodings();
+ exitCode = 0;
+ goto err0;
}
- }
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
-
- // get mapping to output encoding
- if (!(uMap = globalParams->getTextEncoding())) {
- error(errCommandLine, -1, "Couldn't get text encoding");
- delete fileName;
- goto err1;
- }
-
- // open PDF file
- if (ownerPassword[0] != '\001') {
- ownerPW = new GooString(ownerPassword);
- } else {
- ownerPW = nullptr;
- }
- if (userPassword[0] != '\001') {
- userPW = new GooString(userPassword);
- } else {
- userPW = nullptr;
- }
-
- if (fileName->cmp("-") == 0) {
- delete fileName;
- fileName = new GooString("fd://0");
- }
-
- doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
-
- if (userPW) {
- delete userPW;
- }
- if (ownerPW) {
- delete ownerPW;
- }
- if (!doc->isOk()) {
- exitCode = 1;
- goto err2;
- }
-#ifdef ENFORCE_PERMISSIONS
- // check for copy permission
- if (!doc->okToCopy()) {
- error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
- exitCode = 3;
- goto err2;
- }
-#endif
+ fileName = new GooString(argv[1]);
+ if (fixedPitch) {
+ physLayout = true;
+ }
- // construct text file name
- if (argc == 3) {
- textFileName = new GooString(argv[2]);
- } else if (fileName->cmp("fd://0") == 0) {
- error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
- goto err2;
- } else {
- const char *p = fileName->c_str() + fileName->getLength() - 4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
- textFileName = new GooString(fileName->c_str(),
- fileName->getLength() - 4);
+ if (textEncName[0]) {
+ globalParams->setTextEncoding(textEncName);
+ }
+ if (textEOLStr[0]) {
+ if (!strcmp(textEOLStr, "unix")) {
+ textEOL = eolUnix;
+ } else if (!strcmp(textEOLStr, "dos")) {
+ textEOL = eolDOS;
+ } else if (!strcmp(textEOLStr, "mac")) {
+ textEOL = eolMac;
+ } else {
+ fprintf(stderr, "Bad '-eol' value on command line\n");
+ }
+ }
+ if (quiet) {
+ globalParams->setErrQuiet(quiet);
+ }
+
+ // get mapping to output encoding
+ if (!(uMap = globalParams->getTextEncoding())) {
+ error(errCommandLine, -1, "Couldn't get text encoding");
+ delete fileName;
+ goto err1;
+ }
+
+ // open PDF file
+ if (ownerPassword[0] != '\001') {
+ ownerPW = new GooString(ownerPassword);
} else {
- textFileName = fileName->copy();
+ ownerPW = nullptr;
}
- textFileName->append(htmlMeta ? ".html" : ".txt");
- }
-
- // get page range
- if (firstPage < 1) {
- firstPage = 1;
- }
- if (lastPage < 1 || lastPage > doc->getNumPages()) {
- lastPage = doc->getNumPages();
- }
- if (lastPage < firstPage) {
- error(errCommandLine, -1,
- "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
- firstPage, lastPage);
- goto err3;
- }
-
- // write HTML header
- if (htmlMeta) {
- if (!textFileName->cmp("-")) {
- f = stdout;
+ if (userPassword[0] != '\001') {
+ userPW = new GooString(userPassword);
} else {
- if (!(f = fopen(textFileName->c_str(), "wb"))) {
- error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
- exitCode = 2;
- goto err3;
- }
+ userPW = nullptr;
+ }
+
+ if (fileName->cmp("-") == 0) {
+ delete fileName;
+ fileName = new GooString("fd://0");
}
- fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">", f);
- fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n", f);
- fputs("<head>\n", f);
- info = doc->getDocInfo();
- if (info.isDict()) {
- Object obj = info.getDict()->lookup("Title");
- if (obj.isString()) {
- printInfoString(f, info.getDict(), "Title", "<title>", "</title>\n", uMap);
- } else {
- fputs("<title></title>\n", f);
- }
- printInfoString(f, info.getDict(), "Subject",
- "<meta name=\"Subject\" content=\"", "\"/>\n", uMap);
- printInfoString(f, info.getDict(), "Keywords",
- "<meta name=\"Keywords\" content=\"", "\"/>\n", uMap);
- printInfoString(f, info.getDict(), "Author",
- "<meta name=\"Author\" content=\"", "\"/>\n", uMap);
- printInfoString(f, info.getDict(), "Creator",
- "<meta name=\"Creator\" content=\"", "\"/>\n", uMap);
- printInfoString(f, info.getDict(), "Producer",
- "<meta name=\"Producer\" content=\"", "\"/>\n", uMap);
- printInfoDate(f, info.getDict(), "CreationDate",
- "<meta name=\"CreationDate\" content=\"\"/>\n");
- printInfoDate(f, info.getDict(), "LastModifiedDate",
- "<meta name=\"ModDate\" content=\"\"/>\n");
+
+ doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
+
+ if (userPW) {
+ delete userPW;
}
- fputs("</head>\n", f);
- fputs("<body>\n", f);
- if (!bbox) {
- fputs("<pre>\n", f);
- if (f != stdout) {
- fclose(f);
- }
+ if (ownerPW) {
+ delete ownerPW;
}
- }
-
- // write text file
- if (htmlMeta && bbox) { // htmlMeta && is superfluous but makes gcc happier
- textOut = new TextOutputDev(nullptr, physLayout, fixedPitch, rawOrder, htmlMeta, discardDiag);
-
- if (textOut->isOk()) {
- textOut->setTextEOL(textEOL);
- if (noPageBreaks) {
- textOut->setTextPageBreaks(false);
- }
- if (bboxLayout) {
- printDocBBox(f, doc, textOut, firstPage, lastPage);
- }
- else {
- printWordBBox(f, doc, textOut, firstPage, lastPage);
- }
+ if (!doc->isOk()) {
+ exitCode = 1;
+ goto err2;
}
- if (f != stdout) {
- fclose(f);
+
+#ifdef ENFORCE_PERMISSIONS
+ // check for copy permission
+ if (!doc->okToCopy()) {
+ error(errNotAllowed, -1, "Copying of text from this document is not allowed.");
+ exitCode = 3;
+ goto err2;
}
- } else {
- textOut = new TextOutputDev(textFileName->c_str(),
- physLayout, fixedPitch, rawOrder, htmlMeta, discardDiag);
- if (textOut->isOk()) {
- textOut->setTextEOL(textEOL);
- if (noPageBreaks) {
- textOut->setTextPageBreaks(false);
- }
- if ((w==0) && (h==0) && (x==0) && (y==0)) {
- doc->displayPages(textOut, firstPage, lastPage, resolution, resolution, 0,
- true, false, false);
- } else {
-
- for (int page = firstPage; page <= lastPage; ++page) {
- doc->displayPageSlice(textOut, page, resolution, resolution, 0,
- true, false, false,
- x, y, w, h);
- }
- }
+#endif
+ // construct text file name
+ if (argc == 3) {
+ textFileName = new GooString(argv[2]);
+ } else if (fileName->cmp("fd://0") == 0) {
+ error(errCommandLine, -1, "You have to provide an output filename when reading from stdin.");
+ goto err2;
} else {
- delete textOut;
- exitCode = 2;
- goto err3;
+ const char *p = fileName->c_str() + fileName->getLength() - 4;
+ if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
+ textFileName = new GooString(fileName->c_str(), fileName->getLength() - 4);
+ } else {
+ textFileName = fileName->copy();
+ }
+ textFileName->append(htmlMeta ? ".html" : ".txt");
+ }
+
+ // get page range
+ if (firstPage < 1) {
+ firstPage = 1;
+ }
+ if (lastPage < 1 || lastPage > doc->getNumPages()) {
+ lastPage = doc->getNumPages();
+ }
+ if (lastPage < firstPage) {
+ error(errCommandLine, -1, "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).", firstPage, lastPage);
+ goto err3;
+ }
+
+ // write HTML header
+ if (htmlMeta) {
+ if (!textFileName->cmp("-")) {
+ f = stdout;
+ } else {
+ if (!(f = fopen(textFileName->c_str(), "wb"))) {
+ error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
+ exitCode = 2;
+ goto err3;
+ }
+ }
+ fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">", f);
+ fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n", f);
+ fputs("<head>\n", f);
+ info = doc->getDocInfo();
+ if (info.isDict()) {
+ Object obj = info.getDict()->lookup("Title");
+ if (obj.isString()) {
+ printInfoString(f, info.getDict(), "Title", "<title>", "</title>\n", uMap);
+ } else {
+ fputs("<title></title>\n", f);
+ }
+ printInfoString(f, info.getDict(), "Subject", "<meta name=\"Subject\" content=\"", "\"/>\n", uMap);
+ printInfoString(f, info.getDict(), "Keywords", "<meta name=\"Keywords\" content=\"", "\"/>\n", uMap);
+ printInfoString(f, info.getDict(), "Author", "<meta name=\"Author\" content=\"", "\"/>\n", uMap);
+ printInfoString(f, info.getDict(), "Creator", "<meta name=\"Creator\" content=\"", "\"/>\n", uMap);
+ printInfoString(f, info.getDict(), "Producer", "<meta name=\"Producer\" content=\"", "\"/>\n", uMap);
+ printInfoDate(f, info.getDict(), "CreationDate", "<meta name=\"CreationDate\" content=\"\"/>\n");
+ printInfoDate(f, info.getDict(), "LastModifiedDate", "<meta name=\"ModDate\" content=\"\"/>\n");
+ }
+ fputs("</head>\n", f);
+ fputs("<body>\n", f);
+ if (!bbox) {
+ fputs("<pre>\n", f);
+ if (f != stdout) {
+ fclose(f);
+ }
+ }
}
- }
- delete textOut;
- // write end of HTML file
- if (htmlMeta) {
- if (!textFileName->cmp("-")) {
- f = stdout;
+ // write text file
+ if (htmlMeta && bbox) { // htmlMeta && is superfluous but makes gcc happier
+ textOut = new TextOutputDev(nullptr, physLayout, fixedPitch, rawOrder, htmlMeta, discardDiag);
+
+ if (textOut->isOk()) {
+ textOut->setTextEOL(textEOL);
+ if (noPageBreaks) {
+ textOut->setTextPageBreaks(false);
+ }
+ if (bboxLayout) {
+ printDocBBox(f, doc, textOut, firstPage, lastPage);
+ } else {
+ printWordBBox(f, doc, textOut, firstPage, lastPage);
+ }
+ }
+ if (f != stdout) {
+ fclose(f);
+ }
} else {
- if (!(f = fopen(textFileName->c_str(), "ab"))) {
- error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
- exitCode = 2;
- goto err3;
- }
+ textOut = new TextOutputDev(textFileName->c_str(), physLayout, fixedPitch, rawOrder, htmlMeta, discardDiag);
+ if (textOut->isOk()) {
+ textOut->setTextEOL(textEOL);
+ if (noPageBreaks) {
+ textOut->setTextPageBreaks(false);
+ }
+ if ((w == 0) && (h == 0) && (x == 0) && (y == 0)) {
+ doc->displayPages(textOut, firstPage, lastPage, resolution, resolution, 0, true, false, false);
+ } else {
+
+ for (int page = firstPage; page <= lastPage; ++page) {
+ doc->displayPageSlice(textOut, page, resolution, resolution, 0, true, false, false, x, y, w, h);
+ }
+ }
+
+ } else {
+ delete textOut;
+ exitCode = 2;
+ goto err3;
+ }
}
- if (!bbox) fputs("</pre>\n", f);
- fputs("</body>\n", f);
- fputs("</html>\n", f);
- if (f != stdout) {
- fclose(f);
+ delete textOut;
+
+ // write end of HTML file
+ if (htmlMeta) {
+ if (!textFileName->cmp("-")) {
+ f = stdout;
+ } else {
+ if (!(f = fopen(textFileName->c_str(), "ab"))) {
+ error(errIO, -1, "Couldn't open text file '{0:t}'", textFileName);
+ exitCode = 2;
+ goto err3;
+ }
+ }
+ if (!bbox)
+ fputs("</pre>\n", f);
+ fputs("</body>\n", f);
+ fputs("</html>\n", f);
+ if (f != stdout) {
+ fclose(f);
+ }
}
- }
- exitCode = 0;
+ exitCode = 0;
- // clean up
- err3:
- delete textFileName;
- err2:
- delete doc;
- delete fileName;
- err1:
- err0:
+ // clean up
+err3:
+ delete textFileName;
+err2:
+ delete doc;
+ delete fileName;
+err1:
+err0:
- return exitCode;
+ return exitCode;
}
-static void printInfoString(FILE *f, Dict *infoDict, const char *key,
- const char *text1, const char *text2, const UnicodeMap *uMap) {
- const GooString *s1;
- bool isUnicode;
- Unicode u;
- char buf[9];
- int i, n;
-
- Object obj = infoDict->lookup(key);
- if (obj.isString()) {
- fputs(text1, f);
- s1 = obj.getString();
- if ((s1->getChar(0) & 0xff) == 0xfe &&
- (s1->getChar(1) & 0xff) == 0xff) {
- isUnicode = true;
- i = 2;
- } else {
- isUnicode = false;
- i = 0;
- }
- while (i < obj.getString()->getLength()) {
- if (isUnicode) {
- u = ((s1->getChar(i) & 0xff) << 8) |
- (s1->getChar(i+1) & 0xff);
- i += 2;
- } else {
- u = pdfDocEncoding[s1->getChar(i) & 0xff];
- ++i;
- }
- n = uMap->mapUnicode(u, buf, sizeof(buf));
- buf[n] = '\0';
- const std::string myString = myXmlTokenReplace(buf);
- fputs(myString.c_str(), f);
+static void printInfoString(FILE *f, Dict *infoDict, const char *key, const char *text1, const char *text2, const UnicodeMap *uMap)
+{
+ const GooString *s1;
+ bool isUnicode;
+ Unicode u;
+ char buf[9];
+ int i, n;
+
+ Object obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ fputs(text1, f);
+ s1 = obj.getString();
+ if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) {
+ isUnicode = true;
+ i = 2;
+ } else {
+ isUnicode = false;
+ i = 0;
+ }
+ while (i < obj.getString()->getLength()) {
+ if (isUnicode) {
+ u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i + 1) & 0xff);
+ i += 2;
+ } else {
+ u = pdfDocEncoding[s1->getChar(i) & 0xff];
+ ++i;
+ }
+ n = uMap->mapUnicode(u, buf, sizeof(buf));
+ buf[n] = '\0';
+ const std::string myString = myXmlTokenReplace(buf);
+ fputs(myString.c_str(), f);
+ }
+ fputs(text2, f);
}
- fputs(text2, f);
- }
}
-static void printInfoDate(FILE *f, Dict *infoDict, const char *key, const char *fmt) {
- Object obj = infoDict->lookup(key);
- if (obj.isString()) {
- const char *s = obj.getString()->c_str();
- if (s[0] == 'D' && s[1] == ':') {
- s += 2;
+static void printInfoDate(FILE *f, Dict *infoDict, const char *key, const char *fmt)
+{
+ Object obj = infoDict->lookup(key);
+ if (obj.isString()) {
+ const char *s = obj.getString()->c_str();
+ if (s[0] == 'D' && s[1] == ':') {
+ s += 2;
+ }
+ fprintf(f, fmt, s);
}
- fprintf(f, fmt, s);
- }
}
-static void printLine(FILE *f, const TextLine *line) {
- double xMin, yMin, xMax, yMax;
- double lineXMin = 0, lineYMin = 0, lineXMax = 0, lineYMax = 0;
- const TextWord *word;
- std::stringstream wordXML;
- wordXML << std::fixed << std::setprecision(6);
-
- for (word = line->getWords(); word; word = word->getNext()) {
- word->getBBox(&xMin, &yMin, &xMax, &yMax);
-
- if (lineXMin == 0 || lineXMin > xMin) lineXMin = xMin;
- if (lineYMin == 0 || lineYMin > yMin) lineYMin = yMin;
- if (lineXMax < xMax) lineXMax = xMax;
- if (lineYMax < yMax) lineYMax = yMax;
-
- GooString *wordText = word->getText();
- const std::string myString = myXmlTokenReplace(wordText->c_str());
- wordXML << " <word xMin=\"" << xMin << "\" yMin=\"" << yMin << "\" xMax=\"" <<
- xMax << "\" yMax=\"" << yMax << "\">" << myString << "</word>\n";
- delete wordText;
- }
- fprintf(f, " <line xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">\n",
- lineXMin, lineYMin, lineXMax, lineYMax);
- fputs(wordXML.str().c_str(), f);
- fputs(" </line>\n", f);
+static void printLine(FILE *f, const TextLine *line)
+{
+ double xMin, yMin, xMax, yMax;
+ double lineXMin = 0, lineYMin = 0, lineXMax = 0, lineYMax = 0;
+ const TextWord *word;
+ std::stringstream wordXML;
+ wordXML << std::fixed << std::setprecision(6);
+
+ for (word = line->getWords(); word; word = word->getNext()) {
+ word->getBBox(&xMin, &yMin, &xMax, &yMax);
+
+ if (lineXMin == 0 || lineXMin > xMin)
+ lineXMin = xMin;
+ if (lineYMin == 0 || lineYMin > yMin)
+ lineYMin = yMin;
+ if (lineXMax < xMax)
+ lineXMax = xMax;
+ if (lineYMax < yMax)
+ lineYMax = yMax;
+
+ GooString *wordText = word->getText();
+ const std::string myString = myXmlTokenReplace(wordText->c_str());
+ wordXML << " <word xMin=\"" << xMin << "\" yMin=\"" << yMin << "\" xMax=\"" << xMax << "\" yMax=\"" << yMax << "\">" << myString << "</word>\n";
+ delete wordText;
+ }
+ fprintf(f, " <line xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">\n", lineXMin, lineYMin, lineXMax, lineYMax);
+ fputs(wordXML.str().c_str(), f);
+ fputs(" </line>\n", f);
}
-void printDocBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last) {
- double xMin, yMin, xMax, yMax;
- const TextFlow *flow;
- const TextBlock *blk;
- const TextLine *line;
-
- fprintf(f, "<doc>\n");
- for (int page = first; page <= last; ++page) {
- fprintf(f, " <page width=\"%f\" height=\"%f\">\n",doc->getPageMediaWidth(page), doc->getPageMediaHeight(page));
- doc->displayPage(textOut, page, resolution, resolution, 0, true, false, false);
- for (flow = textOut->getFlows(); flow; flow = flow->getNext()) {
- fprintf(f, " <flow>\n");
- for (blk = flow->getBlocks(); blk; blk = blk->getNext()) {
- blk->getBBox(&xMin, &yMin, &xMax, &yMax);
- fprintf(f, " <block xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">\n", xMin, yMin, xMax, yMax);
- for (line = blk->getLines(); line; line = line->getNext()) {
- printLine(f, line);
+void printDocBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last)
+{
+ double xMin, yMin, xMax, yMax;
+ const TextFlow *flow;
+ const TextBlock *blk;
+ const TextLine *line;
+
+ fprintf(f, "<doc>\n");
+ for (int page = first; page <= last; ++page) {
+ fprintf(f, " <page width=\"%f\" height=\"%f\">\n", doc->getPageMediaWidth(page), doc->getPageMediaHeight(page));
+ doc->displayPage(textOut, page, resolution, resolution, 0, true, false, false);
+ for (flow = textOut->getFlows(); flow; flow = flow->getNext()) {
+ fprintf(f, " <flow>\n");
+ for (blk = flow->getBlocks(); blk; blk = blk->getNext()) {
+ blk->getBBox(&xMin, &yMin, &xMax, &yMax);
+ fprintf(f, " <block xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">\n", xMin, yMin, xMax, yMax);
+ for (line = blk->getLines(); line; line = line->getNext()) {
+ printLine(f, line);
+ }
+ fprintf(f, " </block>\n");
+ }
+ fprintf(f, " </flow>\n");
}
- fprintf(f, " </block>\n");
- }
- fprintf(f, " </flow>\n");
+ fprintf(f, " </page>\n");
}
- fprintf(f, " </page>\n");
- }
- fprintf(f, "</doc>\n");
+ fprintf(f, "</doc>\n");
}
-void printWordBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last) {
- fprintf(f, "<doc>\n");
- for (int page = first; page <= last; ++page) {
- fprintf(f, " <page width=\"%f\" height=\"%f\">\n",doc->getPageMediaWidth(page), doc->getPageMediaHeight(page));
- doc->displayPage(textOut, page, resolution, resolution, 0, true, false, false);
- TextWordList *wordlist = textOut->makeWordList();
- const int word_length = wordlist != nullptr ? wordlist->getLength() : 0;
- TextWord *word;
- double xMinA, yMinA, xMaxA, yMaxA;
- if (word_length == 0)
- fprintf(stderr, "no word list\n");
-
- for (int i = 0; i < word_length; ++i) {
- word = wordlist->get(i);
- word->getBBox(&xMinA, &yMinA, &xMaxA, &yMaxA);
- const std::string myString = myXmlTokenReplace(word->getText()->c_str());
- fprintf(f," <word xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">%s</word>\n", xMinA, yMinA, xMaxA, yMaxA, myString.c_str());
+void printWordBBox(FILE *f, PDFDoc *doc, TextOutputDev *textOut, int first, int last)
+{
+ fprintf(f, "<doc>\n");
+ for (int page = first; page <= last; ++page) {
+ fprintf(f, " <page width=\"%f\" height=\"%f\">\n", doc->getPageMediaWidth(page), doc->getPageMediaHeight(page));
+ doc->displayPage(textOut, page, resolution, resolution, 0, true, false, false);
+ TextWordList *wordlist = textOut->makeWordList();
+ const int word_length = wordlist != nullptr ? wordlist->getLength() : 0;
+ TextWord *word;
+ double xMinA, yMinA, xMaxA, yMaxA;
+ if (word_length == 0)
+ fprintf(stderr, "no word list\n");
+
+ for (int i = 0; i < word_length; ++i) {
+ word = wordlist->get(i);
+ word->getBBox(&xMinA, &yMinA, &xMaxA, &yMaxA);
+ const std::string myString = myXmlTokenReplace(word->getText()->c_str());
+ fprintf(f, " <word xMin=\"%f\" yMin=\"%f\" xMax=\"%f\" yMax=\"%f\">%s</word>\n", xMinA, yMinA, xMaxA, yMaxA, myString.c_str());
+ }
+ fprintf(f, " </page>\n");
+ delete wordlist;
}
- fprintf(f, " </page>\n");
- delete wordlist;
- }
- fprintf(f, "</doc>\n");
+ fprintf(f, "</doc>\n");
}
diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc
index a8116e37..1ea1a346 100644
--- a/utils/pdfunite.cc
+++ b/utils/pdfunite.cc
@@ -28,383 +28,371 @@
static bool printVersion = false;
static bool printHelp = false;
-static const ArgDesc argDesc[] = {
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- { }
-};
+static const ArgDesc argDesc[] = { { "-v", argFlag, &printVersion, 0, "print copyright and version info" }, { "-h", argFlag, &printHelp, 0, "print usage information" }, { "-help", argFlag, &printHelp, 0, "print usage information" },
+ { "--help", argFlag, &printHelp, 0, "print usage information" }, { "-?", argFlag, &printHelp, 0, "print usage information" }, {} };
-static void doMergeNameTree(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameTree, Dict *mergeNameTree, int numOffset) {
- Object mergeNameArray = mergeNameTree->lookup("Names");
- Object srcNameArray = srcNameTree->lookup("Names");
- if (mergeNameArray.isArray() && srcNameArray.isArray()) {
- Array *newNameArray = new Array(srcXRef);
- int j = 0;
- for (int i = 0; i < srcNameArray.arrayGetLength() - 1; i += 2) {
- const Object &key = srcNameArray.arrayGetNF(i);
- const Object &value = srcNameArray.arrayGetNF(i + 1);
- if (key.isString() && value.isRef()) {
+static void doMergeNameTree(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameTree, Dict *mergeNameTree, int numOffset)
+{
+ Object mergeNameArray = mergeNameTree->lookup("Names");
+ Object srcNameArray = srcNameTree->lookup("Names");
+ if (mergeNameArray.isArray() && srcNameArray.isArray()) {
+ Array *newNameArray = new Array(srcXRef);
+ int j = 0;
+ for (int i = 0; i < srcNameArray.arrayGetLength() - 1; i += 2) {
+ const Object &key = srcNameArray.arrayGetNF(i);
+ const Object &value = srcNameArray.arrayGetNF(i + 1);
+ if (key.isString() && value.isRef()) {
+ while (j < mergeNameArray.arrayGetLength() - 1) {
+ const Object &mkey = mergeNameArray.arrayGetNF(j);
+ const Object &mvalue = mergeNameArray.arrayGetNF(j + 1);
+ if (mkey.isString() && mvalue.isRef()) {
+ if (mkey.getString()->cmp(key.getString()) < 0) {
+ newNameArray->add(Object(new GooString(mkey.getString()->c_str())));
+ newNameArray->add(Object({ mvalue.getRef().num + numOffset, mvalue.getRef().gen }));
+ j += 2;
+ } else if (mkey.getString()->cmp(key.getString()) == 0) {
+ j += 2;
+ } else {
+ break;
+ }
+ } else {
+ j += 2;
+ }
+ }
+ newNameArray->add(Object(new GooString(key.getString()->c_str())));
+ newNameArray->add(Object(value.getRef()));
+ }
+ }
while (j < mergeNameArray.arrayGetLength() - 1) {
- const Object &mkey = mergeNameArray.arrayGetNF(j);
- const Object &mvalue = mergeNameArray.arrayGetNF(j + 1);
- if (mkey.isString() && mvalue.isRef()) {
- if (mkey.getString()->cmp(key.getString()) < 0) {
- newNameArray->add(Object(new GooString(mkey.getString()->c_str())));
- newNameArray->add(Object( { mvalue.getRef().num + numOffset, mvalue.getRef().gen } ));
- j += 2;
- } else if (mkey.getString()->cmp(key.getString()) == 0) {
- j += 2;
- } else {
- break;
+ const Object &mkey = mergeNameArray.arrayGetNF(j);
+ const Object &mvalue = mergeNameArray.arrayGetNF(j + 1);
+ if (mkey.isString() && mvalue.isRef()) {
+ newNameArray->add(Object(new GooString(mkey.getString()->c_str())));
+ newNameArray->add(Object({ mvalue.getRef().num + numOffset, mvalue.getRef().gen }));
}
- } else {
j += 2;
- }
}
- newNameArray->add(Object(new GooString(key.getString()->c_str())));
- newNameArray->add(Object(value.getRef()));
- }
- }
- while (j < mergeNameArray.arrayGetLength() - 1) {
- const Object &mkey = mergeNameArray.arrayGetNF(j);
- const Object &mvalue = mergeNameArray.arrayGetNF(j + 1);
- if (mkey.isString() && mvalue.isRef()) {
- newNameArray->add(Object(new GooString(mkey.getString()->c_str())));
- newNameArray->add(Object( { mvalue.getRef().num + numOffset, mvalue.getRef().gen } ));
- }
- j += 2;
- }
- srcNameTree->set("Names", Object(newNameArray));
- doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
- } else if (srcNameArray.isNull() && mergeNameArray.isArray()) {
- Array *newNameArray = new Array(srcXRef);
- for (int i = 0; i < mergeNameArray.arrayGetLength() - 1; i += 2) {
- const Object &key = mergeNameArray.arrayGetNF(i);
- const Object &value = mergeNameArray.arrayGetNF(i + 1);
- if (key.isString() && value.isRef()) {
- newNameArray->add(Object(new GooString(key.getString()->c_str())));
- newNameArray->add(Object( { value.getRef().num + numOffset, value.getRef().gen } ));
- }
+ srcNameTree->set("Names", Object(newNameArray));
+ doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
+ } else if (srcNameArray.isNull() && mergeNameArray.isArray()) {
+ Array *newNameArray = new Array(srcXRef);
+ for (int i = 0; i < mergeNameArray.arrayGetLength() - 1; i += 2) {
+ const Object &key = mergeNameArray.arrayGetNF(i);
+ const Object &value = mergeNameArray.arrayGetNF(i + 1);
+ if (key.isString() && value.isRef()) {
+ newNameArray->add(Object(new GooString(key.getString()->c_str())));
+ newNameArray->add(Object({ value.getRef().num + numOffset, value.getRef().gen }));
+ }
+ }
+ srcNameTree->add("Names", Object(newNameArray));
+ doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
}
- srcNameTree->add("Names", Object(newNameArray));
- doc->markPageObjects(mergeNameTree, srcXRef, countRef, numOffset, oldRefNum, newRefNum);
- }
}
-static void doMergeNameDict(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameDict, Dict *mergeNameDict, int numOffset) {
- for (int i = 0; i < mergeNameDict->getLength(); i++) {
- const char *key = mergeNameDict->getKey(i);
- Object mergeNameTree = mergeNameDict->lookup(key);
- Object srcNameTree = srcNameDict->lookup(key);
- if (srcNameTree.isDict() && mergeNameTree.isDict()) {
- doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, srcNameTree.getDict(), mergeNameTree.getDict(), numOffset);
- } else if (srcNameTree.isNull() && mergeNameTree.isDict()) {
- Object newNameTree(new Dict(srcXRef));
- doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, newNameTree.getDict(), mergeNameTree.getDict(), numOffset);
- srcNameDict->add(key, std::move(newNameTree));
+static void doMergeNameDict(PDFDoc *doc, XRef *srcXRef, XRef *countRef, int oldRefNum, int newRefNum, Dict *srcNameDict, Dict *mergeNameDict, int numOffset)
+{
+ for (int i = 0; i < mergeNameDict->getLength(); i++) {
+ const char *key = mergeNameDict->getKey(i);
+ Object mergeNameTree = mergeNameDict->lookup(key);
+ Object srcNameTree = srcNameDict->lookup(key);
+ if (srcNameTree.isDict() && mergeNameTree.isDict()) {
+ doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, srcNameTree.getDict(), mergeNameTree.getDict(), numOffset);
+ } else if (srcNameTree.isNull() && mergeNameTree.isDict()) {
+ Object newNameTree(new Dict(srcXRef));
+ doMergeNameTree(doc, srcXRef, countRef, oldRefNum, newRefNum, newNameTree.getDict(), mergeNameTree.getDict(), numOffset);
+ srcNameDict->add(key, std::move(newNameTree));
+ }
}
- }
}
-static void doMergeFormDict(Dict *srcFormDict, Dict *mergeFormDict, int numOffset) {
- Object srcFields = srcFormDict->lookup("Fields");
- Object mergeFields = mergeFormDict->lookup("Fields");
- if (srcFields.isArray() && mergeFields.isArray()) {
- for (int i = 0; i < mergeFields.arrayGetLength(); i++) {
- const Object &value = mergeFields.arrayGetNF(i);
- srcFields.arrayAdd(Object( { value.getRef().num + numOffset, value.getRef().gen } ));
+static void doMergeFormDict(Dict *srcFormDict, Dict *mergeFormDict, int numOffset)
+{
+ Object srcFields = srcFormDict->lookup("Fields");
+ Object mergeFields = mergeFormDict->lookup("Fields");
+ if (srcFields.isArray() && mergeFields.isArray()) {
+ for (int i = 0; i < mergeFields.arrayGetLength(); i++) {
+ const Object &value = mergeFields.arrayGetNF(i);
+ srcFields.arrayAdd(Object({ value.getRef().num + numOffset, value.getRef().gen }));
+ }
}
- }
}
///////////////////////////////////////////////////////////////////////////
-int main (int argc, char *argv[])
+int main(int argc, char *argv[])
///////////////////////////////////////////////////////////////////////////
// Merge PDF files given by arguments 1 to argc-2 and write the result
// to the file specified by argument argc-1.
///////////////////////////////////////////////////////////////////////////
{
- int objectsCount = 0;
- unsigned int numOffset = 0;
- std::vector<Object> pages;
- std::vector<unsigned int> offsets;
- XRef *yRef, *countRef;
- FILE *f;
- OutStream *outStr;
- int i;
- int j, rootNum;
- std::vector<PDFDoc *>docs;
- int majorVersion = 0;
- int minorVersion = 0;
- char *fileName = argv[argc - 1];
- int exitCode;
+ int objectsCount = 0;
+ unsigned int numOffset = 0;
+ std::vector<Object> pages;
+ std::vector<unsigned int> offsets;
+ XRef *yRef, *countRef;
+ FILE *f;
+ OutStream *outStr;
+ int i;
+ int j, rootNum;
+ std::vector<PDFDoc *> docs;
+ int majorVersion = 0;
+ int minorVersion = 0;
+ char *fileName = argv[argc - 1];
+ int exitCode;
- exitCode = 99;
- const bool ok = parseArgs (argDesc, &argc, argv);
- if (!ok || argc < 3 || printVersion || printHelp) {
- fprintf(stderr, "pdfunite version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "%s\n", popplerCopyright);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("pdfunite", "<PDF-sourcefile-1>..<PDF-sourcefile-n> <PDF-destfile>",
- argDesc);
+ exitCode = 99;
+ const bool ok = parseArgs(argDesc, &argc, argv);
+ if (!ok || argc < 3 || printVersion || printHelp) {
+ fprintf(stderr, "pdfunite version %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "%s\n", popplerCopyright);
+ fprintf(stderr, "%s\n", xpdfCopyright);
+ if (!printVersion) {
+ printUsage("pdfunite", "<PDF-sourcefile-1>..<PDF-sourcefile-n> <PDF-destfile>", argDesc);
+ }
+ if (printVersion || printHelp)
+ exitCode = 0;
+ return exitCode;
}
- if (printVersion || printHelp)
- exitCode = 0;
- return exitCode;
- }
- exitCode = 0;
- globalParams = std::make_unique<GlobalParams>();
+ exitCode = 0;
+ globalParams = std::make_unique<GlobalParams>();
- for (i = 1; i < argc - 1; i++) {
- GooString *gfileName = new GooString(argv[i]);
- PDFDoc *doc = new PDFDoc(gfileName, nullptr, nullptr, nullptr);
- if (doc->isOk() && !doc->isEncrypted() &&
- doc->getXRef()->getCatalog().isDict()) {
- docs.push_back(doc);
- if (doc->getPDFMajorVersion() > majorVersion) {
- majorVersion = doc->getPDFMajorVersion();
- minorVersion = doc->getPDFMinorVersion();
- } else if (doc->getPDFMajorVersion() == majorVersion) {
- if (doc->getPDFMinorVersion() > minorVersion) {
- minorVersion = doc->getPDFMinorVersion();
+ for (i = 1; i < argc - 1; i++) {
+ GooString *gfileName = new GooString(argv[i]);
+ PDFDoc *doc = new PDFDoc(gfileName, nullptr, nullptr, nullptr);
+ if (doc->isOk() && !doc->isEncrypted() && doc->getXRef()->getCatalog().isDict()) {
+ docs.push_back(doc);
+ if (doc->getPDFMajorVersion() > majorVersion) {
+ majorVersion = doc->getPDFMajorVersion();
+ minorVersion = doc->getPDFMinorVersion();
+ } else if (doc->getPDFMajorVersion() == majorVersion) {
+ if (doc->getPDFMinorVersion() > minorVersion) {
+ minorVersion = doc->getPDFMinorVersion();
+ }
+ }
+ } else if (doc->isOk()) {
+ if (doc->isEncrypted()) {
+ error(errUnimplemented, -1, "Could not merge encrypted files ('{0:s}')", argv[i]);
+ return -1;
+ } else if (!doc->getXRef()->getCatalog().isDict()) {
+ error(errSyntaxError, -1, "XRef's Catalog is not a dictionary ('{0:s}')", argv[i]);
+ return -1;
+ }
+ } else {
+ error(errSyntaxError, -1, "Could not merge damaged documents ('{0:s}')", argv[i]);
+ return -1;
}
- }
- } else if (doc->isOk()) {
- if (doc->isEncrypted()) {
- error(errUnimplemented, -1, "Could not merge encrypted files ('{0:s}')", argv[i]);
- return -1;
- } else if (!doc->getXRef()->getCatalog().isDict()) {
- error(errSyntaxError, -1, "XRef's Catalog is not a dictionary ('{0:s}')", argv[i]);
- return -1;
- }
- } else {
- error(errSyntaxError, -1, "Could not merge damaged documents ('{0:s}')", argv[i]);
- return -1;
}
- }
- if (!(f = fopen(fileName, "wb"))) {
- error(errIO, -1, "Could not open file '{0:s}'", fileName);
- return -1;
- }
- outStr = new FileOutStream(f, 0);
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Could not open file '{0:s}'", fileName);
+ return -1;
+ }
+ outStr = new FileOutStream(f, 0);
- yRef = new XRef();
- countRef = new XRef();
- yRef->add(0, 65535, 0, false);
- PDFDoc::writeHeader(outStr, majorVersion, minorVersion);
+ yRef = new XRef();
+ countRef = new XRef();
+ yRef->add(0, 65535, 0, false);
+ PDFDoc::writeHeader(outStr, majorVersion, minorVersion);
- // handle OutputIntents, AcroForm, OCProperties & Names
- Object intents;
- Object names;
- Object afObj;
- Object ocObj;
- if (docs.size() >= 1) {
- Object catObj = docs[0]->getXRef()->getCatalog();
- Dict *catDict = catObj.getDict();
- intents = catDict->lookup("OutputIntents");
- afObj = catDict->lookupNF("AcroForm").copy();
- Ref *refPage = docs[0]->getCatalog()->getPageRef(1);
- if (!afObj.isNull() && refPage) {
- docs[0]->markAcroForm(&afObj, yRef, countRef, 0, refPage->num, refPage->num);
- }
- ocObj = catDict->lookupNF("OCProperties").copy();
- if (!ocObj.isNull() && ocObj.isDict() && refPage) {
- docs[0]->markPageObjects(ocObj.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
- }
- names = catDict->lookup("Names");
- if (!names.isNull() && names.isDict() && refPage) {
- docs[0]->markPageObjects(names.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
- }
- if (intents.isArray() && intents.arrayGetLength() > 0) {
- for (i = 1; i < (int) docs.size(); i++) {
- Object pagecatObj = docs[i]->getXRef()->getCatalog();
- Dict *pagecatDict = pagecatObj.getDict();
- Object pageintents = pagecatDict->lookup("OutputIntents");
- if (pageintents.isArray() && pageintents.arrayGetLength() > 0) {
- for (j = intents.arrayGetLength() - 1; j >= 0; j--) {
- Object intent = intents.arrayGet(j, 0);
- if (intent.isDict()) {
- Object idf = intent.dictLookup("OutputConditionIdentifier");
- if (idf.isString()) {
- const GooString *gidf = idf.getString();
- bool removeIntent = true;
- for (int k = 0; k < pageintents.arrayGetLength(); k++) {
- Object pgintent = pageintents.arrayGet(k, 0);
- if (pgintent.isDict()) {
- Object pgidf = pgintent.dictLookup("OutputConditionIdentifier");
- if (pgidf.isString()) {
- const GooString *gpgidf = pgidf.getString();
- if (gpgidf->cmp(gidf) == 0) {
- removeIntent = false;
- break;
- }
+ // handle OutputIntents, AcroForm, OCProperties & Names
+ Object intents;
+ Object names;
+ Object afObj;
+ Object ocObj;
+ if (docs.size() >= 1) {
+ Object catObj = docs[0]->getXRef()->getCatalog();
+ Dict *catDict = catObj.getDict();
+ intents = catDict->lookup("OutputIntents");
+ afObj = catDict->lookupNF("AcroForm").copy();
+ Ref *refPage = docs[0]->getCatalog()->getPageRef(1);
+ if (!afObj.isNull() && refPage) {
+ docs[0]->markAcroForm(&afObj, yRef, countRef, 0, refPage->num, refPage->num);
+ }
+ ocObj = catDict->lookupNF("OCProperties").copy();
+ if (!ocObj.isNull() && ocObj.isDict() && refPage) {
+ docs[0]->markPageObjects(ocObj.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
+ }
+ names = catDict->lookup("Names");
+ if (!names.isNull() && names.isDict() && refPage) {
+ docs[0]->markPageObjects(names.getDict(), yRef, countRef, 0, refPage->num, refPage->num);
+ }
+ if (intents.isArray() && intents.arrayGetLength() > 0) {
+ for (i = 1; i < (int)docs.size(); i++) {
+ Object pagecatObj = docs[i]->getXRef()->getCatalog();
+ Dict *pagecatDict = pagecatObj.getDict();
+ Object pageintents = pagecatDict->lookup("OutputIntents");
+ if (pageintents.isArray() && pageintents.arrayGetLength() > 0) {
+ for (j = intents.arrayGetLength() - 1; j >= 0; j--) {
+ Object intent = intents.arrayGet(j, 0);
+ if (intent.isDict()) {
+ Object idf = intent.dictLookup("OutputConditionIdentifier");
+ if (idf.isString()) {
+ const GooString *gidf = idf.getString();
+ bool removeIntent = true;
+ for (int k = 0; k < pageintents.arrayGetLength(); k++) {
+ Object pgintent = pageintents.arrayGet(k, 0);
+ if (pgintent.isDict()) {
+ Object pgidf = pgintent.dictLookup("OutputConditionIdentifier");
+ if (pgidf.isString()) {
+ const GooString *gpgidf = pgidf.getString();
+ if (gpgidf->cmp(gidf) == 0) {
+ removeIntent = false;
+ break;
+ }
+ }
+ }
+ }
+ if (removeIntent) {
+ intents.arrayRemove(j);
+ error(errSyntaxWarning, -1, "Output intent {0:s} missing in pdf {1:s}, removed", gidf->c_str(), docs[i]->getFileName()->c_str());
+ }
+ } else {
+ intents.arrayRemove(j);
+ error(errSyntaxWarning, -1, "Invalid output intent dict, missing required OutputConditionIdentifier");
+ }
+ } else {
+ intents.arrayRemove(j);
+ }
}
- }
+ } else {
+ error(errSyntaxWarning, -1, "Output intents differs, remove them all");
+ break;
}
- if (removeIntent) {
- intents.arrayRemove(j);
- error(errSyntaxWarning, -1, "Output intent {0:s} missing in pdf {1:s}, removed",
- gidf->c_str(), docs[i]->getFileName()->c_str());
+ }
+ }
+ if (intents.isArray() && intents.arrayGetLength() > 0) {
+ for (j = intents.arrayGetLength() - 1; j >= 0; j--) {
+ Object intent = intents.arrayGet(j, 0);
+ if (intent.isDict()) {
+ docs[0]->markPageObjects(intent.getDict(), yRef, countRef, numOffset, 0, 0);
+ } else {
+ intents.arrayRemove(j);
}
- } else {
- intents.arrayRemove(j);
- error(errSyntaxWarning, -1, "Invalid output intent dict, missing required OutputConditionIdentifier");
- }
- } else {
- intents.arrayRemove(j);
}
- }
- } else {
- error(errSyntaxWarning, -1, "Output intents differs, remove them all");
- break;
}
- }
}
- if (intents.isArray() && intents.arrayGetLength() > 0) {
- for (j = intents.arrayGetLength() - 1; j >= 0; j--) {
- Object intent = intents.arrayGet(j, 0);
- if (intent.isDict()) {
- docs[0]->markPageObjects(intent.getDict(), yRef, countRef, numOffset, 0, 0);
- } else {
- intents.arrayRemove(j);
+
+ for (i = 0; i < (int)docs.size(); i++) {
+ for (j = 1; j <= docs[i]->getNumPages(); j++) {
+ if (!docs[i]->getCatalog()->getPage(j)) {
+ continue;
+ }
+
+ const PDFRectangle *cropBox = nullptr;
+ if (docs[i]->getCatalog()->getPage(j)->isCropped())
+ cropBox = docs[i]->getCatalog()->getPage(j)->getCropBox();
+ docs[i]->replacePageDict(j, docs[i]->getCatalog()->getPage(j)->getRotate(), docs[i]->getCatalog()->getPage(j)->getMediaBox(), cropBox);
+ Ref *refPage = docs[i]->getCatalog()->getPageRef(j);
+ Object page = docs[i]->getXRef()->fetch(*refPage);
+ Dict *pageDict = page.getDict();
+ Object *resDict = docs[i]->getCatalog()->getPage(j)->getResourceDictObject();
+ if (resDict->isDict()) {
+ pageDict->set("Resources", resDict->copy());
+ }
+ pages.push_back(std::move(page));
+ offsets.push_back(numOffset);
+ docs[i]->markPageObjects(pageDict, yRef, countRef, numOffset, refPage->num, refPage->num);
+ Object annotsObj = pageDict->lookupNF("Annots").copy();
+ if (!annotsObj.isNull()) {
+ docs[i]->markAnnotations(&annotsObj, yRef, countRef, numOffset, refPage->num, refPage->num);
+ }
+ }
+ Object pageCatObj = docs[i]->getXRef()->getCatalog();
+ Dict *pageCatDict = pageCatObj.getDict();
+ Object pageNames = pageCatDict->lookup("Names");
+ if (!pageNames.isNull() && pageNames.isDict()) {
+ if (!names.isDict()) {
+ names = Object(new Dict(yRef));
+ }
+ doMergeNameDict(docs[i], yRef, countRef, 0, 0, names.getDict(), pageNames.getDict(), numOffset);
}
- }
+ Object pageForm = pageCatDict->lookup("AcroForm");
+ if (i > 0 && !pageForm.isNull() && pageForm.isDict()) {
+ if (afObj.isNull()) {
+ afObj = pageCatDict->lookupNF("AcroForm").copy();
+ } else if (afObj.isDict()) {
+ doMergeFormDict(afObj.getDict(), pageForm.getDict(), numOffset);
+ }
+ }
+ objectsCount += docs[i]->writePageObjects(outStr, yRef, numOffset, true);
+ numOffset = yRef->getNumObjects() + 1;
}
- }
-
- for (i = 0; i < (int) docs.size(); i++) {
- for (j = 1; j <= docs[i]->getNumPages(); j++) {
- if (!docs[i]->getCatalog()->getPage(j)) {
- continue;
- }
- const PDFRectangle *cropBox = nullptr;
- if (docs[i]->getCatalog()->getPage(j)->isCropped())
- cropBox = docs[i]->getCatalog()->getPage(j)->getCropBox();
- docs[i]->replacePageDict(j,
- docs[i]->getCatalog()->getPage(j)->getRotate(),
- docs[i]->getCatalog()->getPage(j)->getMediaBox(), cropBox);
- Ref *refPage = docs[i]->getCatalog()->getPageRef(j);
- Object page = docs[i]->getXRef()->fetch(*refPage);
- Dict *pageDict = page.getDict();
- Object *resDict = docs[i]->getCatalog()->getPage(j)->getResourceDictObject();
- if (resDict->isDict()) {
- pageDict->set("Resources", resDict->copy());
- }
- pages.push_back(std::move(page));
- offsets.push_back(numOffset);
- docs[i]->markPageObjects(pageDict, yRef, countRef, numOffset, refPage->num, refPage->num);
- Object annotsObj = pageDict->lookupNF("Annots").copy();
- if (!annotsObj.isNull()) {
- docs[i]->markAnnotations(&annotsObj, yRef, countRef, numOffset, refPage->num, refPage->num);
- }
+ rootNum = yRef->getNumObjects() + 1;
+ yRef->add(rootNum, 0, outStr->getPos(), true);
+ outStr->printf("%d 0 obj\n", rootNum);
+ outStr->printf("<< /Type /Catalog /Pages %d 0 R", rootNum + 1);
+ // insert OutputIntents
+ if (intents.isArray() && intents.arrayGetLength() > 0) {
+ outStr->printf(" /OutputIntents [");
+ for (j = 0; j < intents.arrayGetLength(); j++) {
+ Object intent = intents.arrayGet(j, 0);
+ if (intent.isDict()) {
+ PDFDoc::writeObject(&intent, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
+ }
+ }
+ outStr->printf("]");
}
- Object pageCatObj = docs[i]->getXRef()->getCatalog();
- Dict *pageCatDict = pageCatObj.getDict();
- Object pageNames = pageCatDict->lookup("Names");
- if (!pageNames.isNull() && pageNames.isDict()) {
- if (!names.isDict()) {
- names = Object(new Dict(yRef));
- }
- doMergeNameDict(docs[i], yRef, countRef, 0, 0, names.getDict(), pageNames.getDict(), numOffset);
+ // insert AcroForm
+ if (!afObj.isNull()) {
+ outStr->printf(" /AcroForm ");
+ PDFDoc::writeObject(&afObj, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
}
- Object pageForm = pageCatDict->lookup("AcroForm");
- if (i > 0 && !pageForm.isNull() && pageForm.isDict()) {
- if (afObj.isNull()) {
- afObj = pageCatDict->lookupNF("AcroForm").copy();
- } else if (afObj.isDict()) {
- doMergeFormDict(afObj.getDict(), pageForm.getDict(), numOffset);
- }
+ // insert OCProperties
+ if (!ocObj.isNull() && ocObj.isDict()) {
+ outStr->printf(" /OCProperties ");
+ PDFDoc::writeObject(&ocObj, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
}
- objectsCount += docs[i]->writePageObjects(outStr, yRef, numOffset, true);
- numOffset = yRef->getNumObjects() + 1;
- }
-
- rootNum = yRef->getNumObjects() + 1;
- yRef->add(rootNum, 0, outStr->getPos(), true);
- outStr->printf("%d 0 obj\n", rootNum);
- outStr->printf("<< /Type /Catalog /Pages %d 0 R", rootNum + 1);
- // insert OutputIntents
- if (intents.isArray() && intents.arrayGetLength() > 0) {
- outStr->printf(" /OutputIntents [");
- for (j = 0; j < intents.arrayGetLength(); j++) {
- Object intent = intents.arrayGet(j, 0);
- if (intent.isDict()) {
- PDFDoc::writeObject(&intent, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
- }
+ // insert Names
+ if (!names.isNull() && names.isDict()) {
+ outStr->printf(" /Names ");
+ PDFDoc::writeObject(&names, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
}
- outStr->printf("]");
- }
- // insert AcroForm
- if (!afObj.isNull()) {
- outStr->printf(" /AcroForm ");
- PDFDoc::writeObject(&afObj, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
- }
- // insert OCProperties
- if (!ocObj.isNull() && ocObj.isDict()) {
- outStr->printf(" /OCProperties ");
- PDFDoc::writeObject(&ocObj, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
- }
- // insert Names
- if (!names.isNull() && names.isDict()) {
- outStr->printf(" /Names ");
- PDFDoc::writeObject(&names, outStr, yRef, 0, nullptr, cryptRC4, 0, 0, 0);
- }
- outStr->printf(">>\nendobj\n");
- objectsCount++;
+ outStr->printf(">>\nendobj\n");
+ objectsCount++;
- yRef->add(rootNum + 1, 0, outStr->getPos(), true);
- outStr->printf("%d 0 obj\n", rootNum + 1);
- outStr->printf("<< /Type /Pages /Kids [");
- for (j = 0; j < (int) pages.size(); j++)
- outStr->printf(" %d 0 R", rootNum + j + 2);
- outStr->printf(" ] /Count %zd >>\nendobj\n", pages.size());
- objectsCount++;
+ yRef->add(rootNum + 1, 0, outStr->getPos(), true);
+ outStr->printf("%d 0 obj\n", rootNum + 1);
+ outStr->printf("<< /Type /Pages /Kids [");
+ for (j = 0; j < (int)pages.size(); j++)
+ outStr->printf(" %d 0 R", rootNum + j + 2);
+ outStr->printf(" ] /Count %zd >>\nendobj\n", pages.size());
+ objectsCount++;
- for (i = 0; i < (int) pages.size(); i++) {
- yRef->add(rootNum + i + 2, 0, outStr->getPos(), true);
- outStr->printf("%d 0 obj\n", rootNum + i + 2);
- outStr->printf("<< ");
- Dict *pageDict = pages[i].getDict();
- for (j = 0; j < pageDict->getLength(); j++) {
- if (j > 0)
- outStr->printf(" ");
- const char *key = pageDict->getKey(j);
- Object value = pageDict->getValNF(j).copy();
- if (strcmp(key, "Parent") == 0) {
- outStr->printf("/Parent %d 0 R", rootNum + 1);
- } else {
- outStr->printf("/%s ", key);
- PDFDoc::writeObject(&value, outStr, yRef, offsets[i], nullptr, cryptRC4, 0, 0, 0);
- }
+ for (i = 0; i < (int)pages.size(); i++) {
+ yRef->add(rootNum + i + 2, 0, outStr->getPos(), true);
+ outStr->printf("%d 0 obj\n", rootNum + i + 2);
+ outStr->printf("<< ");
+ Dict *pageDict = pages[i].getDict();
+ for (j = 0; j < pageDict->getLength(); j++) {
+ if (j > 0)
+ outStr->printf(" ");
+ const char *key = pageDict->getKey(j);
+ Object value = pageDict->getValNF(j).copy();
+ if (strcmp(key, "Parent") == 0) {
+ outStr->printf("/Parent %d 0 R", rootNum + 1);
+ } else {
+ outStr->printf("/%s ", key);
+ PDFDoc::writeObject(&value, outStr, yRef, offsets[i], nullptr, cryptRC4, 0, 0, 0);
+ }
+ }
+ outStr->printf(" >>\nendobj\n");
+ objectsCount++;
}
- outStr->printf(" >>\nendobj\n");
- objectsCount++;
- }
- Goffset uxrefOffset = outStr->getPos();
- Ref ref;
- ref.num = rootNum;
- ref.gen = 0;
- Object trailerDict = PDFDoc::createTrailerDict(objectsCount, false, 0, &ref, yRef,
- fileName, outStr->getPos());
- PDFDoc::writeXRefTableTrailer(std::move(trailerDict), yRef, true, // write all entries according to ISO 32000-1, 7.5.4 Cross-Reference Table: "For a file that has never been incrementally updated, the cross-reference section shall contain only one subsection, whose object numbering begins at 0."
- uxrefOffset, outStr, yRef);
+ Goffset uxrefOffset = outStr->getPos();
+ Ref ref;
+ ref.num = rootNum;
+ ref.gen = 0;
+ Object trailerDict = PDFDoc::createTrailerDict(objectsCount, false, 0, &ref, yRef, fileName, outStr->getPos());
+ PDFDoc::writeXRefTableTrailer(std::move(trailerDict), yRef, true, // write all entries according to ISO 32000-1, 7.5.4 Cross-Reference Table: "For a file that has never been incrementally updated, the cross-reference section shall
+ // contain only one subsection, whose object numbering begins at 0."
+ uxrefOffset, outStr, yRef);
- outStr->close();
- delete outStr;
- fclose(f);
- delete yRef;
- delete countRef;
- for (i = 0; i < (int) docs.size (); i++) delete docs[i];
- return exitCode;
+ outStr->close();
+ delete outStr;
+ fclose(f);
+ delete yRef;
+ delete countRef;
+ for (i = 0; i < (int)docs.size(); i++)
+ delete docs[i];
+ return exitCode;
}
diff --git a/utils/printencodings.cc b/utils/printencodings.cc
index 15580de6..5f561483 100644
--- a/utils/printencodings.cc
+++ b/utils/printencodings.cc
@@ -28,16 +28,14 @@
void printEncodings()
{
- std::vector<GooString*> *encNames = globalParams->getEncodingNames();
+ std::vector<GooString *> *encNames = globalParams->getEncodingNames();
- std::sort(encNames->begin(), encNames->end(), [](void *lhs, void *rhs) {
- return static_cast<GooString *>(lhs)->cmp(static_cast<GooString *>(rhs)) < 0;
- });
+ std::sort(encNames->begin(), encNames->end(), [](void *lhs, void *rhs) { return static_cast<GooString *>(lhs)->cmp(static_cast<GooString *>(rhs)) < 0; });
- printf("Available encodings are:\n");
- for (const GooString *enc : *encNames) {
- printf("%s\n", enc->c_str());
- }
+ printf("Available encodings are:\n");
+ for (const GooString *enc : *encNames) {
+ printf("%s\n", enc->c_str());
+ }
- delete encNames;
+ delete encNames;
}