r14298 by fschmid - Gradient Masks Part 1: Framework fixes and Cairo based drawing + Xara Importer adapted.

scribus-commit scribus-commit at lists.scribus.net
Mon Nov 16 20:20:47 CET 2009


Revision: 14298
Author: fschmid
Date: 2009-11-16T11:05:20.770143Z
Commit message: Gradient Masks Part 1: Framework fixes and Cairo based drawing + Xara Importer adapted.

Changeset: 
M  /trunk/Scribus/scribus/scpainter.cpp
M  /trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format.cpp
M  /trunk/Scribus/scribus/pageitem_textframe.cpp
M  /trunk/Scribus/scribus/pageitem.cpp
M  /trunk/Scribus/scribus/scribusXml.cpp
M  /trunk/Scribus/scribus/scpainter.h
M  /trunk/Scribus/scribus/pageitem_desaxe.cpp
M  /trunk/Scribus/scribus/plugins/xarimplugin/importxar.cpp
M  /trunk/Scribus/scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp

Diffs:
Index: scribus/scribusXml.cpp
===================================================================
--- scribus/scribusXml.cpp	(revision 14297)
+++ scribus/scribusXml.cpp	(revision 14298)
@@ -218,6 +218,11 @@
 	OB->GrMask = attrAsInt(attrs, "GRTYPM"  , 0);
 	if (OB->GrMask == 1)
 	{
+		int grM = attrAsInt(attrs, "GRMK", 0);
+		if (grM == 0)
+			OB->mask_gradient = VGradient(VGradient::linear);
+		else
+			OB->mask_gradient = VGradient(VGradient::radial);
 		OB->mask_gradient.clearStops();
 		OB->GrMaskStartX = attrAsDbl(attrs, "GRSTARTXM", 0.0);
 		OB->GrMaskStartY = attrAsDbl(attrs, "GRSTARTYM", 0.0);
@@ -1200,7 +1205,8 @@
 		if (tagName == "Gradient")
 		{
 			VGradient gra;
-			QString grName = attrs.value("Name").toString();gra = VGradient(VGradient::linear);
+			QString grName = attrs.value("Name").toString();
+			gra = VGradient(VGradient::linear);
 			gra.clearStops();
 			while(!(sReader.isEndElement() && sReader.name() == tagName))
 			{
@@ -2564,6 +2570,10 @@
 		}
 		else
 			writer.writeAttribute("GRNAMEM"  , item->gradientMask());
+		if (item->mask_gradient.type() == VGradient::radial)
+			writer.writeAttribute("GRMK", 1);
+		else
+			writer.writeAttribute("GRMK", 0);
 		writer.writeAttribute("GRSTARTXM", item->GrMaskStartX);
 		writer.writeAttribute("GRSTARTYM", item->GrMaskStartY);
 		writer.writeAttribute("GRENDXM", item->GrMaskEndX);
Index: scribus/scpainter.cpp
===================================================================
--- scribus/scpainter.cpp	(revision 14297)
+++ scribus/scpainter.cpp	(revision 14298)
@@ -32,6 +32,7 @@
 	m_height= h;
 	m_stroke = QColor(0,0,0);
 	strokeMode = 0;
+	maskMode = 0;
 	m_fill = QColor(0,0,0);
 	fill_trans = 1.0;
 	stroke_trans = 1.0;
@@ -71,6 +72,7 @@
 	m_height= h;
 	m_stroke = QColor(0,0,0);
 	strokeMode = 0;
+	maskMode = 0;
 	m_fill = QColor(0,0,0);
 	fill_trans = 1.0;
 	stroke_trans = 1.0;
@@ -111,6 +113,7 @@
 	m_height= h;
 	m_stroke = QColor(0,0,0);
 	strokeMode = 0;
+	maskMode = 0;
 	m_fill = QColor(0,0,0);
 	fill_trans = 1.0;
 	stroke_trans = 1.0;
@@ -555,14 +558,30 @@
 		if (m_blendMode == 0)
 		{
 			cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-			cairo_paint_with_alpha (m_cr, m_layerTransparency);
+			if (maskMode == 1)
+			{
+				cairo_pattern_t *patM = getMaskPattern();
+				cairo_mask(m_cr, patM);
+				cairo_pattern_destroy(patM);
+			}
+			else
+				cairo_paint_with_alpha (m_cr, m_layerTransparency);
 		}
 		else
 		{
-			cairo_set_operator(m_cr, CAIRO_OPERATOR_DEST_OUT);
-			cairo_paint_with_alpha (m_cr, m_layerTransparency);
-			cairo_set_operator(m_cr, CAIRO_OPERATOR_ADD);
-			cairo_paint_with_alpha (m_cr, m_layerTransparency);
+			if (maskMode == 1)
+			{
+				cairo_pattern_t *patM = getMaskPattern();
+				cairo_mask(m_cr, patM);
+				cairo_pattern_destroy(patM);
+			}
+			else
+			{
+				cairo_set_operator(m_cr, CAIRO_OPERATOR_DEST_OUT);
+				cairo_paint_with_alpha (m_cr, m_layerTransparency);
+				cairo_set_operator(m_cr, CAIRO_OPERATOR_ADD);
+				cairo_paint_with_alpha (m_cr, m_layerTransparency);
+			}
 		}
 		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
 #else
@@ -995,6 +1014,58 @@
 }
 
 #ifdef HAVE_CAIRO
+
+cairo_pattern_t * ScPainter::getMaskPattern()
+{
+	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();
+	if (mask_gradient.type() == VGradient::linear)
+		pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
+	else
+		pat = cairo_pattern_create_radial (x1, y1, 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);
+	return pat;
+}
+
 void ScPainter::drawVPath( int mode )
 {
 	cairo_save( m_cr );
@@ -1008,58 +1079,11 @@
 		{
 			double r, g, b;
 			m_fill.getRgbF(&r, &g, &b);
-/*
-	Experimental Code for testing gradient masks. */
 			if (maskMode == 1)
 			{
 				cairo_set_source_rgb( m_cr, r, g, b );
 				cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-				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();
-				if (mask_gradient.type() == VGradient::linear)
-					pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
-				else
-					pat = cairo_pattern_create_radial (x1, y1, 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_pattern_t *pat = getMaskPattern();
 				cairo_clip_preserve (m_cr);
 				cairo_mask(m_cr, pat);
 				cairo_pattern_destroy (pat);
@@ -1070,10 +1094,6 @@
 				cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
 				cairo_fill_preserve(m_cr);
 			}
-//				cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-//			else
-//				cairo_set_operator(m_cr, CAIRO_OPERATOR_SOURCE);
-//			cairo_fill_preserve( m_cr );
 		}
 		else if (fillMode == 2)
 		{
@@ -1129,52 +1149,7 @@
 			cairo_clip_preserve (m_cr);
 			if (maskMode == 1)
 			{
-				cairo_pattern_t *patM;
-				double x1 = mask_gradient.origin().x();
-				double y1 = mask_gradient.origin().y();
-				double x2 = mask_gradient.vector().x();
-				double y2 = mask_gradient.vector().y();
-				if (mask_gradient.type() == VGradient::linear)
-					patM = cairo_pattern_create_linear (x1, y1,  x2, y2);
-				else
-					patM = cairo_pattern_create_radial (x1, y1, 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 (patM, 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 (patM, &matrix);
+				cairo_pattern_t *patM = getMaskPattern();
 				cairo_mask(m_cr, patM);
 				cairo_pattern_destroy (patM);
 			}
@@ -1207,52 +1182,7 @@
 			cairo_clip_preserve (m_cr);
 			if (maskMode == 1)
 			{
-				cairo_pattern_t *patM;
-				double x1 = mask_gradient.origin().x();
-				double y1 = mask_gradient.origin().y();
-				double x2 = mask_gradient.vector().x();
-				double y2 = mask_gradient.vector().y();
-				if (mask_gradient.type() == VGradient::linear)
-					patM = cairo_pattern_create_linear (x1, y1,  x2, y2);
-				else
-					patM = cairo_pattern_create_radial (x1, y1, 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 (patM, 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 (patM, &matrix);
+				cairo_pattern_t *patM = getMaskPattern();
 				cairo_mask(m_cr, patM);
 				cairo_pattern_destroy (patM);
 			}
@@ -1700,42 +1630,14 @@
 	cairo_surface_destroy (image2);
 	cairo_surface_destroy (image3);
 	cairo_pop_group_to_source (m_cr);
-/*
-	Experimental Code for testing gradient masks, sadly this feature
-	is only possible with cairo.
-	if (fill_trans != 1.0)
+	if (maskMode == 1)
 	{
-		cairo_pattern_t *pat;
-		double x1 = fill_gradient.origin().x();
-		double y1 = fill_gradient.origin().y();
-		double x2 = fill_gradient.vector().x();
-		double y2 = fill_gradient.vector().y();
-		if (fill_gradient.type() == VGradient::linear)
-			pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
-		else
-			pat = cairo_pattern_create_radial (x1, y1, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
-		QList<VColorStop*> colorStops = fill_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_mask(m_cr, pat);
-		cairo_pattern_destroy (pat);
+		cairo_pattern_t *patM = getMaskPattern();
+		cairo_mask(m_cr, patM);
+		cairo_pattern_destroy(patM);
 	}
 	else
-*/
-	cairo_paint_with_alpha (m_cr, fill_trans);
+		cairo_paint_with_alpha (m_cr, fill_trans);
 #else
 /* Working code, sadly we need to create an additional mask image with the same size as the image to be painted */
 	cairo_surface_t *image3;
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(revision 14297)
+++ scribus/pageitem.cpp	(revision 14298)
@@ -1307,6 +1307,7 @@
 		{
 			if (fillBlendmode() != 0)
 				p->endLayer();
+			p->setMaskMode(0);
 			if (itemType()==PathText || itemType()==PolyLine || itemType()==Line)
 				doStroke=false;
 			if ((doStroke) && (!m_Doc->RePos))
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(revision 14297)
+++ scribus/pageitem_textframe.cpp	(revision 14298)
@@ -2618,6 +2618,7 @@
 	{
 		if (fillBlendmode() != 0)
 			p->endLayer();
+		p->setMaskMode(0);
 		if (!m_Doc->RePos)
 		{
 			if (lineBlendmode() != 0)
Index: scribus/plugins/xarimplugin/importxar.cpp
===================================================================
--- scribus/plugins/xarimplugin/importxar.cpp	(revision 14297)
+++ scribus/plugins/xarimplugin/importxar.cpp	(revision 14298)
@@ -1655,7 +1655,7 @@
 			PageItem *item = gc->Elements.at(a);
 			item->setFillColor(gc->FillCol);
 			item->setFillTransparency(gc->FillOpacity);
-//			item->setFillBlendmode(gc->FillBlend);
+			item->setFillBlendmode(gc->FillBlend);
 			item->setLineTransparency(gc->StrokeOpacity);
 			item->setLineWidth(gc->LWidth);
 			item->setLineColor(gc->StrokeCol);
Index: scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(revision 14297)
+++ scribus/plugins/fileloader/scribus150format/scribus150format_save.cpp	(revision 14298)
@@ -1232,6 +1232,10 @@
 		if (item->GrMask > 0)
 		{
 			docu.writeAttribute("GRTYPM", item->GrMask);
+			if (item->mask_gradient.type() == VGradient::radial)
+				docu.writeAttribute("GRMK", 1);
+			else
+				docu.writeAttribute("GRMK", 0);
 			docu.writeAttribute("GRSTARTXM", item->GrMaskStartX);
 			docu.writeAttribute("GRSTARTYM", item->GrMaskStartY);
 			docu.writeAttribute("GRENDXM", item->GrMaskEndX);
Index: scribus/plugins/fileloader/scribus150format/scribus150format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(revision 14297)
+++ scribus/plugins/fileloader/scribus150format/scribus150format.cpp	(revision 14298)
@@ -2865,6 +2865,11 @@
 	bool mirrorXm = attrs.valueAsBool("pMirrorXM", false);
 	bool mirrorYm = attrs.valueAsBool("pMirrorYM", false);
 	currItem->setMaskFlip(mirrorXm, mirrorYm);
+	int grM = attrs.valueAsInt("GRMK", 0);
+	if (grM == 0)
+		currItem->mask_gradient = VGradient(VGradient::linear);
+	else
+		currItem->mask_gradient = VGradient(VGradient::radial);
 	currItem->mask_gradient.clearStops();
 	currItem->GrMask = attrs.valueAsInt("GRTYPM", 0);
 	currItem->GrMaskStartX = attrs.valueAsDouble("GRSTARTXM", 0.0);
Index: scribus/pageitem_desaxe.cpp
===================================================================
--- scribus/pageitem_desaxe.cpp	(revision 14297)
+++ scribus/pageitem_desaxe.cpp	(revision 14298)
@@ -366,6 +366,10 @@
 	{
 		Xml_attr gradientV;
 		gradientV.insert("GRTYPEM", toXMLString(GrMask));
+		if (mask_gradient.type() == VGradient::radial)
+			gradientV.insert("GRMK", "1");
+		else
+			gradientV.insert("GRMK", "0");
 		gradientV.insert("GRSTARTXM", toXMLString(GrMaskStartX));
 		gradientV.insert("GRSTARTYM", toXMLString(GrMaskStartY));
 		gradientV.insert("GRENDXM", toXMLString(GrMaskEndX));
@@ -641,6 +645,11 @@
 			item->GrMaskScale = parseDouble(attr["GRSCALEM"]);
 			item->GrMaskSkew = parseDouble(attr["GRSKEWM"]);
 			item->setGradientMask(attr["GRNAMEM"]);
+			int grM = parseInt(attr["GRMK"]);
+			if (grM == 0)
+				item->mask_gradient = VGradient(VGradient::linear);
+			else
+				item->mask_gradient = VGradient(VGradient::radial);
 			item->mask_gradient.clearStops();
 		}
 		if (tagName=="Gradient")
Index: scribus/scpainter.h
===================================================================
--- scribus/scpainter.h	(revision 14297)
+++ scribus/scpainter.h	(revision 14298)
@@ -125,6 +125,7 @@
 		FPointArray groupClip;
 		bool pushed;
 	};
+	cairo_pattern_t *getMaskPattern();
 #else
 	QPainter painter;
 	QPainterPath m_path;




More information about the scribus-commit mailing list