r22386 by jghali -
scribus-commit
scribus-commit at lists.scribus.net
Tue Feb 13 12:25:10 UTC 2018
Author: jghali
Date: Tue Feb 13 12:25:10 2018
New Revision: 22386
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=22386
Log:
#15112: Enfocus reports bookmarks and forms inside PDF despite not beeing used
Modified:
trunk/Scribus/scribus/annotation.h
trunk/Scribus/scribus/pdflib_core.cpp
trunk/Scribus/scribus/pdflib_core.h
trunk/Scribus/scribus/pdfwriter.cpp
trunk/Scribus/scribus/pdfwriter.h
trunk/Scribus/scribus/scribusdoc.cpp
trunk/Scribus/scribus/scribusdoc.h
Modified: trunk/Scribus/scribus/annotation.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/annotation.h
==============================================================================
--- trunk/Scribus/scribus/annotation.h (original)
+++ trunk/Scribus/scribus/annotation.h Tue Feb 13 12:25:10 2018
@@ -116,6 +116,20 @@
Flag_RadiosInUnison = 33554432, // Bit 26 for Radio Buttons only
Flag_CommitOnSelChange = 67108864 // Bit 27
};
+
+ bool isAcroFormField() const
+ {
+ if (AnType == Annotation::Button ||
+ AnType == Annotation::Textfield ||
+ AnType == Annotation::Checkbox ||
+ AnType == Annotation::Combobox ||
+ AnType == Annotation::Listbox ||
+ AnType == Annotation::RadioButton)
+ {
+ return true;
+ }
+ return false;
+ }
void setType(int newType) { AnType=newType; }
void setAction(const QString& newAction) { AnAction=newAction; }
Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp (original)
+++ trunk/Scribus/scribus/pdflib_core.cpp Tue Feb 13 12:25:10 2018
@@ -1045,14 +1045,36 @@
void PDFLibCore::PDF_Begin_Catalog()
{
writer.startObj(writer.CatalogObj);
- PutDoc("<<\n/Type /Catalog");
- PutDoc("\n/Outlines " + Pdf::toObjRef(writer.OutlinesObj) +
- "\n/Pages " + Pdf::toObjRef(writer.PagesObj) +
- "\n/Dests " + Pdf::toObjRef(writer.DestsObj) +
- "\n/AcroForm " + Pdf::toObjRef(writer.AcroFormObj) +
- "\n/Names "+ Pdf::toObjRef(writer.NamesObj) +
- "\n/Threads " + Pdf::toObjRef(writer.ThreadsObj) +
- "\n");
+ PutDoc("<<\n/Type /Catalog\n");
+ PutDoc("/Pages " + Pdf::toObjRef(writer.PagesObj) + "\n");
+ if (!PDF_IsPDFX())
+ {
+ if (doc.useAcroFormFields())
+ {
+ writer.AcroFormObj = writer.newObject();
+ PutDoc("/AcroForm " + Pdf::toObjRef(writer.AcroFormObj) + "\n");
+ }
+ if (doc.useAnnotations())
+ {
+ writer.DestsObj = writer.newObject();
+ PutDoc("/Dests " + Pdf::toObjRef(writer.DestsObj) + "\n");
+ }
+ if (doc.JavaScripts.count() > 0)
+ {
+ writer.NamesObj = writer.newObject();
+ PutDoc("/Names " + Pdf::toObjRef(writer.NamesObj) + "\n");
+ }
+ }
+ if (Options.Bookmarks)
+ {
+ writer.OutlinesObj = writer.newObject();
+ PutDoc("/Outlines " + Pdf::toObjRef(writer.OutlinesObj) + "\n");
+ }
+ if (Options.Articles)
+ {
+ writer.ThreadsObj = writer.newObject();
+ PutDoc("/Threads " + Pdf::toObjRef(writer.ThreadsObj) + "\n");
+ }
if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
{
writer.OCPropertiesObj = writer.newObject();
@@ -3583,7 +3605,7 @@
}
uint pageObject = writer.newObject();
writer.startObj(pageObject);
- PutDoc("<<\n/Type /Page\n/Parent 4 0 R\n");
+ PutDoc("<<\n/Type /Page\n/Parent " + Pdf::toObjRef(writer.PagesObj) + "\n");
PutDoc("/MediaBox [0 0 "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+"]\n");
PutDoc("/BleedBox ["+FToStr(markOffs)+" "+FToStr(markOffs)+" "+FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY-markOffs)+"]\n");
PutDoc("/CropBox [0 0 "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+"]\n");
@@ -10896,6 +10918,9 @@
void PDFLibCore::PDF_End_Bookmarks()
{
+ if (writer.OutlinesObj == 0)
+ return;
+
BookMItem* ip;
QByteArray Inhal = "";
QMap<int,QByteArray> Inha;
@@ -10991,10 +11016,12 @@
void PDFLibCore::PDF_End_Outlines()
{
+ if (writer.OutlinesObj == 0)
+ return;
+
writer.startObj(writer.OutlinesObj);
PutDoc("<<\n/Type /Outlines\n");
PutDoc("/Count "+Pdf::toPdf(Outlines.Count)+"\n");
-// if ((Bvie->childCount() != 0) && (Options.Bookmarks))
if ((Bvie->topLevelItemCount() != 0) && (Options.Bookmarks))
{
PutDoc("/First "+Pdf::toPdf(Outlines.First)+" 0 R\n");
@@ -11020,6 +11047,9 @@
void PDFLibCore::PDF_End_NamedDests()
{
+ if (writer.DestsObj == 0)
+ return;
+
writer.startObj(writer.DestsObj);
PutDoc("<<\n");
if (NamedDest.count() != 0)
@@ -11038,6 +11068,9 @@
void PDFLibCore::PDF_End_FormObjects()
{
+ if (writer.AcroFormObj == 0)
+ return;
+
writer.startObj(writer.AcroFormObj);
PutDoc("<<\n");
PutDoc("/Fields [ ");
@@ -11062,6 +11095,9 @@
void PDFLibCore::PDF_End_JavaScripts()
{
+ if (writer.NamesObj == 0)
+ return;
+
PdfId jsNameTreeObj = 0;
if (doc.JavaScripts.count() != 0)
{
@@ -11101,45 +11137,34 @@
void PDFLibCore::PDF_End_Articles()
{
- Threads.clear();
+ if (writer.ThreadsObj == 0)
+ return;
+
+ QList<PdfId> Threads;
+ QList<PdfBead> Beads;
PdfId currentThreadObj = 0;
- if (Options.Articles)
- {
- for (int ele = 0; ele < doc.Items->count(); ++ele)
- {
- PageItem* tel = doc.Items->at(ele);
- if ((tel->asTextFrame()) && (tel->prevInChain() == 0) && (tel->nextInChain() != 0) &&
- (!tel->inPdfArticle))
- {
- Beads.clear();
- PdfBead bd;
- if (currentThreadObj == 0)
- currentThreadObj = writer.newObject();
+
+ for (int ele = 0; ele < doc.Items->count(); ++ele)
+ {
+ PageItem* tel = doc.Items->at(ele);
+ if ((tel->asTextFrame()) && (tel->prevInChain() == 0) && (tel->nextInChain() != 0) &&
+ (!tel->inPdfArticle))
+ {
+ Beads.clear();
+ PdfBead bd;
+ if (currentThreadObj == 0)
+ currentThreadObj = writer.newObject();
- PdfId fir = currentThreadObj + 1;
- PdfId ccb = currentThreadObj + 1;
- bd.Parent = currentThreadObj;
- while (tel->nextInChain() != 0)
- {
- if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
- {
- bd.Next = ccb + 1;
- bd.Prev = ccb - 1;
- ccb++;
- bd.Page = PageTree.Kids[tel->OwnPage];
- bd.Rect = QRect(static_cast<int>(tel->xPos() - doc.DocPages.at(tel->OwnPage)->xOffset()),
- static_cast<int>(doc.DocPages.at(tel->OwnPage)->height() - (tel->yPos() - doc.DocPages.at(tel->OwnPage)->yOffset())),
- static_cast<int>(tel->width()),
- static_cast<int>(tel->height()));
- Beads.append(bd);
- }
- tel->inPdfArticle = true;
- tel = tel->nextInChain();
- }
- bd.Next = ccb + 1;
- bd.Prev = ccb - 1;
+ PdfId fir = currentThreadObj + 1;
+ PdfId ccb = currentThreadObj + 1;
+ bd.Parent = currentThreadObj;
+ while (tel->nextInChain() != 0)
+ {
if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
{
+ bd.Next = ccb + 1;
+ bd.Prev = ccb - 1;
+ ccb++;
bd.Page = PageTree.Kids[tel->OwnPage];
bd.Rect = QRect(static_cast<int>(tel->xPos() - doc.DocPages.at(tel->OwnPage)->xOffset()),
static_cast<int>(doc.DocPages.at(tel->OwnPage)->height() - (tel->yPos() - doc.DocPages.at(tel->OwnPage)->yOffset())),
@@ -11148,39 +11173,53 @@
Beads.append(bd);
}
tel->inPdfArticle = true;
- if (Beads.count() > 0)
- {
- writer.startObj(currentThreadObj);
- Threads.append(currentThreadObj);
- PutDoc("<< /Type /Thread\n");
- PutDoc(" /F "+Pdf::toPdf(fir)+" 0 R\n");
+ tel = tel->nextInChain();
+ }
+ bd.Next = ccb + 1;
+ bd.Prev = ccb - 1;
+ if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
+ {
+ bd.Page = PageTree.Kids[tel->OwnPage];
+ bd.Rect = QRect(static_cast<int>(tel->xPos() - doc.DocPages.at(tel->OwnPage)->xOffset()),
+ static_cast<int>(doc.DocPages.at(tel->OwnPage)->height() - (tel->yPos() - doc.DocPages.at(tel->OwnPage)->yOffset())),
+ static_cast<int>(tel->width()),
+ static_cast<int>(tel->height()));
+ Beads.append(bd);
+ }
+ tel->inPdfArticle = true;
+ if (Beads.count() > 0)
+ {
+ writer.startObj(currentThreadObj);
+ Threads.append(currentThreadObj);
+ PutDoc("<< /Type /Thread\n");
+ PutDoc(" /F "+Pdf::toPdf(fir)+" 0 R\n");
+ PutDoc(">>");
+ writer.endObj(currentThreadObj);
+
+ Beads[0].Prev = fir + Beads.count()-1;
+ Beads.last().Next = fir;
+
+ for (int beac = 0; beac < Beads.count(); ++beac)
+ {
+ PdfId beadObj = writer.startObj();
+ PutDoc("<< /Type /Bead\n");
+ PutDoc(" /T "+Pdf::toPdf(Beads[beac].Parent)+" 0 R\n");
+ PutDoc(" /N "+Pdf::toPdf(Beads[beac].Next)+" 0 R\n");
+ PutDoc(" /V "+Pdf::toPdf(Beads[beac].Prev)+" 0 R\n");
+ PutDoc(" /P "+Pdf::toPdf(Beads[beac].Page)+" 0 R\n");
+ PutDoc(" /R [ "+Pdf::toPdf(Beads[beac].Rect.x())+" "+
+ Pdf::toPdf(Beads[beac].Rect.y())+" ");
+ PutDoc(Pdf::toPdf(Beads[beac].Rect.bottomRight().x())+" "+Pdf::toPdf(Beads[beac].Rect.y()-Beads[beac].Rect.height())+" ]\n");
PutDoc(">>");
- writer.endObj(currentThreadObj);
-
- Beads[0].Prev = fir + Beads.count()-1;
- Beads.last().Next = fir;
-
- for (int beac = 0; beac < Beads.count(); ++beac)
- {
- PdfId beadObj = writer.startObj();
- PutDoc("<< /Type /Bead\n");
- PutDoc(" /T "+Pdf::toPdf(Beads[beac].Parent)+" 0 R\n");
- PutDoc(" /N "+Pdf::toPdf(Beads[beac].Next)+" 0 R\n");
- PutDoc(" /V "+Pdf::toPdf(Beads[beac].Prev)+" 0 R\n");
- PutDoc(" /P "+Pdf::toPdf(Beads[beac].Page)+" 0 R\n");
- PutDoc(" /R [ "+Pdf::toPdf(Beads[beac].Rect.x())+" "+
- Pdf::toPdf(Beads[beac].Rect.y())+" ");
- PutDoc(Pdf::toPdf(Beads[beac].Rect.bottomRight().x())+" "+Pdf::toPdf(Beads[beac].Rect.y()-Beads[beac].Rect.height())+" ]\n");
- PutDoc(">>");
- writer.endObj(beadObj);
- }
- currentThreadObj = 0;
- }
- }
- }
- for (int ele = 0; ele < doc.Items->count(); ++ele)
- doc.Items->at(ele)->inPdfArticle = false;
- }
+ writer.endObj(beadObj);
+ }
+ currentThreadObj = 0;
+ }
+ }
+ }
+ for (int ele = 0; ele < doc.Items->count(); ++ele)
+ doc.Items->at(ele)->inPdfArticle = false;
+
writer.startObj(writer.ThreadsObj);
PutDoc("[ ");
for (int th = 0; th < Threads.count(); ++th)
Modified: trunk/Scribus/scribus/pdflib_core.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/pdflib_core.h
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.h (original)
+++ trunk/Scribus/scribus/pdflib_core.h Tue Feb 13 12:25:10 2018
@@ -256,8 +256,6 @@
//int Dokument;
QMap<QString,ShIm> SharedImages;
QList<PdfDest> NamedDest;
- QList<PdfId> Threads;
- QList<PdfBead> Beads;
QList<PdfId> CalcFields;
Pdf::ResourceMap Patterns;
Pdf::ResourceMap Shadings;
Modified: trunk/Scribus/scribus/pdfwriter.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/pdfwriter.cpp
==============================================================================
--- trunk/Scribus/scribus/pdfwriter.cpp (original)
+++ trunk/Scribus/scribus/pdfwriter.cpp Tue Feb 13 12:25:10 2018
@@ -1,909 +1,909 @@
-/*
-For general Scribus (>=1.3.2) copyright and licensing information please refer
-to the COPYING file provided with the program. Following this notice may exist
-a copyright and/or license notice that predates the release of Scribus 1.3.2
-for which a new license (GPL+exception) is in place.
-*/
-
-#include <QCryptographicHash>
-
-#include "pdfwriter.h"
-#include "rc4.h"
-#include "scstreamfilter_rc4.h"
-#include "util.h"
-
-namespace Pdf
-{
-
-
- bool isWhiteSpace(char c)
- {
- switch (c)
- {
- case 0:
- case 9:
- case 10:
- case 12:
- case 13:
- case 32:
- return true;
- default:
- return false;
- }
- }
-
- bool isDelimiter(char c)
- {
- QByteArray delims("()<>[]{}/%");
- return delims.indexOf(c) >= 0;
- }
-
- bool isRegular(char c)
- {
- return !isWhiteSpace(c) && !isDelimiter(c);
- }
-
- uchar toPdfDocEncoding(QChar c)
- {
- uchar row = c.row();
- uchar cell = c.cell();
- switch(row)
- {
- case 0:
- if (cell <= 23
- || (cell >= 32 && cell <= 127)
- || cell >= 161)
- {
- return cell;
- }
- else
- {
- return 0;
- }
- break;
- case 0x01:
- switch (cell)
- {
- case 0x92:
- return (134);
- case 0x41:
- return (149);
- case 0x52:
- return (150);
- case 0x60:
- return (151);
- case 0x78:
- return (152);
- case 0x7d:
- return (153);
- case 0x31:
- return (154);
- case 0x42:
- return (155);
- case 0x53:
- return (156);
- case 0x61:
- return (157);
- case 0x7e:
- return (158);
- default:
- return (0);
- break;
- }
- break;
-
- case 0x02:
- switch (cell)
- {
- case 0xc7:
- return (25);
- case 0xc6:
- return (26);
- case 0xd8:
- return (24);
- case 0xd9:
- return (27);
- case 0xda:
- return (30);
- case 0xdb:
- return (29);
- case 0xdc:
- return (31);
- case 0xdd:
- return (28);
- default:
- return (0);
- break;
- }
- break;
-
- case 0x20:
- switch (cell)
- {
- case 0x13:
- return (133);
- case 0x14:
- return (132);
- case 0x18:
- return (143);
- case 0x19:
- return (144);
- case 0x1a:
- return (145);
- case 0x1c:
- return (141);
- case 0x1d:
- return (142);
- case 0x1e:
- return (140);
- case 0x20:
- return (129);
- case 0x21:
- return (130);
- case 0x22:
- return (128);
- case 0x26:
- return (131);
- case 0x30:
- return (139);
- case 0x39:
- return (136);
- case 0x3a:
- return (137);
- case 0x44:
- return (135);
- case 0xac:
- return (160);
-
- default:
- return (0);
- break;
- }
- break;
-
- case 0x21:
- switch (cell)
- {
- case 0x22:
- return (146);
- default:
- return (0);
- break;
- }
- break;
-
- case 0x22:
- switch (cell)
- {
- case 0x12:
- return (138);
- default:
- return (0);
- break;
- }
- break;
-
- case 0xfb:
- switch (cell)
- {
- case 0x01:
- return (147);
- case 0x02:
- return (148);
- default:
- return (0);
- break;
- }
- break;
- }
-
- return 0;
- }
-
- QByteArray toPdfDocEncoding(QString s)
- {
- QByteArray result;
- for (int i = 0; i < s.length(); ++i)
- {
- uchar pdfChar = toPdfDocEncoding(s[i]);
- if ((pdfChar != 0) || s[i].isNull())
- result += pdfChar;
- else
- result += "?";
- }
- return result;
- }
-
- int fromPDFDocEncoding(int code)
- {
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include <QCryptographicHash>
+
+#include "pdfwriter.h"
+#include "rc4.h"
+#include "scstreamfilter_rc4.h"
+#include "util.h"
+
+namespace Pdf
+{
+
+
+ bool isWhiteSpace(char c)
+ {
+ switch (c)
+ {
+ case 0:
+ case 9:
+ case 10:
+ case 12:
+ case 13:
+ case 32:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool isDelimiter(char c)
+ {
+ QByteArray delims("()<>[]{}/%");
+ return delims.indexOf(c) >= 0;
+ }
+
+ bool isRegular(char c)
+ {
+ return !isWhiteSpace(c) && !isDelimiter(c);
+ }
+
+ uchar toPdfDocEncoding(QChar c)
+ {
+ uchar row = c.row();
+ uchar cell = c.cell();
+ switch(row)
+ {
+ case 0:
+ if (cell <= 23
+ || (cell >= 32 && cell <= 127)
+ || cell >= 161)
+ {
+ return cell;
+ }
+ else
+ {
+ return 0;
+ }
+ break;
+ case 0x01:
+ switch (cell)
+ {
+ case 0x92:
+ return (134);
+ case 0x41:
+ return (149);
+ case 0x52:
+ return (150);
+ case 0x60:
+ return (151);
+ case 0x78:
+ return (152);
+ case 0x7d:
+ return (153);
+ case 0x31:
+ return (154);
+ case 0x42:
+ return (155);
+ case 0x53:
+ return (156);
+ case 0x61:
+ return (157);
+ case 0x7e:
+ return (158);
+ default:
+ return (0);
+ break;
+ }
+ break;
+
+ case 0x02:
+ switch (cell)
+ {
+ case 0xc7:
+ return (25);
+ case 0xc6:
+ return (26);
+ case 0xd8:
+ return (24);
+ case 0xd9:
+ return (27);
+ case 0xda:
+ return (30);
+ case 0xdb:
+ return (29);
+ case 0xdc:
+ return (31);
+ case 0xdd:
+ return (28);
+ default:
+ return (0);
+ break;
+ }
+ break;
+
+ case 0x20:
+ switch (cell)
+ {
+ case 0x13:
+ return (133);
+ case 0x14:
+ return (132);
+ case 0x18:
+ return (143);
+ case 0x19:
+ return (144);
+ case 0x1a:
+ return (145);
+ case 0x1c:
+ return (141);
+ case 0x1d:
+ return (142);
+ case 0x1e:
+ return (140);
+ case 0x20:
+ return (129);
+ case 0x21:
+ return (130);
+ case 0x22:
+ return (128);
+ case 0x26:
+ return (131);
+ case 0x30:
+ return (139);
+ case 0x39:
+ return (136);
+ case 0x3a:
+ return (137);
+ case 0x44:
+ return (135);
+ case 0xac:
+ return (160);
+
+ default:
+ return (0);
+ break;
+ }
+ break;
+
+ case 0x21:
+ switch (cell)
+ {
+ case 0x22:
+ return (146);
+ default:
+ return (0);
+ break;
+ }
+ break;
+
+ case 0x22:
+ switch (cell)
+ {
+ case 0x12:
+ return (138);
+ default:
+ return (0);
+ break;
+ }
+ break;
+
+ case 0xfb:
+ switch (cell)
+ {
+ case 0x01:
+ return (147);
+ case 0x02:
+ return (148);
+ default:
+ return (0);
+ break;
+ }
+ break;
+ }
+
+ return 0;
+ }
+
+ QByteArray toPdfDocEncoding(QString s)
+ {
+ QByteArray result;
+ for (int i = 0; i < s.length(); ++i)
+ {
+ uchar pdfChar = toPdfDocEncoding(s[i]);
+ if ((pdfChar != 0) || s[i].isNull())
+ result += pdfChar;
+ else
+ result += "?";
+ }
+ return result;
+ }
+
+ int fromPDFDocEncoding(int code)
+ {
if (code <= 23
|| (code >= 32 && code <= 127)
|| (code >= 161))
{
return code;
- }
-
- if (code == 24) return 0x02d8;
- if (code == 25) return 0x02c7;
- if (code == 26) return 0x02c6;
- if (code == 27) return 0x02d9;
- if (code == 28) return 0x02dd;
- if (code == 29) return 0x02db;
- if (code == 30) return 0x02da;
- if (code == 31) return 0x02dc;
-
- if (code == 128) return 0x2022;
- if (code == 129) return 0x2020;
-
- if (code == 130) return 0x2021;
- if (code == 131) return 0x2026;
- if (code == 132) return 0x2014;
- if (code == 133) return 0x2013;
- if (code == 134) return 0x0192;
- if (code == 135) return 0x2044;
- if (code == 136) return 0x2039;
- if (code == 137) return 0x203a;
- if (code == 138) return 0x2212;
- if (code == 139) return 0x2030;
-
- if (code == 140) return 0x201e;
- if (code == 141) return 0x201c;
- if (code == 142) return 0x201d;
- if (code == 143) return 0x2018;
- if (code == 144) return 0x2019;
- if (code == 145) return 0x201a;
- if (code == 146) return 0x2122;
- if (code == 147) return 0xfb01;
- if (code == 148) return 0xfb02;
- if (code == 149) return 0x0141;
-
- if (code == 150) return 0x0152;
- if (code == 151) return 0x0160;
- if (code == 152) return 0x0178;
- if (code == 153) return 0x017d;
- if (code == 154) return 0x0131;
- if (code == 155) return 0x0142;
- if (code == 156) return 0x0153;
- if (code == 157) return 0x0161;
- if (code == 158) return 0x017e;
-
- if (code == 160) return 0x20ac;
-
- return 0;
- }
-
- QByteArray toUTF16(QString s)
- {
- QByteArray result;
- result.append(0xfe);
- result.append(0xff);
- for (int i = 0; i < s.length(); ++i)
- {
- result.append(s[i].row());
- result.append(s[i].cell());
- }
- return result;
- }
-
- QByteArray toAscii(QString s)
- {
- QByteArray result;
- for (int i = 0; i < s.length(); ++i)
- {
- uchar row = s[i].row();
- uchar cell = s[i].cell();
- if (row == 0 && cell <= 127)
- {
- result.append(cell);
- }
- else
- {
- result.append("?");
- }
- }
- return result;
- }
-
- QByteArray toPdf(bool v)
- {
- return v? "true" : "false";
- }
-
- QByteArray toPdf(int v)
- {
- return QByteArray::number(v);
- }
-
- QByteArray toPdf(uint v)
- {
- return QByteArray::number(v);
- }
-
- QByteArray toPdf(qlonglong v)
- {
- return QByteArray::number(v);
- }
-
- QByteArray toPdf(qulonglong v)
- {
- return QByteArray::number(v);
- }
-
- QByteArray toPdf(double v)
- {
- return QByteArray::number(v, 'f');
- }
-
- QByteArray toObjRef(PdfId id)
- {
- return toPdf(id) + " 0 R";
- }
-
-
- QByteArray toLiteralString(QString s)
- {
- return toLiteralString(toPdfDocEncoding(s));
- }
-
- QByteArray toLiteralString(QByteArray s)
- {
- int linelength = 80;
- QByteArray result("(");
- for (int i = 0; i < s.length(); ++i)
- {
- uchar v = s[i];
- if ( v == '(' || v == ')' || v == '\\')
- {
- result.append('\\');
- result.append(v);
- }
- else if (v < 32 || v >= 127)
- {
- result.append('\\');
- result.append("01234567"[ (v/64) % 8]);
- result.append("01234567"[ (v/8) % 8]);
- result.append("01234567"[ v % 8]);
- }
- else
- {
- result.append(v);
- }
- if (i % linelength == linelength-1)
- result.append("\\\n");
- }
- result.append(")");
- return result;
- }
-
- QByteArray toHexString(QByteArray s)
- {
- int linelength = 80;
- QByteArray result("<");
- for (int i = 0; i < s.length(); ++i)
- {
- uchar v = s[i];
- result.append("0123456789ABCDEF"[v / 16]);
- result.append("0123456789ABCDEF"[v % 16]);
- if (i % linelength == linelength-1)
- result.append("\n");
- }
- result.append(">");
- return result;
- }
-
- QByteArray toHexString8(quint8 b)
- {
- QByteArray result("<");
- result.append("0123456789ABCDEF"[b / 16]);
- result.append("0123456789ABCDEF"[b % 16]);
- result.append(">");
- return result;
- }
-
- QByteArray toHexString16(quint16 b)
- {
- QByteArray result("<");
- result.append("0123456789ABCDEF"[(b >> 12) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 8) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 4) & 0xf]);
- result.append("0123456789ABCDEF"[ b & 0xf]);
- result.append(">");
- return result;
- }
-
- QByteArray toHexString32(quint32 b)
- {
- QByteArray result("<");
- result.append("0123456789ABCDEF"[(b >> 28) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 24) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 20) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 16) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 12) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 8) & 0xf]);
- result.append("0123456789ABCDEF"[(b >> 4) & 0xf]);
- result.append("0123456789ABCDEF"[ b & 0xf]);
- result.append(">");
- return result;
- }
-
-
- QByteArray toName(QString s)
- {
- return toName(toPdfDocEncoding(s));
- }
-
-
- QByteArray toName(QByteArray s)
- {
- QByteArray result("/");
- for (int i = 0; i < s.length(); ++i)
- {
- uchar c = s[i];
- if (c <= 32 || c >= 127 || c == '#' || isDelimiter(c))
- {
- result.append("#");
- result.append("0123456789ABCDEF"[c / 16]);
- result.append("0123456789ABCDEF"[c % 16]);
- }
- else
- {
- result.append(c);
- }
- }
- return result;
- }
-
- QByteArray toDateString(QDateTime dt)
- {
- QString tmp = dt.toString("yyyy:MM:dd:HH:mm:ss");
- tmp = tmp.replace(":", "");
- return "D:" + tmp.toLatin1() + "Z";
- }
-
-
- QByteArray toRectangleArray(QRect r)
- {
- return "[" + toPdf(r.left()) + " " + toPdf(r.bottom()) + " " + toPdf(r.right()) + " " + toPdf(r.top()) + "]";
- }
-
- QByteArray toRectangleArray(QRectF r)
- {
- return "[" + toPdf(r.left()) + " " + toPdf(r.bottom()) + " " + toPdf(r.right()) + " " + toPdf(r.top()) + "]";
- }
-
-
-
-
- Writer::Writer()
- {
- CatalogObj = 1;
- InfoObj = 2;
- OutlinesObj = 3;
- PagesObj = 4;
- DestsObj = 5;
- AcroFormObj = 6;
- NamesObj = 7;
- ThreadsObj = 8;
-
- OCPropertiesObj = 0;
- OutputIntentObj = 0;
- EncryptObj = 0;
- MetaDataObj = 0;
- ResourcesObj = 0;
-
- m_ObjCounter = 0;
- m_CurrentObj = 0;
-
- m_KeyLen = 5;
- m_KeyGen.resize(32);
- m_OwnerKey.resize(32);
- m_UserKey.resize(32);
- m_FileID.resize(16);
- m_EncryKey.resize(5);
-
- int kg_array[] = {
- 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
- 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
- 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
- 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a };
- for (int a = 0; a < 32; ++a)
- m_KeyGen[a] = kg_array[a];
-
- }
-
-
- bool Writer::open(const QString& fn)
- {
- m_Spool.setFileName(fn);
- if (!m_Spool.open(QIODevice::WriteOnly))
- return false;
- m_outStream.setDevice(&m_Spool);
- m_ObjCounter = 9;
- return true;
- }
-
-
- ScStreamFilter* Writer::openStreamFilter(bool encrypted, PdfId objId)
- {
- if (encrypted)
- {
- QByteArray step1 = ComputeRC4Key(objId);
- return new ScRC4EncodeFilter(&m_outStream, step1.data(), qMin(m_KeyLen+5, 16));
- }
- else
- {
- return new ScNullEncodeFilter(&m_outStream);
- }
- }
-
-
- bool Writer::close(bool abortExport)
- {
- bool result = (m_Spool.error() == QFile::NoError);
-
- m_Spool.close();
- if (abortExport || !result)
- {
- if (m_Spool.exists())
- m_Spool.remove();
- }
- return result;
- }
-
-
- void Writer::setFileId(const QByteArray& id)
- {
- m_FileID = QCryptographicHash::hash(id, QCryptographicHash::Md5);
- }
-
-
- void Writer::setEncryption(bool keyLen16, const QByteArray& PassOwner, const QByteArray& PassUser, int Permissions)
- {
- QByteArray ok = "";
- QByteArray uk = "";
-
- if (keyLen16)
- m_KeyLen = 16;
- else
- m_KeyLen = 5;
- CalcOwnerKey(PassOwner, PassUser);
- CalcUserKey(PassUser, Permissions);
- for (uint cl2 = 0; cl2 < 32; ++cl2)
- ok += (m_OwnerKey[cl2]);
- if (keyLen16)
- {
- for (uint cl3 = 0; cl3 < 16; ++cl3)
- uk += (m_UserKey[cl3]);
- for (uint cl3r = 0; cl3r < 16; ++cl3r)
- uk += (m_KeyGen[cl3r]);
- }
- else
- {
- for (uint cl = 0; cl < 32; ++cl)
- uk += (m_UserKey[cl]);
- }
-
- EncryptObj = newObject();
- startObj(EncryptObj);
- write("<<\n/Filter /Standard\n");
- write( keyLen16 ? "/R 3\n/V 2\n/Length 128\n" : "/R 2\n/V 1\n");
- write("/O "+Pdf::toHexString(ok)+"\n");
- write("/U "+Pdf::toHexString(uk)+"\n");
- write("/P "+Pdf::toPdf(Permissions)+"\n>>");
- endObj(EncryptObj);
-
- }
-
-
- QByteArray Writer::encryptBytes(const QByteArray& in, PdfId ObjNum)
- {
- rc4_context_t rc4;
- QByteArray result(in.length(), ' ');
- if (in.length() > 0)
- {
- QByteArray step1 = ComputeRC4Key(ObjNum);
- rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), qMin(m_KeyLen+5, 16));
- rc4_encrypt(&rc4, reinterpret_cast<const uchar*>(in.data()), reinterpret_cast<uchar*>(result.data()), in.length());
- }
- return result;
- }
-
- QByteArray Writer::ComputeRC4Key(PdfId ObjNum)
- {
- int dlen = 0;
- QByteArray data(10, ' ');
- if (m_KeyLen > 5)
- data.resize(21);
- for (int cd = 0; cd < m_KeyLen; ++cd)
- {
- data[cd] = m_EncryKey[cd];
- dlen++;
- }
- data[dlen++] = ObjNum;
- data[dlen++] = ObjNum >> 8;
- data[dlen++] = ObjNum >> 16;
- data[dlen++] = 0;
- data[dlen++] = 0;
- QByteArray rc4Key(16, ' ');
- rc4Key = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- rc4Key.resize(qMin(m_KeyLen+5, 16));
- return rc4Key;
- }
-
-
- QByteArray Writer::FitKey(const QByteArray & pass)
- {
- QByteArray pw(pass);
- if (pw.length() < 32)
- {
- uint l = pw.length();
- for (uint a = 0; a < 32 - l; ++a)
- pw += (m_KeyGen[a]);
- }
- else
- pw = pw.left(32);
- return pw;
- }
-
- void Writer::CalcOwnerKey(const QByteArray & Owner, const QByteArray & User)
- {
- rc4_context_t rc4;
- QByteArray pw(FitKey(User));
- QByteArray pw2(FitKey(Owner.isEmpty() ? User : Owner));
- QByteArray step1(16, ' ');
- step1 = QCryptographicHash::hash(pw2, QCryptographicHash::Md5);
- if (m_KeyLen > 5)
- {
- for (int kl = 0; kl < 50; ++kl)
- step1 = QCryptographicHash::hash(step1, QCryptographicHash::Md5);
- }
- QByteArray us(32, ' ');
- QByteArray enk(16, ' ');
- if (m_KeyLen > 5)
- {
- for (uint a2 = 0; a2 < 32; ++a2)
- m_OwnerKey[a2] = QChar(pw.at(a2)).cell();
- for (int rl = 0; rl < 20; rl++)
- {
- for (int j = 0; j < 16; j ++)
- enk[j] = step1[j] ^ rl;
- rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
- rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_OwnerKey.data()),
- reinterpret_cast<uchar*>(m_OwnerKey.data()), 32);
- }
- }
- else
- {
- for (uint a = 0; a < 32; ++a)
- us[a] = static_cast<uchar>(QChar(pw.at(a)).cell());
- rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
- rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()),
- reinterpret_cast<uchar*>(m_OwnerKey.data()), 32);
- }
- }
-
- void Writer::CalcUserKey(const QByteArray & User, int Permission)
- {
- rc4_context_t rc4;
- QByteArray pw(FitKey(User));
- QByteArray step1(16, ' ');
- QByteArray perm(4, ' ');
- uint perm_value = static_cast<uint>(Permission);
- perm[0] = perm_value;
- perm[1] = perm_value >> 8;
- perm[2] = perm_value >> 16;
- perm[3] = perm_value >> 24;
- for (uint a = 0; a < 32; ++a)
- pw += (m_OwnerKey[a]);
- for (uint a1 = 0; a1 < 4; ++a1)
- pw += (perm[a1]);
- for (uint a3 = 0; a3 < 16; ++a3)
- pw += (m_FileID[a3]);
- step1 = QCryptographicHash::hash(pw, QCryptographicHash::Md5);
- if (m_KeyLen > 5)
- {
- for (int kl = 0; kl < 50; ++kl)
- step1 = QCryptographicHash::hash(step1, QCryptographicHash::Md5);
- m_EncryKey.resize(16);
- }
- for (int a2 = 0; a2 < m_KeyLen; ++a2)
- m_EncryKey[a2] = step1[a2];
- if (m_KeyLen > 5)
- {
- QByteArray pr2("");
- for (int kl3 = 0; kl3 < 32; ++kl3)
- pr2 += (m_KeyGen[kl3]);
- for (uint a4 = 0; a4 < 16; ++a4)
- pr2 += (m_FileID[a4]);
- step1 = QCryptographicHash::hash(pr2, QCryptographicHash::Md5);
- QByteArray enk(16, ' ');
- for (uint a3 = 0; a3 < 16; ++a3)
- m_UserKey[a3] = step1[a3];
- for (int rl = 0; rl < 20; rl++)
- {
- for (int j = 0; j < 16; j ++)
- enk[j] = m_EncryKey[j] ^ rl;
- rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
- rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_UserKey.data()), reinterpret_cast<uchar*>(m_UserKey.data()), 16);
- }
- }
- else
- {
- rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
- rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_KeyGen.data()), reinterpret_cast<uchar*>(m_UserKey.data()), 32);
- }
- }
-
-// QByteArray PDFLibCore::ComputeMD5(const QString& in)
-// {
-// uint inlen=in.length();
-// QByteArray TBytes(inlen, ' ');
-// for (uint a = 0; a < inlen; ++a)
-// TBytes[a] = static_cast<uchar>(QChar(in.at(a)).cell());
-// return QCryptographicHash::hash(TBytes, QCryptographicHash::Md5);
-// }
-
-
- void Writer::writeHeader(PDFOptions::PDFVersion Version)
- {
- switch (Version)
- {
- case PDFOptions::PDFVersion_X1a:
- case PDFOptions::PDFVersion_X3:
- case PDFOptions::PDFVersion_13:
- write("%PDF-1.3\n");
- break;
- case PDFOptions::PDFVersion_14:
- write("%PDF-1.4\n");
- break;
- case PDFOptions::PDFVersion_X4:
- case PDFOptions::PDFVersion_15:
- write("%PDF-1.5\n");
- break;
- }
- write("%\xc7\xec\x8f\xa2\n");
- }
-
- void Writer::writeXrefAndTrailer()
- {
- QByteArray tmp;
- uint StX = bytesWritten();
- write("xref\n");
- write("0 "+Pdf::toPdf(m_ObjCounter)+"\n");
- //write("0000000000 65535 f \n");
- for (int a = 0; a < m_XRef.count(); ++a)
- {
- if (m_XRef[a] > 0)
- {
- tmp.setNum(m_XRef[a]);
- while (tmp.length()< 10)
- {
- tmp.prepend('0');
- }
- write(tmp);
- write(" 00000 n \n");
- }
- else
- {
- // unused object, mark as free-never-to-be-used-again
- write("0000000000 65535 f \n");
- }
- }
- write("trailer\n<<\n/Size "+Pdf::toPdf(m_XRef.count())+"\n");
- QByteArray IDs ="";
- for (uint cl = 0; cl < 16; ++cl)
- IDs += (m_FileID[cl]);
- QByteArray IDbytes = Pdf::toHexString(IDs);
- write("/Root 1 0 R\n/Info 2 0 R\n/ID ["+IDbytes+IDbytes+"]\n");
- if (EncryptObj > 0)
- write("/Encrypt "+Pdf::toObjRef(EncryptObj)+"\n");
- write(">>\nstartxref\n");
- write(Pdf::toPdf(StX)+"\n%%EOF\n");
- }
-
-
- void Writer::write(const QByteArray& bytes)
- {
- m_outStream.writeRawData(bytes, bytes.size());
- }
-
- void Writer::write(const ResourceDictionary& dict)
- {
- write("<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
- if (dict.XObject.count() != 0)
- {
- write("/XObject <<\n");
- ResourceMap::ConstIterator iti;
- for (iti = dict.XObject.begin(); iti != dict.XObject.end(); ++iti)
- write(Pdf::toName(iti.key()) + " " + Pdf::toObjRef(iti.value()) + "\n");
- write(">>\n");
- }
- if (dict.Font.count() != 0)
- {
- write("/Font << \n");
- QMap<QByteArray,PdfId>::ConstIterator it2;
- for (it2 = dict.Font.begin(); it2 != dict.Font.end(); ++it2)
- write(Pdf::toName(it2.key()) + " " + Pdf::toObjRef(it2.value()) + "\n");
- write(">>\n");
- }
- if (dict.Shading.count() != 0)
- {
- write("/Shading << \n");
- QMap<QByteArray,PdfId>::ConstIterator it3;
- for (it3 = dict.Shading.begin(); it3 != dict.Shading.end(); ++it3)
- write(Pdf::toName(it3.key()) + " " + Pdf::toObjRef(it3.value()) + "\n");
- write(">>\n");
- }
- if (dict.Pattern.count() != 0)
- {
- write("/Pattern << \n");
- QMap<QByteArray,PdfId>::ConstIterator it3p;
- for (it3p = dict.Pattern.begin(); it3p != dict.Pattern.end(); ++it3p)
- write(Pdf::toName(it3p.key()) + " " + Pdf::toObjRef(it3p.value()) + "\n");
- write(">>\n");
- }
- if (dict.ExtGState.count() != 0)
- {
- write("/ExtGState << \n");
- QMap<QByteArray,PdfId>::ConstIterator it3t;
- for (it3t = dict.ExtGState.begin(); it3t != dict.ExtGState.end(); ++it3t)
- write(Pdf::toName(it3t.key()) + " " + Pdf::toObjRef(it3t.value()) + "\n");
- write(">>\n");
- }
- if (dict.Properties.count() != 0)
- {
- write("/Properties << \n");
- QMap<QByteArray,PdfId>::ConstIterator it4p;
- for (it4p = dict.Properties.begin(); it4p != dict.Properties.end(); ++it4p)
- write(Pdf::toName(it4p.key()) + " " + Pdf::toObjRef(it4p.value()) + "\n");
- write(">>\n");
- }
- if (dict.ColorSpace.count() != 0)
- {
- write("/ColorSpace << \n");
- QList<Resource>::ConstIterator it3c;
- for (it3c = dict.ColorSpace.begin(); it3c != dict.ColorSpace.end(); ++it3c)
- write(Pdf::toName(it3c->ResName) + " " + Pdf::toObjRef(it3c->ResNum) + "\n");
-
- write(">>\n");
- }
- write(">>\n");
- }
-
-
- PdfId Writer::reserveObjects(unsigned int n)
- {
- assert( n < (1<<30) ); // should only be triggered by reserveObjects(-1) or similar
- PdfId result = m_ObjCounter;
- m_ObjCounter += n;
- return result;
- }
-
- void Writer::startObj(PdfId id)
- {
- assert( m_CurrentObj == 0);
- m_CurrentObj = id;
- while (static_cast<uint>(m_XRef.length()) <= id)
- m_XRef.append(0);
- m_XRef[id] = bytesWritten();
- write(toPdf(id));
- write(" 0 obj\n");
- }
-
- void Writer::endObj(PdfId id)
- {
- assert( m_CurrentObj == id);
- m_CurrentObj = 0;
- write("\nendobj\n");
- }
-
- void Writer::endObjectWithStream(bool encrypted, PdfId id, const QByteArray& streamContent)
- {
- assert( m_CurrentObj == id);
- write("\nstream\n");
- write(encrypted? encryptBytes(streamContent, id): streamContent);
- write("\nendstream");
- endObj(id);
- }
-
-} // namespace PDF
+ }
+
+ if (code == 24) return 0x02d8;
+ if (code == 25) return 0x02c7;
+ if (code == 26) return 0x02c6;
+ if (code == 27) return 0x02d9;
+ if (code == 28) return 0x02dd;
+ if (code == 29) return 0x02db;
+ if (code == 30) return 0x02da;
+ if (code == 31) return 0x02dc;
+
+ if (code == 128) return 0x2022;
+ if (code == 129) return 0x2020;
+
+ if (code == 130) return 0x2021;
+ if (code == 131) return 0x2026;
+ if (code == 132) return 0x2014;
+ if (code == 133) return 0x2013;
+ if (code == 134) return 0x0192;
+ if (code == 135) return 0x2044;
+ if (code == 136) return 0x2039;
+ if (code == 137) return 0x203a;
+ if (code == 138) return 0x2212;
+ if (code == 139) return 0x2030;
+
+ if (code == 140) return 0x201e;
+ if (code == 141) return 0x201c;
+ if (code == 142) return 0x201d;
+ if (code == 143) return 0x2018;
+ if (code == 144) return 0x2019;
+ if (code == 145) return 0x201a;
+ if (code == 146) return 0x2122;
+ if (code == 147) return 0xfb01;
+ if (code == 148) return 0xfb02;
+ if (code == 149) return 0x0141;
+
+ if (code == 150) return 0x0152;
+ if (code == 151) return 0x0160;
+ if (code == 152) return 0x0178;
+ if (code == 153) return 0x017d;
+ if (code == 154) return 0x0131;
+ if (code == 155) return 0x0142;
+ if (code == 156) return 0x0153;
+ if (code == 157) return 0x0161;
+ if (code == 158) return 0x017e;
+
+ if (code == 160) return 0x20ac;
+
+ return 0;
+ }
+
+ QByteArray toUTF16(QString s)
+ {
+ QByteArray result;
+ result.append(0xfe);
+ result.append(0xff);
+ for (int i = 0; i < s.length(); ++i)
+ {
+ result.append(s[i].row());
+ result.append(s[i].cell());
+ }
+ return result;
+ }
+
+ QByteArray toAscii(QString s)
+ {
+ QByteArray result;
+ for (int i = 0; i < s.length(); ++i)
+ {
+ uchar row = s[i].row();
+ uchar cell = s[i].cell();
+ if (row == 0 && cell <= 127)
+ {
+ result.append(cell);
+ }
+ else
+ {
+ result.append("?");
+ }
+ }
+ return result;
+ }
+
+ QByteArray toPdf(bool v)
+ {
+ return v? "true" : "false";
+ }
+
+ QByteArray toPdf(int v)
+ {
+ return QByteArray::number(v);
+ }
+
+ QByteArray toPdf(uint v)
+ {
+ return QByteArray::number(v);
+ }
+
+ QByteArray toPdf(qlonglong v)
+ {
+ return QByteArray::number(v);
+ }
+
+ QByteArray toPdf(qulonglong v)
+ {
+ return QByteArray::number(v);
+ }
+
+ QByteArray toPdf(double v)
+ {
+ return QByteArray::number(v, 'f');
+ }
+
+ QByteArray toObjRef(PdfId id)
+ {
+ return toPdf(id) + " 0 R";
+ }
+
+
+ QByteArray toLiteralString(QString s)
+ {
+ return toLiteralString(toPdfDocEncoding(s));
+ }
+
+ QByteArray toLiteralString(QByteArray s)
+ {
+ int linelength = 80;
+ QByteArray result("(");
+ for (int i = 0; i < s.length(); ++i)
+ {
+ uchar v = s[i];
+ if ( v == '(' || v == ')' || v == '\\')
+ {
+ result.append('\\');
+ result.append(v);
+ }
+ else if (v < 32 || v >= 127)
+ {
+ result.append('\\');
+ result.append("01234567"[ (v/64) % 8]);
+ result.append("01234567"[ (v/8) % 8]);
+ result.append("01234567"[ v % 8]);
+ }
+ else
+ {
+ result.append(v);
+ }
+ if (i % linelength == linelength-1)
+ result.append("\\\n");
+ }
+ result.append(")");
+ return result;
+ }
+
+ QByteArray toHexString(QByteArray s)
+ {
+ int linelength = 80;
+ QByteArray result("<");
+ for (int i = 0; i < s.length(); ++i)
+ {
+ uchar v = s[i];
+ result.append("0123456789ABCDEF"[v / 16]);
+ result.append("0123456789ABCDEF"[v % 16]);
+ if (i % linelength == linelength-1)
+ result.append("\n");
+ }
+ result.append(">");
+ return result;
+ }
+
+ QByteArray toHexString8(quint8 b)
+ {
+ QByteArray result("<");
+ result.append("0123456789ABCDEF"[b / 16]);
+ result.append("0123456789ABCDEF"[b % 16]);
+ result.append(">");
+ return result;
+ }
+
+ QByteArray toHexString16(quint16 b)
+ {
+ QByteArray result("<");
+ result.append("0123456789ABCDEF"[(b >> 12) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 8) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 4) & 0xf]);
+ result.append("0123456789ABCDEF"[ b & 0xf]);
+ result.append(">");
+ return result;
+ }
+
+ QByteArray toHexString32(quint32 b)
+ {
+ QByteArray result("<");
+ result.append("0123456789ABCDEF"[(b >> 28) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 24) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 20) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 16) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 12) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 8) & 0xf]);
+ result.append("0123456789ABCDEF"[(b >> 4) & 0xf]);
+ result.append("0123456789ABCDEF"[ b & 0xf]);
+ result.append(">");
+ return result;
+ }
+
+
+ QByteArray toName(QString s)
+ {
+ return toName(toPdfDocEncoding(s));
+ }
+
+
+ QByteArray toName(QByteArray s)
+ {
+ QByteArray result("/");
+ for (int i = 0; i < s.length(); ++i)
+ {
+ uchar c = s[i];
+ if (c <= 32 || c >= 127 || c == '#' || isDelimiter(c))
+ {
+ result.append("#");
+ result.append("0123456789ABCDEF"[c / 16]);
+ result.append("0123456789ABCDEF"[c % 16]);
+ }
+ else
+ {
+ result.append(c);
+ }
+ }
+ return result;
+ }
+
+ QByteArray toDateString(QDateTime dt)
+ {
+ QString tmp = dt.toString("yyyy:MM:dd:HH:mm:ss");
+ tmp = tmp.replace(":", "");
+ return "D:" + tmp.toLatin1() + "Z";
+ }
+
+
+ QByteArray toRectangleArray(QRect r)
+ {
+ return "[" + toPdf(r.left()) + " " + toPdf(r.bottom()) + " " + toPdf(r.right()) + " " + toPdf(r.top()) + "]";
+ }
+
+ QByteArray toRectangleArray(QRectF r)
+ {
+ return "[" + toPdf(r.left()) + " " + toPdf(r.bottom()) + " " + toPdf(r.right()) + " " + toPdf(r.top()) + "]";
+ }
+
+
+
+
+ Writer::Writer()
+ {
+ CatalogObj = 1;
+ InfoObj = 2;
+ PagesObj = 3;
+ AcroFormObj = 0;
+ DestsObj = 0;
+ OutlinesObj = 0;
+ NamesObj = 0;
+ ThreadsObj = 0;
+
+ OCPropertiesObj = 0;
+ OutputIntentObj = 0;
+ EncryptObj = 0;
+ MetaDataObj = 0;
+ ResourcesObj = 0;
+
+ m_ObjCounter = 0;
+ m_CurrentObj = 0;
+
+ m_KeyLen = 5;
+ m_KeyGen.resize(32);
+ m_OwnerKey.resize(32);
+ m_UserKey.resize(32);
+ m_FileID.resize(16);
+ m_EncryKey.resize(5);
+
+ int kg_array[] = {
+ 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
+ 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
+ 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
+ 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a };
+ for (int a = 0; a < 32; ++a)
+ m_KeyGen[a] = kg_array[a];
+
+ }
+
+
+ bool Writer::open(const QString& fn)
+ {
+ m_Spool.setFileName(fn);
+ if (!m_Spool.open(QIODevice::WriteOnly))
+ return false;
+ m_outStream.setDevice(&m_Spool);
+ m_ObjCounter = 4;
+ return true;
+ }
+
+
+ ScStreamFilter* Writer::openStreamFilter(bool encrypted, PdfId objId)
+ {
+ if (encrypted)
+ {
+ QByteArray step1 = ComputeRC4Key(objId);
+ return new ScRC4EncodeFilter(&m_outStream, step1.data(), qMin(m_KeyLen+5, 16));
+ }
+ else
+ {
+ return new ScNullEncodeFilter(&m_outStream);
+ }
+ }
+
+
+ bool Writer::close(bool abortExport)
+ {
+ bool result = (m_Spool.error() == QFile::NoError);
+
+ m_Spool.close();
+ if (abortExport || !result)
+ {
+ if (m_Spool.exists())
+ m_Spool.remove();
+ }
+ return result;
+ }
+
+
+ void Writer::setFileId(const QByteArray& id)
+ {
+ m_FileID = QCryptographicHash::hash(id, QCryptographicHash::Md5);
+ }
+
+
+ void Writer::setEncryption(bool keyLen16, const QByteArray& PassOwner, const QByteArray& PassUser, int Permissions)
+ {
+ QByteArray ok = "";
+ QByteArray uk = "";
+
+ if (keyLen16)
+ m_KeyLen = 16;
+ else
+ m_KeyLen = 5;
+ CalcOwnerKey(PassOwner, PassUser);
+ CalcUserKey(PassUser, Permissions);
+ for (uint cl2 = 0; cl2 < 32; ++cl2)
+ ok += (m_OwnerKey[cl2]);
+ if (keyLen16)
+ {
+ for (uint cl3 = 0; cl3 < 16; ++cl3)
+ uk += (m_UserKey[cl3]);
+ for (uint cl3r = 0; cl3r < 16; ++cl3r)
+ uk += (m_KeyGen[cl3r]);
+ }
+ else
+ {
+ for (uint cl = 0; cl < 32; ++cl)
+ uk += (m_UserKey[cl]);
+ }
+
+ EncryptObj = newObject();
+ startObj(EncryptObj);
+ write("<<\n/Filter /Standard\n");
+ write( keyLen16 ? "/R 3\n/V 2\n/Length 128\n" : "/R 2\n/V 1\n");
+ write("/O "+Pdf::toHexString(ok)+"\n");
+ write("/U "+Pdf::toHexString(uk)+"\n");
+ write("/P "+Pdf::toPdf(Permissions)+"\n>>");
+ endObj(EncryptObj);
+
+ }
+
+
+ QByteArray Writer::encryptBytes(const QByteArray& in, PdfId ObjNum)
+ {
+ rc4_context_t rc4;
+ QByteArray result(in.length(), ' ');
+ if (in.length() > 0)
+ {
+ QByteArray step1 = ComputeRC4Key(ObjNum);
+ rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), qMin(m_KeyLen+5, 16));
+ rc4_encrypt(&rc4, reinterpret_cast<const uchar*>(in.data()), reinterpret_cast<uchar*>(result.data()), in.length());
+ }
+ return result;
+ }
+
+ QByteArray Writer::ComputeRC4Key(PdfId ObjNum)
+ {
+ int dlen = 0;
+ QByteArray data(10, ' ');
+ if (m_KeyLen > 5)
+ data.resize(21);
+ for (int cd = 0; cd < m_KeyLen; ++cd)
+ {
+ data[cd] = m_EncryKey[cd];
+ dlen++;
+ }
+ data[dlen++] = ObjNum;
+ data[dlen++] = ObjNum >> 8;
+ data[dlen++] = ObjNum >> 16;
+ data[dlen++] = 0;
+ data[dlen++] = 0;
+ QByteArray rc4Key(16, ' ');
+ rc4Key = QCryptographicHash::hash(data, QCryptographicHash::Md5);
+ rc4Key.resize(qMin(m_KeyLen+5, 16));
+ return rc4Key;
+ }
+
+
+ QByteArray Writer::FitKey(const QByteArray & pass)
+ {
+ QByteArray pw(pass);
+ if (pw.length() < 32)
+ {
+ uint l = pw.length();
+ for (uint a = 0; a < 32 - l; ++a)
+ pw += (m_KeyGen[a]);
+ }
+ else
+ pw = pw.left(32);
+ return pw;
+ }
+
+ void Writer::CalcOwnerKey(const QByteArray & Owner, const QByteArray & User)
+ {
+ rc4_context_t rc4;
+ QByteArray pw(FitKey(User));
+ QByteArray pw2(FitKey(Owner.isEmpty() ? User : Owner));
+ QByteArray step1(16, ' ');
+ step1 = QCryptographicHash::hash(pw2, QCryptographicHash::Md5);
+ if (m_KeyLen > 5)
+ {
+ for (int kl = 0; kl < 50; ++kl)
+ step1 = QCryptographicHash::hash(step1, QCryptographicHash::Md5);
+ }
+ QByteArray us(32, ' ');
+ QByteArray enk(16, ' ');
+ if (m_KeyLen > 5)
+ {
+ for (uint a2 = 0; a2 < 32; ++a2)
+ m_OwnerKey[a2] = QChar(pw.at(a2)).cell();
+ for (int rl = 0; rl < 20; rl++)
+ {
+ for (int j = 0; j < 16; j ++)
+ enk[j] = step1[j] ^ rl;
+ rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
+ rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_OwnerKey.data()),
+ reinterpret_cast<uchar*>(m_OwnerKey.data()), 32);
+ }
+ }
+ else
+ {
+ for (uint a = 0; a < 32; ++a)
+ us[a] = static_cast<uchar>(QChar(pw.at(a)).cell());
+ rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
+ rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()),
+ reinterpret_cast<uchar*>(m_OwnerKey.data()), 32);
+ }
+ }
+
+ void Writer::CalcUserKey(const QByteArray & User, int Permission)
+ {
+ rc4_context_t rc4;
+ QByteArray pw(FitKey(User));
+ QByteArray step1(16, ' ');
+ QByteArray perm(4, ' ');
+ uint perm_value = static_cast<uint>(Permission);
+ perm[0] = perm_value;
+ perm[1] = perm_value >> 8;
+ perm[2] = perm_value >> 16;
+ perm[3] = perm_value >> 24;
+ for (uint a = 0; a < 32; ++a)
+ pw += (m_OwnerKey[a]);
+ for (uint a1 = 0; a1 < 4; ++a1)
+ pw += (perm[a1]);
+ for (uint a3 = 0; a3 < 16; ++a3)
+ pw += (m_FileID[a3]);
+ step1 = QCryptographicHash::hash(pw, QCryptographicHash::Md5);
+ if (m_KeyLen > 5)
+ {
+ for (int kl = 0; kl < 50; ++kl)
+ step1 = QCryptographicHash::hash(step1, QCryptographicHash::Md5);
+ m_EncryKey.resize(16);
+ }
+ for (int a2 = 0; a2 < m_KeyLen; ++a2)
+ m_EncryKey[a2] = step1[a2];
+ if (m_KeyLen > 5)
+ {
+ QByteArray pr2("");
+ for (int kl3 = 0; kl3 < 32; ++kl3)
+ pr2 += (m_KeyGen[kl3]);
+ for (uint a4 = 0; a4 < 16; ++a4)
+ pr2 += (m_FileID[a4]);
+ step1 = QCryptographicHash::hash(pr2, QCryptographicHash::Md5);
+ QByteArray enk(16, ' ');
+ for (uint a3 = 0; a3 < 16; ++a3)
+ m_UserKey[a3] = step1[a3];
+ for (int rl = 0; rl < 20; rl++)
+ {
+ for (int j = 0; j < 16; j ++)
+ enk[j] = m_EncryKey[j] ^ rl;
+ rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
+ rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_UserKey.data()), reinterpret_cast<uchar*>(m_UserKey.data()), 16);
+ }
+ }
+ else
+ {
+ rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
+ rc4_encrypt(&rc4, reinterpret_cast<uchar*>(m_KeyGen.data()), reinterpret_cast<uchar*>(m_UserKey.data()), 32);
+ }
+ }
+
+// QByteArray PDFLibCore::ComputeMD5(const QString& in)
+// {
+// uint inlen=in.length();
+// QByteArray TBytes(inlen, ' ');
+// for (uint a = 0; a < inlen; ++a)
+// TBytes[a] = static_cast<uchar>(QChar(in.at(a)).cell());
+// return QCryptographicHash::hash(TBytes, QCryptographicHash::Md5);
+// }
+
+
+ void Writer::writeHeader(PDFOptions::PDFVersion Version)
+ {
+ switch (Version)
+ {
+ case PDFOptions::PDFVersion_X1a:
+ case PDFOptions::PDFVersion_X3:
+ case PDFOptions::PDFVersion_13:
+ write("%PDF-1.3\n");
+ break;
+ case PDFOptions::PDFVersion_14:
+ write("%PDF-1.4\n");
+ break;
+ case PDFOptions::PDFVersion_X4:
+ case PDFOptions::PDFVersion_15:
+ write("%PDF-1.5\n");
+ break;
+ }
+ write("%\xc7\xec\x8f\xa2\n");
+ }
+
+ void Writer::writeXrefAndTrailer()
+ {
+ QByteArray tmp;
+ uint StX = bytesWritten();
+ write("xref\n");
+ write("0 "+Pdf::toPdf(m_ObjCounter)+"\n");
+ //write("0000000000 65535 f \n");
+ for (int a = 0; a < m_XRef.count(); ++a)
+ {
+ if (m_XRef[a] > 0)
+ {
+ tmp.setNum(m_XRef[a]);
+ while (tmp.length()< 10)
+ {
+ tmp.prepend('0');
+ }
+ write(tmp);
+ write(" 00000 n \n");
+ }
+ else
+ {
+ // unused object, mark as free-never-to-be-used-again
+ write("0000000000 65535 f \n");
+ }
+ }
+ write("trailer\n<<\n/Size "+Pdf::toPdf(m_XRef.count())+"\n");
+ QByteArray IDs ="";
+ for (uint cl = 0; cl < 16; ++cl)
+ IDs += (m_FileID[cl]);
+ QByteArray IDbytes = Pdf::toHexString(IDs);
+ write("/Root 1 0 R\n/Info 2 0 R\n/ID ["+IDbytes+IDbytes+"]\n");
+ if (EncryptObj > 0)
+ write("/Encrypt "+Pdf::toObjRef(EncryptObj)+"\n");
+ write(">>\nstartxref\n");
+ write(Pdf::toPdf(StX)+"\n%%EOF\n");
+ }
+
+
+ void Writer::write(const QByteArray& bytes)
+ {
+ m_outStream.writeRawData(bytes, bytes.size());
+ }
+
+ void Writer::write(const ResourceDictionary& dict)
+ {
+ write("<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
+ if (dict.XObject.count() != 0)
+ {
+ write("/XObject <<\n");
+ ResourceMap::ConstIterator iti;
+ for (iti = dict.XObject.begin(); iti != dict.XObject.end(); ++iti)
+ write(Pdf::toName(iti.key()) + " " + Pdf::toObjRef(iti.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.Font.count() != 0)
+ {
+ write("/Font << \n");
+ QMap<QByteArray,PdfId>::ConstIterator it2;
+ for (it2 = dict.Font.begin(); it2 != dict.Font.end(); ++it2)
+ write(Pdf::toName(it2.key()) + " " + Pdf::toObjRef(it2.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.Shading.count() != 0)
+ {
+ write("/Shading << \n");
+ QMap<QByteArray,PdfId>::ConstIterator it3;
+ for (it3 = dict.Shading.begin(); it3 != dict.Shading.end(); ++it3)
+ write(Pdf::toName(it3.key()) + " " + Pdf::toObjRef(it3.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.Pattern.count() != 0)
+ {
+ write("/Pattern << \n");
+ QMap<QByteArray,PdfId>::ConstIterator it3p;
+ for (it3p = dict.Pattern.begin(); it3p != dict.Pattern.end(); ++it3p)
+ write(Pdf::toName(it3p.key()) + " " + Pdf::toObjRef(it3p.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.ExtGState.count() != 0)
+ {
+ write("/ExtGState << \n");
+ QMap<QByteArray,PdfId>::ConstIterator it3t;
+ for (it3t = dict.ExtGState.begin(); it3t != dict.ExtGState.end(); ++it3t)
+ write(Pdf::toName(it3t.key()) + " " + Pdf::toObjRef(it3t.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.Properties.count() != 0)
+ {
+ write("/Properties << \n");
+ QMap<QByteArray,PdfId>::ConstIterator it4p;
+ for (it4p = dict.Properties.begin(); it4p != dict.Properties.end(); ++it4p)
+ write(Pdf::toName(it4p.key()) + " " + Pdf::toObjRef(it4p.value()) + "\n");
+ write(">>\n");
+ }
+ if (dict.ColorSpace.count() != 0)
+ {
+ write("/ColorSpace << \n");
+ QList<Resource>::ConstIterator it3c;
+ for (it3c = dict.ColorSpace.begin(); it3c != dict.ColorSpace.end(); ++it3c)
+ write(Pdf::toName(it3c->ResName) + " " + Pdf::toObjRef(it3c->ResNum) + "\n");
+
+ write(">>\n");
+ }
+ write(">>\n");
+ }
+
+
+ PdfId Writer::reserveObjects(unsigned int n)
+ {
+ assert( n < (1<<30) ); // should only be triggered by reserveObjects(-1) or similar
+ PdfId result = m_ObjCounter;
+ m_ObjCounter += n;
+ return result;
+ }
+
+ void Writer::startObj(PdfId id)
+ {
+ assert( m_CurrentObj == 0);
+ m_CurrentObj = id;
+ while (static_cast<uint>(m_XRef.length()) <= id)
+ m_XRef.append(0);
+ m_XRef[id] = bytesWritten();
+ write(toPdf(id));
+ write(" 0 obj\n");
+ }
+
+ void Writer::endObj(PdfId id)
+ {
+ assert( m_CurrentObj == id);
+ m_CurrentObj = 0;
+ write("\nendobj\n");
+ }
+
+ void Writer::endObjectWithStream(bool encrypted, PdfId id, const QByteArray& streamContent)
+ {
+ assert( m_CurrentObj == id);
+ write("\nstream\n");
+ write(encrypted? encryptBytes(streamContent, id): streamContent);
+ write("\nendstream");
+ endObj(id);
+ }
+
+} // namespace PDF
Modified: trunk/Scribus/scribus/pdfwriter.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/pdfwriter.h
==============================================================================
--- trunk/Scribus/scribus/pdfwriter.h (original)
+++ trunk/Scribus/scribus/pdfwriter.h Tue Feb 13 12:25:10 2018
@@ -202,12 +202,12 @@
// private:
PdfId CatalogObj; // 1
PdfId InfoObj; // 2
- PdfId OutlinesObj; // 3
- PdfId PagesObj; // 4
- PdfId DestsObj; // 5
- PdfId AcroFormObj; // 6
- PdfId NamesObj; // 7
- PdfId ThreadsObj; // 8
+ PdfId PagesObj; // 3
+ PdfId AcroFormObj;
+ PdfId DestsObj;
+ PdfId OutlinesObj;
+ PdfId NamesObj;
+ PdfId ThreadsObj;
PdfId OCPropertiesObj; // (9)
PdfId OutputIntentObj; // (9 or 10)
PdfId EncryptObj;
Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp (original)
+++ trunk/Scribus/scribus/scribusdoc.cpp Tue Feb 13 12:25:10 2018
@@ -3927,7 +3927,7 @@
docPatterns = patterns;
}
-QStringList ScribusDoc::getUsedPatterns()
+QStringList ScribusDoc::getUsedPatterns() const
{
QList<PageItem*> allItems;
QStringList results;
@@ -3981,7 +3981,7 @@
}
allItems.clear();
}
- for (QHash<int, PageItem*>::iterator itf = FrameItems.begin(); itf != FrameItems.end(); ++itf)
+ for (QHash<int, PageItem*>::const_iterator itf = FrameItems.begin(); itf != FrameItems.end(); ++itf)
{
PageItem *currItem = itf.value();
if (currItem->isGroup())
@@ -4006,7 +4006,7 @@
}
allItems.clear();
}
- for (QHash<QString, ScPattern>::Iterator it = docPatterns.begin(); it != docPatterns.end(); ++it)
+ for (QHash<QString, ScPattern>::const_iterator it = docPatterns.begin(); it != docPatterns.end(); ++it)
{
for (int i = 0; i < it.value().items.count(); ++i)
{
@@ -4727,6 +4727,129 @@
}
}
+bool ScribusDoc::useAcroFormFields() const
+{
+ QList<PageItem*> allItems;
+ const QList<PageItem*>* itemLists[] = { &MasterItems, &DocItems };
+ const PageItem* it = NULL;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ allItems = *(itemLists[i]);
+ while (allItems.count() > 0)
+ {
+ it = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if ((it->itemType() != PageItem::TextFrame) || !it->isAnnotation())
+ continue;
+ if (it->annotation().isAcroFormField())
+ return true;
+ }
+ }
+
+ allItems = FrameItems.values();
+ while (allItems.count() > 0)
+ {
+ PageItem *ite = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if ((it->itemType() != PageItem::TextFrame) || !it->isAnnotation())
+ continue;
+ if (it->annotation().isAcroFormField())
+ return true;
+ }
+
+ QStringList patterns = getUsedPatterns();
+ for (int c = 0; c < patterns.count(); ++c)
+ {
+ ScPattern pa = docPatterns[patterns[c]];
+ allItems = pa.items;
+ while (allItems.count() > 0)
+ {
+ it = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if ((it->itemType() != PageItem::TextFrame) || !it->isAnnotation())
+ continue;
+ if (it->annotation().isAcroFormField())
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ScribusDoc::useAnnotations() const
+{
+ QList<PageItem*> allItems;
+ const QList<PageItem*>* itemLists[] = { &MasterItems, &DocItems };
+ const PageItem* it = NULL;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ allItems = *(itemLists[i]);
+ while (allItems.count() > 0)
+ {
+ it = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if (it->itemType() != PageItem::TextFrame)
+ continue;
+ if (it->isAnnotation())
+ return true;
+ }
+ }
+
+ allItems = FrameItems.values();
+ while (allItems.count() > 0)
+ {
+ PageItem *ite = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if (it->itemType() != PageItem::TextFrame)
+ continue;
+ if (it->isAnnotation())
+ return true;
+ }
+
+ QStringList patterns = getUsedPatterns();
+ for (int c = 0; c < patterns.count(); ++c)
+ {
+ ScPattern pa = docPatterns[patterns[c]];
+ allItems = pa.items;
+ while (allItems.count() > 0)
+ {
+ it = allItems.takeFirst();
+ if (it->isGroup() || it->isTable())
+ {
+ allItems += it->getChildren();
+ continue;
+ }
+ if (it->itemType() != PageItem::TextFrame)
+ continue;
+ if (it->isAnnotation())
+ return true;
+ }
+ }
+
+ return false;
+}
void ScribusDoc::setUnitIndex(const int newIndex)
{
Modified: trunk/Scribus/scribus/scribusdoc.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22386&path=/trunk/Scribus/scribus/scribusdoc.h
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.h (original)
+++ trunk/Scribus/scribus/scribusdoc.h Tue Feb 13 12:25:10 2018
@@ -702,7 +702,7 @@
/*!
* @brief Builds a QStringList of the patterns used within the document
*/
- QStringList getUsedPatterns();
+ QStringList getUsedPatterns() const;
QStringList getUsedPatternsSelection(Selection* customSelection);
QStringList getUsedPatternsHelper(QString pattern, QStringList &results);
QStringList getPatternDependencyList(QStringList used);
@@ -711,6 +711,17 @@
*/
QStringList getUsedSymbols();
QStringList getUsedSymbolsHelper(QString pattern, QStringList &results);
+
+ /*!
+ * @brief Check if document use Acrobat Form Fields
+ */
+ bool useAcroFormFields() const;
+
+ /*!
+ * @brief Check if document use PDF Annotations
+ */
+ bool useAnnotations() const;
+
/**
* @brief Set and get the document's unit index
*/
More information about the scribus-commit
mailing list