r14043 by jghali - merge tachtran pdf export work from gsoc 2009

scribus-commit scribus-commit at lists.scribus.net
Sat Sep 26 02:05:41 CEST 2009


Revision: 14043
Author: jghali
Date: 2009-09-26T00:06:42.171998Z
Commit message: merge tachtran pdf export work from gsoc 2009

Changeset: 
M  /trunk/Scribus/scribus/ui/tabpdfoptions.cpp
M  /trunk/Scribus/scribus/pdfoptions.h
M  /trunk/Scribus/scribus/CMakeLists.txt
M  /trunk/Scribus/scribus/ui/pdfopts.cpp
M  /trunk/Scribus/scribus/commonstrings.cpp
M  /trunk/Scribus/scribus/documentchecker.cpp
M  /trunk/Scribus/scribus/commonstrings.h
M  /trunk/Scribus/scribus/scribusstructs.h
M  /trunk/Scribus/scribus/pdflib_core.cpp
M  /trunk/Scribus/scribus/prefsmanager.cpp
M  /trunk/Scribus/scribus/prefsstructs.h
M  /trunk/Scribus/scribus/pdflib_core.h
M  /trunk/Scribus/scribus/pdfoptionsio.cpp
A  /trunk/Scribus/scribus/pdf_analyzer.cpp
A  /trunk/Scribus/scribus/pdf_analyzer.h
M  /trunk/Scribus/win32/vc8/Scribus.vcproj

Diffs:
Index: scribus/documentchecker.cpp
===================================================================
--- scribus/documentchecker.cpp	(revision 14042)
+++ scribus/documentchecker.cpp	(revision 14043)
@@ -21,9 +21,12 @@
 *                                                                         *
 ***************************************************************************/
 
+#include "commonstrings.h"
 #include "documentchecker.h"
 #include "page.h"
 #include "pageitem.h"
+#include "pdf_analyzer.h"
+#include "sccolor.h"
 #include "sclayer.h"
 #include "scribusdoc.h"
 #include "scribusstructs.h"
@@ -31,6 +34,8 @@
 #include "util.h"
 #include "util_formats.h"
 
+#include <QList>
+
 bool DocumentChecker::checkDocument(ScribusDoc *currDoc)
 {
 	PageItem* currItem;
@@ -50,6 +55,10 @@
 	checkerSettings.checkRasterPDF = currDoc->checkerProfiles[currDoc->curCheckProfile].checkRasterPDF;
 	checkerSettings.checkForGIF = currDoc->checkerProfiles[currDoc->curCheckProfile].checkForGIF;
 	checkerSettings.ignoreOffLayers = currDoc->checkerProfiles[currDoc->curCheckProfile].ignoreOffLayers;
+	checkerSettings.checkNotCMYKOrSpot = currDoc->checkerProfiles[currDoc->curCheckProfile].checkNotCMYKOrSpot;
+	checkerSettings.checkDeviceColorsAndOutputIntend = currDoc->checkerProfiles[currDoc->curCheckProfile].checkDeviceColorsAndOutputIntend;
+	checkerSettings.checkFontNotEmbedded = currDoc->checkerProfiles[currDoc->curCheckProfile].checkFontNotEmbedded;
+	checkerSettings.checkFontIsOpenType = currDoc->checkerProfiles[currDoc->curCheckProfile].checkFontIsOpenType;
 	currDoc->docItemErrors.clear();
 	currDoc->masterItemErrors.clear();
 	currDoc->docLayerErrors.clear();
@@ -108,15 +117,15 @@
 		if (currItem->asImageFrame())
 #endif
 		{
-		 	if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures))
+			if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures))
 				itemError.insert(MissingImage, 0);
 			else
 			{
 				if  (((qRound(72.0 / currItem->imageXScale()) < checkerSettings.minResolution) || (qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution))
-				          && (currItem->isRaster) && (checkerSettings.checkResolution))
+						  && (currItem->isRaster) && (checkerSettings.checkResolution))
 					itemError.insert(ImageDPITooLow, 0);
 				if  (((qRound(72.0 / currItem->imageXScale()) > checkerSettings.maxResolution) || (qRound(72.0 / currItem->imageYScale()) > checkerSettings.maxResolution))
-				          && (currItem->isRaster) && (checkerSettings.checkResolution))
+						  && (currItem->isRaster) && (checkerSettings.checkResolution))
 					itemError.insert(ImageDPITooHigh, 0);
 				QFileInfo fi = QFileInfo(currItem->Pfile);
 				QString ext = fi.suffix().toLower();
@@ -124,6 +133,80 @@
 					itemError.insert(PlacedPDF, 0);
 				if ((ext == "gif") && (checkerSettings.checkForGIF))
 					itemError.insert(ImageIsGIF, 0);
+
+				if (extensionIndicatesPDF(ext))
+				{
+					PDFAnalyzer analyst(currItem->Pfile);
+					QList<PDFColorSpace> usedColorSpaces;
+					bool hasTransparency = false;
+					QList<PDFFont> usedFonts;
+					int pageNum = qMin(qMax(1, currItem->pixm.imgInfo.actualPageNumber), currItem->pixm.imgInfo.numberOfPages) - 1;
+					QList<PDFImage> imgs;
+					bool succeeded = analyst.inspectPDF(pageNum, usedColorSpaces, hasTransparency, usedFonts, imgs);
+					if (succeeded)
+					{
+						if (checkerSettings.checkNotCMYKOrSpot || checkerSettings.checkDeviceColorsAndOutputIntend)
+						{
+							int currPrintProfCS = -1;
+							if (currDoc->HasCMS)
+							{
+								cmsHPROFILE printerProf = currDoc->DocPrinterProf;
+								currPrintProfCS = static_cast<int>(cmsGetColorSpace(printerProf));
+							}
+							if (checkerSettings.checkNotCMYKOrSpot)
+							{
+								for (int i=0; i<usedColorSpaces.size(); ++i)
+								{
+									if (usedColorSpaces[i] == CS_DeviceRGB || usedColorSpaces[i] == CS_ICCBased || usedColorSpaces[i] == CS_CalGray
+										|| usedColorSpaces[i] == CS_CalRGB || usedColorSpaces[i] == CS_Lab)
+									{
+										itemError.insert(NotCMYKOrSpot, 0);
+										break;
+									}
+								}
+							}
+							if (checkerSettings.checkDeviceColorsAndOutputIntend && currDoc->HasCMS)
+							{
+								for (int i=0; i<usedColorSpaces.size(); ++i)
+								{
+									if (currPrintProfCS == icSigCmykData && (usedColorSpaces[i] == CS_DeviceRGB || usedColorSpaces[i] == CS_DeviceGray))
+									{
+										itemError.insert(DeviceColorAndOutputIntend, 0);
+										break;
+									}
+									else if (currPrintProfCS == icSigRgbData && (usedColorSpaces[i] == CS_DeviceCMYK || usedColorSpaces[i] == CS_DeviceGray))
+									{
+										itemError.insert(DeviceColorAndOutputIntend, 0);
+										break;
+									}
+								}
+							}
+						}
+						if (checkerSettings.checkTransparency && hasTransparency)
+							itemError.insert(Transparency, 0);
+						if (checkerSettings.checkFontNotEmbedded || checkerSettings.checkFontIsOpenType)
+						{
+							for (int i=0; i<usedFonts.size(); ++i)
+							{
+								PDFFont currentFont = usedFonts[i];
+								if (!currentFont.isEmbedded && checkerSettings.checkFontNotEmbedded)
+									itemError.insert(FontNotEmbedded, 0);
+								if (currentFont.isEmbedded && currentFont.isOpenType && checkerSettings.checkFontIsOpenType)
+									itemError.insert(EmbeddedFontIsOpenType, 0);
+							}
+						}
+						if (checkerSettings.checkResolution)
+						{
+							for (int i=0; i<imgs.size(); ++i)
+							{
+								if ((imgs[i].dpiX < checkerSettings.minResolution) || (imgs[i].dpiY < checkerSettings.minResolution))
+									itemError.insert(ImageDPITooLow, 0);
+								if ((imgs[i].dpiX > checkerSettings.maxResolution) || (imgs[i].dpiY > checkerSettings.maxResolution))
+									itemError.insert(ImageDPITooHigh, 0);
+							}
+						}
+					}
+				}
 			}
 		}
 		if ((currItem->asTextFrame()) || (currItem->asPathText()))
@@ -131,7 +214,7 @@
 #ifndef NLS_PROTO
 			if ( currItem->frameOverflows() && (checkerSettings.checkOverflow) && (!((currItem->isAnnotation()) && ((currItem->annotation().Type() == 5) || (currItem->annotation().Type() == 6)))))
 				itemError.insert(TextOverflow, 0);
-			if (currItem->isAnnotation()) 
+			if (currItem->isAnnotation())
 			{
 				ScFace::FontFormat fformat = currItem->itemText.defaultStyle().charStyle().font().format();
 				if (!(fformat == ScFace::SFNT || fformat == ScFace::TTCF))
@@ -195,6 +278,24 @@
 			}
 #endif
 		}
+		if (((currItem->fillColor() != CommonStrings::None) || (currItem->lineColor() != CommonStrings::None)) && (checkerSettings.checkNotCMYKOrSpot))
+		{
+			bool rgbUsed = false;
+			if ((currItem->fillColor() != CommonStrings::None))
+			{
+				ScColor tmpC = currDoc->PageColors[currItem->fillColor()];
+				if (tmpC.getColorModel() == colorModelRGB)
+					rgbUsed = true;
+			}
+			if ((currItem->lineColor() != CommonStrings::None))
+			{
+				ScColor tmpC = currDoc->PageColors[currItem->lineColor()];
+				if (tmpC.getColorModel() == colorModelRGB)
+					rgbUsed = true;
+			}
+			if (rgbUsed)
+				itemError.insert(NotCMYKOrSpot, 0);
+		}
 		if (itemError.count() != 0)
 			currDoc->masterItemErrors.insert(currItem->ItemNr, itemError);
 	}
@@ -230,15 +331,15 @@
 		if (currItem->asImageFrame())
 #endif
 		{
-		 	if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures))
+			if ((!currItem->PictureIsAvailable) && (checkerSettings.checkPictures))
 				itemError.insert(MissingImage, 0);
 			else
 			{
-				if  (((qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution) || (qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution))
-				           && (currItem->isRaster) && (checkerSettings.checkResolution))
+				if  (((qRound(72.0 / currItem->imageXScale()) < checkerSettings.minResolution) || (qRound(72.0 / currItem->imageYScale()) < checkerSettings.minResolution))
+						   && (currItem->isRaster) && (checkerSettings.checkResolution))
 					itemError.insert(ImageDPITooLow, 0);
 				if  (((qRound(72.0 / currItem->imageXScale()) > checkerSettings.maxResolution) || (qRound(72.0 / currItem->imageYScale()) > checkerSettings.maxResolution))
-				          && (currItem->isRaster) && (checkerSettings.checkResolution))
+						  && (currItem->isRaster) && (checkerSettings.checkResolution))
 					itemError.insert(ImageDPITooHigh, 0);
 				QFileInfo fi = QFileInfo(currItem->Pfile);
 				QString ext = fi.suffix().toLower();
@@ -246,6 +347,79 @@
 					itemError.insert(PlacedPDF, 0);
 				if ((ext == "gif") && (checkerSettings.checkForGIF))
 					itemError.insert(ImageIsGIF, 0);
+				if (extensionIndicatesPDF(ext))
+				{
+					PDFAnalyzer analyst(currItem->Pfile);
+					QList<PDFColorSpace> usedColorSpaces;
+					bool hasTransparency = false;
+					QList<PDFFont> usedFonts;
+					int pageNum = qMin(qMax(1, currItem->pixm.imgInfo.actualPageNumber), currItem->pixm.imgInfo.numberOfPages) - 1;
+					QList<PDFImage> imgs;
+					bool succeeded = analyst.inspectPDF(pageNum, usedColorSpaces, hasTransparency, usedFonts, imgs);
+					if (succeeded)
+					{
+						if (checkerSettings.checkNotCMYKOrSpot || checkerSettings.checkDeviceColorsAndOutputIntend)
+						{
+							int currPrintProfCS = -1;
+							if (currDoc->HasCMS)
+							{
+								cmsHPROFILE printerProf = currDoc->DocPrinterProf;
+								currPrintProfCS = static_cast<int>(cmsGetColorSpace(printerProf));
+							}
+							if (checkerSettings.checkNotCMYKOrSpot)
+							{
+								for (int i=0; i<usedColorSpaces.size(); ++i)
+								{
+									if (usedColorSpaces[i] == CS_DeviceRGB || usedColorSpaces[i] == CS_ICCBased || usedColorSpaces[i] == CS_CalGray
+										|| usedColorSpaces[i] == CS_CalRGB || usedColorSpaces[i] == CS_Lab)
+									{
+										itemError.insert(NotCMYKOrSpot, 0);
+										break;
+									}
+								}
+							}
+							if (checkerSettings.checkDeviceColorsAndOutputIntend && currDoc->HasCMS)
+							{
+								for (int i=0; i<usedColorSpaces.size(); ++i)
+								{
+									if (currPrintProfCS == icSigCmykData && (usedColorSpaces[i] == CS_DeviceRGB || usedColorSpaces[i] == CS_DeviceGray))
+									{
+										itemError.insert(DeviceColorAndOutputIntend, 0);
+										break;
+									}
+									else if (currPrintProfCS == icSigRgbData && (usedColorSpaces[i] == CS_DeviceCMYK || usedColorSpaces[i] == CS_DeviceGray))
+									{
+										itemError.insert(DeviceColorAndOutputIntend, 0);
+										break;
+									}
+								}
+							}
+						}
+						if (checkerSettings.checkTransparency && hasTransparency)
+							itemError.insert(Transparency, 0);
+						if (checkerSettings.checkFontNotEmbedded || checkerSettings.checkFontIsOpenType)
+						{
+							for (int i=0; i<usedFonts.size(); ++i)
+							{
+								PDFFont currentFont = usedFonts[i];
+								if (!currentFont.isEmbedded && checkerSettings.checkFontNotEmbedded)
+									itemError.insert(FontNotEmbedded, 0);
+								if (currentFont.isEmbedded && currentFont.isOpenType && checkerSettings.checkFontIsOpenType)
+									itemError.insert(EmbeddedFontIsOpenType, 0);
+							}
+						}
+						if (checkerSettings.checkResolution)
+						{
+							for (int i=0; i<imgs.size(); ++i)
+							{
+								if ((imgs[i].dpiX < checkerSettings.minResolution) || (imgs[i].dpiY < checkerSettings.minResolution))
+									itemError.insert(ImageDPITooLow, 0);
+								if ((imgs[i].dpiX > checkerSettings.maxResolution) || (imgs[i].dpiY > checkerSettings.maxResolution))
+									itemError.insert(ImageDPITooHigh, 0);
+							}
+						}
+					}
+				}
 			}
 		}
 		if ((currItem->asTextFrame()) || (currItem->asPathText()))
@@ -253,7 +427,7 @@
 #ifndef NLS_PROTO
 			if ( currItem->frameOverflows() && (checkerSettings.checkOverflow) && (!((currItem->isAnnotation()) && ((currItem->annotation().Type() == 5) || (currItem->annotation().Type() == 6)))))
 				itemError.insert(TextOverflow, 0);
-			if (currItem->isAnnotation()) 
+			if (currItem->isAnnotation())
 			{
 				ScFace::FontFormat fformat = currItem->itemText.defaultStyle().charStyle().font().format();
 				if (!(fformat == ScFace::SFNT || fformat == ScFace::TTCF))
@@ -317,9 +491,27 @@
 			}
 #endif
 		}
+		if (((currItem->fillColor() != CommonStrings::None) || (currItem->lineColor() != CommonStrings::None)) && (checkerSettings.checkNotCMYKOrSpot))
+		{
+			bool rgbUsed = false;
+			if ((currItem->fillColor() != CommonStrings::None))
+			{
+				ScColor tmpC = currDoc->PageColors[currItem->fillColor()];
+				if (tmpC.getColorModel() == colorModelRGB)
+					rgbUsed = true;
+			}
+			if ((currItem->lineColor() != CommonStrings::None))
+			{
+				ScColor tmpC = currDoc->PageColors[currItem->lineColor()];
+				if (tmpC.getColorModel() == colorModelRGB)
+					rgbUsed = true;
+			}
+			if (rgbUsed)
+				itemError.insert(NotCMYKOrSpot, 0);
+		}
 		if (itemError.count() != 0)
 			currDoc->docItemErrors.insert(currItem->ItemNr, itemError);
 	}
-	
+
 	return ((currDoc->docItemErrors.count() != 0) || (currDoc->masterItemErrors.count() != 0) || (currDoc->docLayerErrors.count() != 0));
 }
Index: scribus/pdflib_core.cpp
===================================================================
--- scribus/pdflib_core.cpp	(revision 14042)
+++ scribus/pdflib_core.cpp	(revision 14043)
@@ -5,11 +5,11 @@
 for which a new license (GPL+exception) is in place.
 */
 /***************************************************************************
-                          pdflib_core.cpp  -  description
-                             -------------------
-    begin                : Sat Jan 19 2002
-    copyright            : (C) 2002 by Franz Schmid
-    email                : Franz.Schmid at altmuehlnet.de
+						  pdflib_core.cpp  -  description
+							 -------------------
+	begin                : Sat Jan 19 2002
+	copyright            : (C) 2002 by Franz Schmid
+	email                : Franz.Schmid at altmuehlnet.de
  ***************************************************************************/
 
 /***************************************************************************
@@ -50,6 +50,8 @@
 #include <QString>
 #include <QTemporaryFile>
 #include <QTextCodec>
+#include <QtXml>
+#include <QUuid>
 
 
 #include "ui/bookmwin.h"
@@ -240,7 +242,7 @@
 		ret = true;//Even when aborting we return true. Dont want that "couldnt write msg"
 		if (!abortExport)
 		{
-			if (doc.PDF_Options.Version == PDFOptions::PDFVersion_X3)
+			if ((doc.PDF_Options.Version == PDFOptions::PDFVersion_X3) || (doc.PDF_Options.Version == PDFOptions::PDFVersion_X1a) || (doc.PDF_Options.Version == PDFOptions::PDFVersion_X4))
 				ret = PDF_End_Doc(ScCore->PrinterProfiles[doc.PDF_Options.PrintProf], nam, Components);
 			else
 				ret = PDF_End_Doc();
@@ -341,7 +343,7 @@
 		default:
 			return "";
 	}
-}	
+}
 
 QByteArray PDFLibCore::EncodeUTF16(const QString &in)
 {
@@ -477,7 +479,7 @@
 			succeed &= rc4Encode.closeFilter();
 			bytesWritten = rc4Encode.writtenToStream();
 		}
- 	}
+	}
 	else
 	{
 		ScNullEncodeFilter nullEncode(&outStream);
@@ -496,7 +498,7 @@
 	return (succeed ? bytesWritten : 0);
 }
 
-int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, bool cmyk, 
+int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, bool cmyk,
 										bool gray, bool sameFile, bool precal)
 {
 	bool succeed = true;
@@ -559,7 +561,7 @@
 			succeed &= flateEncode.closeFilter();
 			bytesWritten = flateEncode.writtenToStream();
 		}
- 	}
+	}
 	else
 	{
 		ScFlateEncodeFilter flateEncode(&outStream);
@@ -729,12 +731,13 @@
 	BookMinUse = false;
 	UsedFontsP.clear();
 	UsedFontsF.clear();
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+	if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 		ObjCounter = 10;
 	else
 		ObjCounter = 9;
 	switch (Options.Version)
 	{
+		case PDFOptions::PDFVersion_X1a:
 		case PDFOptions::PDFVersion_X3:
 		case PDFOptions::PDFVersion_13:
 			PutDoc("%PDF-1.3\n");
@@ -742,19 +745,25 @@
 		case PDFOptions::PDFVersion_14:
 			PutDoc("%PDF-1.4\n");
 			break;
+		case PDFOptions::PDFVersion_X4:
 		case PDFOptions::PDFVersion_15:
 			PutDoc("%PDF-1.5\n");
 			break;
 	}
-	if (Options.Version == PDFOptions::PDFVersion_X3)
+	if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4))
 		ObjCounter++;
 	PutDoc("%\xc7\xec\x8f\xa2\n");
 	StartObj(1);
 	PutDoc("<<\n/Type /Catalog\n/Outlines 3 0 R\n/Pages 4 0 R\n/Dests 5 0 R\n/AcroForm 6 0 R\n/Names 7 0 R\n/Threads 8 0 R\n");
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+	if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 		PutDoc("/OCProperties 9 0 R\n");
-	if (Options.Version == PDFOptions::PDFVersion_X3)
+	if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4))
 		PutDoc("/OutputIntents [ "+QString::number(ObjCounter-1)+" 0 R ]\n");
+	if ((Options.Version == PDFOptions::PDFVersion_X4))
+	{
+		ObjCounter++;
+		PutDoc("/Metadata "+QString::number(ObjCounter-1)+" 0 R\n");
+	}
 	PutDoc("/PageLayout ");
 	switch (Options.PageLayout)
 	{
@@ -783,8 +792,8 @@
 	{
 		PutDoc("/OpenAction << /S /JavaScript /JS (this."+Options.openAction+"\\(\\)) >>\n");
 	}
-
-	QDate d = QDate::currentDate();
+	QDateTime dt = QDateTime::currentDateTime().toUTC();
+	QDate d = dt.date();
 	Datum = "D:";
 	tmp.sprintf("%4d", d.year());
 	tmp.replace(QRegExp(" "), "0");
@@ -795,10 +804,15 @@
 	tmp.sprintf("%2d", d.day());
 	tmp.replace(QRegExp(" "), "0");
 	Datum += tmp;
-	tmp = QTime::currentTime().toString();
+	tmp = dt.time().toString();
 	tmp.replace(QRegExp(":"), "");
 	Datum += tmp;
+	Datum += "Z";
 
+	// only include XMP to PDF/X-4 at the moment, could easily be extended to include it to any PDF
+	if (Options.Version == PDFOptions::PDFVersion_X4)
+		generateXMP(dt.toString("yyyy-MM-ddThh:mm:ssZ"));
+
 /* The following code makes the resulting PDF "Reader enabled" in Acrobat Reader 8
    but sadly it doesn't work with newer version, because its based on a bug in AR 8
 	PutDoc("/Perms\n");
@@ -871,7 +885,7 @@
 	PutDoc("<<\n/Creator "+EncString("(Scribus "+QString(VERSION)+")",2)+"\n");
 	PutDoc("/Producer "+EncString("(Scribus PDF Library "+QString(VERSION)+")",2)+"\n");
 	QString docTitle = doc.documentInfo.getTitle();
-	if ((Options.Version == PDFOptions::PDFVersion_X3) && (docTitle.isEmpty()))
+	if (((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4)) && (docTitle.isEmpty()))
 		PutDoc("/Title "+EncStringUTF16("("+doc.DocName+")",2)+"\n");
 	else
 		PutDoc("/Title "+EncStringUTF16("("+doc.documentInfo.getTitle()+")",2)+"\n");
@@ -882,13 +896,22 @@
 	PutDoc("/ModDate "+EncString("("+Datum+")",2)+"\n");
 	if (Options.Version == PDFOptions::PDFVersion_X3)
 		PutDoc("/GTS_PDFXVersion (PDF/X-3:2002)\n");
+	if (Options.Version == PDFOptions::PDFVersion_X1a)
+	{
+		PutDoc("/GTS_PDFXVersion (PDF/X-1:2001)\n");
+		PutDoc("/GTS_PDFXConformance (PDF/X-1a:2001)\n");
+	}
+	if (Options.Version == PDFOptions::PDFVersion_X4)
+		PutDoc("/GTS_PDFXVersion (PDF/X-4)\n");
 	PutDoc("/Trapped /False\n>>\nendobj\n");
 	for (int t = 0; t < 6; ++t)
 		XRef.append(bytesWritten());
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+	if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 		XRef.append(bytesWritten());
-	if (Options.Version == PDFOptions::PDFVersion_X3)
+	if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4))
 		XRef.append(bytesWritten());
+	if (Options.Version == PDFOptions::PDFVersion_X4)
+		XRef.append(bytesWritten());
 	if (Options.Encrypt)
 	{
 		Encrypt = newObject();
@@ -1425,82 +1448,40 @@
 				++nglyphs;
 //				qDebug() << QString("pdflib: nglyphs %1 max %2").arg(nglyphs).arg(AllFonts[it.key()].maxGlyph());
 				uint FontDes = fontDescriptor;
-				uint Fcc = nglyphs / 224;
-				if ((nglyphs % 224) != 0)
-					Fcc += 1;
-				for (uint Fc = 0; Fc < Fcc; ++Fc)
+				if (Options.Version == PDFOptions::PDFVersion_X4 && (fformat == ScFace::SFNT || fformat == ScFace::TTCF))
 				{
 					uint fontWidths2 = newObject();
 					StartObj(fontWidths2);
-					int chCount = 32;
-					PutDoc("[ 0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 ");
-					for (int ww = 32; ww < 256; ++ww)
-					{
-						uint glyph = 224 * Fc + ww - 32;
-						if (gl.contains(glyph))
-							PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
-						else
-							PutDoc("0 ");
-						chCount++;
-						if (signed(glyph) == nglyphs-1)
-							break;
-					}
-					PutDoc("]\nendobj\n");
-					uint fontEncoding2 = newObject();
-					StartObj(fontEncoding2);
 					QStringList toUnicodeMaps;
 					QList<int> toUnicodeMapsCount;
 					QString toUnicodeMap = "";
 					int toUnicodeMapCounter = 0;
-					PutDoc("<< /Type /Encoding\n");
-					PutDoc("/Differences [ \n");
-					int crc = 0;
-					bool startOfSeq = true;
-					for (int ww2 = 32; ww2 < 256; ++ww2)
+
+					PutDoc("[ ");
+					QList<uint> keys = gl.uniqueKeys();
+					QList<uint>::iterator git;
+					for (git = keys.begin(); git != keys.end(); ++git)
 					{
-						uint glyph = 224 * Fc + ww2 - 32;
-						QMap<uint,std::pair<QChar,QString> >::Iterator glIt = gl.find(glyph);
-						if (glIt != gl.end() && !glIt.value().second.isEmpty())
+						PutDoc(QString::number(*git)+" ["+QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(*git)* 1000))+"] " );
+						QString tmp, tmp2;
+						tmp.sprintf("%02X", *git);
+						tmp2.sprintf("%04X", gl.value(*git).first.unicode());
+						toUnicodeMap += QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
+						toUnicodeMapCounter++;
+						if (toUnicodeMapCounter == 100)
 						{
-							if (startOfSeq)
-							{
-								PutDoc(QString::number(ww2)+" ");
-								startOfSeq = false;
-							}
-							PutDoc("/"+glIt.value().second+" ");
-							QString tmp, tmp2;
-							tmp.sprintf("%02X", ww2);
-							tmp2.sprintf("%04X", glIt.value().first.unicode());
-							toUnicodeMap += QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
-							toUnicodeMapCounter++;
-							if (toUnicodeMapCounter == 100)
-							{
-								toUnicodeMaps.append(toUnicodeMap);
-								toUnicodeMapsCount.append(toUnicodeMapCounter);
-								toUnicodeMap = "";
-								toUnicodeMapCounter = 0;
-							}
-							crc++;
+							toUnicodeMaps.append(toUnicodeMap);
+							toUnicodeMapsCount.append(toUnicodeMapCounter);
+							toUnicodeMap = "";
+							toUnicodeMapCounter = 0;
 						}
-						else
-						{
-							startOfSeq = true;
-						}
-						if (signed(glyph) == nglyphs-1)
-							break;
-						if (crc > 8)
-						{
-							PutDoc("\n");
-							crc = 0;
-						}
 					}
+					PutDoc("]\nendobj\n");
 					if (toUnicodeMapCounter != 0)
 					{
 						toUnicodeMaps.append(toUnicodeMap);
 						toUnicodeMapsCount.append(toUnicodeMapCounter);
 					}
-					PutDoc("]\n");
-					PutDoc(">>\nendobj\n");
 					QString toUnicodeMapStream = "";
 					toUnicodeMapStream += "/CIDInit /ProcSet findresource begin\n";
 					toUnicodeMapStream += "12 dict begin\n";
@@ -1528,69 +1509,195 @@
 					uint fontToUnicode2 = WritePDFStream(toUnicodeMapStream);
 					uint fontObject2 = newObject();
 					StartObj(fontObject2);
+					PutDoc("<<\n/Type /Font\n/Subtype /Type0\n");
+					PutDoc("/Name /Fo"+QString::number(a)+"\n");
+					PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
+					PutDoc("/Encoding /Identity-H\n");
+					PutDoc("/ToUnicode "+QString::number(fontToUnicode2)+" 0 R\n");
+					PutDoc("/DescendantFonts [");
+					PutDoc("<</Type /Font");
+					PutDoc("/Subtype /CIDFontType2");
+					PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ));
+					PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R");
+					PutDoc("/CIDSystemInfo <</Ordering(Identity)/Registry(Adobe)/Supplement 0>>");
+					PutDoc("/DW 1000");
+					PutDoc("/W "+QString::number(fontWidths2)+" 0 R");
+					PutDoc("/CIDToGIDMap /Identity");
+					PutDoc(">>"); // close CIDFont dictionary
+					PutDoc("]\n"); // close DescendantFonts array
+					PutDoc(">>\nendobj\n");
+					Seite.FObjects["Fo"+QString::number(a)] = fontObject2;
+				}
+				else
+				{
+					uint Fcc = nglyphs / 224;
+					if ((nglyphs % 224) != 0)
+						Fcc += 1;
+					for (uint Fc = 0; Fc < Fcc; ++Fc)
+					{
+						uint fontWidths2 = newObject();
+						StartObj(fontWidths2);
+						int chCount = 32;
+						PutDoc("[ 0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 ");
+						for (int ww = 32; ww < 256; ++ww)
+						{
+							uint glyph = 224 * Fc + ww - 32;
+							if (gl.contains(glyph))
+								PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
+							else
+								PutDoc("0 ");
+							chCount++;
+							if (signed(glyph) == nglyphs-1)
+								break;
+						}
+						PutDoc("]\nendobj\n");
+						uint fontEncoding2 = newObject();
+						StartObj(fontEncoding2);
+						QStringList toUnicodeMaps;
+						QList<int> toUnicodeMapsCount;
+						QString toUnicodeMap = "";
+						int toUnicodeMapCounter = 0;
+						PutDoc("<< /Type /Encoding\n");
+						PutDoc("/Differences [ \n");
+						int crc = 0;
+						bool startOfSeq = true;
+						for (int ww2 = 32; ww2 < 256; ++ww2)
+						{
+							uint glyph = 224 * Fc + ww2 - 32;
+							QMap<uint,std::pair<QChar,QString> >::Iterator glIt = gl.find(glyph);
+							if (glIt != gl.end() && !glIt.value().second.isEmpty())
+							{
+								if (startOfSeq)
+								{
+									PutDoc(QString::number(ww2)+" ");
+									startOfSeq = false;
+								}
+								PutDoc("/"+glIt.value().second+" ");
+								QString tmp, tmp2;
+								tmp.sprintf("%02X", ww2);
+								tmp2.sprintf("%04X", glIt.value().first.unicode());
+								toUnicodeMap += QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
+								toUnicodeMapCounter++;
+								if (toUnicodeMapCounter == 100)
+								{
+									toUnicodeMaps.append(toUnicodeMap);
+									toUnicodeMapsCount.append(toUnicodeMapCounter);
+									toUnicodeMap = "";
+									toUnicodeMapCounter = 0;
+								}
+								crc++;
+							}
+							else
+							{
+								startOfSeq = true;
+							}
+							if (signed(glyph) == nglyphs-1)
+								break;
+							if (crc > 8)
+							{
+								PutDoc("\n");
+								crc = 0;
+							}
+						}
+						if (toUnicodeMapCounter != 0)
+						{
+							toUnicodeMaps.append(toUnicodeMap);
+							toUnicodeMapsCount.append(toUnicodeMapCounter);
+						}
+						PutDoc("]\n");
+						PutDoc(">>\nendobj\n");
+						QString toUnicodeMapStream = "";
+						toUnicodeMapStream += "/CIDInit /ProcSet findresource begin\n";
+						toUnicodeMapStream += "12 dict begin\n";
+						toUnicodeMapStream += "begincmap\n";
+						toUnicodeMapStream += "/CIDSystemInfo <<\n";
+						toUnicodeMapStream += "/Registry (Adobe)\n";
+						toUnicodeMapStream += "/Ordering (UCS)\n";
+						toUnicodeMapStream += "/Supplement 0\n";
+						toUnicodeMapStream += ">> def\n";
+						toUnicodeMapStream += "/CMapName /Adobe-Identity-UCS def\n";
+						toUnicodeMapStream += "/CMapType 2 def\n";
+						toUnicodeMapStream += "1 begincodespacerange\n";
+						toUnicodeMapStream += "<0000> <FFFF>\n";
+						toUnicodeMapStream += "endcodespacerange\n";
+						for (int uniC = 0; uniC < toUnicodeMaps.count(); uniC++)
+						{
+							toUnicodeMapStream += QString("%1 beginbfchar\n").arg(toUnicodeMapsCount[uniC]);
+							toUnicodeMapStream += toUnicodeMaps[uniC];
+							toUnicodeMapStream += "endbfchar\n";
+						}
+						toUnicodeMapStream += "endcmap\n";
+						toUnicodeMapStream += "CMapName currentdict /CMap defineresource pop\n";
+						toUnicodeMapStream += "end\n";
+						toUnicodeMapStream += "end\n";
+						uint fontToUnicode2 = WritePDFStream(toUnicodeMapStream);
+						uint fontObject2 = newObject();
+						StartObj(fontObject2);
+						PutDoc("<<\n/Type /Font\n/Subtype ");
+						PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
+						PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
+						PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
+						PutDoc("/FirstChar 0\n");
+						PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
+						PutDoc("/Widths "+QString::number(fontWidths2)+" 0 R\n");
+						PutDoc("/Encoding "+QString::number(fontEncoding2)+" 0 R\n");
+						PutDoc("/ToUnicode "+QString::number(fontToUnicode2)+" 0 R\n");
+						PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
+						PutDoc(">>\nendobj\n");
+						Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = fontObject2;
+					} // for(Fc)
+					uint fontWidthsForm = newObject();
+					StartObj(fontWidthsForm);
+					PutDoc("[ 0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 ");
+					for (int ww = 32; ww < 256; ++ww)
+					{
+						uint glyph = AllFonts[it.key()].char2CMap(QChar(ww));
+						if (gl.contains(glyph))
+							PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
+						else
+							PutDoc("0 ");
+					}
+					PutDoc("]\nendobj\n");
+					uint fontObjectForm = newObject();
+					StartObj(fontObjectForm);
 					PutDoc("<<\n/Type /Font\n/Subtype ");
 					PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
-					PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
+	//				if (fformat == ScFace::SFNT || fformat == ScFace::TTCF)
+	//				{
+	//					PutDoc("/TrueType\n");
+						PutDoc("/Name /Fo"+QString::number(a)+"Form"+"\n");
+						Seite.FObjects["Fo"+QString::number(a)+"Form"] = fontObjectForm;
+						UsedFontsF.insert(it.key(), "/Fo"+QString::number(a)+"Form");
+	/*				}
+					else
+					{
+						PutDoc("/Type1\n");
+						PutDoc("/Name /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
+						Seite.FObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )] = ObjCounter;
+						UsedFontsF.insert(it.key(), "/"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ));
+					} */
 					PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
+					PutDoc("/Encoding << \n");
+					PutDoc("/Differences [ \n");
+					PutDoc("24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde\n");
+					PutDoc("39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright\n");
+					PutDoc("/minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron\n");
+					PutDoc("/Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot\n");
+					PutDoc("/.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine\n");
+					PutDoc("188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex\n");
+					PutDoc("/Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
+					PutDoc("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n");
+					PutDoc("/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
+					PutDoc("/divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n");
+					PutDoc("] >>\n");
 					PutDoc("/FirstChar 0\n");
-					PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
-					PutDoc("/Widths "+QString::number(fontWidths2)+" 0 R\n");
-					PutDoc("/Encoding "+QString::number(fontEncoding2)+" 0 R\n");
-					PutDoc("/ToUnicode "+QString::number(fontToUnicode2)+" 0 R\n");
+					PutDoc("/LastChar 255\n");
+					PutDoc("/Widths "+QString::number(fontWidthsForm)+" 0 R\n");
 					PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
 					PutDoc(">>\nendobj\n");
-					Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = fontObject2;
-				} // for(Fc)
-				uint fontWidthsForm = newObject();
-				StartObj(fontWidthsForm);
-				PutDoc("[ 0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 ");
-				for (int ww = 32; ww < 256; ++ww)
-				{
-					uint glyph = AllFonts[it.key()].char2CMap(QChar(ww));
-					if (gl.contains(glyph))
-						PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
-					else
-						PutDoc("0 ");
+	//			} // FT_Has_PS_Glyph_Names
 				}
-				PutDoc("]\nendobj\n");
-				uint fontObjectForm = newObject();
-				StartObj(fontObjectForm);
-				PutDoc("<<\n/Type /Font\n/Subtype ");
-				PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
-//				if (fformat == ScFace::SFNT || fformat == ScFace::TTCF)
-//				{
-//					PutDoc("/TrueType\n");
-					PutDoc("/Name /Fo"+QString::number(a)+"Form"+"\n");
-					Seite.FObjects["Fo"+QString::number(a)+"Form"] = fontObjectForm;
-					UsedFontsF.insert(it.key(), "/Fo"+QString::number(a)+"Form");
-/*				}
-				else
-				{
-					PutDoc("/Type1\n");
-					PutDoc("/Name /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
-					Seite.FObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )] = ObjCounter;
-					UsedFontsF.insert(it.key(), "/"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ));
-				} */
-				PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
-				PutDoc("/Encoding << \n");
-				PutDoc("/Differences [ \n");
-				PutDoc("24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde\n");
-				PutDoc("39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright\n");
-				PutDoc("/minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron\n");
-				PutDoc("/Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot\n");
-				PutDoc("/.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine\n");
-				PutDoc("188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex\n");
-				PutDoc("/Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
-				PutDoc("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n");
-				PutDoc("/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
-				PutDoc("/divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n");
-				PutDoc("] >>\n");
-				PutDoc("/FirstChar 0\n");
-				PutDoc("/LastChar 255\n");
-				PutDoc("/Widths "+QString::number(fontWidthsForm)+" 0 R\n");
-				PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
-				PutDoc(">>\nendobj\n");
-//			} // FT_Has_PS_Glyph_Names
+
 		}
 		a++;
 	}
@@ -1631,7 +1738,7 @@
 		Transpar[HTName] = writeGState("/HT "+QString::number(halftones)+" 0 R\n");
 		ResCount++;
 	}
-	if ((doc.HasCMS) && (Options.UseProfiles))
+	if ((doc.HasCMS) && (Options.UseProfiles) && (Options.Version != PDFOptions::PDFVersion_X1a ))
 	{
 		uint iccProfileObject = newObject();
 		StartObj(iccProfileObject);
@@ -1721,7 +1828,9 @@
 		spotMapReg.insert("Register", spotD);
 		spotCount++;
 	}
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+
+
+	if ( ((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 	{
 		ScLayer ll;
 		struct OCGInfo ocg;
@@ -1780,9 +1889,9 @@
 	{
 		doc.Layers.levelToLayer(ll, Lnr);
 		PItems = doc.MasterItems;
-		if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
+		if ((ll.isPrintable) || (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers)))
 		{
-			if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+			if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 				PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
 			for (int a = 0; a < PItems.count(); ++a)
 			{
@@ -1888,9 +1997,9 @@
 				switch (ite->itemType())
 				{
 					case PageItem::ImageFrame:
-					case PageItem::LatexFrame: 
+					case PageItem::LatexFrame:
 						// Same functions as for ImageFrames work for LatexFrames too
-						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 							PutPage(PDF_TransparenzFill(ite));
 						if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
 						{
@@ -1927,7 +2036,7 @@
 						PutPage("Q\n");
 						if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
 						{
-							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 								PutPage(PDF_TransparenzStroke(ite));
 							if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
 							{
@@ -1952,7 +2061,7 @@
 					case PageItem::TextFrame:
 						break;
 					case PageItem::Line:
-						if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+						if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 							PutPage(PDF_TransparenzStroke(ite));
 						if (ite->NamedLStyle.isEmpty())
 						{
@@ -1965,13 +2074,13 @@
 							multiLine ml = doc.MLineStyles[ite->NamedLStyle];
 							for (int it = ml.size()-1; it > -1; it--)
 							{
-								if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
-								{
-									PutPage(setStrokeMulti(&ml[it]));
-									PutPage("0 0 m\n");
-									PutPage(FToStr(ite->width())+" 0 l\n");
-									PutPage("S\n");
-								}
+									if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
+									{
+										PutPage(setStrokeMulti(&ml[it]));
+										PutPage("0 0 m\n");
+										PutPage(FToStr(ite->width())+" 0 l\n");
+										PutPage("S\n");
+									}
 							}
 						}
 						if (ite->startArrowIndex() != 0)
@@ -1989,7 +2098,7 @@
 					case PageItem::ItemType1:
 					case PageItem::ItemType3:
 					case PageItem::Polygon:
-						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 							PutPage(PDF_TransparenzFill(ite));
 						if (ite->GrType != 0)
 						{
@@ -2007,7 +2116,7 @@
 						}
 						if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 						{
-							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 								PutPage(PDF_TransparenzStroke(ite));
 							if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
 							{
@@ -2032,7 +2141,7 @@
 					case PageItem::PolyLine:
 						if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
 						{
-							if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+							if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 								PutPage(PDF_TransparenzFill(ite));
 							if (ite->GrType != 0)
 							{
@@ -2051,7 +2160,7 @@
 						}
 						if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 						{
-							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+							if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 								PutPage(PDF_TransparenzStroke(ite));
 							if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
 							{
@@ -2115,7 +2224,7 @@
 								PutPage("q\n");
 								if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 								{
-									if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+									if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 										PutPage(PDF_TransparenzStroke(ite));
 									if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
 									{
@@ -2139,7 +2248,7 @@
 								PutPage("Q\n");
 							}
 						}
-						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+						if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 							PutPage(PDF_TransparenzFill(ite));
 						PutPage(setTextSt(ite, pag->pageNr(), pag));
 						break;
@@ -2229,7 +2338,7 @@
 				QString name = QString("master_page_obj_%1_%2").arg(pIndex).arg(ite->ItemNr);
 				Seite.XObjects[name] = templateObject;
 			}
-			if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+			if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 				PutPage("EMC\n");
 		}
 		Lnr++;
@@ -2262,7 +2371,7 @@
 		PutDoc("<<\n/Width "+QString::number(img.width())+"\n");
 		PutDoc("/Height "+QString::number(img.height())+"\n");
 		PutDoc("/ColorSpace /DeviceRGB\n/BitsPerComponent 8\n");
-		
+
 		PutDoc("/Length "+QString::number(array.size()+1)+"\n");
 		if (Options.Compress && compDataAvail)
 			PutDoc("/Filter /FlateDecode\n");
@@ -2469,7 +2578,7 @@
 	}
 	Seite.ObjNum = WritePDFStream(Content);
 	int Gobj = 0;
-	if (Options.Version >= 14)
+	if ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4))
 	{
 		Gobj = newObject();
 		StartObj(Gobj);
@@ -2501,7 +2610,7 @@
 		PutDoc("/ArtBox ["+FToStr(bleedLeft+markOffs)+" "+FToStr(Options.bleeds.Bottom+markOffs)+" "+FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+"]\n");
 	PutDoc("/Rotate "+QString::number(Options.RotateDeg)+"\n");
 	PutDoc("/Contents "+QString::number(Seite.ObjNum)+" 0 R\n");
-	if (Options.Version >= PDFOptions::PDFVersion_14) // && (Transpar.count() != 0))
+	if ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)) // && (Transpar.count() != 0))
 		PutDoc("/Group "+QString::number(Gobj)+" 0 R\n");
 	if (Options.Thumbnails)
 		PutDoc("/Thumb "+QString::number(Seite.Thumb)+" 0 R\n");
@@ -2754,9 +2863,9 @@
 
 	if (!Options.MirrorH)
 		PutPage("1 0 0 1 0 0 cm\n");
-	if ((layer.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
+	if ((layer.isPrintable) || (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers)))
 	{
-		if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+		if ((((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4))) && (Options.useLayers))
 			PutPage("/OC /"+OCGEntries[layer.Name].Name+" BDC\n");
 		for (int am = 0; am < pag->FromMaster.count() && !abortExport; ++am)
 		{
@@ -2834,7 +2943,7 @@
 			ite->BoundingX = OldBX;
 			ite->BoundingY = OldBY;
 		}
-		if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+		if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 			PutPage("EMC\n");
 	}
 	return true;
@@ -2851,10 +2960,10 @@
 
 	int pc_exportpagesitems = usingGUI ? progressDialog->progress("ECPI") : 0;
 	PItems = (pag->pageName().isEmpty()) ? doc.DocItems : doc.MasterItems;
-	if ((layer.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
+	if ((layer.isPrintable) || (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers)))
 	{
 		QString inh = "";
-		if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+		if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 			PutPage("/OC /"+OCGEntries[layer.Name].Name+" BDC\n");
 		for (int a = 0; a < PItems.count() && !abortExport; ++a)
 		{
@@ -2881,7 +2990,7 @@
 				grcon += "h W* n\n";
 				groupStack.push(ite->groupsLastItem);
 				groupStackS.push(ite);
-				if (((layer.transparency != 1) || (layer.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((layer.transparency != 1) || (layer.blendMode != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				{
 					inh += grcon;
 					groupDataStack.push(inh);
@@ -2898,7 +3007,7 @@
 			}
 			if (!PDF_ProcessItem(output, ite, pag, PNr))
 				return false;
-			if (((layer.transparency != 1) || (layer.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((layer.transparency != 1) || (layer.blendMode != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				inh += output;
 			else
 				PutPage(output);
@@ -2908,11 +3017,11 @@
 				{
 					QString tmpData;
 					PageItem *controlItem = groupStackS.pop();
-					if (((layer.transparency != 1) || (layer.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+					if (((layer.transparency != 1) || (layer.blendMode != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 					{
 						tmpData = inh;
 						inh = groupDataStack.pop();
-						if (Options.Version >= PDFOptions::PDFVersion_14)
+						if (Options.Version >= PDFOptions::PDFVersion_14 || Options.Version == PDFOptions::PDFVersion_X4)
 							inh += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
 						else
 							inh += tmpData;
@@ -2922,7 +3031,7 @@
 					{
 						tmpData = Content;
 						Content = groupDataStack.pop();
-						if (Options.Version >= PDFOptions::PDFVersion_14)
+						if (Options.Version >= PDFOptions::PDFVersion_14 || Options.Version == PDFOptions::PDFVersion_X4)
 							Content += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
 						else
 							Content += tmpData;
@@ -2965,12 +3074,12 @@
 				continue;
 			if (!ite->printEnabled())
 				continue;
-			if (((layer.transparency != 1) || (layer.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((layer.transparency != 1) || (layer.blendMode != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				inh += PDF_ProcessTableItem(ite, pag);
 			else
 				PutPage(PDF_ProcessTableItem(ite, pag));
 		}
-		if (((layer.transparency != 1) || (layer.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+		if (((layer.transparency != 1) || (layer.blendMode != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) ||(Options.Version == PDFOptions::PDFVersion_X4)))
 		{
 			int Gobj = newObject();
 			StartObj(Gobj);
@@ -3008,7 +3117,7 @@
 			PutPage("/"+name+" Do\n");
 			PutPage("Q\n");
 		}
-		if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+		if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 			PutPage("EMC\n");
 	}
 	return true;
@@ -3075,7 +3184,7 @@
 //		tmp += PDF_Transparenz(ite);
 //	if (ite->fillColor() != CommonStrings::None)
 //		tmp += putColor(ite->fillColor(), ite->fillShade(), true);
-	if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+	if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 		tmp += PDF_TransparenzStroke(ite);
 	if (ite->lineColor() != CommonStrings::None)
 		tmp += putColor(ite->lineColor(), ite->lineShade(), false);
@@ -3291,7 +3400,7 @@
 			}
 #endif
 			// Same functions as for ImageFrames work for LatexFrames too
-			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4) ))
 				tmp += PDF_TransparenzFill(ite);
 			if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
 			{
@@ -3328,7 +3437,7 @@
 			tmp += "Q\n";
 			if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
 			{
-				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4) ))
 					tmp += PDF_TransparenzStroke(ite);
 				if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
 				{
@@ -3355,14 +3464,14 @@
 			break;
 		case PageItem::TextFrame:
 //			qDebug() << "case TextFrame";
-			if ((ite->isAnnotation()) && (Options.Version != PDFOptions::PDFVersion_X3))
+			if ((ite->isAnnotation()) && (Options.Version != PDFOptions::PDFVersion_X3) && (Options.Version != PDFOptions::PDFVersion_X1a) && (Options.Version != PDFOptions::PDFVersion_X4))
 			{
 //				qDebug() << "Annotation";
 				if (!PDF_Annotation(ite, PNr))
 					return false;
 				break;
 			}
-			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4) ))
 				tmp += PDF_TransparenzFill(ite);
 			if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
 			{
@@ -3387,7 +3496,7 @@
 			tmp += "Q\n";
 			if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
 			{
-				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4) ))
 					tmp += PDF_TransparenzStroke(ite);
 				if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
 				{
@@ -3413,7 +3522,7 @@
 			}
 			break;
 		case PageItem::Line:
-			if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				tmp += PDF_TransparenzStroke(ite);
 			if (ite->NamedLStyle.isEmpty())
 			{
@@ -3454,7 +3563,7 @@
 		case PageItem::ItemType1:
 		case PageItem::ItemType3:
 		case PageItem::Polygon:
-			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				tmp += PDF_TransparenzFill(ite);
 			if (ite->GrType != 0)
 			{
@@ -3475,7 +3584,7 @@
 			}
 			if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 			{
-				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 					tmp += PDF_TransparenzStroke(ite);
 				if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
 				{
@@ -3503,7 +3612,7 @@
 		case PageItem::PolyLine:
 			if (ite->PoLine.size() > 4)  // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
 			{
-				if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 					tmp += PDF_TransparenzFill(ite);
 				if (ite->GrType != 0)
 				{
@@ -3522,7 +3631,7 @@
 			}
 			if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 			{
-				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+				if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 					tmp += PDF_TransparenzStroke(ite);
 				if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
 				{
@@ -3589,7 +3698,7 @@
 					tmp += "q\n";
 					if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
 					{
-						if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+						if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 							tmp += PDF_TransparenzStroke(ite);
 						if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
 						{
@@ -3616,7 +3725,7 @@
 					tmp += "Q\n";
 				}
 			}
-			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				tmp += PDF_TransparenzFill(ite);
 			tmp += setTextSt(ite, PNr, pag);
 			break;
@@ -3645,7 +3754,7 @@
 			arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
 	}
 	arrow.map(arrowTrans);
-	if ((ite->lineTransparency() != 0) && (Options.Version >= PDFOptions::PDFVersion_14))
+	if ((ite->lineTransparency() != 0) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 	{
 		QString ShName = ResNam+QString::number(ResCount);
 		ResCount++;
@@ -4044,7 +4153,7 @@
 					}
 					tabCc++;
 				}
-				if (ch == SpecialChars::TAB) 
+				if (ch == SpecialChars::TAB)
 				{
 					CurX += hl->glyph.wide();
 					continue;
@@ -4143,7 +4252,7 @@
 					tabCc++;
 				}
 			}
-			if (ch == SpecialChars::TAB) 
+			if (ch == SpecialChars::TAB)
 			{
 				CurX += hl->glyph.wide();
 				continue;
@@ -4219,7 +4328,7 @@
 	double tsz = hl->fontSize();
 	QChar chstr = hl->ch;
 	const CharStyle& style(*hl);
-	
+
 /*	if (hl->effects() & ScStyle_DropCap)
 	{
 		if (pstyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -4316,7 +4425,7 @@
 											"/OPM 1\n");
 				tmp2 += "/"+ShName+" gs\n";
 			}
-			if (((embedded->lineTransparency() != 0) || (embedded->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((embedded->lineTransparency() != 0) || (embedded->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				tmp2 += PDF_TransparenzStroke(embedded);
 			if (embedded->lineColor() != CommonStrings::None)
 				tmp2 += putColor(embedded->lineColor(), embedded->lineShade(), false);
@@ -4389,7 +4498,7 @@
 	uint glyph = hl->glyph.glyph;
 
 	if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
-		glyph == (ScFace::CONTROL_GLYPHS + 32)) 
+		glyph == (ScFace::CONTROL_GLYPHS + 32))
 	{
 		glyph = style.font().char2CMap(QChar(' '));
 		chstr = ' ';
@@ -4399,7 +4508,7 @@
 		glyph = style.font().char2CMap(QChar('-'));
 		chstr = '-';
 	}
-	
+
 	if (glyph < ScFace::CONTROL_GLYPHS)
 	{
 		if (style.strokeColor() != CommonStrings::None)
@@ -4578,7 +4687,13 @@
 					idx1 = Type3Fonts[UsedFontsP[style.font().replacementName()]][idx] / 255;
 				else
 					idx1 = idx / 224;
-				tmp += UsedFontsP[style.font().replacementName()]+"S"+QString::number(idx1)+" "+FToStr(tsz / 10.0)+" Tf\n";
+				ScFace currentFace = style.font();
+				if (Options.Version == PDFOptions::PDFVersion_X4
+					&& (currentFace.format() == ScFace::SFNT || currentFace.format() == ScFace::TTCF)
+					&& ( !Options.SubsetList.contains(style.font().replacementName()) ) )
+					tmp+= UsedFontsP[currentFace.replacementName()]+" "+FToStr(tsz / 10.0)+" Tf\n";
+				else
+					tmp += UsedFontsP[style.font().replacementName()]+"S"+QString::number(idx1)+" "+FToStr(tsz / 10.0)+" Tf\n";
 				if (style.strokeColor() != CommonStrings::None)
 					tmp += StrokeColor;
 				if (style.fillColor() != CommonStrings::None)
@@ -4685,6 +4800,15 @@
 						tmp += "<"+QString(toHex(idx2))+"> Tj\n";
 					}
 				}
+				else if (Options.Version == PDFOptions::PDFVersion_X4 && (currentFace.format() == ScFace::SFNT || currentFace.format() == ScFace::TTCF))
+				{
+					QString val;
+					val.setNum(idx,16);
+					int numberOfZero = 4-val.size();
+					for (int i=0; i<numberOfZero; ++i)
+						val.prepend("0");
+					tmp += "<"+val+"> Tj\n";
+				}
 				else
 				{
 					idx2 = idx % 224 + 32;
@@ -5124,7 +5248,7 @@
 											"/OPM 1\n");
 				tmp2 += "/"+ShName+" gs\n";
 			}
-			if (((item->lineTransparency() != 0) || (item->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
+			if (((item->lineTransparency() != 0) || (item->lineBlendmode() != 0)) && ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
 				tmp2 += PDF_TransparenzStroke(item);
 			if (item->lineColor() != CommonStrings::None)
 				tmp2 += putColor(item->lineColor(), item->lineShade(), false);
@@ -5381,7 +5505,7 @@
 		QString spot1 = colorNames[c].simplified().replace("#", "#23").replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" );
 		QString spot2 = colorNames[c+1].simplified().replace("#", "#23").replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" );
 		QString TRes("");
-		if ((Options.Version >= PDFOptions::PDFVersion_14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
+		if (((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
 		{
 			uint shadingObject = newObject();
 			StartObj(shadingObject);
@@ -5476,7 +5600,7 @@
 						oneSameSpot = (colorNames[c] == colorNames[c+1]);
 						twoSpot  = true;
 					}
-					if (((!oneSpot1) && (!oneSpot2) && (!twoSpot)) || (!Options.UseSpotColors)) 
+					if (((!oneSpot1) && (!oneSpot2) && (!twoSpot)) || (!Options.UseSpotColors))
 						PutDoc("/ColorSpace /DeviceCMYK\n");
 					else
 					{
@@ -5662,7 +5786,7 @@
 			PutDoc(">>\nstream\n"+EncStream(colorDesc, spotObject)+"\nendstream\nendobj\n");
 		}
 		tmp += "q\n";
-		if ((Options.Version >= PDFOptions::PDFVersion_14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
+				if (((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
 			tmp += "/"+TRes+" gs\n";
 		tmp += SetClipPath(currItem);
 		tmp += "h\nW* n\n";
@@ -5946,7 +6070,7 @@
 				if (ite->annotation().borderColor() != CommonStrings::None)
 					PutDoc("/BC [ "+SetColor(ite->annotation().borderColor(), 100)+" ] ");
 			}
-      			else
+				else
 			{
 				if (ite->fillColor() != CommonStrings::None)
 					PutDoc("/BG [ "+SetColor(ite->fillColor(), ite->fillShade())+" ] ");
@@ -6052,7 +6176,7 @@
 					PutDoc("/A << /Type /Action /S /SubmitForm\n/F << /FS /URL /F "+ EncString("("+ite->annotation().Action()+")",annotationObj)+" >>\n");
 //					if (ite->annotation().HTML())
 //						PutDoc("/Flags 4");
-					switch (ite->annotation().HTML()) 
+					switch (ite->annotation().HTML())
 					{
 					case 1:
 					  // HTML
@@ -6222,8 +6346,8 @@
 		PDF_xForm(appearanceObj, ite->width(), ite->height(), cc);
 	}
 	return true;
-}		
-		
+}
+
 uint PDFLibCore::writeActions(const Annotation&	annot, uint annotationObj)
 {
 	// write actions
@@ -6326,7 +6450,7 @@
 }
 
 uint PDFLibCore::WritePDFString(const QString& cc)
-{	
+{
 	QString tmp;
 	for (int i = 0; i < cc.length(); ++i)
 	{
@@ -6401,7 +6525,7 @@
 {
 	if (!Options.embedPDF)
 		return false;
-	
+
 #ifdef HAVE_PODOFO
 	try
 	{
@@ -6485,8 +6609,6 @@
 			mlen = oStream.GetLength();
 			mbuffer = oStream.TakeBuffer();
 #else
-
-
 			stream->GetCopy(&mbuffer, &mlen);
 #endif
 			if (mbuffer[mlen-1] == '\n')
@@ -6532,7 +6654,7 @@
 				nextObj = allObjects->GetObject(referencedObjects[i]);
 				copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
 			}
-			
+
 			Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
 			imgInfo.ResNum = ResCount;
 			ResCount++;
@@ -6545,10 +6667,10 @@
 			// pagesize.GetHeight(). Adjust scale factor to compensate for the difference.
 			imgInfo.sxa = sx * pagesize.GetWidth()/imgInfo.Width;
 			imgInfo.sya = sy * pagesize.GetHeight()/imgInfo.Height;
-			
+
 			return true;
 		}
-		else if (contents && contents->GetDataType() ==  PoDoFo::ePdfDataType_Array)//Page contents might be an array 
+		else if (contents && contents->GetDataType() ==  PoDoFo::ePdfDataType_Array)//Page contents might be an array
 		{
 			QMap<PoDoFo::PdfReference, uint> importedObjects;
 			QList<PoDoFo::PdfReference> referencedObjects;
@@ -6573,12 +6695,12 @@
 				PutDoc("\n/Group "); // PDF 1.4
 				copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
 			}
-			
+
 			char * mbuffer = NULL;
 			long mlen = 0;
 			// copied from podofoimpose
 			PoDoFo::PdfMemoryOutputStream outMemStream ( 1 );
-//			PoDoFo::PdfFilteredEncodeStream outMemStream (outMemStreamRaw, ePdfFilter_FlateDecode, false); 
+//			PoDoFo::PdfFilteredEncodeStream outMemStream (outMemStreamRaw, ePdfFilter_FlateDecode, false);
 			PoDoFo::PdfArray carray(page->GetContents()->GetArray());
 			for(unsigned int ci = 0; ci < carray.size(); ++ci)
 			{
@@ -6588,12 +6710,12 @@
 				}
 				else if(carray[ci].IsReference())
 				{
-				
+
 					nextObj = doc.GetObjects().GetObject(carray[ci].GetReference());
-				
+
 					while(nextObj != NULL)
 					{
-					
+
 						if(nextObj->IsReference())
 						{
 							nextObj = doc.GetObjects().GetObject(nextObj->GetReference());
@@ -6604,9 +6726,9 @@
 							break;
 						}
 					}
-				
+
 				}
-			
+
 			}
 			// end of copy
 			mlen = outMemStream.GetLength();
@@ -6656,7 +6778,7 @@
 				nextObj = allObjects->GetObject(referencedObjects[i]);
 				copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
 			}
-			
+
 			Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
 			imgInfo.ResNum = ResCount;
 			ResCount++;
@@ -6669,10 +6791,10 @@
 			// pagesize.GetHeight(). Adjust scale factor to compensate for the difference.
 			imgInfo.sxa = sx * pagesize.GetWidth()/imgInfo.Width;
 			imgInfo.sya = sy * pagesize.GetHeight()/imgInfo.Height;
-			
+
 			return true;
 		}
-		
+
 	}
 	catch(PoDoFo::PdfError& e)
 	{
@@ -6680,7 +6802,7 @@
 		e.PrintErrorMsg();
 		assert (false);
 		return false;
-	}	
+	}
 #endif
 	return false;
 }
@@ -6738,7 +6860,7 @@
 		PutDoc(" " + str);
 		}
 	}
-	
+
 }
 
 void PDFLibCore::copyPoDoFoObject(const PoDoFo::PdfObject* obj, uint scObjID, QMap<PoDoFo::PdfReference, uint>& importedObjects)
@@ -6770,7 +6892,7 @@
 			QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
 			EncodeArrayToStream(buffer, scObjID);
 		}  // disconnect QByteArray from raw data
-		free (mbuffer);		
+		free (mbuffer);
 		PutDoc("\nendstream");
 	}
 	PutDoc("\nendobj\n");
@@ -6861,7 +6983,7 @@
 			qDebug() << "Failed to embed the PDF file";
 		// no embedded PDF:
 		if (!imageLoaded)
-		{ 
+		{
 			if ((extensionIndicatesPDF(ext) || extensionIndicatesEPSorPS(ext)) && (c->pixm.imgInfo.type != ImageType7))
 			{
 				bitmapFromGS = true;
@@ -7157,7 +7279,7 @@
 			else
 			{
 				bool gotAlpha = false;
-				bool pdfVer14 = (Options.Version >= PDFOptions::PDFVersion_14);
+				bool pdfVer14 = (Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4);
 				gotAlpha = img2.getAlpha(fn, c->pixm.imgInfo.actualPageNumber, im2, true, pdfVer14, afl, img.width(), img.height());
 				if (!gotAlpha)
 				{
@@ -7200,7 +7322,7 @@
 						compAlphaAvail = true;
 					}
 				}
-				if (Options.Version >= PDFOptions::PDFVersion_14)
+				if ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4))
 				{
 					PutDoc("/Width "+QString::number(origWidth)+"\n");
 					PutDoc("/Height "+QString::number(origHeight)+"\n");
@@ -7334,7 +7456,7 @@
 //				PutDoc("/Decode [1 0 1 0 1 0 1 0]\n");
 			if (alphaM)
 			{
-				if (Options.Version >= PDFOptions::PDFVersion_14)
+				if ((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4))
 					PutDoc("/SMask "+QString::number(maskObj)+" 0 R\n");
 				else
 					PutDoc("/Mask "+QString::number(maskObj)+" 0 R\n");
@@ -7557,7 +7679,7 @@
 		}
 		PutDoc(">>\n");
 	}
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+	if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4))&& (Options.useLayers))
 	{
 		PutDoc("/Properties <<\n");
 		ScLayer ll;
@@ -7734,7 +7856,7 @@
 	for (int th = 0; th < Threads.count(); ++th)
 		PutDoc(QString::number(Threads[th])+" 0 R ");
 	PutDoc("]\nendobj\n");
-	if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
+	if (((Options.Version == PDFOptions::PDFVersion_15) || (Options.Version == PDFOptions::PDFVersion_X4)) && (Options.useLayers))
 	{
 		XRef[8] = bytesWritten();
 		QStringList lay;
@@ -7753,9 +7875,16 @@
 		}
 		for (int layc = 0; layc < lay.count(); ++layc)
 		{
-			PutDoc(lay[layc]);
+			if (Options.Version != PDFOptions::PDFVersion_X4)
+				PutDoc(lay[layc]);
 		}
 		PutDoc("]\n");
+		if (Options.Version == PDFOptions::PDFVersion_X4)
+		{
+			PutDoc("/BaseState /ON\n");
+			QString occdName = "Default";
+			PutDoc("/Name ("+PDFEncode(occdName)+")\n");
+		}
 		PutDoc("/OFF [ ");
 		QHash<QString, OCGInfo>::Iterator itoc;
 		for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
@@ -7764,17 +7893,20 @@
 				PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
 		}
 		PutDoc("]\n");
-		PutDoc("/AS [<</Event /Print /OCGs [ ");
-		for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
+		if (Options.Version != PDFOptions::PDFVersion_X4)
 		{
-			PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
+			PutDoc("/AS [<</Event /Print /OCGs [ ");
+			for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
+			{
+				PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
+			}
+			PutDoc("] /Category [/Print]>> <</Event /View /OCGs [");
+			for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
+			{
+				PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
+			}
+			PutDoc("] /Category [/View]>>]\n");
 		}
-		PutDoc("] /Category [/Print]>> <</Event /View /OCGs [");
-		for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
-		{
-			PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
-		}
-		PutDoc("] /Category [/View]>>]\n");
 		PutDoc(">>\n");
 		PutDoc("/OCGs [ ");
 		for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
@@ -7784,7 +7916,7 @@
 		PutDoc("]\n");
 		PutDoc(">>\nendobj\n");
 	}
-	if (Options.Version == PDFOptions::PDFVersion_X3)
+	if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4))
 	{
 		StartObj(ObjCounter);
 		ObjCounter++;
@@ -7805,8 +7937,18 @@
 		PutDoc(">>\nstream\n");
 		PutDoc(dataP);
 		PutDoc("\nendstream\nendobj\n");
-		XRef[8] = bytesWritten();
-		PutDoc("9 0 obj\n");
+
+		if ((Options.Version == PDFOptions::PDFVersion_X4) && (Options.useLayers))
+		{
+			XRef[9] = bytesWritten();
+			PutDoc("10 0 obj\n");
+		}
+		if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || ((Options.Version == PDFOptions::PDFVersion_X4) && !(Options.useLayers)))
+		{
+			XRef[8] = bytesWritten();
+			PutDoc("9 0 obj\n");
+		}
+
 		PutDoc("<<\n/Type /OutputIntent\n/S /GTS_PDFX\n");
 		PutDoc("/DestOutputProfile "+QString::number(ObjCounter-1)+" 0 R\n");
 		PutDoc("/OutputConditionIdentifier (Custom)\n");
@@ -7814,6 +7956,26 @@
 		PutDoc("/OutputCondition ("+PDFEncode(Name)+")\n");
 		PutDoc(">>\nendobj\n");
 	}
+	if (Options.Version == PDFOptions::PDFVersion_X4)
+	{
+		if (Options.useLayers) // OCProperties dictionary was included as '9 0 obj', OutputIntents was included as '10 0 obj'
+		{
+			XRef[10] = bytesWritten();
+			PutDoc("11 0 obj\n");
+		}
+		else // There was no OCProperties dictionary
+		{
+			XRef[9] = bytesWritten();
+			PutDoc("10 0 obj\n");
+		}
+		PutDoc("<<\n");
+		PutDoc("/Length "+QString::number(xmpPacket.size()+1)+"\n");
+		PutDoc("/Type /Metadata\n");
+		PutDoc("/Subtype /XML\n");
+		PutDoc(">>\nstream\n");
+		PutDoc(xmpPacket);
+		PutDoc("\nendstream\nendobj\n");
+	}
 	StX = bytesWritten();
 	PutDoc("xref\n");
 	PutDoc("0 "+QString::number(ObjCounter)+"\n");
@@ -7844,7 +8006,111 @@
 	PutDoc(QString::number(StX)+"\n%%EOF\n");
 	return closeAndCleanup();
 }
+void PDFLibCore::generateXMP(const QString& timeStamp)
+{
+	/*
+		This is a rather 'manual' way to generate XMP. Since only a few basic properties are included here,
+		this method tries to build XMP from the generic XML's API of Qt and follow the XMP's spec very closely.
+		A better (and less typing) way to support XMP is to use an XMP's API such as Exiv2 or Exempi
+	*/
+	QDomDocument xmpDoc;
+	QDomProcessingInstruction xpacket = xmpDoc.createProcessingInstruction("xpacket", "begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"");
+	xmpDoc.appendChild(xpacket);
+	QString xNS = "adobe:ns:meta/";
+	QDomElement xmpmeta = xmpDoc.createElementNS(xNS, "x:xmpmeta");
+	xmpmeta.setAttributeNS(xNS, "x:xmptk", "Scribus PDF Library "+QString(VERSION));
+	xmpDoc.appendChild(xmpmeta);
+	QString rdfNS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+	QDomElement rdf = xmpDoc.createElementNS(rdfNS, "rdf:RDF");
+	xmpmeta.appendChild(rdf);
+	QDomElement desc = xmpDoc.createElement("rdf:Description");
+	desc.setAttribute("rdf:about", "");
 
+	QDomElement descXMP = desc.cloneNode().toElement();
+	rdf.appendChild(descXMP);
+	QString xmpNS = "http://ns.adobe.com/xap/1.0/";
+	descXMP.setAttributeNS(xmpNS, "xmp:CreateDate", timeStamp);
+	descXMP.setAttribute("xmp:ModifyDate", timeStamp);
+	descXMP.setAttribute("xmp:MetadataDate", timeStamp);
+	descXMP.setAttribute("xmp:CreatorTool", "Scribus "+QString(VERSION));
+
+	QDomElement descPDF = desc.cloneNode().toElement();
+	rdf.appendChild(descPDF);
+	QString pdfNS = "http://ns.adobe.com/pdf/1.3/";
+	descPDF.setAttributeNS(pdfNS, "pdf:Producer", "Scribus PDF Library "+QString(VERSION));
+	descPDF.setAttribute("pdf:Trapped", "False");
+	descPDF.setAttribute("pdf:Keywords", doc.documentInfo.getKeywords());
+
+	QDomElement descDC = desc.cloneNode().toElement();
+	rdf.appendChild(descDC);
+	QString dcNS = "http://purl.org/dc/elements/1.1/";
+	descDC.setAttributeNS(dcNS, "dc:format", "application/pdf");
+	QDomElement title = xmpDoc.createElement("dc:title");
+	descDC.appendChild(title);
+	QDomElement alt1 = xmpDoc.createElement("rdf:Alt");
+	title.appendChild(alt1);
+	QDomElement li1 = xmpDoc.createElement("rdf:li");
+	li1.setAttribute("xml:lang", "x-default");
+	alt1.appendChild(li1);
+	QString docTitle = doc.documentInfo.getTitle();
+	if (((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4)) && (docTitle.isEmpty()))
+		docTitle = doc.DocName;
+	li1.appendChild(xmpDoc.createTextNode(docTitle));
+	QDomElement creator = xmpDoc.createElement("dc:creator");
+	descDC.appendChild(creator);
+	QDomElement seq = xmpDoc.createElement("rdf:Seq");
+	creator.appendChild(seq);
+	QDomElement li2 = xmpDoc.createElement("rdf:li");
+	seq.appendChild(li2);
+	li2.appendChild(xmpDoc.createTextNode(doc.documentInfo.getAuthor()));
+	// Subject's entry in Document Info dictionary is actually dc:description in XMP, not dc:subject.
+	QDomElement description = xmpDoc.createElement("dc:description");
+	descDC.appendChild(description);
+	QDomElement alt2 = xmpDoc.createElement("rdf:Alt");
+	description.appendChild(alt2);
+	QDomElement li3 = xmpDoc.createElement("rdf:li");
+	li3.setAttribute("xml:lang", "x-default");
+	alt2.appendChild(li3);
+	li3.appendChild(xmpDoc.createTextNode(doc.documentInfo.getSubject()));
+
+	if ((Options.Version == PDFOptions::PDFVersion_X3) || (Options.Version == PDFOptions::PDFVersion_X1a) || (Options.Version == PDFOptions::PDFVersion_X4))
+	{
+		QDomElement descPDFXID = desc.cloneNode().toElement();
+		rdf.appendChild(descPDFXID);
+		QString pdfxidNS = "http://www.npes.org/pdfx/ns/id/";
+		if (Options.Version == PDFOptions::PDFVersion_X1a)
+		{
+			descPDFXID.setAttributeNS(pdfxidNS, "pdfx:GTS_PDFXConformance", "PDF/X-1a:2001");
+			descPDFXID.setAttribute("pdfx:GTS_PDFXVersion", "PDF/X-1:2001");
+		}
+		else if (Options.Version == PDFOptions::PDFVersion_X3)
+			descPDFXID.setAttributeNS(pdfxidNS, "pdfxid:GTS_PDFXVersion", "PDF/X-3");
+		else if (Options.Version == PDFOptions::PDFVersion_X4)
+			descPDFXID.setAttributeNS(pdfxidNS, "pdfxid:GTS_PDFXVersion", "PDF/X-4");
+	}
+
+
+	QDomElement descXMPMM = desc.cloneNode().toElement();
+	rdf.appendChild(descXMPMM);
+	QString xmpmmNS = "http://ns.adobe.com/xap/1.0/mm/";
+	QString uuid = QUuid::createUuid().toString();
+	// remove the enclosing braces
+	uuid.remove(0, 1);
+	uuid.chop(1);
+	descXMPMM.setAttributeNS(xmpmmNS, "xmpMM:DocumentID", "uuid:"+uuid);
+	descXMPMM.setAttribute("xmpMM:RenditionClass", "default");
+	descXMPMM.setAttribute("xmpMM:VersionID", 1);
+
+	xmpPacket.append(xmpDoc.toString(4));
+	QString tenSpaces = "          ";
+	for (int i=0; i<25; ++i)
+	{
+		for (int j=0; j<10; ++j)
+			xmpPacket.append(tenSpaces);
+		xmpPacket.append("\n");
+	}
+	xmpPacket.append("<?xpacket end='w'?>");
+}
 void PDFLibCore::PDF_Error(const QString& errorMsg)
 {
 	ErrorMessage = errorMsg;
Index: scribus/pdf_analyzer.h
===================================================================
--- scribus/pdf_analyzer.h	(revision 0)
+++ scribus/pdf_analyzer.h	(revision 14043)
@@ -0,0 +1,187 @@
+/*
+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.
+*/
+
+#ifndef PDFANALYZER_H
+#define PDFANALYZER_H
+
+#include <QList>
+#include <QPair>
+#include <QString>
+#include <QMatrix>
+#include "scconfig.h"
+
+#ifdef HAVE_PODOFO
+#include <podofo/podofo.h>
+#endif
+
+enum PDFContentStreamKeyword
+{
+	KW_k,
+	KW_K,
+	KW_rg,
+	KW_RG,
+	KW_g,
+	KW_G,
+	KW_CS,
+	KW_cs,
+	KW_SC,
+	KW_SCN,
+	KW_sc,
+	KW_scn,
+	KW_Do,
+	KW_BI,
+	KW_ID,
+	KW_EI,
+	KW_gs,
+	KW_Tf,
+	KW_cm,
+	KW_q,
+	KW_Q,
+	KW_w,
+	KW_J,
+	KW_j,
+	KW_M,
+	KW_d,
+	KW_Undefined
+};
+enum PDFColorSpace
+{
+	CS_DeviceGray,
+	CS_DeviceRGB,
+	CS_DeviceCMYK,
+	CS_CalGray,
+	CS_CalRGB,
+	CS_Lab,
+	CS_ICCBased,
+	CS_Pattern,
+	CS_Indexed,
+	CS_Separation,
+	CS_DeviceN,
+	CS_Unknown
+};
+enum PDFFontType
+{
+	F_Type1,
+	F_MMType1,
+	F_TrueType,
+	F_Type3,
+	F_CIDFontType0,
+	F_CIDFontType2,
+	F_Unknown
+};
+struct PDFFont
+{
+	PDFFontType fontType;
+	bool isEmbedded;
+	bool isOpenType;
+	PDFFont()
+	{
+		fontType = F_Unknown;
+		isEmbedded = false;
+		isOpenType = false;
+	}
+};
+struct PDFGraphicState
+{
+	QMatrix ctm;
+	PDFColorSpace strokeCS;
+	PDFColorSpace fillCS;
+	QList<double> strokeColor;
+	QList<double> fillColor;
+	double lineWidth;
+	int lineCap;
+	int lineJoin;
+	double miterLimit;
+	QPair<QList<int>, int> dashPattern;
+	QPair<PDFFont, double> font;
+	QList<QString> blendModes;
+	double fillAlphaConstant;
+	double strokeAlphaConstant;
+	PDFGraphicState()
+	{
+		strokeCS = CS_DeviceGray;
+		fillCS = CS_DeviceGray;
+		strokeColor.append(0);
+		fillColor.append(0);
+		lineWidth = 1;
+		lineCap = 0;
+		lineJoin = 0;
+		miterLimit = 10;
+		QList<int> dashArray;
+		int dashPhase = 0;
+		dashPattern.first = dashArray;
+		dashPattern.second = dashPhase;
+		blendModes.append("Normal");
+		fillAlphaConstant = 1;
+		strokeAlphaConstant = 1;
+	}
+};
+struct PDFImage
+{
+	QString imgName;
+	int dpiX;
+	int dpiY;
+};
+
+/**
+ * PDFAnalyzer provides the facility to report various properties of a PDF.
+ * At the moment, it can parse/analyze and record used color spaces, the use of transparency,
+ * used fonts, and existing images in a page of a PDF.
+ *
+ * This class will be used by DocumentChecker's class to preflight and report any incompatible
+ * properties according to a checker's profile.
+ */
+class PDFAnalyzer : public QObject
+{
+	Q_OBJECT
+
+public:
+	/**
+	 * Instantiate a new PDFAnalyzer that will operate on the PDF specified by `filename'.
+	 *
+	 * \param filename Path to the PDF being analyzed.
+	 */
+	PDFAnalyzer(QString& filename);
+	~PDFAnalyzer();
+
+	/**
+	 * Perform the actual inspection on one page of the PDF.
+	 *
+	 * \return A boolean is return indicating whether the process is successful.
+	 * \param pageNum Specifying the page's number (zero-based) in the PDF where the analyzing process is opearted on.
+	 * \param usedColorSpaces List of used color spaces in the page which will be filled while processing.
+	 * \param hasTransparency A boolean which will be set to true after analyzing if the page contains transparency.
+	 * \param usedFonts List of used fonts in the page which will be filled while processing.
+	 * \param imgs List of images that this page contains.
+	 */
+	bool inspectPDF(int pageNum, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, QList<PDFImage> & imgs);
+#ifdef HAVE_PODOFO
+private:
+	// pointer to the PoDoFo Pdf's object
+	PoDoFo::PdfMemDocument* m_doc;
+
+	// Call to this method to inspect a PdfCanvas (either a PdfPage or PdfXObject of subtype Form). This method will be called by inspectPDF
+	// to start inspecting a PDF's page; it could well be called recursively to continue analyzing further in case form XObjects are painted
+	// onto the page.
+	bool inspectCanvas(PoDoFo::PdfCanvas* canvas, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, QList<PDFImage> & imgs);
+
+	// Helper method to analyze a ColorSpace's array. They all have the form [/csType ...] (section 4.5 in PDF Spec 1.6).
+	// csObject is a pointer to a PoDoFo's PdfObject which is in fact a PdfArray underneath.
+	// A color space's type is returned.
+	PDFColorSpace getCSType(PoDoFo::PdfObject* csObject);
+
+	// Helper method to inspect a graphic state parameter dictionary (ExtGState subdictionary in the resource dictionary; Section 4.3.4 in PDF Spec 1.6).
+	// Triggered by hitting a gs operator in the content stream.
+	// extGStateObj is a pointer to a PoDoFo's PdfObject which is in fact a dictionary underneath.
+	void inspectExtGStateObj(PoDoFo::PdfObject* extGStateObj, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, PDFGraphicState & currGS);
+
+	// Helper method to analyze a font dictionary (section 5.4-5.8 in PDF Spec 1.6)
+	// A PDFFont struct is returned containing some basic info regarding the specified font.
+	PDFFont getFontInfo(PoDoFo::PdfObject* fontObj);
+#endif
+};
+#endif
Index: scribus/pdflib_core.h
===================================================================
--- scribus/pdflib_core.h	(revision 14042)
+++ scribus/pdflib_core.h	(revision 14043)
@@ -79,7 +79,7 @@
 		double origYsc;
 		QMap<int, ImageLoadRequest> RequestProps;
 	};
-	
+
 	bool PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, QMap<QString, QMap<uint, FPointArray> > DocFonts, BookMView* vi);
 	void PDF_Begin_Page(const Page* pag, QPixmap pm = 0);
 	void PDF_End_Page();
@@ -146,7 +146,7 @@
 //	QString    PDFEncode(const QString & in);
 	QByteArray ComputeMD5(const QString& in);
 	QByteArray ComputeRC4Key(int ObjNum);
-	
+
 	bool    PDF_ProcessItem(QString& output, PageItem* ite, const Page* pag, uint PNr, bool embedded = false, bool pattern = false);
 	QString PDF_ProcessTableItem(PageItem* ite, const Page* pag);
 	QString drawArrow(PageItem *ite, QTransform &arrowTrans, int arrowIndex);
@@ -167,10 +167,11 @@
 	void copyPoDoFoObject(const PoDoFo::PdfObject* obj, uint scObjID, QMap<PoDoFo::PdfReference, uint>& importedObjects);
 	void copyPoDoFoDirect(const PoDoFo::PdfVariant* obj, QList<PoDoFo::PdfReference>& referencedObjects, QMap<PoDoFo::PdfReference, uint>& importedObjects);
 #endif
-		
+
+	void generateXMP(const QString& timeStamp);
 	int bytesWritten() { return Spool.pos(); }
 
-	
+
 	QString Content;
 	QString ErrorMessage;
 	ScribusDoc & doc;
@@ -293,7 +294,8 @@
 	double bleedDisplacementX;
 	double bleedDisplacementY;
 	QMap<QString, QMap<uint, uint> > Type3Fonts;
-	
+	QString xmpPacket;
+
 protected slots:
 	void cancelRequested();
 };
@@ -301,3 +303,4 @@
 #endif
 
 
+
Index: scribus/prefsmanager.cpp
===================================================================
--- scribus/prefsmanager.cpp	(revision 14042)
+++ scribus/prefsmanager.cpp	(revision 14043)
@@ -72,17 +72,17 @@
 
 PrefsManager* PrefsManager::instance()
 {
-    if (_instance == 0)
-        _instance = new PrefsManager();
+	if (_instance == 0)
+		_instance = new PrefsManager();
 
-    return _instance;
+	return _instance;
 }
 
 void PrefsManager::deleteInstance()
 {
-    if (_instance)
-        delete _instance;
-    _instance = 0;
+	if (_instance)
+		delete _instance;
+	_instance = 0;
 }
 
 
@@ -136,7 +136,7 @@
 
 	/** Default colours **/
 	appPrefs.colorPrefs.DColors.clear();
-	
+
 	ColorSetManager csm;
 	csm.initialiseDefaultPrefs(appPrefs);
 	csm.findPaletteLocations();
@@ -487,7 +487,7 @@
 	//Attribute setup
 	appPrefs.itemAttrPrefs.defaultItemAttributes.clear();
 	appPrefs.tocPrefs.defaultToCSetups.clear();
-	
+
 	initDefaultActionKeys();
 }
 
@@ -920,8 +920,8 @@
 		{
 			appPrefs.uiPrefs.language = userprefsContext->get("gui_language","");
 			appPrefs.uiPrefs.mainWinState = QByteArray::fromBase64(userprefsContext->get("mainwinstate","").toAscii());
-            //continue here...
-            //Prefs."blah blah" =...
+			//continue here...
+			//Prefs."blah blah" =...
 		}
 		if (prefsFile->hasContext("print_options"))
 		{
@@ -974,8 +974,8 @@
 		{
 			userprefsContext->set("gui_language", appPrefs.uiPrefs.language);
 			userprefsContext->set("mainwinstate", QString::fromAscii(appPrefs.uiPrefs.mainWinState.toBase64()));
-            //continue here...
-            //Prefs."blah blah" =...
+			//continue here...
+			//Prefs."blah blah" =...
 		}
 		prefsFile->write();
 	}
@@ -1456,6 +1456,10 @@
 		dc79a.setAttribute("ignoreOffLayers", static_cast<int>(itcp.value().ignoreOffLayers));
 		dc79a.setAttribute("minResolution",ScCLocale::toQStringC(itcp.value().minResolution));
 		dc79a.setAttribute("maxResolution",ScCLocale::toQStringC(itcp.value().maxResolution));
+		dc79a.setAttribute("checkNotCMYKOrSpot", static_cast<int>(itcp.value().checkNotCMYKOrSpot));
+		dc79a.setAttribute("checkDeviceColorsAndOutputIntend", static_cast<int>(itcp.value().checkDeviceColorsAndOutputIntend));
+		dc79a.setAttribute("checkFontNotEmbedded", static_cast<int>(itcp.value().checkFontNotEmbedded));
+		dc79a.setAttribute("checkFontIsOpenType", static_cast<int>(itcp.value().checkFontIsOpenType));
 		elem.appendChild(dc79a);
 	}
 	QDomElement dc81=docu.createElement("CMS");
@@ -1705,7 +1709,7 @@
 			result = true;
 		else
 			m_lastError = tr("Writing to preferences file \"%1\" failed: "
-				             "QIODevice status code %2")
+							 "QIODevice status code %2")
 				.arg(ho).arg(f.errorString());
 	}
 	if (f.isOpen())
@@ -2089,7 +2093,7 @@
 			appPrefs.curCheckProfile = dc.attribute("currentProfile", CommonStrings::PostScript);
 			//#2516 work around old values until people wont have them anymore, not that these
 			//translated strings should be going into prefs anyway!
-			if ((appPrefs.curCheckProfile == tr("PostScript")) || ((appPrefs.curCheckProfile == tr("Postscript")) || 
+			if ((appPrefs.curCheckProfile == tr("PostScript")) || ((appPrefs.curCheckProfile == tr("Postscript")) ||
 				(appPrefs.curCheckProfile == "Postscript")))
 			{
 				appPrefs.curCheckProfile = CommonStrings::PostScript;
@@ -2115,6 +2119,10 @@
 			checkerSettings.checkRasterPDF = static_cast<bool>(dc.attribute("checkRasterPDF", "1").toInt());
 			checkerSettings.checkForGIF = static_cast<bool>(dc.attribute("checkForGIF", "1").toInt());
 			checkerSettings.ignoreOffLayers = static_cast<bool>(dc.attribute("ignoreOffLayers", "0").toInt());
+			checkerSettings.checkNotCMYKOrSpot = static_cast<bool>(dc.attribute("checkNotCMYKOrSpot", "0").toInt());
+			checkerSettings.checkDeviceColorsAndOutputIntend = static_cast<bool>(dc.attribute("checkDeviceColorsAndOutputIntend", "0").toInt());
+			checkerSettings.checkFontNotEmbedded = static_cast<bool>(dc.attribute("checkFontNotEmbedded", "0").toInt());
+			checkerSettings.checkFontIsOpenType = static_cast<bool>(dc.attribute("checkFontIsOpenType", "0").toInt());
 			appPrefs.checkerPrefsList[name] = checkerSettings;
 		}
 		if (dc.tagName()=="PRINTER")
@@ -2417,8 +2425,14 @@
 		checkerSettings.ignoreOffLayers = false;
 		checkerSettings.minResolution = 144.0;
 		checkerSettings.maxResolution = 2400.0;
+		checkerSettings.checkNotCMYKOrSpot = false;
+		checkerSettings.checkDeviceColorsAndOutputIntend = false;
+		checkerSettings.checkFontNotEmbedded = false;
+		checkerSettings.checkFontIsOpenType = false;
 		//TODO Stop translating these into settings!!!!!!!!!
 		cp->insert( CommonStrings::PostScript, checkerSettings);
+		checkerSettings.checkFontNotEmbedded = true;
+		checkerSettings.checkFontIsOpenType = true;
 		cp->insert( CommonStrings::PDF_1_3   , checkerSettings);
 		checkerSettings.checkTransparency = false;
 		cp->insert( CommonStrings::PDF_1_4   , checkerSettings);
@@ -2426,7 +2440,16 @@
 		checkerSettings.checkTransparency = true;
 		checkerSettings.checkAnnotations = true;
 		checkerSettings.minResolution = 144.0;
+		checkerSettings.checkDeviceColorsAndOutputIntend = true;
 		cp->insert( CommonStrings::PDF_X3    , checkerSettings);
+		checkerSettings.checkNotCMYKOrSpot = true;
+		checkerSettings.checkDeviceColorsAndOutputIntend = false;
+		cp->insert( CommonStrings::PDF_X1a    , checkerSettings);
+		checkerSettings.checkNotCMYKOrSpot = false;
+		checkerSettings.checkDeviceColorsAndOutputIntend = true;
+		checkerSettings.checkTransparency = false;
+		checkerSettings.checkFontIsOpenType = false;
+		cp->insert( CommonStrings::PDF_X4    , checkerSettings);
 	}
 }
 
Index: scribus/prefsstructs.h
===================================================================
--- scribus/prefsstructs.h	(revision 14042)
+++ scribus/prefsstructs.h	(revision 14043)
@@ -35,6 +35,10 @@
 	bool checkRasterPDF;
 	bool checkForGIF;
 	bool ignoreOffLayers;
+	bool checkNotCMYKOrSpot; // colors must be either CMYK or spot (PDF/X-1a)
+	bool checkDeviceColorsAndOutputIntend; // unmanaged colors (device colors) must agree with output intend
+	bool checkFontNotEmbedded; // embedded PDF might use fonts without embedding
+	bool checkFontIsOpenType; // embedded PDF might use OpenType font program (only allowed in PDF/X-4 and PDF 1.6)
 };
 
 typedef QMap<QString, CheckerPrefs> CheckerPrefsList;
Index: scribus/pdf_analyzer.cpp
===================================================================
--- scribus/pdf_analyzer.cpp	(revision 0)
+++ scribus/pdf_analyzer.cpp	(revision 14043)
@@ -0,0 +1,821 @@
+/*
+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.
+*/
+/***************************************************************************
+						  pdf_analyzer.cpp  -  can be used to report color
+						  and font usages and detect transparency in an
+						  embedded PDF
+							 -------------------
+	begin                : July 2009
+	author				 : Thach Tran <tranngocthachs at gmail.com>, (C) 2009
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <QtDebug>
+#include <QHash>
+#include <QStack>
+#include "pdf_analyzer.h"
+
+#ifdef HAVE_PODOFO
+using namespace PoDoFo;
+
+static QHash<QString, PDFContentStreamKeyword> kwNameMap;
+
+// we gonna need a map from string values to the defined enum of pdf keywords
+// this will be used to switch the keyword we encounter while parsing pdf's page content
+static void generateKWNameMap()
+{
+	kwNameMap.insert("k",	KW_k);
+	kwNameMap.insert("K",	KW_K);
+	kwNameMap.insert("rg",	KW_rg);
+	kwNameMap.insert("RG",	KW_RG);
+	kwNameMap.insert("g",	KW_g);
+	kwNameMap.insert("G",	KW_G);
+	kwNameMap.insert("cs",	KW_cs);
+	kwNameMap.insert("CS",	KW_CS);
+	kwNameMap.insert("sc",	KW_sc);
+	kwNameMap.insert("SC",	KW_SC);
+	kwNameMap.insert("scn",	KW_scn);
+	kwNameMap.insert("SCN",	KW_SCN);
+	kwNameMap.insert("Do",	KW_Do);
+	kwNameMap.insert("BI",	KW_BI);
+	kwNameMap.insert("ID",	KW_ID);
+	kwNameMap.insert("EI",	KW_EI);
+	kwNameMap.insert("gs",	KW_gs);
+	kwNameMap.insert("Tf",	KW_Tf);
+	kwNameMap.insert("cm",	KW_cm);
+	kwNameMap.insert("q",	KW_q);
+	kwNameMap.insert("w",	KW_w);
+	kwNameMap.insert("J",	KW_J);
+	kwNameMap.insert("j",	KW_j);
+	kwNameMap.insert("M",	KW_M);
+	kwNameMap.insert("d",	KW_d);
+	kwNameMap.insert("Q",	KW_Q);
+}
+
+
+PDFAnalyzer::PDFAnalyzer(QString & filename) : QObject()
+{
+	static bool nameMapInited = false;
+	if (!nameMapInited)
+	{
+		generateKWNameMap();
+		nameMapInited = true;
+	}
+
+	PdfError::EnableDebug( false );
+	try {
+		m_doc = new PdfMemDocument(filename.toLocal8Bit().data());
+	}
+	catch (PdfError & e)
+	{
+		qDebug() << "Can't open the file";
+		e.PrintErrorMsg();
+		return;
+	}
+}
+
+PDFAnalyzer::~PDFAnalyzer()
+{
+	delete m_doc;
+}
+
+bool PDFAnalyzer::inspectPDF(int pageNum, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, QList<PDFImage> & imgs)
+{
+	PdfPage* page = m_doc->GetPage(pageNum);
+	return page?inspectCanvas(page, usedColorSpaces, hasTransparency, usedFonts, imgs):false;
+}
+
+PDFColorSpace PDFAnalyzer::getCSType(PdfObject* cs)
+{
+	try {
+		// colorspace is either a name or an array
+		if (cs && cs->IsName())
+		{
+			PdfName csName = cs->GetName();
+			if (csName == "DeviceGray")
+				return CS_DeviceGray;
+			else if (csName == "DeviceRGB")
+				return CS_DeviceRGB;
+			else if (csName == "DeviceCMYK")
+				return CS_DeviceCMYK;
+		}
+		else if (cs && cs->IsArray())
+		{
+			PdfArray csArr = cs->GetArray();
+			PdfObject csTypePdfName = csArr[0];
+			if (csTypePdfName.IsName())
+			{
+				PdfName csTypeName = csTypePdfName.GetName();
+				if (csTypeName == "ICCBased")
+					return CS_ICCBased;
+				else if (csTypeName == "CalGray")
+					return CS_CalGray;
+				else if (csTypeName == "CalRGB")
+					return CS_CalRGB;
+				else if (csTypeName == "Lab")
+					return CS_Lab;
+				else if (csTypeName == "Indexed")
+				{
+					PdfObject base = cs->GetArray()[1];
+					PdfObject* pBase = &base;
+					if (base.IsReference())
+					{
+						pBase = cs->GetOwner()->GetObject(base.GetReference());
+					}
+					pBase->SetOwner(cs->GetOwner());
+					return getCSType(pBase);
+				}
+				else if (csTypeName == "Separation")
+					return CS_Separation;
+				else if (csTypeName == "DeviceN")
+					return CS_DeviceN;
+				else if (csTypeName == "Pattern")
+					return CS_Pattern;
+			}
+		}
+	}
+	catch (PdfError & e)
+	{
+		qDebug() << "Error in identifying the color type";
+		e.PrintErrorMsg();
+		return CS_Unknown;
+	}
+	return CS_Unknown;
+}
+bool PDFAnalyzer::inspectCanvas(PdfCanvas* canvas, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, QList<PDFImage> & imgs)
+{
+	// this method can be used to get used color spaces, detect transparency, and get used fonts in either PdfPage or PdfXObject
+	PdfObject* colorSpaceRes;
+	PdfObject* xObjects;
+	PdfObject* transGroup;
+	PdfObject* extGState;
+	PdfObject* fontRes;
+	QMap<PdfName, PDFColorSpace> processedNamedCS;
+	QMap<PdfName, PDFFont> processedNamedFont;
+	QList<PdfName> processedNamedXObj;
+	QList<PdfName> processedNamedGS;
+	try {
+		// get hold of a PdfObject pointer of this canvas
+		// needed for the finding resources code below to work
+		PdfPage* page = dynamic_cast<PdfPage*>(canvas);
+		PdfObject* canvasObject = page?(page->GetObject()):((dynamic_cast<PdfXObject*>(canvas))->GetObject());
+
+		// find a resource with ColorSpace entry
+		PdfObject* resources = canvas->GetResources();
+		for (PdfObject* par = canvasObject; par && !resources; par = par->GetIndirectKey("Parent"))
+		{
+			resources = par->GetIndirectKey("Resources");
+		}
+		colorSpaceRes = resources?resources->GetIndirectKey("ColorSpace"):NULL;
+		xObjects = resources?resources->GetIndirectKey("XObject"):NULL;
+		extGState = resources?resources->GetIndirectKey("ExtGState"):NULL;
+		fontRes = resources?resources->GetIndirectKey("Font"):NULL;
+
+		// getting the transparency group of this content stream (if available)
+		transGroup = canvasObject?canvasObject->GetIndirectKey("Group"):NULL;
+		if (transGroup)
+		{
+			PdfObject* subtype = transGroup->GetIndirectKey("S");
+			if (subtype && subtype->GetName() == "Transparency")
+			{
+				// having transparency group means there's transparency in the PDF
+				hasTransparency = true;
+
+				// reporting the color space used in transparency group (Section 7.5.5, PDF 1.6 Spec)
+				PdfObject* cs = transGroup->GetIndirectKey("CS");
+				if (cs)
+				{
+					PDFColorSpace retval = getCSType(cs);
+					if (retval != CS_Unknown && !usedColorSpaces.contains(retval))
+						usedColorSpaces.append(retval);
+				}
+			}
+		}
+	}
+	catch (PdfError & e)
+	{
+		qDebug() << "Error in analyzing stream's resources.";
+		e.PrintErrorMsg();
+		return false;
+	}
+
+	try {
+		// start parsing the content stream
+		PdfContentsTokenizer tokenizer(canvas);
+		EPdfContentsType t;
+		const char * kwText;
+		PdfVariant var;
+		bool readToken;
+
+		int tokenNumber = 0;
+		QList<PdfVariant> args;
+		bool inlineImgDict = false;
+		QStack<PDFGraphicState> gsStack;
+		PDFGraphicState currGS;
+		while ((readToken = tokenizer.ReadNext(t, kwText, var)))
+		{
+			++tokenNumber;
+			if (t == ePdfContentsType_Variant)
+			{
+				args.append(var);
+			}
+			else if (t == ePdfContentsType_Keyword)
+			{
+				QString kw(kwText);
+				switch(kwNameMap.value(kw, KW_Undefined))
+				{
+				case KW_q:
+					gsStack.push(currGS);
+					break;
+				case KW_Q:
+					currGS = gsStack.pop();
+					break;
+				case KW_cm:
+					{
+					if (args.size() == 6)
+					{
+						double mt[6];
+						for (int i=0; i<6; ++i)
+						{
+							mt[i] = args[i].GetReal();
+						}
+						QMatrix transMatrix(mt[0], mt[1], mt[2], mt[3], mt[4], mt[5]);
+						currGS.ctm = transMatrix*currGS.ctm;
+					}
+					}
+					break;
+				case KW_w:
+					currGS.lineWidth = args[0].GetReal();
+					break;
+				case KW_J:
+					currGS.lineCap = args[0].GetNumber();
+					break;
+				case KW_j:
+					currGS.lineJoin = args[0].GetNumber();
+					break;
+				case KW_M:
+					currGS.lineJoin = args[0].GetReal();
+					break;
+				case KW_d:
+					{
+					currGS.dashPattern.first.clear();
+					PdfArray dashArr = args[0].GetArray();
+					for (int i=0; i<dashArr.size(); ++i)
+						currGS.dashPattern.first.append(dashArr[i].GetNumber());
+					currGS.dashPattern.second = args[0].GetNumber();
+					}
+					break;
+				case KW_g:
+					if (!usedColorSpaces.contains(CS_DeviceGray))
+						usedColorSpaces.append(CS_DeviceGray);
+					currGS.fillCS = CS_DeviceGray;
+					currGS.fillColor.clear();
+					currGS.fillColor.append(args[0].GetReal());
+					break;
+				case KW_G:
+					if (!usedColorSpaces.contains(CS_DeviceGray))
+						usedColorSpaces.append(CS_DeviceGray);
+					currGS.strokeCS = CS_DeviceGray;
+					currGS.strokeColor.clear();
+					currGS.strokeColor.append(args[0].GetReal());
+					break;
+				case KW_rg:
+					if (!usedColorSpaces.contains(CS_DeviceRGB))
+						usedColorSpaces.append(CS_DeviceRGB);
+					currGS.fillCS = CS_DeviceRGB;
+					currGS.fillColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.fillColor.append(args[i].GetReal());
+					break;
+				case KW_RG:
+					if (!usedColorSpaces.contains(CS_DeviceRGB))
+						usedColorSpaces.append(CS_DeviceRGB);
+					currGS.strokeCS = CS_DeviceRGB;
+					currGS.strokeColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.strokeColor.append(args[i].GetReal());
+					break;
+				case KW_k:
+					if (!usedColorSpaces.contains(CS_DeviceCMYK))
+						usedColorSpaces.append(CS_DeviceCMYK);
+					currGS.fillCS = CS_DeviceCMYK;
+					currGS.fillColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.fillColor.append(args[i].GetReal());
+					break;
+				case KW_K:
+					if (!usedColorSpaces.contains(CS_DeviceCMYK))
+						usedColorSpaces.append(CS_DeviceCMYK);
+					currGS.strokeCS = CS_DeviceCMYK;
+					currGS.strokeColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.strokeColor.append(args[i].GetReal());
+					break;
+				case KW_cs:
+					{
+					if (args.size() == 1 && args[0].IsName())
+					{
+						if (args[0].GetName() == "DeviceGray")
+						{
+							currGS.fillCS = CS_DeviceGray;
+							currGS.fillColor.clear();
+							currGS.fillColor.append(0);
+							if (!usedColorSpaces.contains(CS_DeviceGray))
+								usedColorSpaces.append(CS_DeviceGray);
+						}
+						else if (args[0].GetName() == "DeviceRGB")
+						{
+							currGS.fillCS = CS_DeviceRGB;
+							currGS.fillColor.clear();
+							for (int i=0; i<3; ++i)
+								currGS.fillColor.append(0);
+							if (!usedColorSpaces.contains(CS_DeviceRGB))
+								usedColorSpaces.append(CS_DeviceRGB);
+						}
+						else if (args[0].GetName() == "DeviceCMYK")
+						{
+							currGS.fillCS = CS_DeviceCMYK;
+							currGS.fillColor.clear();
+							for (int i=0; i<3; ++i)
+								currGS.fillColor.append(0);
+							currGS.fillColor.append(1);
+							if (!usedColorSpaces.contains(CS_DeviceCMYK))
+								usedColorSpaces.append(CS_DeviceCMYK);
+						}
+						else if (args[0].GetName() == "Pattern")
+						{
+							currGS.fillCS = CS_Pattern;
+							if (!usedColorSpaces.contains(CS_Pattern))
+								usedColorSpaces.append(CS_Pattern);
+						}
+						else
+						{
+							if (processedNamedCS.contains(args[0].GetName()))
+							{
+								currGS.fillCS = processedNamedCS.value(args[0].GetName());
+							}
+							else
+							{
+								if (colorSpaceRes && colorSpaceRes->GetIndirectKey(args[0].GetName()))
+								{
+									PdfObject* csEntry = colorSpaceRes->GetIndirectKey(args[0].GetName());
+									PDFColorSpace retval = getCSType(csEntry);
+									if (retval != CS_Unknown && !usedColorSpaces.contains(retval))
+										usedColorSpaces.append(retval);
+									currGS.fillCS = retval;
+									processedNamedCS.insert(args[0].GetName(), retval);
+								}
+								else
+								{
+									qDebug() << "Supplied colorspace is undefined!";
+									return false;
+								}
+							}
+						}
+					}
+					else
+					{
+						qDebug() << "Wrong syntax in specifying color space!";
+						return false;
+					}
+					}
+					break;
+				case KW_CS:
+					{
+					if (args.size() == 1 && args[0].IsName())
+					{
+						if (args[0].GetName() == "DeviceGray")
+						{
+							currGS.strokeCS = CS_DeviceGray;
+							currGS.strokeColor.clear();
+							currGS.strokeColor.append(0);
+							if (!usedColorSpaces.contains(CS_DeviceGray))
+								usedColorSpaces.append(CS_DeviceGray);
+						}
+						else if (args[0].GetName() == "DeviceRGB")
+						{
+							currGS.fillCS = CS_DeviceRGB;
+							currGS.strokeColor.clear();
+							for (int i=0; i<3; ++i)
+								currGS.strokeColor.append(0);
+							if (!usedColorSpaces.contains(CS_DeviceRGB))
+								usedColorSpaces.append(CS_DeviceRGB);
+						}
+						else if (args[0].GetName() == "DeviceCMYK")
+						{
+							currGS.fillCS = CS_DeviceCMYK;
+							currGS.strokeColor.clear();
+							for (int i=0; i<3; ++i)
+								currGS.strokeColor.append(0);
+							currGS.strokeColor.append(1);
+							if (!usedColorSpaces.contains(CS_DeviceCMYK))
+								usedColorSpaces.append(CS_DeviceCMYK);
+						}
+						else if (args[0].GetName() == "Pattern")
+						{
+							currGS.fillCS = CS_Pattern;
+							if (!usedColorSpaces.contains(CS_Pattern))
+								usedColorSpaces.append(CS_Pattern);
+						}
+						else
+						{
+							if (processedNamedCS.contains(args[0].GetName()))
+							{
+								currGS.strokeCS = processedNamedCS.value(args[0].GetName());
+							}
+							else
+							{
+								if (colorSpaceRes && colorSpaceRes->GetIndirectKey(args[0].GetName()))
+								{
+									PdfObject* csEntry = colorSpaceRes->GetIndirectKey(args[0].GetName());
+									PDFColorSpace retval = getCSType(csEntry);
+									if (retval != CS_Unknown && !usedColorSpaces.contains(retval))
+										usedColorSpaces.append(retval);
+									currGS.strokeCS = retval;
+									processedNamedCS.insert(args[0].GetName(), retval);
+								}
+								else
+								{
+									qDebug() << "Supplied colorspace is undefined!";
+									return false;
+								}
+							}
+						}
+					}
+					else
+					{
+						qDebug() << "Wrong syntax in specifying color space!";
+						return false;
+					}
+					}
+					break;
+				case KW_sc:
+					currGS.fillColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.fillColor.append(args[i].GetReal());
+					break;
+				case KW_SC:
+					currGS.strokeColor.clear();
+					for (int i=0; i<args.size(); ++i)
+						currGS.strokeColor.append(args[i].GetReal());
+					break;
+				case KW_scn:
+					currGS.fillColor.clear();
+					for (int i=0; i<args.size(); ++i)
+					{
+						if (args[i].IsReal() || args[i].IsNumber())
+							currGS.fillColor.append(args[i].GetReal());
+					}
+					break;
+				case KW_SCN:
+					currGS.strokeColor.clear();
+					for (int i=0; i<args.size(); ++i)
+					{
+						if (args[i].IsReal() || args[i].IsNumber())
+							currGS.strokeColor.append(args[i].GetReal());
+					}
+					break;
+				case KW_Do: // image or form XObject
+					{
+					if (!processedNamedXObj.contains(args[0].GetName()))
+					{
+						if (args.size() == 1 && args[0].IsName() && xObjects)
+						{
+							PdfObject* xObject = xObjects->GetIndirectKey(args[0].GetName());
+							PdfObject* subtypeObject = xObject?xObject->GetIndirectKey("Subtype"):NULL;
+							if (subtypeObject && subtypeObject->IsName())
+							{
+								if (subtypeObject->GetName() == "Image")
+								{
+									PdfObject* imgColorSpace = xObject->GetIndirectKey("ColorSpace");
+									if (imgColorSpace)
+									{
+										PDFColorSpace retval = getCSType(imgColorSpace);
+										if (retval != CS_Unknown && !usedColorSpaces.contains(retval))
+											usedColorSpaces.append(retval);
+									}
+									PdfObject* sMaskObj = xObject->GetIndirectKey("SMask");
+									if (sMaskObj)
+										hasTransparency = true;
+									PDFImage img;
+									img.imgName = args[0].GetName().GetEscapedName().c_str();
+									double width = xObject->GetIndirectKey("Width")->GetReal();
+									double height = xObject->GetIndirectKey("Height")->GetReal();
+									img.dpiX = qRound(width/(currGS.ctm.m11()/72));
+									img.dpiY = qRound(height/(currGS.ctm.m22()/72));
+									imgs.append(img);
+								}
+								else if (subtypeObject->GetName() == "Form")
+								{
+									PdfXObject xObj(xObject);
+									inspectCanvas(&xObj, usedColorSpaces, hasTransparency, usedFonts, imgs); // recursive call
+								}
+							}
+							else
+							{
+								qDebug() << "Supplied external object is undefined!";
+								return false;
+							}
+							processedNamedXObj.append(args[0].GetName());
+						}
+						else
+						{
+							qDebug() << "Wrong syntax for Do operator or there's no XObject defined!";
+							return false;
+						}
+
+					}
+					}
+					break;
+				case KW_BI:
+					inlineImgDict = true;
+					break;
+				case KW_ID:
+					if (inlineImgDict)
+					{
+						PdfName colorspace("ColorSpace");
+						PdfName cs("CS");
+						if (args.contains(colorspace) || args.contains(cs))
+						{
+							int csIdx = args.contains(colorspace)?args.indexOf(colorspace):args.indexOf(cs);
+							if (args[csIdx+1].IsName())
+							{
+								PdfName csName = args[csIdx+1].GetName();
+								if ((csName == "G" || csName == "DeviceGray") && !usedColorSpaces.contains(CS_DeviceGray))
+									usedColorSpaces.append(CS_DeviceGray);
+								else if ((csName == "RGB" || csName == "DeviceRGB") && !usedColorSpaces.contains(CS_DeviceRGB))
+									usedColorSpaces.append(CS_DeviceRGB);
+								else if ((csName == "CMYK" || csName == "DeviceCMYK") && !usedColorSpaces.contains(CS_DeviceCMYK))
+									usedColorSpaces.append(CS_DeviceCMYK);
+								else if (!processedNamedCS.contains(csName))
+								{
+									if (colorSpaceRes && colorSpaceRes->GetIndirectKey(csName))
+									{
+										PdfObject* csEntry = colorSpaceRes->GetIndirectKey(csName);
+										if (csEntry)
+										{
+											PDFColorSpace retval = getCSType(csEntry);
+											if (retval != CS_Unknown && !usedColorSpaces.contains(retval))
+												usedColorSpaces.append(retval);
+											processedNamedCS.insert(csName, retval);
+										}
+									}
+									else
+									{
+										qDebug() << "Supplied colorspace for inline image is undefined!";
+										return false;
+									}
+								}
+							}
+						}
+						PdfName height("Height");
+						PdfName h("H");
+						PdfName width("Width");
+						PdfName w("W");
+						if ((args.contains(height) || args.contains(h)) && (args.contains(width) || args.contains(w)))
+						{
+							int heightIdx = args.contains(height)?args.indexOf(height):args.indexOf(h);
+							int widthIdx = args.contains(width)?args.indexOf(width):args.indexOf(w);
+							double height = args[heightIdx+1].GetReal();
+							double width = args[widthIdx+1].GetReal();
+							PDFImage img;
+							img.imgName = "Inline Image";
+							img.dpiX = qRound(width/(currGS.ctm.m11()/72));
+							img.dpiY = qRound(height/(currGS.ctm.m22()/72));
+							imgs.append(img);
+						}
+						inlineImgDict = false;
+					}
+					break;
+				case KW_gs:
+					{
+					if (!processedNamedGS.contains(args[0].GetName()))
+					{
+						if (args.size() == 1 && args[0].IsName() && extGState)
+						{
+							PdfObject* extGStateObj = extGState->GetIndirectKey(args[0].GetName());
+							if (extGStateObj)
+							{
+								inspectExtGStateObj(extGStateObj, usedColorSpaces, hasTransparency, usedFonts, currGS);
+							}
+							else
+							{
+								qDebug() << "Named graphic state used with gs operator is undefined in current ExtGState";
+								return false;
+							}
+							processedNamedGS.append(args[0].GetName());
+						}
+						else
+						{
+							qDebug() << "Wrong syntax in applying extended graphic state (gs operator) or there's no ExtGState defined!";
+							return false;
+						}
+					}
+					}
+					break;
+				case KW_Tf:
+					{
+					if (processedNamedFont.contains(args[0].GetName()))
+					{
+						currGS.font.first = processedNamedFont.value(args[0].GetName());
+						currGS.font.second = args[1].GetReal();
+					}
+					else
+					{
+						if (args.size() == 2 && args[0].IsName() && fontRes)
+						{
+							PdfObject* fontObj = fontRes->GetIndirectKey(args[0].GetName());
+							if (fontObj)
+							{
+								PDFFont retval = getFontInfo(fontObj);
+								usedFonts.append(retval);
+								processedNamedFont.insert(args[0].GetName(), retval);
+								currGS.font.first = retval;
+								currGS.font.second = args[1].GetReal();
+							}
+							else
+							{
+								qDebug() << "The specified font cannot be found in current Resources!";
+								return false;
+							}
+						}
+						else
+						{
+							qDebug() << "Wrong syntax in use of Tf operator or there's no Font defined in current Resources dictionary!";
+							return false;
+						}
+					}
+					}
+					break;
+				case KW_Undefined:
+				default:
+					break;
+				}
+				args.clear();
+			}
+		}
+	}
+	catch (PdfError & e)
+	{
+		qDebug() << "Error in parsing content stream";
+		e.PrintErrorMsg();
+		return false;
+	}
+	return true;
+}
+void PDFAnalyzer::inspectExtGStateObj(PdfObject* extGStateObj, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, PDFGraphicState & currGS)
+{
+	PdfObject* bmObj = extGStateObj->GetIndirectKey("BM");
+	if (bmObj && bmObj->IsName())
+	{
+		currGS.blendModes.clear();
+		currGS.blendModes.append(bmObj->GetName().GetEscapedName().c_str());
+		if (!(bmObj->GetName() == "Normal" || bmObj->GetName() == "Compatible"))
+			hasTransparency = true;
+	}
+	else if (bmObj && bmObj->IsArray())
+	{
+		PdfArray arr = bmObj->GetArray();
+		currGS.blendModes.clear();
+		for(int i=0; i<arr.GetSize(); ++i)
+			currGS.blendModes.append(arr[i].GetName().GetEscapedName().c_str());
+		if (arr[0].IsName() && !(arr[0].GetName() == "Normal" || arr[0].GetName() == "Compatible"))
+			hasTransparency = true;
+	}
+	PdfObject* caObj = extGStateObj->GetIndirectKey("ca");
+	if (caObj && (caObj->IsReal() || caObj->IsNumber()))
+	{
+		currGS.fillAlphaConstant = caObj->GetReal();
+		if (caObj->GetReal() < 1)
+			hasTransparency = true;
+	}
+	PdfObject* cAObj = extGStateObj->GetIndirectKey("CA");
+	if (cAObj && (cAObj->IsReal() || cAObj->IsNumber()))
+	{
+		if (cAObj->GetReal() < 1)
+		hasTransparency = true;
+	}
+	PdfObject* sMaskObj = extGStateObj->GetIndirectKey("SMask");
+	if (sMaskObj && !(sMaskObj->IsName() && sMaskObj->GetName() == "None"))
+		hasTransparency = true;
+	PdfObject* fontObj = extGStateObj->GetIndirectKey("Font");
+	if (fontObj && fontObj->IsArray())
+	{
+		PdfArray arr = fontObj->GetArray();
+		if (arr[0].IsReference())
+		{
+			PdfReference ref = arr[0].GetReference();
+			PdfObject* fontObject = m_doc->GetObjects().GetObject(ref);
+			if (fontObject)
+			{
+				PDFFont font = getFontInfo(fontObject);
+				usedFonts.append(font);
+				currGS.font.first = font;
+				currGS.font.second = arr[1].GetReal();
+			}
+
+		}
+	}
+	PdfObject* lwObj = extGStateObj->GetIndirectKey("LW");
+	if (lwObj)
+		currGS.lineWidth = lwObj->GetReal();
+	PdfObject* lcObj = extGStateObj->GetIndirectKey("LC");
+	if (lcObj)
+		currGS.lineCap = lcObj->GetNumber();
+	PdfObject* ljObj = extGStateObj->GetIndirectKey("LJ");
+	if (ljObj)
+		currGS.lineJoin = ljObj->GetNumber();
+	PdfObject* mlObj = extGStateObj->GetIndirectKey("ML");
+	if (mlObj)
+		currGS.miterLimit = mlObj->GetReal();
+	PdfObject* dObj = extGStateObj->GetIndirectKey("D");
+	if (dObj)
+	{
+		PdfArray dashArr = dObj->GetArray()[0];
+		currGS.dashPattern.first.clear();
+		for (int i=0; i<dashArr.GetSize(); ++i)
+			currGS.dashPattern.first.append(dashArr[i].GetNumber());
+		currGS.dashPattern.second = dObj->GetArray()[1].GetNumber();
+	}
+}
+PDFFont PDFAnalyzer::getFontInfo(PdfObject* fontObj)
+{
+	PDFFont currFont;
+	PdfObject* subtype = fontObj->GetIndirectKey("Subtype");
+	if (subtype && subtype->IsName())
+	{
+		PdfObject* fontDesc = fontObj->GetIndirectKey("FontDescriptor");
+		if (subtype->GetName() == "Type1")
+			currFont.fontType = F_Type1;
+		else if (subtype->GetName() == "MMType1")
+			currFont.fontType = F_MMType1;
+		else if (subtype->GetName() == "TrueType")
+			currFont.fontType = F_TrueType;
+		else if (subtype->GetName() == "Type3")
+		{
+			currFont.fontType = F_Type3;
+			currFont.isEmbedded = true;
+			fontDesc = NULL;
+		}
+		else if (subtype->GetName() == "Type0")
+		{
+			PdfObject* descendantFonts = fontObj->GetIndirectKey("DescendantFonts");
+			if (descendantFonts && descendantFonts->IsArray())
+			{
+				PdfObject descendantFont = descendantFonts->GetArray()[0];
+				descendantFont.SetOwner(descendantFonts->GetOwner());
+				PdfObject* subtypeDescFont = descendantFont.GetIndirectKey("Subtype");
+				fontDesc = descendantFont.MustGetIndirectKey("FontDescriptor");
+				if (subtypeDescFont && subtypeDescFont->IsName())
+				{
+					if (subtypeDescFont->GetName() == "CIDFontType0")
+						currFont.fontType = F_CIDFontType0;
+					else if (subtypeDescFont->GetName() == "CIDFontType2")
+						currFont.fontType = F_CIDFontType2;
+				}
+			}
+		}
+		if (fontDesc)
+		{
+			PdfObject* fontFile = fontDesc->GetIndirectKey("FontFile");
+			PdfObject* fontFile2 = fontDesc->GetIndirectKey("FontFile2");
+			PdfObject* fontFile3 = fontDesc->GetIndirectKey("FontFile3");
+			if (fontFile && fontFile->HasStream())
+				currFont.isEmbedded = true;
+			if (fontFile2 && fontFile2->HasStream())
+				currFont.isEmbedded = true;
+			if (fontFile3 && fontFile3->HasStream())
+			{
+				currFont.isEmbedded = true;
+				PdfObject* ff3Subtype = fontFile3->GetIndirectKey("Subtype");
+				if (ff3Subtype && ff3Subtype->IsName() && ff3Subtype->GetName() == "OpenType")
+					currFont.isOpenType = true;
+			}
+		}
+	}
+	return currFont;
+}
+#else
+PDFAnalyzer::PDFAnalyzer(QString & filename) : QObject()
+{
+}
+PDFAnalyzer::~PDFAnalyzer()
+{
+}
+bool PDFAnalyzer::inspectPDF(int pageNum, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts)
+{
+	return false;
+}
+#endif
Index: scribus/commonstrings.cpp
===================================================================
--- scribus/commonstrings.cpp	(revision 14042)
+++ scribus/commonstrings.cpp	(revision 14043)
@@ -146,7 +146,9 @@
 QString CommonStrings::PDF_1_3      = "";
 QString CommonStrings::PDF_1_4      = "";
 QString CommonStrings::PDF_1_5      = "";
+QString CommonStrings::PDF_X1a		= "";
 QString CommonStrings::PDF_X3       = "";
+QString CommonStrings::PDF_X4		= "";
 
 QString CommonStrings::PostScript1   = "";
 QString CommonStrings::trPostScript1 = "";
@@ -264,7 +266,7 @@
 	CommonStrings::trNo       = tr("No");
 	CommonStrings::trYesKey   = tr("&Yes");
 	CommonStrings::trNoKey    = tr("&No");
-	
+
 	CommonStrings::itemType_TextFrame  = tr("Text Frame");
 	CommonStrings::itemType_ImageFrame = tr("Image Frame");
 	CommonStrings::itemType_Line       = tr("Line");
@@ -282,7 +284,7 @@
 	CommonStrings::itemSubType_PDF_TextAnnotation = tr("PDF Text Annotation");
 	CommonStrings::itemSubType_PDF_LinkAnnotation = tr("PDF Link Annotation");
 
-	
+
 	CommonStrings::customPageSize = "Custom";
 	CommonStrings::trCustomPageSize = tr( "Custom", "CommonStrings, custom page size" );
 
@@ -305,7 +307,7 @@
 	CommonStrings::trPageLocMiddleLeft  = tr( "Middle Left", "Middle Left page location" );
 	CommonStrings::trPageLocMiddleRight = tr( "Middle Right", "Middle Right page location" );
 	CommonStrings::trPageLocRight       = tr( "Right Page", "Right page location" );
-	
+
 	CommonStrings::masterPageNormal         = "Normal";
 	CommonStrings::trMasterPageNormal       = tr( "Normal", "Default single master page" );
 	CommonStrings::masterPageNormalLeft     = "Normal Left";
@@ -314,13 +316,13 @@
 	CommonStrings::trMasterPageNormalMiddle = tr( "Normal Middle", "Default middle master page" );
 	CommonStrings::masterPageNormalRight    = "Normal Right";
 	CommonStrings::trMasterPageNormalRight  = tr( "Normal Right", "Default right master page" );
-	
+
 	CommonStrings::trPenStyle_SolidLine      = tr("Solid Line");
 	CommonStrings::trPenStyle_DashedLine     = tr("Dashed Line");
 	CommonStrings::trPenStyle_DottedLine     = tr("Dotted Line");
 	CommonStrings::trPenStyle_DashDotLine    = tr("Dash Dot Line");
 	CommonStrings::trPenStyle_DashDotDotLine = tr("Dash Dot Dot Line");
-	
+
 	CommonStrings::DefaultParagraphStyle     = "Default Paragraph Style";
 	CommonStrings::DefaultCharacterStyle     = "Default Character Style";
 	CommonStrings::DefaultLineStyle          = "Default Line Style";
@@ -328,7 +330,7 @@
 	CommonStrings::trDefaultCharacterStyle   = tr("Default Character Style");
 	CommonStrings::trDefaultLineStyle        = tr("Default Line Style");
 
-	
+
 	CommonStrings::monday    = tr("Monday");
 	CommonStrings::tuesday   = tr("Tuesday");
 	CommonStrings::wednesday = tr("Wednesday");
@@ -354,26 +356,26 @@
 	CommonStrings::trGrayscale = tr("Grayscale", "Colorspace");
 	CommonStrings::trDuotone   = tr("Duotone", "Colorspace");
 	CommonStrings::trUnknownCS = tr("Unknown", "Colorspace (Unknown)");
-	
+
 	CommonStrings::trVisionNormal         = tr("Normal Vision", "Color Blindness - Normal Vision");
 	CommonStrings::trVisionProtanopia     = tr("Protanopia (Red)", "Color Blindness - Red Color Blind");
 	CommonStrings::trVisionDeuteranopia   = tr("Deuteranopia (Green)", "Color Blindness - Greed Color Blind");
 	CommonStrings::trVisionTritanopia     = tr("Tritanopia (Blue)", "Color Blindness - Blue Color Blind");
 	CommonStrings::trVisionFullColorBlind = tr("Full Color Blindness", "Color Blindness - Full Color Blindness");
-	
+
 	CommonStrings::trCustomTabFill = tr("Custom: ","Custom Tab Fill Option");
-	
+
 	CommonStrings::trOpticalMarginsNone            = tr("None", "Optical Margin Setting");
 	CommonStrings::trOpticalMarginsLeftProtruding  = tr("Left Protruding", "Optical Margin Setting");
 	CommonStrings::trOpticalMarginsRightProtruding = tr("Right Protruding", "Optical Margin Setting");
 	CommonStrings::trOpticalMarginsLeftHangPunct   = tr("Left Hanging Punctuation", "Optical Margin Setting");
 	CommonStrings::trOpticalMarginsRightHangPunct  = tr("Right Hanging Punctuation", "Optical Margin Setting");
 	CommonStrings::trOpticalMarginsDefault         = tr("Default", "Optical Margin Setting");
-	
+
 	//Paragraph Style Word Tracking
 	CommonStrings::trMinWordTracking = tr("Min. Word Tracking");
 	CommonStrings::trMaxWordTracking = tr("Max. Word Tracking");
-	
+
 	//Paragraph Style Glyph Extension
 	CommonStrings::trMinGlyphExtension = tr("Min. Glyph Extension");
 	CommonStrings::trMaxGlyphExtension = tr("Max. Glyph Extension");
@@ -384,7 +386,9 @@
 	CommonStrings::PDF_1_3      = "PDF 1.3";
 	CommonStrings::PDF_1_4      = "PDF 1.4";
 	CommonStrings::PDF_1_5      = "PDF 1.5";
+	CommonStrings::PDF_X1a      = "PDF/X-1a";
 	CommonStrings::PDF_X3       = "PDF/X-3";
+	CommonStrings::PDF_X4       = "PDF/X-4";
 
 	CommonStrings::PostScript1   = "PostScript Level 1";
 	CommonStrings::trPostScript1 = tr( "PostScript Level 1" );
@@ -394,7 +398,7 @@
 	CommonStrings::trPostScript3 = tr( "PostScript Level 3" );
 	CommonStrings::WindowsGDI    = "Windows GDI";
 	CommonStrings::trWindowsGDI  = tr( "Windows GDI" );
-	
+
 	//Units
 	CommonStrings::trStrPT=unitGetStrFromIndex(SC_PT);
 	CommonStrings::trStrMM=unitGetStrFromIndex(SC_MM);
@@ -425,3 +429,4 @@
 	return trPenStyle_SolidLine;
 }
 
+
Index: scribus/scribusstructs.h
===================================================================
--- scribus/scribusstructs.h	(revision 14042)
+++ scribus/scribusstructs.h	(revision 14043)
@@ -387,7 +387,11 @@
 	ImageDPITooHigh=9,
 	ImageIsGIF=10,
 	BlendMode=11,
-	WrongFontInAnnotation=12
+	WrongFontInAnnotation=12,
+	NotCMYKOrSpot=13,
+	DeviceColorAndOutputIntend=14,
+	FontNotEmbedded=15,
+	EmbeddedFontIsOpenType=16
 } PreflightError;
 
 typedef QMap<PreflightError, int> errorCodes;
@@ -452,8 +456,8 @@
 typedef QList<double> Guides;
 
 //! \brief from ols scribusXml
-struct Linked 
-{ 
+struct Linked
+{
 	int Start;
 	int StPag;
 };
@@ -473,3 +477,4 @@
 #endif
 
 
+
Index: scribus/commonstrings.h
===================================================================
--- scribus/commonstrings.h	(revision 14042)
+++ scribus/commonstrings.h	(revision 14043)
@@ -50,7 +50,7 @@
 	Q_OBJECT
 public:
 	CommonStrings();
-	
+
 	virtual void changeEvent(QEvent *e);
 
 	/**
@@ -105,7 +105,7 @@
 	static QString trYesKey;
 	//! \brief Translated "No" with key accelerator "&No"
 	static QString trNoKey;
-	
+
 	//Item Types
 	static QString itemType_TextFrame;
 	static QString itemType_ImageFrame;
@@ -116,7 +116,7 @@
 	static QString itemType_LatexFrame;
 	static QString itemType_OSGFrame;
 	static QString itemType_Multiple;
-	
+
 	static QString itemSubType_PDF_PushButton;
 	static QString itemSubType_PDF_TextField;
 	static QString itemSubType_PDF_CheckBox;
@@ -124,7 +124,7 @@
 	static QString itemSubType_PDF_ListBox;
 	static QString itemSubType_PDF_TextAnnotation;
 	static QString itemSubType_PDF_LinkAnnotation;
-	
+
 	//Page Size
 	static QString customPageSize;
 	static QString trCustomPageSize;
@@ -148,7 +148,7 @@
 	static QString trPageLocMiddleLeft;
 	static QString trPageLocMiddleRight;
 	static QString trPageLocRight;
-	
+
 	//Master Page Default Names
 	static QString masterPageNormal;
 	static QString trMasterPageNormal;
@@ -158,14 +158,14 @@
 	static QString trMasterPageNormalMiddle;
 	static QString masterPageNormalRight;
 	static QString trMasterPageNormalRight;
-	
+
 	//Pen Styles
 	static QString trPenStyle_SolidLine;
 	static QString trPenStyle_DashedLine;
 	static QString trPenStyle_DottedLine;
 	static QString trPenStyle_DashDotLine;
 	static QString trPenStyle_DashDotDotLine;
-	
+
 	//Default Styles
 	static QString DefaultParagraphStyle;
 	static QString DefaultCharacterStyle;
@@ -173,9 +173,9 @@
 	static QString trDefaultParagraphStyle;
 	static QString trDefaultCharacterStyle;
 	static QString trDefaultLineStyle;
-	
+
 	//Days and Months
-	static QString monday; 
+	static QString monday;
 	static QString tuesday;
 	static QString wednesday;
 	static QString thursday;
@@ -195,7 +195,7 @@
 	static QString october;
 	static QString november;
 	static QString december;
-	
+
 	//Color Related
 	static QString trRGB;
 	static QString trCMYK;
@@ -209,10 +209,10 @@
 	static QString trVisionDeuteranopia;
 	static QString trVisionTritanopia;
 	static QString trVisionFullColorBlind;
-	
+
 	//Tab Fill Custom
 	static QString trCustomTabFill;
-	
+
 	//Paragraph Style Optical Margins
 	static QString trOpticalMarginsNone;
 	static QString trOpticalMarginsLeftProtruding;
@@ -220,11 +220,11 @@
 	static QString trOpticalMarginsLeftHangPunct;
 	static QString trOpticalMarginsRightHangPunct;
 	static QString trOpticalMarginsDefault;
-	
+
 	//Paragraph Style Word Tracking
 	static QString trMinWordTracking;
 	static QString trMaxWordTracking;
-	
+
 	//Paragraph Style Glyph Extension
 	static QString trMinGlyphExtension;
 	static QString trMaxGlyphExtension;
@@ -235,7 +235,9 @@
 	static QString PDF_1_3;
 	static QString PDF_1_4;
 	static QString PDF_1_5;
+	static QString PDF_X1a;
 	static QString PDF_X3;
+	static QString PDF_X4;
 
 	static QString PostScript1;
 	static QString trPostScript1;
@@ -245,7 +247,7 @@
 	static QString trPostScript3;
 	static QString WindowsGDI;
 	static QString trWindowsGDI;
-	
+
 	//Units strings
 	static QString trStrPT;
 	static QString trStrMM;
Index: scribus/pdfoptions.h
===================================================================
--- scribus/pdfoptions.h	(revision 14042)
+++ scribus/pdfoptions.h	(revision 14043)
@@ -52,6 +52,8 @@
 		PDFVersion_14 = 14,
 		PDFVersion_15 = 15,
 		PDFVersion_X3 = 12,
+		PDFVersion_X1a = 11,
+		PDFVersion_X4 = 10
 	};
 
 	enum PDFPageLayout
Index: scribus/ui/pdfopts.cpp
===================================================================
--- scribus/ui/pdfopts.cpp	(revision 14042)
+++ scribus/ui/pdfopts.cpp	(revision 14043)
@@ -121,7 +121,7 @@
 //	setMaximumSize( sizeHint() );
 //tooltips
 	multiFile->setToolTip( "<qt>" + tr( "This enables exporting one individually named PDF file for each page in the document. Page numbers are added automatically. This is most useful for imposing PDF for commercial printing.") + "</qt>" );
-	OK->setToolTip( "<qt>" + tr( "The save button will be disabled if you are trying to export PDF/X-3 and the info string is missing from the PDF/X-3 tab.") + "</qt>" );
+	OK->setToolTip( "<qt>" + tr( "The save button will be disabled if you are trying to export PDF/X and the info string is missing from the PDF/X tab.") + "</qt>" );
 	// signals and slots connections
 	connect( FileC, SIGNAL( clicked() ), this, SLOT( ChangeFile() ) );
 	connect( OK, SIGNAL( clicked() ), this, SLOT( DoExport() ) );
@@ -309,7 +309,11 @@
 	if (Options->PDFVersionCombo->currentIndex() == 2)
 		Opts.Version = PDFOptions::PDFVersion_15;
 	if (Options->PDFVersionCombo->currentIndex() == 3)
+		Opts.Version = PDFOptions::PDFVersion_X1a;
+	if (Options->PDFVersionCombo->currentIndex() == 4)
 		Opts.Version = PDFOptions::PDFVersion_X3;
+	if (Options->PDFVersionCombo->currentIndex() == 5)
+		Opts.Version = PDFOptions::PDFVersion_X4;
 	if (Options->OutCombo->currentIndex() == 0)
 	{
 		Opts.UseRGB = true;
@@ -334,13 +338,16 @@
 			{
 				Opts.UseProfiles = Options->EmbedProfs->isChecked();
 				Opts.UseProfiles2 = Options->EmbedProfs2->isChecked();
-				Opts.Intent = Options->IntendS->currentIndex();
-				Opts.Intent2 = Options->IntendI->currentIndex();
-				Opts.EmbeddedI = Options->NoEmbedded->isChecked();
-				Opts.SolidProf = Options->SolidPr->currentText();
-				Opts.ImageProf = Options->ImageP->currentText();
+				if (Opts.Version != PDFOptions::PDFVersion_X1a)
+				{
+					Opts.Intent = Options->IntendS->currentIndex();
+					Opts.Intent2 = Options->IntendI->currentIndex();
+					Opts.EmbeddedI = Options->NoEmbedded->isChecked();
+					Opts.SolidProf = Options->SolidPr->currentText();
+					Opts.ImageProf = Options->ImageP->currentText();
+				}
 				Opts.PrintProf = Options->PrintProfC->currentText();
-				if (Opts.Version == PDFOptions::PDFVersion_X3)
+				if ((Opts.Version == PDFOptions::PDFVersion_X3) || (Opts.Version == PDFOptions::PDFVersion_X1a) || (Opts.Version == PDFOptions::PDFVersion_X4))
 				{
 					cmsHPROFILE hIn;
 					QByteArray profilePath( appPrinterProfiles[Opts.PrintProf].toLocal8Bit() );
Index: scribus/ui/tabpdfoptions.cpp
===================================================================
--- scribus/ui/tabpdfoptions.cpp	(revision 14042)
+++ scribus/ui/tabpdfoptions.cpp	(revision 14043)
@@ -322,7 +322,11 @@
 	PDFVersionCombo->addItem("PDF 1.5 (Acrobat 6)");
 	cms = doc ? (ScCore->haveCMS() && doc->HasCMS) : false;
 	if (cms && (!PDFXProfiles.isEmpty()))
+	{
+		PDFVersionCombo->addItem("PDF/X-1a");
 		PDFVersionCombo->addItem("PDF/X-3");
+		PDFVersionCombo->addItem("PDF/X-4");
+	}
 	GroupBox1Layout->addWidget( PDFVersionCombo, 0, 1, 1, 2 );
 	TextLabel1x = new QLabel( tr( "&Binding:" ), GroupBox1 );
 	TextLabel1x->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
@@ -847,7 +851,7 @@
 	tabPDFXLayout->addWidget( BleedGroup );
 
 	X3Group = new QGroupBox( tabPDFX );
-	X3Group->setTitle( tr( "PDF/X-3 Output Intent" ) );
+	X3Group->setTitle( tr( "PDF/X Output Intent" ) );
 	X3GroupLayout = new QGridLayout( X3Group );
 	X3GroupLayout->setSpacing( 5 );
 	X3GroupLayout->setMargin( 10 );
@@ -953,7 +957,7 @@
 		                                    "a token can be * for all the pages, 1-5 for "
 		                                    "a range of pages or a single page number.") + "</qt>" );
 
-	PDFVersionCombo->setToolTip( "<qt>" + tr( "Determines the PDF compatibility.<br/>The default is <b>PDF 1.3</b> which gives the widest compatibility.<br/>Choose <b>PDF 1.4</b> if your file uses features such as transparency or you require 128 bit encryption.<br/><b>PDF 1.5</b> is necessary when you wish to preserve objects in separate layers within the PDF.<br/><b>PDF/X-3</b> is for exporting the PDF when you want color managed RGB for commercial printing and is selectable when you have activated color management. Use only when advised by your printer or in some cases printing to a 4 color digital color laser printer." ) + "</qt>");
+	PDFVersionCombo->setToolTip( "<qt>" + tr( "Determines the PDF compatibility.<br/>The default is <b>PDF 1.3</b> which gives the widest compatibility.<br/>Choose <b>PDF 1.4</b> if your file uses features such as transparency or you require 128 bit encryption.<br/><b>PDF 1.5</b> is necessary when you wish to preserve objects in separate layers within the PDF.<br/><b>PDF/X-3</b> is for exporting the PDF when you want color managed RGB for commercial printing and is selectable when you have activated color management. Use only when advised by your printer or in some cases printing to a 4 color digital color laser printer.<br/><b>PDF/X-1a</b> is for blind exchange with colors strictly specified in CMYK or spot colors.<br/><b>PDF/X-4</b> is an extension of PDF/X-3 to support transparancy and layering." ) + "</qt>");
 	ComboBind->setToolTip( "<qt>" + tr( "Determines the binding of pages in the PDF. Unless you know you need to change it leave the default choice - Left." ) + "</qt>" );
 	CheckBox1->setToolTip( "<qt>" + tr( "Generates thumbnails of each page in the PDF. Some viewers can use the thumbnails for navigation." ) + "</qt>" );
 	Article->setToolTip( "<qt>" + tr( "Generate PDF Articles, which is useful for navigating linked articles in a PDF." ) + "</qt>" );
@@ -999,7 +1003,7 @@
 	BleedRight->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 	docBleeds->setToolTip( "<qt>" + tr( "Use the existing bleed settings from the document preferences" ) + "</qt>" );
 	PrintProfC->setToolTip( "<qt>" + tr( "Output profile for printing. If possible, get some guidance from your printer on profile selection." ) + "</qt>" );
-	InfoString->setToolTip( "<qt>" + tr( "Mandatory string for PDF/X-3 or the PDF will fail PDF/X-3 conformance. We recommend you use the title of the document." ) + "</qt>" );
+	InfoString->setToolTip( "<qt>" + tr( "Mandatory string for PDF/X or the PDF will fail PDF/X conformance. We recommend you use the title of the document." ) + "</qt>" );
 }
 
 void TabPDFOptions::restoreDefaults(PDFOptions & Optionen,
@@ -1020,8 +1024,12 @@
 	bool cmsUse = mdoc ? (ScCore->haveCMS() && mdoc->HasCMS) : false;
 	if (cmsUse)
 	{
+		if (Opts.Version == PDFOptions::PDFVersion_X1a)
+			PDFVersionCombo->setCurrentIndex(3);
 		if (Opts.Version == PDFOptions::PDFVersion_X3)
-			PDFVersionCombo->setCurrentIndex(3);
+			PDFVersionCombo->setCurrentIndex(4);
+		if (Opts.Version == PDFOptions::PDFVersion_X4)
+			PDFVersionCombo->setCurrentIndex(5);
 	}
 	else
 		PDFVersionCombo->setCurrentIndex(0);
@@ -1036,7 +1044,7 @@
 	Article->setChecked(Opts.Articles);
 	CheckBM->setChecked(Opts.Bookmarks);
 	useLayers->setChecked(Opts.useLayers);
-	if (Opts.Version == 15)
+	if (Opts.Version == PDFOptions::PDFVersion_15 || Opts.Version == PDFOptions::PDFVersion_X4)
 		useLayers->setEnabled(true);
 	else
 		useLayers->setEnabled(false);
@@ -1190,7 +1198,7 @@
 			doublePageLeft->setChecked(true);
 		else if (Opts.PageLayout == PDFOptions::TwoColumnRight)
 			doublePageRight->setChecked(true);
-		if (Opts.Version == 15)
+		if ((Opts.Version == PDFOptions::PDFVersion_15) || (Opts.Version == PDFOptions::PDFVersion_X4))
 			useLayers2->setEnabled(true);
 		else
 			useLayers2->setEnabled(false);
@@ -1326,8 +1334,12 @@
 	docInfoMarks->setChecked(Opts.docInfoMarks);
 	if (!cmsUse)
 		X3Group->setEnabled(false);
-	if (cmsUse && (Opts.Version == 12) && (!PDFXProfiles.isEmpty()))
+	if (cmsUse && (Opts.Version == PDFOptions::PDFVersion_X1a) && (!PDFXProfiles.isEmpty()))
 		EnablePDFX(3);
+	else if (cmsUse && (Opts.Version == PDFOptions::PDFVersion_X3) && (!PDFXProfiles.isEmpty()))
+		EnablePDFX(4);
+	else if (cmsUse && (Opts.Version == PDFOptions::PDFVersion_X4) && (!PDFXProfiles.isEmpty()))
+		EnablePDFX(5);
 	else
 		X3Group->setEnabled(false);
 	if (mdoc != 0  && exporting)
@@ -1428,7 +1440,11 @@
 	if (PDFVersionCombo->currentIndex() == 2)
 		pdfOptions.Version = PDFOptions::PDFVersion_15;
 	if (PDFVersionCombo->currentIndex() == 3)
+		pdfOptions.Version = PDFOptions::PDFVersion_X1a;
+	if (PDFVersionCombo->currentIndex() == 4)
 		pdfOptions.Version = PDFOptions::PDFVersion_X3;
+	if (PDFVersionCombo->currentIndex() == 5)
+		pdfOptions.Version = PDFOptions::PDFVersion_X4;
 	if (OutCombo->currentIndex() == 0)
 	{
 		pdfOptions.isGrayscale = false;
@@ -1496,7 +1512,7 @@
 
 void TabPDFOptions::checkInfo()
 {
-	if ((PDFVersionCombo->currentIndex() == 3) && (InfoString->text().isEmpty()))
+	if ((PDFVersionCombo->currentIndex() >= 3) && (InfoString->text().isEmpty()))
 		emit noInfo();
 	else
 		emit hasInfo();
@@ -1519,9 +1535,13 @@
 	PDFVersionCombo->addItem("PDF 1.5 (Acrobat 6)");
 	cms=enable;
 	if (enable)
+	{
+		PDFVersionCombo->addItem("PDF/X-1a");
 		PDFVersionCombo->addItem("PDF/X-3");
+		PDFVersionCombo->addItem("PDF/X-4");
+	}
 	else
-		a = qMin(a, 3);
+		a = qMin(a, 2);
 	PDFVersionCombo->setCurrentIndex(a);
 	EnablePr(1);
 	connect(PDFVersionCombo, SIGNAL(activated(int)), this, SLOT(EnablePDFX(int)));
@@ -1529,9 +1549,9 @@
 
 void TabPDFOptions::EnablePDFX(int a)
 {
-	useLayers->setEnabled(a == 2);
+	useLayers->setEnabled((a == 2) || (a == 5));
 	if (useLayers2)
-		useLayers2->setEnabled(a == 2);
+		useLayers2->setEnabled((a == 2) || (a == 5));
 	if (doc != 0 && pdfExport)
 	{
 		int currentEff = EffectType->currentIndex();
@@ -1570,7 +1590,7 @@
 		}
 		connect(EffectType, SIGNAL(activated(int)), this, SLOT(SetEffOpts(int)));
 	}
-	if (a != 3)
+	if (a < 3)  // not PDF/X
 	{
 		X3Group->setEnabled(false);
 		setTabEnabled(indexOf(tabSecurity), true);
@@ -1587,12 +1607,16 @@
 		}
 		return;
 	}
+	// PDF/X is selected
 	disconnect(OutCombo, SIGNAL(activated(int)), this, SLOT(EnablePr(int)));
 	OutCombo->setCurrentIndex(1);
 	OutCombo->setEnabled(false);
 	EnablePr(1);
-	EmbedProfs2->setChecked(true);
-	EmbedProfs2->setEnabled(false);
+	if ((a == 4) || (a == 5)) // X3 or X4, enforcing color profiles on images
+	{
+		EmbedProfs2->setChecked(true);
+		EmbedProfs2->setEnabled(false);
+	}
 	if (doc != 0 && pdfExport)
 	{
 //		EmbedFonts->setChecked(true);
@@ -1655,7 +1679,15 @@
 void TabPDFOptions::EnablePr(int a)
 {
 	EnableLPI(a);
-	bool setter = a == 1 ? true : false;
+	bool setter = false;
+	if (a == 1)
+	{
+		if (PDFVersionCombo->currentIndex() == 3)
+			setter = false;
+		else
+			setter = true;
+	}
+
 	GroupBox9->setEnabled(setter);
 	ProfsGroup->setEnabled(setter);
 }
@@ -2092,7 +2124,7 @@
 {
 	if (c != NULL)
 	{
-		if ((PDFVersionCombo->currentIndex() != 3) && (c->flags() & Qt::ItemIsSelectable))
+		if ((PDFVersionCombo->currentIndex() < 3) && (c->flags() & Qt::ItemIsSelectable))
 			FromEmbed->setEnabled(true);
 		else
 			FromEmbed->setEnabled(false);
@@ -2109,7 +2141,7 @@
 {
 	if (c != NULL)
 	{
-		if (PDFVersionCombo->currentIndex() == 3)
+		if (PDFVersionCombo->currentIndex() == 4)
 		{
 			if ((AllFonts[c->text()].type() == ScFace::OTF) || (AllFonts[c->text()].subset()))
 				FromOutline->setEnabled(false);
Index: scribus/pdfoptionsio.cpp
===================================================================
--- scribus/pdfoptionsio.cpp	(revision 14042)
+++ scribus/pdfoptionsio.cpp	(revision 14043)
@@ -113,9 +113,15 @@
 	QString pdfVersString;
 	switch (m_opts->Version)
 	{
+		case PDFOptions::PDFVersion_X1a:
+			pdfVersString = "X1a";
+			break;
 		case PDFOptions::PDFVersion_X3:
 			pdfVersString = "X3";
 			break;
+		case PDFOptions::PDFVersion_X4:
+			pdfVersString = "X4";
+			break;
 		default:
 			pdfVersString = QString::number(m_opts->Version);
 			break;
@@ -416,11 +422,21 @@
 	QString pdfVersString;
 	if (!readElem(m_root, "pdfVersion", &pdfVersString))
 		return false;
-	if (pdfVersString == "X3")
+	if (pdfVersString == "X1a")
 	{
+		m_opts->Version = PDFOptions::PDFVersion_X1a;
+		return true;
+	}
+	else if (pdfVersString == "X3")
+	{
 		m_opts->Version = PDFOptions::PDFVersion_X3;
 		return true;
 	}
+	else if (pdfVersString == "X4")
+	{
+		m_opts->Version = PDFOptions::PDFVersion_X4;
+		return true;
+	}
 	else if (pdfVersString == "13")
 	{
 		m_opts->Version = PDFOptions::PDFVersion_13;
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(revision 14042)
+++ scribus/CMakeLists.txt	(revision 14043)
@@ -266,6 +266,7 @@
   ui/pagepalette.h
   ui/pageselector.h
   ui/patterndialog.h
+  pdf_analyzer.h
   pdflib.h
   pdflib_core.h
   ui/pdfopts.h
@@ -567,6 +568,7 @@
   ui/pageselector.cpp
   pagesize.cpp
   ui/patterndialog.cpp
+  pdf_analyzer.cpp
   pdflib.cpp
   pdflib_core.cpp
   pdfoptions.cpp
Index: win32/vc8/Scribus.vcproj
===================================================================
--- win32/vc8/Scribus.vcproj	(revision 14042)
+++ win32/vc8/Scribus.vcproj	(revision 14043)
@@ -1196,6 +1196,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scribus\pdf_analyzer.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\scribus\pdflib.cpp"
 				>
 			</File>
@@ -1512,6 +1516,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scribus\scimgdataloader_pict.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\scribus\scimgdataloader_ps.cpp"
 				>
 			</File>
@@ -8245,6 +8253,54 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath="..\..\scribus\pdf_analyzer.h"
+				>
+				<FileConfiguration
+					Name="Debug-cairo|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing $(InputFileName)"
+						CommandLine="$(QT4_DIR)\bin\moc.exe &quot;$(InputPath)&quot; -o  &quot;$(InputDir)\moc_$(InputName).cpp&quot;"
+						AdditionalDependencies="$(QT4_DIR)\bin\moc.exe"
+						Outputs="$(InputDir)\moc_$(InputName).cpp"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-cairo|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing $(InputFileName)"
+						CommandLine="$(QT4_DIR)\bin\moc.exe &quot;$(InputPath)&quot; -o  &quot;$(InputDir)\moc_$(InputName).cpp&quot;"
+						AdditionalDependencies="$(QT4_DIR)\bin\moc.exe"
+						Outputs="$(InputDir)\moc_$(InputName).cpp"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug-arthur|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing $(InputFileName)"
+						CommandLine="$(QT4_DIR)\bin\moc.exe &quot;$(InputPath)&quot; -o  &quot;$(InputDir)\moc_$(InputName).cpp&quot;"
+						AdditionalDependencies="$(QT4_DIR)\bin\moc.exe"
+						Outputs="$(InputDir)\moc_$(InputName).cpp"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release-arthur|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing $(InputFileName)"
+						CommandLine="$(QT4_DIR)\bin\moc.exe &quot;$(InputPath)&quot; -o  &quot;$(InputDir)\moc_$(InputName).cpp&quot;"
+						AdditionalDependencies="$(QT4_DIR)\bin\moc.exe"
+						Outputs="$(InputDir)\moc_$(InputName).cpp"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath="..\..\scribus\pdflib.h"
 				>
 				<FileConfiguration
@@ -10913,6 +10969,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scribus\scimgdataloader_pict.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\scribus\scimgdataloader_ps.h"
 				>
 			</File>
@@ -15651,6 +15711,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scribus\moc_pdf_analyzer.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\scribus\moc_pdflib.cpp"
 				>
 			</File>




More information about the scribus-commit mailing list