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
         */


_______________________________________________
scribus-commit mailing list
scribus-commit@lists.scribus.net
http://lists.scribus.net/mailman/listinfo/scribus-commit

Reply via email to