r14308 by fschmid - Implemented "Pattern Masks", same as gradient masks but working with patterns.

scribus-commit scribus-commit at lists.scribus.net
Thu Nov 19 14:31:06 CET 2009


Revision: 14308
Author: fschmid
Date: 2009-11-19T04:48:31.359146Z
Commit message: Implemented "Pattern Masks", same as gradient masks but working with patterns.

Changeset: 
M  /trunk/Scribus/scribus/scpainter.cpp
M  /trunk/Scribus/scribus/ui/propertiespalette.cpp
M  /trunk/Scribus/scribus/pageitem.cpp
M  /trunk/Scribus/scribus/CMakeLists.txt
A  /trunk/Scribus/scribus/ui/patternpropsdialog.cpp
M  /trunk/Scribus/scribus/scribusdoc.cpp
M  /trunk/Scribus/scribus/plugins/aiimplugin/importai.cpp
A  /trunk/Scribus/scribus/ui/patternpropsdialog.h
M  /trunk/Scribus/scribus/plugins/xarimplugin/importxar.cpp
M  /trunk/Scribus/scribus/scribusdoc.h
M  /trunk/Scribus/scribus/ui/transparencypalette.cpp
M  /trunk/Scribus/scribus/pdflib_core.cpp
M  /trunk/Scribus/scribus/ui/transparencypalette.h
M  /trunk/Scribus/scribus/pdflib_core.h
M  /trunk/Scribus/scribus/ui/cpalette.cpp
M  /trunk/Scribus/scribus/ui/cpalette.h

Diffs:
Index: scribus/pdflib_core.cpp
===================================================================
--- scribus/pdflib_core.cpp	(revision 14307)
+++ scribus/pdflib_core.cpp	(revision 14308)
@@ -2060,7 +2060,7 @@
 								PutPage(SetClipPath(ite));
 								if (!ite->strokePattern().isEmpty())
 								{
-									if (!PDF_PatternFillStroke(tmpOut, ite, true))
+									if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 										return false;
 									PutPage(SetClipPath(ite));
 									PutPage(tmpOut);
@@ -2106,7 +2106,7 @@
 						{
 							if (!ite->strokePattern().isEmpty())
 							{
-								if (!PDF_PatternFillStroke(tmpOut, ite, true))
+								if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 									return false;
 								PutPage(tmpOut);
 								PutPage("0 0 m\n");
@@ -2205,7 +2205,7 @@
 							{
 								if (!ite->strokePattern().isEmpty())
 								{
-									if (!PDF_PatternFillStroke(tmpOut, ite, true))
+									if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 										return false;
 									PutPage(tmpOut);
 									PutPage("h\nS\n");
@@ -2291,7 +2291,7 @@
 							{
 								if (!ite->strokePattern().isEmpty())
 								{
-									if (!PDF_PatternFillStroke(tmpOut, ite, true))
+									if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 										return false;
 									PutPage(tmpOut);
 									PutPage(SetClipPath(ite, false));
@@ -2376,7 +2376,7 @@
 									{
 										if (!ite->strokePattern().isEmpty())
 										{
-											if (!PDF_PatternFillStroke(tmpOut, ite, true))
+											if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 												return false;
 											PutPage(tmpOut);
 											PutPage(SetClipPath(ite, false));
@@ -3639,7 +3639,7 @@
 					if (!ite->strokePattern().isEmpty())
 					{
 						tmp += SetClipPath(ite);
-						if (!PDF_PatternFillStroke(tmpOut, ite, true))
+						if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 							return false;
 						tmp += tmpOut;
 						tmp += "h\nS\n";
@@ -3738,7 +3738,7 @@
 					if (!ite->strokePattern().isEmpty())
 					{
 						tmp += SetClipPath(ite);
-						if (!PDF_PatternFillStroke(tmpOut, ite, true))
+						if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 							return false;
 						tmp += tmpOut;
 						tmp += "h\nS\n";
@@ -3781,7 +3781,7 @@
 			{
 				if (!ite->strokePattern().isEmpty())
 				{
-					if (!PDF_PatternFillStroke(tmpOut, ite, true))
+					if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 						return false;
 					tmp += tmpOut;
 					tmp += "0 0 m\n";
@@ -3883,7 +3883,7 @@
 					if (!ite->strokePattern().isEmpty())
 					{
 						tmp += SetClipPath(ite);
-						if (!PDF_PatternFillStroke(tmpOut, ite, true))
+						if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 							return false;
 						tmp += tmpOut;
 						tmp += "h\nS\n";
@@ -3970,7 +3970,7 @@
 					if (!ite->strokePattern().isEmpty())
 					{
 						tmp += SetClipPath(ite, false);
-						if (!PDF_PatternFillStroke(tmpOut, ite, true))
+						if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 							return false;
 						tmp += tmpOut;
 						tmp += "S\n";
@@ -4055,7 +4055,7 @@
 							if (!ite->strokePattern().isEmpty())
 							{
 								tmp += SetClipPath(ite, false);
-								if (!PDF_PatternFillStroke(tmpOut, ite, true))
+								if (!PDF_PatternFillStroke(tmpOut, ite, 1))
 									return false;
 								tmp += tmpOut;
 								tmp += "S\n";
@@ -4144,7 +4144,7 @@
 		{
 			tmp += SetClipPathArray(&arrow);
 			QString tmpOut;
-			PDF_PatternFillStroke(tmpOut, ite, true, true);
+			PDF_PatternFillStroke(tmpOut, ite, 1, true);
 			tmp += tmpOut;
 			tmp += "h\nf*\n";
 		}
@@ -5562,9 +5562,9 @@
 	QString ShName = ResNam+QString::number(ResCount);
 	ResCount++;
 	QString tmp;
-	if (currItem->GrMask > 0)
+	QString GXName;
+	if ((currItem->GrMask == 1) || (currItem->GrMask == 2))
 	{
-		QString GXName;
 		QList<double> StopVec;
 		QList<double> TransVec;
 		VGradient gradient;
@@ -5630,95 +5630,144 @@
 			}
 		}
 		QString TRes("");
-		if (((Options.Version >= PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_X4)))
+		uint patObject = newObject();
+		StartObj(patObject);
+		PutDoc("<<\n/Type /Pattern\n");
+		PutDoc("/PatternType 2\n");
+		PutDoc("/Matrix ["+FToStr(mpa.m11())+" "+FToStr(mpa.m12())+" "+FToStr(mpa.m21())+" "+FToStr(mpa.m22())+" 0 0]\n");
+		PutDoc("/Shading\n");
+		PutDoc("<<\n");
+		if (GType == 1)
+			PutDoc("/ShadingType 2\n");
+		else
+			PutDoc("/ShadingType 3\n");
+		PutDoc("/ColorSpace /DeviceGray\n");
+		PutDoc("/Extend [true true]\n");
+		if (GType == 1)
+			PutDoc("/Coords ["+FToStr(StartX)+" "+FToStr(-StartY)+" "+FToStr(EndX)+" "+FToStr(-EndY)+"]\n");
+		else
+			PutDoc("/Coords ["+FToStr(FocalX)+" "+FToStr(-FocalY)+" 0.0 "+FToStr(StartX)+" "+FToStr(-StartY)+" "+FToStr(sqrt(pow(EndX - StartX, 2) + pow(EndY - StartY,2)))+"]\n");
+		PutDoc("/Function\n");
+		PutDoc("<<\n");
+		PutDoc("/FunctionType 3\n");
+		PutDoc("/Domain [0 1]\n");
+		if (StopVec.count() > 2)
 		{
-			uint patObject = newObject();
-			StartObj(patObject);
-			PutDoc("<<\n/Type /Pattern\n");
-			PutDoc("/PatternType 2\n");
-			PutDoc("/Matrix ["+FToStr(mpa.m11())+" "+FToStr(mpa.m12())+" "+FToStr(mpa.m21())+" "+FToStr(mpa.m22())+" 0 0]\n");
-			PutDoc("/Shading\n");
+			PutDoc("/Bounds [");
+			QString bctx = "";
+			for (int bc = 1; bc < StopVec.count() - 1; bc++)
+			{
+				bctx += FToStr(StopVec.at(bc))+" ";
+			}
+			PutDoc(bctx.trimmed()+"]\n");
+		}
+		else
+			PutDoc("/Bounds []\n");
+		QString entx = "";
+		PutDoc("/Functions\n");
+		PutDoc("[\n");
+		for (int cc = 0; cc < TransVec.count() - 1; cc++)
+		{
+			entx += "0 1 ";
 			PutDoc("<<\n");
-			if (GType == 1)
-				PutDoc("/ShadingType 2\n");
-			else
-				PutDoc("/ShadingType 3\n");
-			PutDoc("/ColorSpace /DeviceGray\n");
-			PutDoc("/Extend [true true]\n");
-			if (GType == 1)
-				PutDoc("/Coords ["+FToStr(StartX)+" "+FToStr(-StartY)+" "+FToStr(EndX)+" "+FToStr(-EndY)+"]\n");
-			else
-				PutDoc("/Coords ["+FToStr(FocalX)+" "+FToStr(-FocalY)+" 0.0 "+FToStr(StartX)+" "+FToStr(-StartY)+" "+FToStr(sqrt(pow(EndX - StartX, 2) + pow(EndY - StartY,2)))+"]\n");
-			PutDoc("/Function\n");
-			PutDoc("<<\n");
-			PutDoc("/FunctionType 3\n");
+			PutDoc("/FunctionType 2\n");
 			PutDoc("/Domain [0 1]\n");
-			if (StopVec.count() > 2)
-			{
-				PutDoc("/Bounds [");
-				QString bctx = "";
-				for (int bc = 1; bc < StopVec.count() - 1; bc++)
-				{
-					bctx += FToStr(StopVec.at(bc))+" ";
-				}
-				PutDoc(bctx.trimmed()+"]\n");
-			}
-			else
-				PutDoc("/Bounds []\n");
-			QString entx = "";
-			PutDoc("/Functions\n");
-			PutDoc("[\n");
-			for (int cc = 0; cc < TransVec.count() - 1; cc++)
-			{
-				entx += "0 1 ";
-				PutDoc("<<\n");
-				PutDoc("/FunctionType 2\n");
-				PutDoc("/Domain [0 1]\n");
-				PutDoc("/C0 ["+FToStr(TransVec.at(cc))+"]\n");
-				PutDoc("/C1 ["+FToStr(TransVec.at(cc+1))+"]\n");
-				PutDoc("/N 1\n");
-				PutDoc(">>\n");
-			}
-			PutDoc("]\n");
-			PutDoc("/Encode ["+entx.trimmed()+"]\n");
+			PutDoc("/C0 ["+FToStr(TransVec.at(cc))+"]\n");
+			PutDoc("/C1 ["+FToStr(TransVec.at(cc+1))+"]\n");
+			PutDoc("/N 1\n");
 			PutDoc(">>\n");
+		}
+		PutDoc("]\n");
+		PutDoc("/Encode ["+entx.trimmed()+"]\n");
+		PutDoc(">>\n");
+		PutDoc(">>\n");
+		PutDoc(">>\n");
+		Patterns.insert("Pattern"+QString::number(patObject), patObject);
+		uint formObject = newObject();
+		StartObj(formObject);
+		PutDoc("<<\n/Type /XObject\n/Subtype /Form\n");
+		PutDoc("/FormType 1\n");
+		PutDoc("/Group << /S /Transparency /CS /DeviceGray >>\n");
+		double lw = currItem->lineWidth();
+		PutDoc("/BBox ["+FToStr(-lw / 2.0)+" "+FToStr(lw / 2.0)+" "+FToStr(currItem->width()+lw)+" "+FToStr(-(currItem->height()+lw))+" ]\n");
+		PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
+		if (Patterns.count() != 0)
+		{
+			PutDoc("/Pattern << \n");
+			QMap<QString,int>::Iterator it3p;
+			for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
+				PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
 			PutDoc(">>\n");
-			PutDoc(">>\n");
-			Patterns.insert("Pattern"+QString::number(patObject), patObject);
-			uint formObject = newObject();
-			StartObj(formObject);
-			PutDoc("<<\n/Type /XObject\n/Subtype /Form\n");
-			PutDoc("/FormType 1\n");
-			PutDoc("/Group << /S /Transparency /CS /DeviceGray >>\n");
-			double lw = currItem->lineWidth();
-			PutDoc("/BBox ["+FToStr(-lw / 2.0)+" "+FToStr(lw / 2.0)+" "+FToStr(currItem->width()+lw)+" "+FToStr(-(currItem->height()+lw))+" ]\n");
-			PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
-			if (Patterns.count() != 0)
+		}
+		PutDoc(">>\n");
+		QString stre = "q\n"+SetClipPath(currItem)+"h\n";
+		stre += FToStr(fabs(currItem->lineWidth()))+" w\n";
+		stre += "/Pattern cs\n";
+		stre += "/Pattern"+QString::number(patObject)+" scn\nf*\n";
+		stre += "Q\n";
+		if (Options.Compress)
+			stre = CompressStr(&stre);
+		PutDoc("/Length "+QString::number(stre.length())+"\n");
+		if (Options.Compress)
+			PutDoc("/Filter /FlateDecode\n");
+		PutDoc(">>\nstream\n"+EncStream(stre, formObject)+"\nendstream\nendobj\n");
+		Seite.XObjects[ResNam+QString::number(ResCount)] = formObject;
+		ResCount++;
+		GXName = ResNam+QString::number(ResCount);
+		ResCount++;
+		Transpar[GXName] = writeGState("/SMask << /S /Luminosity /G "+QString::number(formObject)+" 0 R >>\n/BM /" + blendMode(currItem->fillBlendmode()) + "\n");
+		tmp = "/"+GXName+" gs\n";
+	}
+	else if (currItem->GrMask == 3)
+	{
+		QString tmpOut = "";
+		PDF_PatternFillStroke(tmpOut, currItem, 2);
+		uint formObject = newObject();
+		StartObj(formObject);
+		PutDoc("<<\n/Type /XObject\n/Subtype /Form\n");
+		PutDoc("/FormType 1\n");
+		PutDoc("/Group << /S /Transparency ");
+		if (Options.UseRGB)
+			PutDoc("/CS /DeviceRGB");
+		else
+		{
+			if (Options.isGrayscale)
+				PutDoc("/CS /DeviceGray");
+			else
 			{
-				PutDoc("/Pattern << \n");
-				QMap<QString,int>::Iterator it3p;
-				for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
-					PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
-				PutDoc(">>\n");
+				if ((doc.HasCMS) && (Options.UseProfiles))
+					PutDoc("/CS "+ICCProfiles[Options.SolidProf].ICCArray);
+				else
+					PutDoc("/CS /DeviceCMYK");
 			}
+		}
+		PutDoc(" >>\n");
+		PutDoc("/BBox [0 0 "+FToStr(currItem->width())+" "+FToStr(-(currItem->height()))+" ]\n");
+		PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
+		if (Patterns.count() != 0)
+		{
+			PutDoc("/Pattern << \n");
+			QMap<QString,int>::Iterator it3p;
+			for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
+				PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
 			PutDoc(">>\n");
-			QString stre = "q\n"+SetClipPath(currItem)+"h\n";
-			stre += FToStr(fabs(currItem->lineWidth()))+" w\n";
-			stre += "/Pattern cs\n";
-			stre += "/Pattern"+QString::number(patObject)+" scn\nf*\n";
-			stre += "Q\n";
-			if (Options.Compress)
-				stre = CompressStr(&stre);
-			PutDoc("/Length "+QString::number(stre.length())+"\n");
-			if (Options.Compress)
-				PutDoc("/Filter /FlateDecode\n");
-			PutDoc(">>\nstream\n"+EncStream(stre, formObject)+"\nendstream\nendobj\n");
-			Seite.XObjects[ResNam+QString::number(ResCount)] = formObject;
-			ResCount++;
-			GXName = ResNam+QString::number(ResCount);
-			ResCount++;
-			Transpar[GXName] = writeGState("/SMask << /S /Luminosity /G "+QString::number(formObject)+" 0 R >>\n/BM /" + blendMode(currItem->fillBlendmode()) + "\n");
 		}
+		PutDoc(">>\n");
+		QString stre = "q\n"+SetClipPath(currItem)+"h\n";
+		stre += FToStr(fabs(currItem->lineWidth()))+" w\n";
+		stre += tmpOut+" f*\n";
+		stre += "Q\n";
+		if (Options.Compress)
+			stre = CompressStr(&stre);
+		PutDoc("/Length "+QString::number(stre.length())+"\n");
+		if (Options.Compress)
+			PutDoc("/Filter /FlateDecode\n");
+		PutDoc(">>\nstream\n"+EncStream(stre, formObject)+"\nendstream\nendobj\n");
+		Seite.XObjects[ResNam+QString::number(ResCount)] = formObject;
+		ResCount++;
+		GXName = ResNam+QString::number(ResCount);
+		ResCount++;
+		Transpar[GXName] = writeGState("/SMask << /S /Alpha      /G "+QString::number(formObject)+" 0 R >>\n/BM /" + blendMode(currItem->fillBlendmode()) + "\n");
 		tmp = "/"+GXName+" gs\n";
 	}
 	else
@@ -5740,15 +5789,17 @@
 	return tmp;
 }
 
-bool PDFLibCore::PDF_PatternFillStroke(QString& output, PageItem *currItem, bool stroke, bool forArrow)
+bool PDFLibCore::PDF_PatternFillStroke(QString& output, PageItem *currItem, int kind, bool forArrow)
 {
 	QStack<PageItem*> groupStack;
 	QString tmp2 = "", tmpOut;
 	ScPattern *pat;
-	if (stroke)
+	if (kind == 0)
+		pat = &doc.docPatterns[currItem->pattern()];
+	else if (kind == 1)
 		pat = &doc.docPatterns[currItem->strokePattern()];
-	else
-		pat = &doc.docPatterns[currItem->pattern()];
+	else if (kind == 2)
+		pat = &doc.docPatterns[currItem->patternMask()];
 	for (int em = 0; em < pat->items.count(); ++em)
 	{
 		PageItem* item = pat->items.at(em);
@@ -5888,24 +5939,30 @@
 	PutDoc("/TilingType 1\n");
 	PutDoc("/BBox [ 0 0 "+FToStr(pat->width)+" "+FToStr(pat->height)+" ]\n");
 	QTransform mpa;
-	if (inPattern == 0)
+	if ((inPattern == 0) && (kind != 2))
 	{
 		mpa.translate(currItem->xPos() - ActPageP->xOffset(), ActPageP->height() - (currItem->yPos() - ActPageP->yOffset()));
 		mpa.rotate(-currItem->rotation());
 	}
 	double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
 	bool mirrorX, mirrorY;
-	if (stroke)
+	if (kind == 0)
 	{
+		currItem->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
+		currItem->patternFlip(mirrorX, mirrorY);
+	}
+	else if (kind == 1)
+	{
 		currItem->strokePatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
 		currItem->strokePatternFlip(mirrorX, mirrorY);
 	}
-	else
+	else if (kind == 2)
 	{
-		currItem->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
-		currItem->patternFlip(mirrorX, mirrorY);
+		currItem->maskTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
+		currItem->maskFlip(mirrorX, mirrorY);
 	}
-	mpa.translate(-currItem->lineWidth() / 2.0, currItem->lineWidth() / 2.0);
+	if (kind == 1)
+		mpa.translate(-currItem->lineWidth() / 2.0, currItem->lineWidth() / 2.0);
 	mpa.translate(patternOffsetX, -patternOffsetY);
 	mpa.rotate(-patternRotation);
 	mpa.shear(patternSkewX, -patternSkewY);
@@ -5983,7 +6040,7 @@
 	PutDoc(" >>\nstream\n"+EncStream(tmp2, patObject)+"\nendstream\nendobj\n");
 	Patterns.insert("Pattern"+QString::number(patObject), patObject);
 	QString tmp;
-	if ((forArrow) || (!stroke))
+	if ((forArrow) || (kind != 1))
 	{
 		tmp = "/Pattern cs\n";
 		tmp += "/Pattern"+QString::number(patObject)+" scn\n";
Index: scribus/pdflib_core.h
===================================================================
--- scribus/pdflib_core.h	(revision 14307)
+++ scribus/pdflib_core.h	(revision 14308)
@@ -151,7 +151,7 @@
 	QString PDF_ProcessTableItem(PageItem* ite, const Page* pag);
 	QString drawArrow(PageItem *ite, QTransform &arrowTrans, int arrowIndex);
 	void    PDF_Bookmark(PageItem *currItem, double ypos);
-	bool    PDF_PatternFillStroke(QString& output, PageItem *currItem, bool stroke = false, bool forArrow = false);
+	bool    PDF_PatternFillStroke(QString& output, PageItem *currItem, int kind = 0, bool forArrow = false);
 	bool    PDF_GradientFillStroke(QString& output, PageItem *currItem, bool stroke = false, bool forArrow = false);
 
 		/* deprecated */
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(revision 14307)
+++ scribus/scribusdoc.cpp	(revision 14308)
@@ -5946,6 +5946,43 @@
 	}
 }
 
+void ScribusDoc::itemSelection_SetItemPatternMask(QString pattern)
+{
+	uint selectedItemCount=m_Selection->count();
+	if (selectedItemCount != 0)
+	{
+		m_updateManager.setUpdatesDisabled();
+		PageItem *currItem;
+		for (uint a = 0; a < selectedItemCount; ++a)
+		{
+			currItem = m_Selection->itemAt(a);
+			currItem->setPatternMask(pattern);
+			currItem->update();
+		}
+		m_updateManager.setUpdatesEnabled();
+		changed();
+	}
+}
+
+void ScribusDoc::itemSelection_SetItemPatternMaskProps(double imageScaleX, double imageScaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
+{
+	uint selectedItemCount=m_Selection->count();
+	if (selectedItemCount != 0)
+	{
+		m_updateManager.setUpdatesDisabled();
+		PageItem *currItem;
+		for (uint a = 0; a < selectedItemCount; ++a)
+		{
+			currItem = m_Selection->itemAt(a);
+			currItem->setMaskTransform(imageScaleX, imageScaleY, offsetX, offsetY, rotation, skewX, skewY);
+			currItem->setMaskFlip(mirrorX, mirrorY);
+			currItem->update();
+		}
+		m_updateManager.setUpdatesEnabled();
+		changed();
+	}
+}
+
 void ScribusDoc::itemSelection_SetEffects(int s, Selection* customSelection)
 {
 	CharStyle newStyle;
Index: scribus/scpainter.cpp
===================================================================
--- scribus/scpainter.cpp	(revision 14307)
+++ scribus/scpainter.cpp	(revision 14308)
@@ -42,6 +42,8 @@
 	m_offset = 0;
 	m_layerTransparency = transparency;
 	m_blendMode = blendmode;
+	m_blendModeFill = 0;
+	m_blendModeStroke = 0;
 	m_array.clear();
 	mf_underline = false;
 	mf_strikeout = false;
@@ -82,6 +84,8 @@
 	m_offset = 0;
 	m_layerTransparency = transparency;
 	m_blendMode = blendmode;
+	m_blendModeFill = 0;
+	m_blendModeStroke = 0;
 	m_array.clear();
 	mf_underline = false;
 	mf_strikeout = false;
@@ -123,6 +127,8 @@
 	m_offset = 0;
 	m_layerTransparency = transparency;
 	m_blendMode = blendmode;
+	m_blendModeFill = 0;
+	m_blendModeStroke = 0;
 	m_array.clear();
 	mf_underline = false;
 	mf_strikeout = false;
@@ -198,15 +204,19 @@
 			setupPolygon(&la.groupClip);
 			setClipPath();
 		}
-		setRasterOp(m_blendMode);
-		if (maskMode == 1)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
+		if (maskMode > 0)
 		{
 			cairo_pattern_t *patM = getMaskPattern();
+			setRasterOp(m_blendMode);
 			cairo_mask(m_cr, patM);
 			cairo_pattern_destroy(patM);
 		}
 		else
+		{
+			setRasterOp(m_blendMode);
 			cairo_paint_with_alpha (m_cr, m_layerTransparency);
+		}
 		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
 	}
 	m_layerTransparency = la.tranparency;
@@ -1078,6 +1088,8 @@
 		cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_COLOR);
 	else if (blendMode == 15)
 		cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
+	else
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
 #endif
 #endif
 }
@@ -1110,54 +1122,80 @@
 
 cairo_pattern_t * ScPainter::getMaskPattern()
 {
+	cairo_save( m_cr );
 	cairo_pattern_t *pat;
-	double x1 = mask_gradient.origin().x();
-	double y1 = mask_gradient.origin().y();
-	double x2 = mask_gradient.vector().x();
-	double y2 = mask_gradient.vector().y();
-	double fx = mask_gradient.focalPoint().x();
-	double fy = mask_gradient.focalPoint().y();
-	if (mask_gradient.type() == VGradient::linear)
-		pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
-	else
-		pat = cairo_pattern_create_radial (fx, fy, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
-	QList<VColorStop*> colorStops = mask_gradient.colorStops();
-	QColor qStopColor;
-	for( int offset = 0 ; offset < colorStops.count() ; offset++ )
+	if (maskMode == 1)
 	{
-		qStopColor = colorStops[ offset ]->color;
-		int h, s, v, sneu, vneu;
-		int shad = colorStops[offset]->shade;
-		qStopColor.getHsv(&h, &s, &v);
-		sneu = s * shad / 100;
-		vneu = 255 - ((255 - v) * shad / 100);
-		qStopColor.setHsv(h, sneu, vneu);
-		double a = colorStops[offset]->opacity;
-		double r, g, b;
-		qStopColor.getRgbF(&r, &g, &b);
-		cairo_pattern_add_color_stop_rgba (pat, colorStops[ offset ]->rampPoint, r, g, b, a);
+		double x1 = mask_gradient.origin().x();
+		double y1 = mask_gradient.origin().y();
+		double x2 = mask_gradient.vector().x();
+		double y2 = mask_gradient.vector().y();
+		double fx = mask_gradient.focalPoint().x();
+		double fy = mask_gradient.focalPoint().y();
+		if (mask_gradient.type() == VGradient::linear)
+			pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
+		else
+			pat = cairo_pattern_create_radial (fx, fy, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
+		QList<VColorStop*> colorStops = mask_gradient.colorStops();
+		QColor qStopColor;
+		for( int offset = 0 ; offset < colorStops.count() ; offset++ )
+		{
+			qStopColor = colorStops[ offset ]->color;
+			int h, s, v, sneu, vneu;
+			int shad = colorStops[offset]->shade;
+			qStopColor.getHsv(&h, &s, &v);
+			sneu = s * shad / 100;
+			vneu = 255 - ((255 - v) * shad / 100);
+			qStopColor.setHsv(h, sneu, vneu);
+			double a = colorStops[offset]->opacity;
+			double r, g, b;
+			qStopColor.getRgbF(&r, &g, &b);
+			cairo_pattern_add_color_stop_rgba (pat, colorStops[ offset ]->rampPoint, r, g, b, a);
+		}
+		cairo_matrix_t matrix;
+		QTransform qmatrix;
+		if (mask_gradient.type() == VGradient::radial)
+		{
+			double rotEnd = xy2Deg(x2 - x1, y2 - y1);
+			qmatrix.translate(x1, y1);
+			qmatrix.rotate(rotEnd);
+			qmatrix.shear(mask_gradientSkew, 0);
+			qmatrix.translate(0, y1 * (1.0 - mask_gradientScale));
+			qmatrix.translate(-x1, -y1);
+			qmatrix.scale(1, mask_gradientScale);
+		}
+		else
+		{
+			qmatrix.translate(x1, y1);
+			qmatrix.shear(-mask_gradientSkew, 0);
+			qmatrix.translate(-x1, -y1);
+		}
+		cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
+		cairo_matrix_invert(&matrix);
+		cairo_pattern_set_matrix (pat, &matrix);
 	}
-	cairo_matrix_t matrix;
-	QTransform qmatrix;
-	if (mask_gradient.type() == VGradient::radial)
-	{
-		double rotEnd = xy2Deg(x2 - x1, y2 - y1);
-		qmatrix.translate(x1, y1);
-		qmatrix.rotate(rotEnd);
-		qmatrix.shear(mask_gradientSkew, 0);
-		qmatrix.translate(0, y1 * (1.0 - mask_gradientScale));
-		qmatrix.translate(-x1, -y1);
-		qmatrix.scale(1, mask_gradientScale);
-	}
 	else
 	{
-		qmatrix.translate(x1, y1);
-		qmatrix.shear(-mask_gradientSkew, 0);
-		qmatrix.translate(-x1, -y1);
+		cairo_surface_t *image = cairo_image_surface_create_for_data ((uchar*)m_maskPattern->getPattern()->bits(), CAIRO_FORMAT_ARGB32, m_maskPattern->getPattern()->width(), m_maskPattern->getPattern()->height(), m_maskPattern->getPattern()->width()*4);
+		pat = cairo_pattern_create_for_surface(image);
+		cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
+		cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
+		cairo_matrix_t matrix;
+		QTransform qmatrix;
+		qmatrix.translate(mask_patternOffsetX, mask_patternOffsetY);
+		qmatrix.rotate(mask_patternRotation);
+		qmatrix.shear(-mask_patternSkewX, mask_patternSkewY);
+		qmatrix.scale(mask_patternScaleX, mask_patternScaleY);
+		qmatrix.scale(m_maskPattern->width / static_cast<double>(m_maskPattern->getPattern()->width()), m_maskPattern->height / static_cast<double>(m_maskPattern->getPattern()->height()));
+		if (mask_patternMirrorX)
+			qmatrix.scale(-1, 1);
+		if (mask_patternMirrorY)
+			qmatrix.scale(1, -1);
+		cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
+		cairo_matrix_invert(&matrix);
+		cairo_pattern_set_matrix (pat, &matrix);
 	}
-	cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
-	cairo_matrix_invert(&matrix);
-	cairo_pattern_set_matrix (pat, &matrix);
+	cairo_restore( m_cr );
 	return pat;
 }
 
@@ -1175,16 +1213,16 @@
 		{
 			double r, g, b;
 			m_fill.getRgbF(&r, &g, &b);
-			if (maskMode == 1)
+			if (maskMode > 0)
 			{
+				cairo_pattern_t *pat = getMaskPattern();
 				cairo_set_source_rgb( m_cr, r, g, b );
-				cairo_pattern_t *pat = getMaskPattern();
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
 				setRasterOp(m_blendModeFill);
 #endif
-				cairo_clip_preserve (m_cr);
+				cairo_clip_preserve(m_cr);
 				cairo_mask(m_cr, pat);
-				cairo_pattern_destroy (pat);
+				cairo_pattern_destroy(pat);
 			}
 			else
 			{
@@ -1247,7 +1285,7 @@
 			cairo_pattern_set_matrix (pat, &matrix);
 			cairo_set_source (m_cr, pat);
 			cairo_clip_preserve (m_cr);
-			if (maskMode == 1)
+			if (maskMode > 0)
 			{
 				cairo_pattern_t *patM = getMaskPattern();
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
@@ -1288,7 +1326,7 @@
 			cairo_pattern_set_matrix (m_pat, &matrix);
 			cairo_set_source (m_cr, m_pat);
 			cairo_clip_preserve (m_cr);
-			if (maskMode == 1)
+			if (maskMode > 0)
 			{
 				cairo_pattern_t *patM = getMaskPattern();
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
@@ -1437,8 +1475,8 @@
 			cairo_stroke_preserve( m_cr );
 		}
 	}
+	cairo_restore( m_cr );
 	cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-	cairo_restore( m_cr );
 }
 #else
 	// not HAVE_CAIRO
@@ -1926,7 +1964,7 @@
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
 	setRasterOp(m_blendModeFill);
 #endif
-	if (maskMode == 1)
+	if (maskMode > 0)
 	{
 		cairo_pattern_t *patM = getMaskPattern();
 		cairo_mask(m_cr, patM);
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(revision 14307)
+++ scribus/pageitem.cpp	(revision 14308)
@@ -1284,6 +1284,16 @@
 				else
 					p->setGradientMask(VGradient::radial, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskFocalX, GrMaskFocalY), GrMaskScale, GrMaskSkew);
 			}
+			else if (GrMask == 3)
+			{
+				if ((patternMaskVal.isEmpty()) || (!m_Doc->docPatterns.contains(patternMaskVal)))
+					p->setMaskMode(0);
+				else
+				{
+					p->setPatternMask(&m_Doc->docPatterns[patternMaskVal], patternMaskScaleX, patternMaskScaleY, patternMaskOffsetX, patternMaskOffsetY, patternMaskRotation, patternMaskSkewX, patternMaskSkewY, patternMaskMirrorX, patternMaskMirrorY);
+					p->setMaskMode(2);
+				}
+			}
 			else
 				p->setMaskMode(0);
 		}
@@ -1334,8 +1344,7 @@
 			if (fillBlendmode() != 0)
 				p->endLayer();
 	#else
-			if (fillBlendmode() != 0)
-				p->setBlendModeFill(0);
+			p->setBlendModeFill(0);
 	#endif
 #else
 			if (fillBlendmode() != 0)
@@ -1437,8 +1446,7 @@
 				if (lineBlendmode() != 0)
 					p->endLayer();
 	#else
-				if (lineBlendmode() != 0)
-					p->setBlendModeStroke(0);
+				p->setBlendModeStroke(0);
 	#endif
 #else
 				if (lineBlendmode() != 0)
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(revision 14307)
+++ scribus/scribusdoc.h	(revision 14308)
@@ -1227,6 +1227,8 @@
 	void itemSelection_SetItemPatternProps(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
 	void itemSelection_SetItemStrokePattern(QString pattern);
 	void itemSelection_SetItemStrokePatternProps(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
+	void itemSelection_SetItemPatternMask(QString pattern);
+	void itemSelection_SetItemPatternMaskProps(double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
 
 	void undoRedoBegin();
 	void undoRedoDone();
Index: scribus/ui/cpalette.cpp
===================================================================
--- scribus/ui/cpalette.cpp	(revision 14307)
+++ scribus/ui/cpalette.cpp	(revision 14308)
@@ -54,211 +54,12 @@
 #include "pageitem.h"
 #include "util_icon.h"
 #include "commonstrings.h"
-#include "linkbutton.h"
 #include "sccolorengine.h"
 #include "scpainter.h"
 #include "scpattern.h"
 #include "util.h"
 #include "util_math.h"
 
-PatternPropsDialog::PatternPropsDialog(QWidget* parent, int unitIndex) : QDialog( parent )
-{
-	setModal(true);
-	frame3Layout = new QVBoxLayout( this );
-	frame3Layout->setMargin(0);
-	frame3Layout->setSpacing(2);
-
-	groupOffset = new QGroupBox( this );
-	groupOffsetLayout = new QHBoxLayout( groupOffset );
-	groupOffsetLayout->setSpacing( 2 );
-	groupOffsetLayout->setMargin( 3 );
-	groupOffsetLayout->setAlignment( Qt::AlignTop );
-	textLabel1 = new QLabel( groupOffset );
-	groupOffsetLayout->addWidget( textLabel1 );
-	spinXoffset = new ScrSpinBox( -3000, 3000, groupOffset, 0);
-	groupOffsetLayout->addWidget( spinXoffset );
-	textLabel2 = new QLabel( groupOffset );
-	groupOffsetLayout->addWidget( textLabel2 );
-	spinYoffset = new ScrSpinBox( -3000, 3000, groupOffset, 0);
-	groupOffsetLayout->addWidget( spinYoffset );
-	frame3Layout->addWidget( groupOffset );
-
-	groupScale = new QGroupBox( this );
-	groupScaleLayout = new QGridLayout( groupScale );
-	groupScaleLayout->setSpacing( 2 );
-	groupScaleLayout->setMargin( 3 );
-	groupScaleLayout->setAlignment( Qt::AlignTop );
-	textLabel5 = new QLabel( groupScale );
-	groupScaleLayout->addWidget( textLabel5, 0, 0 );
-	spinXscaling = new ScrSpinBox( 0.01, 500, groupScale, 0);
-	spinXscaling->setValue( 100 );
-	groupScaleLayout->addWidget( spinXscaling, 0, 1 );
-	textLabel6 = new QLabel( groupScale );
-	groupScaleLayout->addWidget( textLabel6, 1, 0 );
-	spinYscaling = new ScrSpinBox( 0.01, 500, groupScale, 0 );
-	spinYscaling->setValue( 100 );
-	groupScaleLayout->addWidget( spinYscaling, 1, 1 );
-	keepScaleRatio = new LinkButton( groupScale );
-	keepScaleRatio->setCheckable( true );
-	keepScaleRatio->setAutoRaise( true );
-	keepScaleRatio->setMaximumSize( QSize( 15, 32767 ) );
-	groupScaleLayout->addWidget( keepScaleRatio, 0, 2, 2, 1 );
-	frame3Layout->addWidget( groupScale );
-	groupRotation = new QGroupBox( this );
-	groupRotationLayout = new QHBoxLayout( groupRotation );
-	groupRotationLayout->setSpacing( 2 );
-	groupRotationLayout->setMargin( 3 );
-	groupRotationLayout->setAlignment( Qt::AlignTop );
-	textLabel7 = new QLabel( groupRotation );
-	groupRotationLayout->addWidget( textLabel7 );
-	spinAngle = new ScrSpinBox( -180, 180, groupRotation, 6 );
-	groupRotationLayout->addWidget( spinAngle );
-	frame3Layout->addWidget( groupRotation );
-
-	groupSkew = new QGroupBox( this );
-	groupSkewLayout = new QGridLayout( groupSkew );
-	groupSkewLayout->setSpacing( 2 );
-	groupSkewLayout->setMargin( 3 );
-	groupSkewLayout->setAlignment( Qt::AlignTop );
-	textLabel8 = new QLabel( groupSkew );
-	groupSkewLayout->addWidget( textLabel8, 0, 0 );
-	spinXSkew = new ScrSpinBox( -89, 89, groupSkew, 6);
-	spinXSkew->setValue( 0 );
-	groupSkewLayout->addWidget( spinXSkew, 0, 1 );
-	textLabel9 = new QLabel( groupSkew );
-	groupSkewLayout->addWidget( textLabel9, 1, 0 );
-	spinYSkew = new ScrSpinBox( -89, 89, groupSkew, 6 );
-	spinYSkew->setValue( 0 );
-	groupSkewLayout->addWidget( spinYSkew, 1, 1 );
-	frame3Layout->addWidget( groupSkew );
-
-	groupFlipLayout = new QHBoxLayout();
-	groupFlipLayout->setSpacing( 2 );
-	groupFlipLayout->setMargin( 3 );
-	textLabel15 = new QLabel( this );
-	groupFlipLayout->addWidget( textLabel15 );
-	QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
-	groupFlipLayout->addItem( spacer );
-	FlipH = new QToolButton( this );
-	FlipH->setIcon(QIcon(loadIcon("16/flip-object-horizontal.png")));
-	FlipH->setCheckable( true );
-	groupFlipLayout->addWidget( FlipH );
-	FlipV = new QToolButton( this );
-	FlipV->setIcon(QIcon(loadIcon("16/flip-object-vertical.png")));
-	FlipV->setCheckable( true );
-	groupFlipLayout->addWidget( FlipV );
-	frame3Layout->addLayout( groupFlipLayout );
-
-	buttonLayout = new QHBoxLayout;
-	buttonLayout->setMargin(0);
-	buttonLayout->setSpacing(5);
-	QSpacerItem* hspacing = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
-	buttonLayout->addItem(hspacing);
-	buttonOk = new QPushButton( this );
-	buttonOk->setAutoDefault( TRUE );
-	buttonOk->setDefault( TRUE );
-	buttonLayout->addWidget( buttonOk );
-	frame3Layout->addLayout( buttonLayout );
-	spinXoffset->setNewUnit(unitIndex);
-	spinYoffset->setNewUnit(unitIndex);
-	languageChange();
-	connect(spinXoffset, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
-	connect(spinYoffset, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
-	connect(spinXSkew, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
-	connect(spinYSkew, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
-	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-	connect(keepScaleRatio, SIGNAL(clicked()), this, SLOT(ToggleKette()));
-	connect(spinAngle, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
-	connect(FlipH, SIGNAL(clicked()), this, SLOT(changePatternProps()));
-	connect(FlipV, SIGNAL(clicked()), this, SLOT(changePatternProps()));
-	connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
-}
-
-void PatternPropsDialog::changeEvent(QEvent *e)
-{
-	if (e->type() == QEvent::LanguageChange)
-	{
-		languageChange();
-	}
-	else
-		QWidget::changeEvent(e);
-}
-
-void PatternPropsDialog::languageChange()
-{
-	setWindowTitle( tr( "Pattern Properties" ));
-	QString ptSuffix=tr(" pt");
-	QString pctSuffix=tr(" %");
-	groupOffset->setTitle( tr( "Offsets" ) );
-	textLabel1->setText( tr( "X:" ) );
-	spinXoffset->setSuffix( ptSuffix );
-	textLabel2->setText( tr( "Y:" ) );
-	spinYoffset->setSuffix( ptSuffix );
-	groupScale->setTitle( tr( "Scaling" ) );
-	textLabel5->setText( tr( "X-Scale:" ) );
-	spinXscaling->setSuffix( pctSuffix );
-	textLabel6->setText( tr( "Y-Scale:" ) );
-	spinYscaling->setSuffix( pctSuffix );
-	groupRotation->setTitle( tr( "Rotation" ) );
-	groupSkew->setTitle( tr( "Skewing" ) );
-	textLabel8->setText( tr( "X-Skew:" ) );
-	textLabel9->setText( tr( "Y-Skew:" ) );
-	textLabel7->setText( tr( "Angle:" ) );
-	textLabel15->setText( tr( "Flip:" ) );
-	buttonOk->setText( tr("Close"));
-	resize(minimumSizeHint());
-}
-
-void PatternPropsDialog::changePatternProps()
-{
-	double a    = M_PI / 180.0 * spinXSkew->value();
-	double b    = M_PI / 180.0 * spinYSkew->value();
-	double sina = tan(a);
-	double sinb = tan(b);
-	bool fH = FlipH->isChecked();
-	bool fV = FlipV->isChecked();
-	emit NewPatternProps(spinXscaling->value(), spinYscaling->value(), spinXoffset->value(), spinYoffset->value(), spinAngle->value(), sina, sinb, fH, fV);
-}
-
-void PatternPropsDialog::ToggleKette()
-{
-	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-	if (keepScaleRatio->isChecked())
-	{
-		spinYscaling->setValue(spinXscaling->value());
-		changePatternProps();
-		keepScaleRatio->setChecked(true);
-	}
-	else
-		keepScaleRatio->setChecked(false);
-	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-}
-
-void PatternPropsDialog::HChange()
-{
-	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-	if (keepScaleRatio->isChecked())
-		spinYscaling->setValue(spinXscaling->value());
-	changePatternProps();
-	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-}
-
-void PatternPropsDialog::VChange()
-{
-	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-	if (keepScaleRatio->isChecked())
-		spinXscaling->setValue(spinYscaling->value());
-	changePatternProps();
-	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
-	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
-}
-
 Cpalette::Cpalette(QWidget* parent) : QWidget(parent)
 {
 	currentItem = NULL;
@@ -332,9 +133,8 @@
 	disconnect(gradientTypeStroke, SIGNAL(activated(int)), this, SLOT(slotGradTypeStroke(int)));
 	disconnect(gradEdit, SIGNAL(gradientChanged()), this, SIGNAL(gradientChanged()));
 	disconnect(gradEditStroke, SIGNAL(gradientChanged()), this, SIGNAL(strokeGradientChanged()));
+	disconnect(gradientType, SIGNAL(activated(int)), this, SLOT(slotGradType(int)));
 	updateCList();
-//	setActTrans(currentItem->fillTransparency(), currentItem->lineTransparency());
-//	setActBlend(currentItem->fillBlendmode(), currentItem->lineBlendmode());
 	if (currentItem->doOverprint)
 		setActOverprint(1);
 	else
@@ -392,6 +192,7 @@
 	connect(gradientTypeStroke, SIGNAL(activated(int)), this, SLOT(slotGradTypeStroke(int)));
 	connect(gradEdit, SIGNAL(gradientChanged()), this, SIGNAL(gradientChanged()));
 	connect(gradEditStroke, SIGNAL(gradientChanged()), this, SIGNAL(strokeGradientChanged()));
+	connect(gradientType, SIGNAL(activated(int)), this, SLOT(slotGradType(int)));
 }
 
 void Cpalette::updateCList()
@@ -429,27 +230,7 @@
 		updateFromItem();
 	}
 }
-/*
-void Cpalette::setActTrans(double val, double val2)
-{
-	disconnect(strokeOpacity, SIGNAL(valueChanged(int)), this, SLOT(slotTransS(int)));
-	disconnect(fillOpacity, SIGNAL(valueChanged(int)), this, SLOT(slotTransF(int)));
-	strokeOpacity->setValue(qRound(100 - (val2 * 100)));
-	fillOpacity->setValue(qRound(100 - (val * 100)));
-	connect(strokeOpacity, SIGNAL(valueChanged(int)), this, SLOT(slotTransS(int)));
-	connect(fillOpacity, SIGNAL(valueChanged(int)), this, SLOT(slotTransF(int)));
-}
 
-void Cpalette::setActBlend(int val, int val2)
-{
-	disconnect(blendModeFill, SIGNAL(activated(int)), this, SIGNAL(NewBlend(int)));
-	disconnect(blendModeStroke, SIGNAL(activated(int)), this, SIGNAL(NewBlendS(int)));
-	blendModeFill->setCurrentIndex(val);
-	blendModeStroke->setCurrentIndex(val2);
-	connect(blendModeFill, SIGNAL(activated(int)), this, SIGNAL(NewBlend(int)));
-	connect(blendModeStroke, SIGNAL(activated(int)), this, SIGNAL(NewBlendS(int)));
-}
-*/
 void Cpalette::setActOverprint(int val)
 {
 	disconnect(overPrintCombo, SIGNAL(activated(int)), this, SIGNAL(NewOverprint(int)));
@@ -510,17 +291,7 @@
 		return;
 	emit NewBrush(sFarbe);
 }
-/*
-void Cpalette::slotTransS(int val)
-{
-	emit NewTransS(static_cast<double>(100 - val) / 100.0);
-}
 
-void Cpalette::slotTransF(int val)
-{
-	emit NewTrans(static_cast<double>(100 - val) / 100.0);
-}
-*/
 void Cpalette::SetColors(ColorList newColorList)
 {
 	colorList.clear();
@@ -752,7 +523,7 @@
 	}
 	else if (number == 2)
 	{
-		emit NewGradientS(0);
+		emit NewGradientS(8);
 		if (patternBoxStroke->currentItem())
 			emit NewPatternS(patternBoxStroke->currentItem()->text());
 	}
@@ -798,6 +569,8 @@
 	if (number == 1)
 	{
 		disconnect(namedGradient, SIGNAL(activated(const QString &)), this, SLOT(setNamedGradient(const QString &)));
+		disconnect(gradientType, SIGNAL(activated(int)), this, SLOT(slotGradType(int)));
+		disconnect(gradEdit, SIGNAL(gradientChanged()), this, SIGNAL(gradientChanged()));
 		if (!currentItem->gradient().isEmpty())
 		{
 			setCurrentComboItem(namedGradient, currentItem->gradient());
@@ -815,6 +588,8 @@
 		else
 			emit NewGradient(7);
 		connect(namedGradient, SIGNAL(activated(const QString &)), this, SLOT(setNamedGradient(const QString &)));
+		connect(gradientType, SIGNAL(activated(int)), this, SLOT(slotGradType(int)));
+		connect(gradEdit, SIGNAL(gradientChanged()), this, SIGNAL(gradientChanged()));
 	}
 	else if (number == 2)
 		emit NewGradient(8);
Index: scribus/ui/transparencypalette.h
===================================================================
--- scribus/ui/transparencypalette.h	(revision 14307)
+++ scribus/ui/transparencypalette.h	(revision 14308)
@@ -35,6 +35,7 @@
 #include "ui/scrpalettebase.h"
 #include "ui_transparencypalette.h"
 #include "ui/gradientvectordialog.h"
+#include "ui/patternpropsdialog.h"
 
 class PageItem;
 class ColorListBox;
@@ -75,11 +76,17 @@
 	void setNamedGradient(const QString &name);
 	void editGradientVector();
 	void setActiveGradDia(bool active);
+	void updatePatternList();
+	void SetPatterns(QMap<QString, ScPattern> *docPatterns);
+	void selectPattern(QListWidgetItem *c);
+	void setActPattern(QString pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
+	void changePatternProps();
 	void setSpecialGradient(double x1, double y1, double x2, double y2, double fx, double fy, double sg, double sk);
 	void setActTrans(double, double);
 	void setActBlend(int, int);
 	void slotTransS(int val);
 	void slotTransF(int val);
+	void unitChange(double, double, int unitIndex);
 
 signals:
 	void NewTrans(double);
@@ -90,6 +97,8 @@
 	void editGradient();
 	void NewGradient(int);
 	void NewSpecial(double, double, double, double, double, double, double, double);
+	void NewPattern(QString);
+	void NewPatternProps(double, double, double, double, double, double, double, bool, bool);
 
 protected:
 	GradientVectorDialog* TGradDia;
@@ -99,5 +108,14 @@
 	int currentUnit;
 	QMap<QString, ScPattern> *patternList;
 	QMap<QString, VGradient> *gradientList;
+	double m_Pattern_scaleX;
+	double m_Pattern_scaleY;
+	double m_Pattern_offsetX;
+	double m_Pattern_offsetY;
+	double m_Pattern_rotation;
+	double m_Pattern_skewX;
+	double m_Pattern_skewY;
+	bool m_Pattern_mirrorX;
+	bool m_Pattern_mirrorY;
 };
 #endif
Index: scribus/ui/patternpropsdialog.cpp
===================================================================
--- scribus/ui/patternpropsdialog.cpp	(revision 0)
+++ scribus/ui/patternpropsdialog.cpp	(revision 14308)
@@ -0,0 +1,224 @@
+/*
+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.
+*/
+/***************************************************************************
+                          patternpropsdialog.cpp  -  description
+                             -------------------
+    begin                : Thu Nov 19 2009
+    copyright            : (C) 2009 by Franz Schmid
+    email                : Franz.Schmid at altmuehlnet.de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 "patternpropsdialog.h"
+#include "util_icon.h"
+#include "util_math.h"
+
+PatternPropsDialog::PatternPropsDialog(QWidget* parent, int unitIndex) : QDialog( parent )
+{
+	setModal(true);
+	frame3Layout = new QVBoxLayout( this );
+	frame3Layout->setMargin(0);
+	frame3Layout->setSpacing(2);
+
+	groupOffset = new QGroupBox( this );
+	groupOffsetLayout = new QHBoxLayout( groupOffset );
+	groupOffsetLayout->setSpacing( 2 );
+	groupOffsetLayout->setMargin( 3 );
+	groupOffsetLayout->setAlignment( Qt::AlignTop );
+	textLabel1 = new QLabel( groupOffset );
+	groupOffsetLayout->addWidget( textLabel1 );
+	spinXoffset = new ScrSpinBox( -3000, 3000, groupOffset, 0);
+	groupOffsetLayout->addWidget( spinXoffset );
+	textLabel2 = new QLabel( groupOffset );
+	groupOffsetLayout->addWidget( textLabel2 );
+	spinYoffset = new ScrSpinBox( -3000, 3000, groupOffset, 0);
+	groupOffsetLayout->addWidget( spinYoffset );
+	frame3Layout->addWidget( groupOffset );
+
+	groupScale = new QGroupBox( this );
+	groupScaleLayout = new QGridLayout( groupScale );
+	groupScaleLayout->setSpacing( 2 );
+	groupScaleLayout->setMargin( 3 );
+	groupScaleLayout->setAlignment( Qt::AlignTop );
+	textLabel5 = new QLabel( groupScale );
+	groupScaleLayout->addWidget( textLabel5, 0, 0 );
+	spinXscaling = new ScrSpinBox( 0.01, 500, groupScale, 0);
+	spinXscaling->setValue( 100 );
+	groupScaleLayout->addWidget( spinXscaling, 0, 1 );
+	textLabel6 = new QLabel( groupScale );
+	groupScaleLayout->addWidget( textLabel6, 1, 0 );
+	spinYscaling = new ScrSpinBox( 0.01, 500, groupScale, 0 );
+	spinYscaling->setValue( 100 );
+	groupScaleLayout->addWidget( spinYscaling, 1, 1 );
+	keepScaleRatio = new LinkButton( groupScale );
+	keepScaleRatio->setCheckable( true );
+	keepScaleRatio->setAutoRaise( true );
+	keepScaleRatio->setMaximumSize( QSize( 15, 32767 ) );
+	groupScaleLayout->addWidget( keepScaleRatio, 0, 2, 2, 1 );
+	frame3Layout->addWidget( groupScale );
+	groupRotation = new QGroupBox( this );
+	groupRotationLayout = new QHBoxLayout( groupRotation );
+	groupRotationLayout->setSpacing( 2 );
+	groupRotationLayout->setMargin( 3 );
+	groupRotationLayout->setAlignment( Qt::AlignTop );
+	textLabel7 = new QLabel( groupRotation );
+	groupRotationLayout->addWidget( textLabel7 );
+	spinAngle = new ScrSpinBox( -180, 180, groupRotation, 6 );
+	groupRotationLayout->addWidget( spinAngle );
+	frame3Layout->addWidget( groupRotation );
+
+	groupSkew = new QGroupBox( this );
+	groupSkewLayout = new QGridLayout( groupSkew );
+	groupSkewLayout->setSpacing( 2 );
+	groupSkewLayout->setMargin( 3 );
+	groupSkewLayout->setAlignment( Qt::AlignTop );
+	textLabel8 = new QLabel( groupSkew );
+	groupSkewLayout->addWidget( textLabel8, 0, 0 );
+	spinXSkew = new ScrSpinBox( -89, 89, groupSkew, 6);
+	spinXSkew->setValue( 0 );
+	groupSkewLayout->addWidget( spinXSkew, 0, 1 );
+	textLabel9 = new QLabel( groupSkew );
+	groupSkewLayout->addWidget( textLabel9, 1, 0 );
+	spinYSkew = new ScrSpinBox( -89, 89, groupSkew, 6 );
+	spinYSkew->setValue( 0 );
+	groupSkewLayout->addWidget( spinYSkew, 1, 1 );
+	frame3Layout->addWidget( groupSkew );
+
+	groupFlipLayout = new QHBoxLayout();
+	groupFlipLayout->setSpacing( 2 );
+	groupFlipLayout->setMargin( 3 );
+	textLabel15 = new QLabel( this );
+	groupFlipLayout->addWidget( textLabel15 );
+	QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
+	groupFlipLayout->addItem( spacer );
+	FlipH = new QToolButton( this );
+	FlipH->setIcon(QIcon(loadIcon("16/flip-object-horizontal.png")));
+	FlipH->setCheckable( true );
+	groupFlipLayout->addWidget( FlipH );
+	FlipV = new QToolButton( this );
+	FlipV->setIcon(QIcon(loadIcon("16/flip-object-vertical.png")));
+	FlipV->setCheckable( true );
+	groupFlipLayout->addWidget( FlipV );
+	frame3Layout->addLayout( groupFlipLayout );
+
+	buttonLayout = new QHBoxLayout;
+	buttonLayout->setMargin(0);
+	buttonLayout->setSpacing(5);
+	QSpacerItem* hspacing = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+	buttonLayout->addItem(hspacing);
+	buttonOk = new QPushButton( this );
+	buttonOk->setAutoDefault( TRUE );
+	buttonOk->setDefault( TRUE );
+	buttonLayout->addWidget( buttonOk );
+	frame3Layout->addLayout( buttonLayout );
+	spinXoffset->setNewUnit(unitIndex);
+	spinYoffset->setNewUnit(unitIndex);
+	languageChange();
+	connect(spinXoffset, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
+	connect(spinYoffset, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
+	connect(spinXSkew, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
+	connect(spinYSkew, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
+	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+	connect(keepScaleRatio, SIGNAL(clicked()), this, SLOT(ToggleKette()));
+	connect(spinAngle, SIGNAL(valueChanged(double)), this, SLOT(changePatternProps()));
+	connect(FlipH, SIGNAL(clicked()), this, SLOT(changePatternProps()));
+	connect(FlipV, SIGNAL(clicked()), this, SLOT(changePatternProps()));
+	connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
+}
+
+void PatternPropsDialog::changeEvent(QEvent *e)
+{
+	if (e->type() == QEvent::LanguageChange)
+	{
+		languageChange();
+	}
+	else
+		QWidget::changeEvent(e);
+}
+
+void PatternPropsDialog::languageChange()
+{
+	setWindowTitle( tr( "Pattern Properties" ));
+	QString ptSuffix=tr(" pt");
+	QString pctSuffix=tr(" %");
+	groupOffset->setTitle( tr( "Offsets" ) );
+	textLabel1->setText( tr( "X:" ) );
+	spinXoffset->setSuffix( ptSuffix );
+	textLabel2->setText( tr( "Y:" ) );
+	spinYoffset->setSuffix( ptSuffix );
+	groupScale->setTitle( tr( "Scaling" ) );
+	textLabel5->setText( tr( "X-Scale:" ) );
+	spinXscaling->setSuffix( pctSuffix );
+	textLabel6->setText( tr( "Y-Scale:" ) );
+	spinYscaling->setSuffix( pctSuffix );
+	groupRotation->setTitle( tr( "Rotation" ) );
+	groupSkew->setTitle( tr( "Skewing" ) );
+	textLabel8->setText( tr( "X-Skew:" ) );
+	textLabel9->setText( tr( "Y-Skew:" ) );
+	textLabel7->setText( tr( "Angle:" ) );
+	textLabel15->setText( tr( "Flip:" ) );
+	buttonOk->setText( tr("Close"));
+	resize(minimumSizeHint());
+}
+
+void PatternPropsDialog::changePatternProps()
+{
+	double a    = M_PI / 180.0 * spinXSkew->value();
+	double b    = M_PI / 180.0 * spinYSkew->value();
+	double sina = tan(a);
+	double sinb = tan(b);
+	bool fH = FlipH->isChecked();
+	bool fV = FlipV->isChecked();
+	emit NewPatternProps(spinXscaling->value(), spinYscaling->value(), spinXoffset->value(), spinYoffset->value(), spinAngle->value(), sina, sinb, fH, fV);
+}
+
+void PatternPropsDialog::ToggleKette()
+{
+	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+	if (keepScaleRatio->isChecked())
+	{
+		spinYscaling->setValue(spinXscaling->value());
+		changePatternProps();
+		keepScaleRatio->setChecked(true);
+	}
+	else
+		keepScaleRatio->setChecked(false);
+	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+}
+
+void PatternPropsDialog::HChange()
+{
+	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+	if (keepScaleRatio->isChecked())
+		spinYscaling->setValue(spinXscaling->value());
+	changePatternProps();
+	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+}
+
+void PatternPropsDialog::VChange()
+{
+	disconnect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	disconnect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+	if (keepScaleRatio->isChecked())
+		spinXscaling->setValue(spinYscaling->value());
+	changePatternProps();
+	connect(spinXscaling, SIGNAL(valueChanged(double)), this, SLOT(HChange()));
+	connect(spinYscaling, SIGNAL(valueChanged(double)), this, SLOT(VChange()));
+}
Index: scribus/ui/cpalette.h
===================================================================
--- scribus/ui/cpalette.h	(revision 14307)
+++ scribus/ui/cpalette.h	(revision 14308)
@@ -35,70 +35,18 @@
 #include "ui/scrpalettebase.h"
 #include "ui_colorpalette.h"
 #include "ui/gradientvectordialog.h"
+#include "ui/patternpropsdialog.h"
 
 class PageItem;
 class ColorListBox;
 class ScrSpinBox;
 class ScComboBox;
 class ScPattern;
-class LinkButton;
 
 /**
   *@author Franz Schmid
   */
 
-class SCRIBUS_API PatternPropsDialog : public QDialog
-{
-	Q_OBJECT
-
-public:
-	PatternPropsDialog(QWidget* parent, int unitIndex);
-	~PatternPropsDialog() {};
-	virtual void changeEvent(QEvent *e);
-	ScrSpinBox* spinXoffset;
-	ScrSpinBox* spinYoffset;
-	ScrSpinBox* spinXscaling;
-	ScrSpinBox* spinYscaling;
-	ScrSpinBox* spinAngle;
-	ScrSpinBox* spinXSkew;
-	ScrSpinBox* spinYSkew;
-	QToolButton* FlipH;
-	QToolButton* FlipV;
-
-public slots:
-	void languageChange();
-	void changePatternProps();
-	void ToggleKette();
-	void HChange();
-	void VChange();
-
-signals:
-	void NewPatternProps(double, double, double, double, double, double, double, bool, bool);
-
-protected:
-	QGroupBox* groupOffset;
-	QLabel* textLabel1;
-	QLabel* textLabel2;
-	QGroupBox* groupScale;
-	QLabel* textLabel5;
-	QLabel* textLabel6;
-	LinkButton* keepScaleRatio;
-	QGroupBox* groupRotation;
-	QLabel* textLabel7;
-	QGroupBox* groupSkew;
-	QLabel* textLabel8;
-	QLabel* textLabel9;
-	QLabel* textLabel15;
-	QVBoxLayout* frame3Layout;
-	QHBoxLayout* groupOffsetLayout;
-	QGridLayout* groupScaleLayout;
-	QGridLayout* groupSkewLayout;
-	QHBoxLayout* groupRotationLayout;
-	QPushButton* buttonOk;
-	QHBoxLayout* buttonLayout;
-	QHBoxLayout* groupFlipLayout;
-};
-
 class SCRIBUS_API Cpalette : public QWidget, Ui::colorPalette
 {
 	Q_OBJECT
@@ -119,11 +67,7 @@
 	void editLineColorSelectorButton();
 	void editFillColorSelectorButton();
 	void SetColors(ColorList newColorList);
-//	void setActTrans(double, double);
-//	void setActBlend(int, int);
 	void setActOverprint(int);
-//	void slotTransS(int val);
-//	void slotTransF(int val);
 	void updateCList();
 	void ToggleColorDisplay();
 	void SetPatterns(QMap<QString, ScPattern> *docPatterns);
@@ -164,10 +108,6 @@
 	void NewPatternS(QString);
 	void NewPatternPropsS(double, double, double, double, double, double, double, bool, bool);
 	void NewSpecial(double, double, double, double, double, double, double, double);
-//	void NewTrans(double);
-//	void NewTransS(double);
-//	void NewBlend(int);
-//	void NewBlendS(int);
 	void NewOverprint(int);
 	void gradientChanged();
 	void strokeGradientChanged();
Index: scribus/ui/patternpropsdialog.h
===================================================================
--- scribus/ui/patternpropsdialog.h	(revision 0)
+++ scribus/ui/patternpropsdialog.h	(revision 14308)
@@ -0,0 +1,89 @@
+/*
+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.
+*/
+/***************************************************************************
+                          patternpropsdialog.h  -  description
+                             -------------------
+    begin                : Thu Nov 19 2009
+    copyright            : (C) 2009 by Franz Schmid
+    email                : Franz.Schmid at altmuehlnet.de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef PATTERNPROPSDIALOG_H
+#define PATTERNPROPSDIALOG_H
+
+#include <QDialog>
+#include <QLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QToolButton>
+#include <QPushButton>
+#include <QEvent>
+#include "scribusapi.h"
+#include "scrspinbox.h"
+#include "linkbutton.h"
+
+class SCRIBUS_API PatternPropsDialog : public QDialog
+{
+	Q_OBJECT
+
+public:
+	PatternPropsDialog(QWidget* parent, int unitIndex);
+	~PatternPropsDialog() {};
+	virtual void changeEvent(QEvent *e);
+	ScrSpinBox* spinXoffset;
+	ScrSpinBox* spinYoffset;
+	ScrSpinBox* spinXscaling;
+	ScrSpinBox* spinYscaling;
+	ScrSpinBox* spinAngle;
+	ScrSpinBox* spinXSkew;
+	ScrSpinBox* spinYSkew;
+	QToolButton* FlipH;
+	QToolButton* FlipV;
+
+public slots:
+	void languageChange();
+	void changePatternProps();
+	void ToggleKette();
+	void HChange();
+	void VChange();
+
+signals:
+	void NewPatternProps(double, double, double, double, double, double, double, bool, bool);
+
+protected:
+	QGroupBox* groupOffset;
+	QLabel* textLabel1;
+	QLabel* textLabel2;
+	QGroupBox* groupScale;
+	QLabel* textLabel5;
+	QLabel* textLabel6;
+	LinkButton* keepScaleRatio;
+	QGroupBox* groupRotation;
+	QLabel* textLabel7;
+	QGroupBox* groupSkew;
+	QLabel* textLabel8;
+	QLabel* textLabel9;
+	QLabel* textLabel15;
+	QVBoxLayout* frame3Layout;
+	QHBoxLayout* groupOffsetLayout;
+	QGridLayout* groupScaleLayout;
+	QGridLayout* groupSkewLayout;
+	QHBoxLayout* groupRotationLayout;
+	QPushButton* buttonOk;
+	QHBoxLayout* buttonLayout;
+	QHBoxLayout* groupFlipLayout;
+};
+#endif
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(revision 14307)
+++ scribus/ui/propertiespalette.cpp	(revision 14308)
@@ -1870,6 +1870,8 @@
 	disconnect(this->Tpal, SIGNAL(NewGradient(int)), 0, 0);
 	disconnect(this->Tpal, SIGNAL(NewBlend(int)), 0, 0);
 	disconnect(this->Tpal, SIGNAL(NewBlendS(int)), 0, 0);
+	disconnect(this->Tpal, SIGNAL(NewPattern(QString)), 0, 0);
+	disconnect(this->Tpal, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)), 0, 0);
 
 	disconnect(this->Cpal, SIGNAL(NewPen(QString)), 0, 0);
 	disconnect(this->Cpal, SIGNAL(NewBrush(QString)), 0, 0);
@@ -1952,6 +1954,8 @@
 	connect(this->Tpal, SIGNAL(NewBlend(int)), doc, SLOT(itemSelection_SetItemFillBlend(int)));
 	connect(this->Tpal, SIGNAL(NewBlendS(int)), doc, SLOT(itemSelection_SetItemLineBlend(int)));
 	connect(this->Tpal, SIGNAL(NewGradient(int)), doc, SLOT(itemSelection_SetItemGradMask(int)));
+	connect(this->Tpal, SIGNAL(NewPattern(QString)), doc, SLOT(itemSelection_SetItemPatternMask(QString)));
+	connect(this->Tpal, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)), doc, SLOT(itemSelection_SetItemPatternMaskProps(double, double, double, double, double, double, double, bool, bool)));
 
 	connect(this->Cpal, SIGNAL(NewPen(QString)), doc, SLOT(itemSelection_SetItemPen(QString)));
 	connect(this->Cpal, SIGNAL(NewBrush(QString)), doc, SLOT(itemSelection_SetItemBrush(QString)));
@@ -2257,6 +2261,11 @@
 	i->strokePatternFlip(mirrorX, mirrorY);
 	Cpal->setActPatternStroke(i->strokePattern(), patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, mirrorX, mirrorY);
 
+	i->maskTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
+	i->maskFlip(mirrorX, mirrorY);
+	Tpal->setActPattern(i->patternMask(), patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, mirrorX, mirrorY);
+
+
 //CB TODO reconnect PP signals from here
 	connect(Xpos, SIGNAL(valueChanged(double)), this, SLOT(NewX()));
 	connect(Ypos, SIGNAL(valueChanged(double)), this, SLOT(NewY()));
@@ -2801,6 +2810,7 @@
 	RoundRect->setNewUnit( m_unitIndex );
 	LSize->setNewUnit( m_unitIndex );
 	Cpal->unitChange(oldRatio, m_unitRatio, doc->unitIndex());
+	Tpal->unitChange(oldRatio, m_unitRatio, doc->unitIndex());
 	HaveItem = tmp;
 }
 
@@ -4847,6 +4857,7 @@
 	Cpal->SetPatterns(&doc->docPatterns);
 	Cpal->SetGradients(&doc->docGradients);
 	Tpal->SetColors(doc->PageColors);
+	Tpal->SetPatterns(&doc->docPatterns);
 	Tpal->SetGradients(&doc->docGradients);
 	assert (doc->PageColors.document());
 	TxFill->updateBox(doc->PageColors, ColorCombo::fancyPixmaps, true);
Index: scribus/ui/transparencypalette.cpp
===================================================================
--- scribus/ui/transparencypalette.cpp	(revision 14307)
+++ scribus/ui/transparencypalette.cpp	(revision 14308)
@@ -27,6 +27,7 @@
 #include "scpattern.h"
 #include "util_icon.h"
 #include "util.h"
+#include "util_math.h"
 
 Tpalette::Tpalette(QWidget* parent) : QWidget(parent)
 {
@@ -53,7 +54,8 @@
 	connect(TGradDia, SIGNAL(paletteShown(bool)), this, SLOT(setActiveGradDia(bool)));
 	connect(gradientType, SIGNAL(activated(int)), this, SLOT(slotGradType(int)));
 	connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotGrad(int)));
-	tabWidget->setTabEnabled(2, false);
+	connect(patternBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(selectPattern(QListWidgetItem*)));
+	connect(editPatternProps, SIGNAL(clicked()), this, SLOT(changePatternProps()));
 }
 
 void Tpalette::setCurrentItem(PageItem* item)
@@ -100,6 +102,10 @@
 		tabWidget->setCurrentIndex(1);
 	else
 		tabWidget->setCurrentIndex(2);
+	if (patternList->count() == 0)
+		tabWidget->setTabEnabled(2, false);
+	else
+		tabWidget->setTabEnabled(2, true);
 	connect(gradEdit, SIGNAL(gradientChanged()), this, SIGNAL(gradientChanged()));
 	connect(namedGradient, SIGNAL(activated(const QString &)), this, SLOT(setNamedGradient(const QString &)));
 	connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotGrad(int)));
@@ -245,6 +251,99 @@
 		TGradDia->setValues(x1, y1, x2, y2, fx, fy, sg, sk);
 }
 
+void Tpalette::updatePatternList()
+{
+	disconnect(patternBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(selectPattern(QListWidgetItem*)));
+	patternBox->clear();
+	patternBox->setIconSize(QSize(48, 48));
+	for (QMap<QString, ScPattern>::Iterator it = patternList->begin(); it != patternList->end(); ++it)
+	{
+		QPixmap pm;
+		if (it.value().getPattern()->width() >= it.value().getPattern()->height())
+			pm=QPixmap::fromImage(it.value().getPattern()->scaledToWidth(48, Qt::SmoothTransformation));
+		else
+			pm=QPixmap::fromImage(it.value().getPattern()->scaledToHeight(48, Qt::SmoothTransformation));
+		QPixmap pm2(48, 48);
+		pm2.fill(palette().color(QPalette::Base));
+		QPainter p;
+		p.begin(&pm2);
+		p.drawPixmap(24 - pm.width() / 2, 24 - pm.height() / 2, pm);
+		p.end();
+		QListWidgetItem *item = new QListWidgetItem(pm2, it.key(), patternBox);
+		item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+	}
+	patternBox->clearSelection();
+	connect(patternBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(selectPattern(QListWidgetItem*)));
+}
+
+void Tpalette::SetPatterns(QMap<QString, ScPattern> *docPatterns)
+{
+	patternList = docPatterns;
+	updatePatternList();
+}
+
+void Tpalette::selectPattern(QListWidgetItem *c)
+{
+	if (c == NULL)
+		return;
+	emit NewPattern(c->text());
+}
+
+void Tpalette::setActPattern(QString pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
+{
+	disconnect(patternBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(selectPattern(QListWidgetItem*)));
+	QList<QListWidgetItem*> itl = patternBox->findItems(pattern, Qt::MatchExactly);
+	if (itl.count() != 0)
+	{
+		QListWidgetItem *it = itl[0];
+		patternBox->setCurrentItem(it);
+	}
+	else
+		patternBox->clearSelection();
+	m_Pattern_scaleX = scaleX;
+	m_Pattern_scaleY = scaleX;
+	m_Pattern_offsetX = offsetX;
+	m_Pattern_offsetY = offsetY;
+	m_Pattern_rotation = rotation;
+	m_Pattern_skewX = skewX;
+	m_Pattern_skewY = skewY;
+	m_Pattern_mirrorX = mirrorX;
+	m_Pattern_mirrorY = mirrorY;
+	connect(patternBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(selectPattern(QListWidgetItem*)));
+}
+
+void Tpalette::changePatternProps()
+{
+	PatternPropsDialog *dia = new PatternPropsDialog(this, currentUnit);
+	dia->spinXscaling->setValue(m_Pattern_scaleX);
+	dia->spinYscaling->setValue(m_Pattern_scaleY);
+	dia->spinXoffset->setValue(m_Pattern_offsetX);
+	dia->spinYoffset->setValue(m_Pattern_offsetY);
+	dia->spinAngle->setValue(m_Pattern_rotation);
+	double asina = atan(m_Pattern_skewX);
+	dia->spinXSkew->setValue(asina / (M_PI / 180.0));
+	double asinb = atan(m_Pattern_skewY);
+	dia->spinYSkew->setValue(asinb / (M_PI / 180.0));
+	dia->FlipH->setChecked(m_Pattern_mirrorX);
+	dia->FlipV->setChecked(m_Pattern_mirrorY);
+	connect(dia, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)), this, SIGNAL(NewPatternProps(double, double, double, double, double, double, double, bool, bool)));
+	dia->exec();
+	m_Pattern_scaleX = dia->spinXscaling->value();
+	m_Pattern_scaleY = dia->spinYscaling->value();
+	m_Pattern_offsetX = dia->spinXoffset->value();
+	m_Pattern_offsetY = dia->spinYoffset->value();
+	m_Pattern_rotation = dia->spinAngle->value();
+	double a    = M_PI / 180.0 * dia->spinXSkew->value();
+	double b    = M_PI / 180.0 * dia->spinYSkew->value();
+	double sina = tan(a);
+	double sinb = tan(b);
+	m_Pattern_skewX = sina;
+	m_Pattern_skewY = sinb;
+	m_Pattern_mirrorX = dia->FlipH->isChecked();
+	m_Pattern_mirrorY = dia->FlipV->isChecked();
+	delete dia;
+}
+
 void Tpalette::setActTrans(double val, double val2)
 {
 	disconnect(strokeOpacity, SIGNAL(valueChanged(int)), this, SLOT(slotTransS(int)));
@@ -295,6 +394,13 @@
 	updateFromItem();
 }
 
+void Tpalette::unitChange(double, double, int unitIndex)
+{
+	if (TGradDia)
+		TGradDia->unitChange(unitIndex);
+	currentUnit = unitIndex;
+}
+
 void Tpalette::changeEvent(QEvent *e)
 {
 	if (e->type() == QEvent::LanguageChange)
Index: scribus/plugins/aiimplugin/importai.cpp
===================================================================
--- scribus/plugins/aiimplugin/importai.cpp	(revision 14307)
+++ scribus/plugins/aiimplugin/importai.cpp	(revision 14308)
@@ -54,6 +54,9 @@
 #include "util_icon.h"
 #include "util_math.h"
 
+#ifdef HAVE_CAIRO
+	#include <cairo.h>
+#endif
 
 #ifdef HAVE_PODOFO
 	#include <podofo/podofo.h>
@@ -1166,8 +1169,12 @@
 					ite->setFillEvenOdd(fillRule);
 					ite->setFillTransparency(1.0 - Opacity);
 					ite->setLineTransparency(1.0 - Opacity);
-	//				ite->setFillBlendmode(blendMode);
-	//				ite->setLineBlendmode(blendMode);
+#ifdef HAVE_CAIRO
+	#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4))
+					ite->setFillBlendmode(blendMode);
+					ite->setLineBlendmode(blendMode);
+	#endif
+#endif
 					if (!currentPatternName.isEmpty())
 					{
 						ite->setPattern(currentPatternName);
Index: scribus/plugins/xarimplugin/importxar.cpp
===================================================================
--- scribus/plugins/xarimplugin/importxar.cpp	(revision 14307)
+++ scribus/plugins/xarimplugin/importxar.cpp	(revision 14308)
@@ -153,6 +153,8 @@
 	qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
 	QString CurDirP = QDir::currentPath();
 	QDir::setCurrent(fi.path());
+	if (!m_Doc->PageColors.contains("Black"))
+		m_Doc->PageColors.insert("Black", ScColor(0, 0, 0, 255));
 	if (convert(fName))
 	{
 		tmpSel->clear();
Index: scribus/CMakeLists.txt
===================================================================
--- scribus/CMakeLists.txt	(revision 14307)
+++ scribus/CMakeLists.txt	(revision 14308)
@@ -273,6 +273,7 @@
   ui/pagepalette.h
   ui/pageselector.h
   ui/patterndialog.h
+  ui/patternpropsdialog.h
   pdf_analyzer.h
   pdflib.h
   pdflib_core.h
@@ -582,6 +583,7 @@
   ui/pageselector.cpp
   pagesize.cpp
   ui/patterndialog.cpp
+  ui/patternpropsdialog.cpp
   pdf_analyzer.cpp
   pdflib.cpp
   pdflib_core.cpp




More information about the scribus-commit mailing list